File: SVDraw3dImpl.mesa
Last edited by Bier on December 18, 1982 1:19 am
Author: Eric Bier on August 1, 1985 0:25:48 am PDT
Reconstructed from memory on July 18, 1985 1:02:55 pm PDT
Contents: Some useful combinations of Imager operations
DIRECTORY
CoordSys,
CSGGraphics,
Imager,
SVMatrix2d,
Matrix3d,
SV2d,
SV3d,
SVBoundBox,
SVBoundSphere,
SVDraw3d,
SVModelTypes,
SVRayTypes,
SVVector2d,
SVVector3d;
SVDraw3dImpl: PROGRAM
IMPORTS CoordSys, CSGGraphics, Imager, SVBoundBox, SVBoundSphere, Matrix3d, SVVector2d, SVVector3d
EXPORTS SVDraw3d =
BEGIN
Camera: TYPE = SVModelTypes.Camera;
Composite: TYPE = SVRayTypes.Composite;
CoordSystem: TYPE = SVModelTypes.CoordSystem;
CSGTree: TYPE = SVRayTypes.CSGTree;
Matrix4by4: TYPE = SV3d.Matrix4by4;
Point2d: TYPE = SV2d.Point2d;
Point3d: TYPE = SV3d.Point3d;
Primitive: TYPE = SVRayTypes.Primitive;
Vector: TYPE = SV3d.Vector;
Vector2d: TYPE = SV2d.Vector2d;
DrawCoordSys: PUBLIC PROC [dc: Imager.Context, csCAMERA: Matrix4by4, camera: Camera] = {
origin: Point3d;
xAxis, yAxis, zAxis: Vector;
length: REAL = 50.0;
origin ← Matrix3d.OriginOfMatrix[csCAMERA];
xAxis ← SVVector3d.Normalize[Matrix3d.XAxisOfMatrix[csCAMERA]];
yAxis ← SVVector3d.Normalize[Matrix3d.YAxisOfMatrix[csCAMERA]];
zAxis ← SVVector3d.Normalize[Matrix3d.ZAxisOfMatrix[csCAMERA]];
xAxis ← SVVector3d.Scale[xAxis, length];
yAxis ← SVVector3d.Scale[yAxis, length];
zAxis ← SVVector3d.Scale[zAxis, length];
DrawVector[dc, xAxis, origin, camera];
CSGGraphics.DrawChar[dc, 'x, camera];
DrawVector[dc, yAxis, origin, camera];
CSGGraphics.DrawChar[dc, 'y, camera];
DrawVector[dc, zAxis, origin, camera];
CSGGraphics.DrawChar[dc, 'z, camera];
};
DrawTargetCoordSys: PUBLIC PROC [dc: Imager.Context, csCAMERA: Matrix4by4, camera: Camera] = {
origin: Point3d;
xAxis, yAxis, zAxis: Vector;
upLeftVector, upRightVector, downRightVector, downLeftVector: Vector;
length: REAL = 50.0;
scalar: REAL = 0.8;
origin ← Matrix3d.OriginOfMatrix[csCAMERA];
xAxis ← SVVector3d.Normalize[Matrix3d.XAxisOfMatrix[csCAMERA]];
yAxis ← SVVector3d.Normalize[Matrix3d.YAxisOfMatrix[csCAMERA]];
zAxis ← SVVector3d.Normalize[Matrix3d.ZAxisOfMatrix[csCAMERA]];
xAxis ← SVVector3d.Scale[xAxis, length];
yAxis ← SVVector3d.Scale[yAxis, length];
zAxis ← SVVector3d.Scale[zAxis, length];
DrawVector[dc, xAxis, origin, camera];
CSGGraphics.DrawChar[dc, 'x, camera];
DrawVector[dc, yAxis, origin, camera];
CSGGraphics.DrawChar[dc, 'y, camera];
DrawVector[dc, zAxis, origin, camera];
CSGGraphics.DrawChar[dc, 'z, camera];
Now draw the landing pad (in the z = 0 plane).
upLeftVector ← SVVector3d.Sub[yAxis, xAxis];
upRightVector ← SVVector3d.Add[yAxis, xAxis];
downRightVector ← SVVector3d.Negate[upLeftVector];
downLeftVector ← SVVector3d.Negate[upRightVector];
upLeftVector ← SVVector3d.Scale[upLeftVector, scalar];
upRightVector ← SVVector3d.Scale[upRightVector, scalar];
downRightVector ← SVVector3d.Scale[downRightVector, scalar];
downLeftVector ← SVVector3d.Scale[downLeftVector, scalar];
CSGGraphics.SetCPAbsolute[dc, SVVector3d.Add[origin, upLeftVector], camera];
CSGGraphics.DrawToAbsolute[dc, SVVector3d.Add[origin, upRightVector], camera];
CSGGraphics.DrawToAbsolute[dc, SVVector3d.Add[origin, downRightVector], camera];
CSGGraphics.DrawToAbsolute[dc, SVVector3d.Add[origin, downLeftVector], camera];
CSGGraphics.DrawToAbsolute[dc, SVVector3d.Add[origin, upLeftVector], camera];
};
DrawJack: PUBLIC PROC [dc: Imager.Context, cs: CoordSystem, camera: Camera] = {
csCAMERA: Matrix4by4 ← CoordSys.FindInTermsOfCamera[cs, camera.coordSys];
DrawCoordSys[dc, csCAMERA, camera];
};
DrawMovee: PUBLIC PROC [dc: Imager.Context, cs: CoordSystem, camera: Camera] = {
origin: Point3d;
xAxis, yAxis, zAxis: Vector;
csCAMERA: Matrix4by4 ← CoordSys.FindInTermsOfCamera[cs, camera.coordSys];
upLeftVector, upRightVector, downRightVector, downLeftVector: Vector;
length: REAL = 50.0;
scalar: REAL = 0.2;
origin ← Matrix3d.OriginOfMatrix[csCAMERA];
xAxis ← SVVector3d.Normalize[Matrix3d.XAxisOfMatrix[csCAMERA]];
yAxis ← SVVector3d.Normalize[Matrix3d.YAxisOfMatrix[csCAMERA]];
zAxis ← SVVector3d.Normalize[Matrix3d.ZAxisOfMatrix[csCAMERA]];
xAxis ← SVVector3d.Scale[xAxis, length];
yAxis ← SVVector3d.Scale[yAxis, length];
zAxis ← SVVector3d.Scale[zAxis, length];
DrawVector[dc, xAxis, origin, camera];
CSGGraphics.DrawChar[dc, 'x, camera];
DrawVector[dc, yAxis, origin, camera];
CSGGraphics.DrawChar[dc, 'y, camera];
DrawVector[dc, zAxis, origin, camera];
CSGGraphics.DrawChar[dc, 'z, camera];
Now draw the landing pad (in the z = 0 plane).
upLeftVector ← SVVector3d.Sub[yAxis, xAxis];
upRightVector ← SVVector3d.Add[yAxis, xAxis];
downRightVector ← SVVector3d.Negate[upLeftVector];
downLeftVector ← SVVector3d.Negate[upRightVector];
upLeftVector ← SVVector3d.Scale[upLeftVector, scalar];
upRightVector ← SVVector3d.Scale[upRightVector, scalar];
downRightVector ← SVVector3d.Scale[downRightVector, scalar];
downLeftVector ← SVVector3d.Scale[downLeftVector, scalar];
CSGGraphics.SetCPAbsolute[dc, SVVector3d.Add[origin, upLeftVector], camera];
CSGGraphics.DrawToAbsolute[dc, SVVector3d.Add[origin, upRightVector], camera];
CSGGraphics.DrawToAbsolute[dc, SVVector3d.Add[origin, downRightVector], camera];
CSGGraphics.DrawToAbsolute[dc, SVVector3d.Add[origin, downLeftVector], camera];
CSGGraphics.DrawToAbsolute[dc, SVVector3d.Add[origin, upLeftVector], camera];
};
DrawPlaneSelection: PUBLIC PROC [dc: Imager.Context, cs: CoordSystem, planeNum: NAT, camera: Camera] = {
origin: Point3d;
csCAMERA: Matrix4by4 ← CoordSys.FindInTermsOfCamera[cs, camera.coordSys];
xAxis, yAxis, zAxis: Vector;
tightRopeStart, tightRopeEnd: Point3d;
upLeftVector, upRightVector, downRightVector, downLeftVector: Vector;
length: REAL = 50.0;
SELECT planeNum FROM
1 => { -- x = 0 plane
csCAMERA ← Matrix3d.LocalRotateAboutYAxis[csCAMERA, -90];
};
2 => { -- y = 0 plane
csCAMERA ← Matrix3d.LocalRotateAboutXAxis[csCAMERA, 90];
};
3 => { -- z = 0 plane
};
ENDCASE => ERROR;
origin ← Matrix3d.OriginOfMatrix[csCAMERA];
xAxis ← SVVector3d.Normalize[Matrix3d.XAxisOfMatrix[csCAMERA]];
yAxis ← SVVector3d.Normalize[Matrix3d.YAxisOfMatrix[csCAMERA]];
zAxis ← SVVector3d.Normalize[Matrix3d.ZAxisOfMatrix[csCAMERA]];
xAxis ← SVVector3d.Scale[xAxis, length];
yAxis ← SVVector3d.Scale[yAxis, length];
zAxis ← SVVector3d.Scale[zAxis, length];
Now draw the landing pad (in the z = 0 plane).
upLeftVector ← SVVector3d.Sub[yAxis, xAxis];
upRightVector ← SVVector3d.Add[yAxis, xAxis];
downRightVector ← SVVector3d.Negate[upLeftVector];
downLeftVector ← SVVector3d.Negate[upRightVector];
CSGGraphics.SetCPAbsolute[dc, SVVector3d.Add[origin, upLeftVector], camera];
CSGGraphics.DrawToAbsolute[dc, SVVector3d.Add[origin, upRightVector], camera];
CSGGraphics.DrawToAbsolute[dc, SVVector3d.Add[origin, downRightVector], camera];
CSGGraphics.DrawToAbsolute[dc, SVVector3d.Add[origin, downLeftVector], camera];
CSGGraphics.DrawToAbsolute[dc, SVVector3d.Add[origin, upLeftVector], camera];
Now draw the tightrope (along the z axis).
tightRopeStart ← SVVector3d.Sub[origin, zAxis];
tightRopeEnd ← SVVector3d.Add[origin, zAxis];
CSGGraphics.SetCPAbsolute[dc, tightRopeStart, camera];
CSGGraphics.DrawToAbsolute[dc, tightRopeEnd, camera];
};
DrawXPlane: PUBLIC PROC [dc: Imager.Context, left, right, down, up: REAL, cs: CoordSystem, camera: Camera] = {
Draw the square bounded by left, right, down, and up (left-right = z, down-up = y) in the x = 0 plane of cs. In other words, draw the square [left, up], [right, up], [right, down], [left, down] defined in the coordinates of cs.
CSGGraphics.SetCP[dc, [0, up, left], camera, cs];
CSGGraphics.DrawTo[dc, [0, up, right], camera, cs];
CSGGraphics.DrawTo[dc, [0, down, right], camera, cs];
CSGGraphics.DrawTo[dc, [0, down, left], camera, cs];
CSGGraphics.DrawTo[dc, [0, up, left], camera, cs];
};
DrawYPlane: PUBLIC PROC [dc: Imager.Context, left, right, down, up: REAL, cs: CoordSystem, camera: Camera];
Draw the square bounded by left, right, down, and up (left-right = x, down-up = z) in the y = 0 plane of cs.
DrawZPlane: PUBLIC PROC [dc: Imager.Context, left, right, down, up: REAL, cs: CoordSystem, camera: Camera];
Draw the square bounded by left, right, down, and up (left-right = x, down-up = y) in the z = 0 plane of cs.
DrawVector: PUBLIC PROC [dc: Imager.Context, v: Vector, origin: Point3d, camera: Camera] = {
Assumes v and origin are in camera coords.
tip: Point3d;
originOnScreen, tipOnScreen, textOnScreen: Point2d;
vProjected: Vector2d;
mag: REAL;
epsilon: REAL = 1.0e-3;
tip ← SVVector3d.Add[origin, v];
CSGGraphics.SetCPAbsolute[dc, origin, camera];
CSGGraphics.DrawToAbsolute[dc, tip, camera];
Now set current position in case the caller wants to draw a character after this vector.
originOnScreen ← CSGGraphics.DoProjection[origin, camera];
tipOnScreen ← CSGGraphics.DoProjection[tip, camera];
vProjected ← SVVector2d.Sub[tipOnScreen, originOnScreen];
mag ← SVVector2d.Magnitude[vProjected];
IF mag < epsilon THEN vProjected ← [-7.0, 0.0]
ELSE vProjected ← SVVector2d.Scale[vProjected, 7.0/mag];
textOnScreen ← SVVector2d.Add[tipOnScreen, vProjected];
CSGGraphics.SetCPAbsolute[dc, [textOnScreen[1], textOnScreen[2], 0.0], camera];
};
DrawLocalVector: PUBLIC PROC [dc: Imager.Context, v: Vector, origin: Point3d, camera: Camera, localCS: CoordSystem] = {
Assumes v and origin are in localCS coords.
tip: Point3d;
tip ← SVVector3d.Add[origin, v];
CSGGraphics.SetCP[dc, origin, camera, localCS];
CSGGraphics.DrawTo[dc, tip, camera, localCS];
};
Draw2dCoordSys: PUBLIC PROC [dc: Imager.Context, origin: Point2d, camera: Camera] = {
Poorly named. This function draws cross hairs. origin is in camera coordinates.
originScreen: Point2d;
big: REAL = 9999.0;
originScreen ← CoordSys.CameraToScreen[origin, camera.screenCS];
Imager.MaskVector[dc, [originScreen[1]-big, originScreen[2]],
[originScreen[1]+big, originScreen[2]]];
Imager.MaskVector[dc, [originScreen[1], originScreen[2] + big], [originScreen[1], originScreen[2] - big]];
};
DrawX: PUBLIC PROC [dc: Imager.Context, point: Point2d, camera: Camera] = {
Used by Draw Point to indicate a point of interest. Would be in SVDraw, except that the point is in camera coordinates.
origin: Point2d;
side: REAL ← 7.0;
origin ← CoordSys.CameraToScreen[point, camera.screenCS];
Imager.MaskVector[dc, [origin[1]-side, origin[2] + side], [origin[1]+side, origin[2] - side]];
Imager.MaskVector[dc, [origin[1] + side, origin[2] + side], [origin[1]-side, origin[2] - side]];
};
DrawBoundBoxes: PUBLIC PROC [dc: Imager.Context, tree: CSGTree, camera: Camera] = {
DrawBoundBoxNode[dc, tree.son, camera];
};
DrawBoundBoxNode: PROC [dc: Imager.Context, node: REF ANY, camera: Camera] = {
IF node = NIL THEN RETURN;
WITH node SELECT FROM
composite: Composite => {
SVBoundBox.DrawBoundBox[dc, composite.boundBox, camera.screenCS];
DrawBoundBoxNode[dc, composite.leftSolid, camera];
DrawBoundBoxNode[dc, composite.rightSolid, camera];
};
prim: Primitive => {
SVBoundBox.DrawBoundBox[dc, prim.boundBox, camera.screenCS];
};
ENDCASE => ERROR;
};
DrawBoundBox: PUBLIC PROC [dc: Imager.Context, node: REF ANY, camera: Camera, xor: BOOL] = {};
DrawBoundSpheres: PUBLIC PROC [dc: Imager.Context, tree: CSGTree, camera: Camera] = {
DrawBoundSphereNode[dc, tree.son, camera];
};
DrawBoundSphereNode: PROC [dc: Imager.Context, node: REF ANY, camera: Camera] = {
IF node = NIL THEN RETURN;
WITH node SELECT FROM
composite: Composite => {
SVBoundSphere.DrawBoundSphere[dc, composite.boundSphere, camera];
DrawBoundSphereNode[dc, composite.leftSolid, camera];
DrawBoundSphereNode[dc, composite.rightSolid, camera];
};
prim: Primitive => {
SVBoundSphere.DrawBoundSphere[dc, prim.boundSphere, camera];
};
ENDCASE => ERROR;
};
END.