SimpleCubeFromPairs:
PUBLIC
PROC [
context: Context,
pairs: OctantPairs,
cube: Cube ¬ NIL,
drawType: DrawType ¬ dashed]
~ {
IF cube #
NIL
THEN {
l: Cube ~ G3dOctree.FaceNeighbor[cube, l];
r: Cube ~ G3dOctree.FaceNeighbor[cube, r];
b: Cube ~ G3dOctree.FaceNeighbor[cube, b];
t: Cube ~ G3dOctree.FaceNeighbor[cube, t];
n: Cube ~ G3dOctree.FaceNeighbor[cube, n];
f: Cube ~ G3dOctree.FaceNeighbor[cube, f];
rf: Cube ~ IF r # NIL THEN G3dOctree.FaceNeighbor[r, f] ELSE G3dOctree.FaceNeighbor[f, r];
rt: Cube ~ IF r # NIL THEN G3dOctree.FaceNeighbor[r, t] ELSE G3dOctree.FaceNeighbor[t, r];
tf: Cube ~ IF t # NIL THEN G3dOctree.FaceNeighbor[t, f] ELSE G3dOctree.FaceNeighbor[f, t];
Draw2d.Line[context, pairs[lbn], pairs[lbf], drawType]; -- lb
Draw2d.Line[context, pairs[lbn], pairs[ltn], drawType]; -- ln
Draw2d.Line[context, pairs[lbn], pairs[rbn], drawType]; -- bn
IF rf=NIL THEN Draw2d.Line[context, pairs[rbf], pairs[rtf], drawType]; -- rf
IF rt=NIL THEN Draw2d.Line[context, pairs[rtn], pairs[rtf], drawType]; -- rt
IF tf=NIL THEN Draw2d.Line[context, pairs[ltf], pairs[rtf], drawType]; -- tf
IF l=NIL AND t=NIL THEN Draw2d.Line[context, pairs[ltn], pairs[ltf], drawType]; -- lt
IF l=NIL AND f=NIL THEN Draw2d.Line[context, pairs[lbf], pairs[ltf], drawType]; -- lf
IF t=NIL AND n=NIL THEN Draw2d.Line[context, pairs[ltn], pairs[rtn], drawType];-- tn
IF b=NIL AND f=NIL THEN Draw2d.Line[context, pairs[lbf], pairs[rbf], drawType];-- bf
IF r=NIL AND n=NIL THEN Draw2d.Line[context, pairs[rbn], pairs[rtn], drawType];--rn
IF r=NIL AND b=NIL THEN Draw2d.Line[context, pairs[rbn], pairs[rbf], drawType];--rb
}
ELSE {
Draw2d.Line[context, pairs[lbn], pairs[lbf], drawType]; -- lb edge
Draw2d.Line[context, pairs[ltn], pairs[ltf], drawType]; -- lt edge
Draw2d.Line[context, pairs[lbn], pairs[ltn], drawType]; -- ln edge
Draw2d.Line[context, pairs[lbf], pairs[ltf], drawType]; -- lf edge
Draw2d.Line[context, pairs[lbn], pairs[rbn], drawType]; -- bn edge
Draw2d.Line[context, pairs[ltn], pairs[rtn], drawType]; -- tn edge
Draw2d.Line[context, pairs[lbf], pairs[rbf], drawType]; -- bf edge
Draw2d.Line[context, pairs[ltf], pairs[rtf], drawType]; -- tf edge
Draw2d.Line[context, pairs[rbn], pairs[rtn], drawType]; -- rn edge
Draw2d.Line[context, pairs[rbf], pairs[rtf], drawType]; -- rf edge
Draw2d.Line[context, pairs[rbn], pairs[rbf], drawType]; -- rb edge
Draw2d.Line[context, pairs[rtn], pairs[rtf], drawType]; -- rt edge
};
};
FaceOnly:
PUBLIC
PROC [
context: Context,
cube: Cube,
face: Face,
view: Matrix,
viewport: Viewport ¬ [],
drawType: DrawType ¬ dashed]
~ {
VP:
PROC [p: Pair]
RETURNS [x: Pair] ~ {
x ¬ [viewport.scale.x*p.x+viewport.translate.x, viewport.scale.y*p.y+viewport.translate.y];
};
corners: Corners ~ cube.corners;
faceCorners:
ARRAY [0..4)
OF Corner ¬
SELECT face
FROM
l => [corners[lbn], corners[lbf], corners[ltf], corners[ltn]],
r => [corners[rbn], corners[rbf], corners[rtf], corners[rtn]],
b => [corners[lbn], corners[lbf], corners[rbf], corners[rbn]],
t => [corners[ltn], corners[ltf], corners[rtf], corners[rtn]],
n => [corners[lbn], corners[ltn], corners[rtn], corners[rbn]],
ENDCASE => [corners[lbf], corners[ltf], corners[rtf], corners[rbf]];
p0: Pair ¬ VP[G3dMatrix.TransformD[faceCorners[3].point, view]];
FOR n:
NAT
IN [0..4)
DO
p1: Pair ¬ VP[G3dMatrix.TransformD[faceCorners[n].point, view]];
Draw2d.Line[context, p0, p1, drawType];
p0 ¬ p1;
ENDLOOP;
};
FancyCubeFromPairs:
PUBLIC
PROC [
context: Context,
pairs: DirectionPairs,
cornerConnect: DrawType ¬ solid,
edgeConnect: DrawType ¬ dashed,
faceConnect: DrawType ¬ dotted,
label: BOOL ¬ TRUE]
~ {
Draw2d.Line[context, pairs[lbn], pairs[rbn], cornerConnect]; -- left to right edges:
Draw2d.Line[context, pairs[lbf], pairs[rbf], cornerConnect];
Draw2d.Line[context, pairs[ltn], pairs[rtn], cornerConnect];
Draw2d.Line[context, pairs[ltf], pairs[rtf], cornerConnect];
Draw2d.Line[context, pairs[lb], pairs[rb], edgeConnect];
Draw2d.Line[context, pairs[lt], pairs[rt], edgeConnect];
Draw2d.Line[context, pairs[ln], pairs[rn], edgeConnect];
Draw2d.Line[context, pairs[lf], pairs[rf], edgeConnect];
Draw2d.Line[context, pairs[l], pairs[r], faceConnect];
Draw2d.Line[context, pairs[lbn], pairs[ltn], cornerConnect]; -- bottom to top edges:
Draw2d.Line[context, pairs[rbn], pairs[rtn], cornerConnect];
Draw2d.Line[context, pairs[lbf], pairs[ltf], cornerConnect];
Draw2d.Line[context, pairs[rbf], pairs[rtf], cornerConnect];
Draw2d.Line[context, pairs[lb], pairs[lt], edgeConnect];
Draw2d.Line[context, pairs[rb], pairs[rt], edgeConnect];
Draw2d.Line[context, pairs[bn], pairs[tn], edgeConnect];
Draw2d.Line[context, pairs[bf], pairs[tf], edgeConnect];
Draw2d.Line[context, pairs[b], pairs[t], faceConnect];
Draw2d.Line[context, pairs[lbn], pairs[lbf], cornerConnect]; -- near to far edges:
Draw2d.Line[context, pairs[rbn], pairs[rbf], cornerConnect];
Draw2d.Line[context, pairs[ltn], pairs[ltf], cornerConnect];
Draw2d.Line[context, pairs[rtn], pairs[rtf], cornerConnect];
Draw2d.Line[context, pairs[ln], pairs[lf], edgeConnect];
Draw2d.Line[context, pairs[rn], pairs[rf], edgeConnect];
Draw2d.Line[context, pairs[bn], pairs[bf], edgeConnect];
Draw2d.Line[context, pairs[tn], pairs[tf], edgeConnect];
Draw2d.Line[context, pairs[n], pairs[f], faceConnect];
IF label THEN LabelDirections[context, pairs];
};
Neighbors:
PUBLIC
PROC [
context: Context,
neighborhood: Neighborhood,
view: Matrix,
viewport: Viewport ¬ [],
drawType: DrawType ¬ dashed]
~ {
DirectionsToCheck:
PROC [direction: Direction]
RETURNS [directionsToCheck: ARRAY Face OF Direction] ~ {
directionsToCheck ¬
SELECT direction
FROM
center:
c => [l, r, b, t, n, f],
six face neighbors:
l => [none, c, lb, lt, ln, lf],
r => [c, none, rb, rt, rn, rf],
b => [lb, rb, none, c, bn, bf],
t => [lt, rt, c, none, tn, tf],
n => [ln, rn, bn, tn, none, c],
f => [lf, rf, bf, tf, c, none],
twelve edge neighbors:
lb => [none, b, none, l, lbn, lbf],
lt => [none, t, l, none, ltn, ltf],
ln => [none, n, lbn, ltn, none, l],
lf => [none, f, lbf, ltf, l, none],
rb => [b, none, none, r, rbn, rbf],
rt => [t, none, r, none, rtn, rtf],
rn => [n, none, rbn, rtn, none, r],
rf => [f, none, rbf, rtf, r, none],
bn => [lbn, rbn, none, n, none, b],
bf => [lbf, rbf, none, f, b, none],
tn => [ltn, rtn, n, none, none, t],
tf => [ltf, rtf, f, none, t, none],
eight corner neighbors:
lbn => [none, bn, none, ln, none, lb],
lbf => [none, bf, none, lf, lb, none],
ltn => [none, tn, ln, none, none, lt],
ltf => [none, tf, lf, none, lt, none],
rbn => [bn, none, none, rn, none, rb],
rbf => [bf, none, none, rf, rb, none],
rtn => [tn, none, rn, none, none, rt],
rtf => [tf, none, rf, none, rt, none],
ENDCASE => [none, none, none, none, none, none];
};
visible: ARRAY Face OF BOOL;
visible[r] ¬ NOT(visible[l] ¬ G3dVector.FrontFacingNoPerspective[[-1, 0, 0], view]);
visible[t] ¬ NOT(visible[b] ¬ G3dVector.FrontFacingNoPerspective[[0, -1, 0], view]);
visible[f] ¬ NOT(visible[n] ¬ G3dVector.FrontFacingNoPerspective[[0, 0, -1], view]);
FOR direction: Direction
IN Direction
DO
cube: Cube ~ neighborhood[direction];
IF cube #
NIL
THEN {
directionsToCheck: ARRAY Face OF Direction ¬ DirectionsToCheck[direction];
FOR face: Face
IN Face
DO
IF visible[face]
THEN {
check: Direction ¬ directionsToCheck[face];
IF check = none
OR neighborhood[check] =
NIL
THEN FaceOnly[context, cube, face, view, viewport, drawType];
};
ENDLOOP;
};
ENDLOOP;
};