-- File: Draw3dImpl.mesa -- Last edited by Bier on December 18, 1982 1:32 am -- Author: Eric Bier on July 3, 1983 1:34 pm -- Contents: Some useful combinations of Graphics operations DIRECTORY CoordSys, CSG, CSGGraphics, DisplayList3d, Draw3d, Graphics, Matrix3d, RealFns, SVBoundBox, SVPolygon3d, SVVector2d, SVVector3d; Draw3dImpl: PROGRAM IMPORTS CSGGraphics, Graphics, Matrix3d, RealFns, SVBoundBox, SVPolygon3d, SVVector2d, SVVector3d EXPORTS Draw3d = BEGIN Camera: TYPE = CSGGraphics.Camera; CoordSystem: TYPE = REF CoordSysObj; CoordSysObj: TYPE = CoordSys.CoordSysObj; CSGTree: TYPE = REF CSGTreeObj; CSGTreeObj: TYPE = CSG.CSGTreeObj; MasterObject: TYPE = DisplayList3d.MasterObject; Matrix4by4: TYPE = Matrix3d.Matrix4by4; Point2d: TYPE = Matrix3d.Point2d; Point3d: TYPE = Matrix3d.Point3d; Poly3d: TYPE = SVPolygon3d.Poly3d; Primitive: TYPE = CSG.Primitive; Composite: TYPE = CSG.Composite; Vector: TYPE = SVVector3d.Vector; Vector2d: TYPE = SVVector2d.Vector2d; DrawCoordSys: PUBLIC PROC [dc: Graphics.Context, mat: Matrix4by4, camera: Camera] = { origin: Point3d; XAxis, YAxis, ZAxis: Vector; -- assume that mat is a CAMERA to LOCAL transform matrix -- The last column of a homogenous transform, is the origin of the coordinate system it represents in terms of the world coord system. origin[1] _ mat[1][4]; origin[2] _ mat[2][4]; origin[3] _ mat[3][4]; -- The columns correspond to the directional vectors of the mat coord system. XAxis _ [mat[1][1],mat[2][1],mat[3][1]]; YAxis _ [mat[1][2],mat[2][2],mat[3][2]]; ZAxis _ [mat[1][3],mat[2][3],mat[3][3]]; DrawVector[dc, XAxis, origin, camera]; Graphics.DrawChar[dc,'x]; DrawVector[dc, YAxis, origin, camera]; Graphics.DrawChar[dc,'y]; DrawVector[dc, ZAxis, origin, camera]; Graphics.DrawChar[dc,'z]; }; -- Could be faster if I expand out the Draw Vectors internally. DrawVector: PUBLIC PROC [dc: Graphics.Context, v: Vector, origin: Point3d, camera: Camera] = { -- assumes vector is in camera coordinates VectorEnd: Point3d; leftBarb, rightBarb, v50, v90: Vector; leftBarb2d, rightBarb2d, v2d: Vector2d; v _ SVVector3d.Normalize[v]; v50 _ SVVector3d.Scale[v, 50]; VectorEnd _ SVVector3d.Add[origin,v50]; -- the barbs on the arrow head are of length 10 and shoot off at 45 degrees from the vector, parallel to the xy plane. To find them, we project v onto the xy plane and rotate 45 degrees. v2d _ SVVector3d.ProjectOntoXYPlane[v50]; rightBarb2d _ SVVector2d.VectorPlusAngle[v2d, 135]; leftBarb2d _ SVVector2d.VectorPlusAngle[v2d, -135]; rightBarb _ SVVector3d.Vector2DAsXYVector[rightBarb2d]; rightBarb _ SVVector3d.Scale[rightBarb, 10]; leftBarb _ SVVector3d.Vector2DAsXYVector[leftBarb2d]; leftBarb _ SVVector3d.Scale[leftBarb, 10]; -- rear facing vectors are shown with barbs IF v[3] < 0 THEN { CSGGraphics.SetCPAbsolute[dc, origin, camera]; CSGGraphics.DrawToAbsolute[dc, VectorEnd, camera]; CSGGraphics.DrawToAbsolute[dc, SVVector3d.Add[VectorEnd, rightBarb], camera]; CSGGraphics.SetCPAbsolute[dc, VectorEnd, camera]; CSGGraphics.DrawToAbsolute[dc, SVVector3d.Add[VectorEnd, leftBarb], camera]; } -- forward facing vectors have filled-in tips. ELSE { headPoly: Poly3d _ SVPolygon3d.CreatePoly[3]; CSGGraphics.SetCPAbsolute[dc, origin, camera]; CSGGraphics.DrawToAbsolute[dc, VectorEnd, camera]; headPoly _ SVPolygon3d.AddPolyPoint[headPoly, VectorEnd]; headPoly _ SVPolygon3d.AddPolyPoint[headPoly, SVVector3d.Add[VectorEnd, rightBarb]]; headPoly _ SVPolygon3d.AddPolyPoint[headPoly, SVVector3d.Add[VectorEnd, leftBarb]]; CSGGraphics.DrawAreaAbsolute[dc, headPoly, camera]; }; v90 _ SVVector3d.Scale[v, 90]; CSGGraphics.SetCPAbsolute[dc, SVVector3d.Add[origin, v90], camera]; -- prepare to draw a character after this vector }; DrawForwardVector: PUBLIC PROC [dc: Graphics.Context, v: Vector, origin: Point3d, camera: Camera] = { -- assumes vector is in camera coordinates VectorEnd: Point3d; leftBarb, rightBarb: Vector; leftBarb2d, rightBarb2d, v2d: Vector2d; v _ SVVector3d.Normalize[v]; v _ SVVector3d.Scale[v, 50]; VectorEnd _ SVVector3d.Add[origin,v]; -- the barbs on the arrow head are of length 10 and shoot off at 45 degrees from the vector, parallel to the xy plane. To find them, we project v onto the xy plane and rotate 45 degrees. v2d _ SVVector3d.ProjectOntoXYPlane[v]; rightBarb2d _ SVVector2d.VectorPlusAngle[v2d, 135]; leftBarb2d _ SVVector2d.VectorPlusAngle[v2d, -135]; rightBarb _ SVVector3d.Vector2DAsXYVector[rightBarb2d]; rightBarb _ SVVector3d.Scale[rightBarb, 10]; leftBarb _ SVVector3d.Vector2DAsXYVector[leftBarb2d]; leftBarb _ SVVector3d.Scale[leftBarb, 10]; -- rear facing vectors are shown with barbs IF v[3] < 0 THEN { --CSGGraphics.MoveToAbsolute[dc, origin, camera]; --CSGGraphics.DrawToAbsolute[dc, VectorEnd, camera]; --CSGGraphics.DrawToAbsolute[dc, SVVector3d.Add[VectorEnd, rightBarb], camera]; --CSGGraphics.MoveToAbsolute[dc, VectorEnd, camera]; --CSGGraphics.DrawToAbsolute[dc, SVVector3d.Add[VectorEnd, leftBarb], camera]; } -- forward facing vectors have filled-in tips. ELSE { headPoly: Poly3d _ SVPolygon3d.CreatePoly[3]; CSGGraphics.SetCPAbsolute[dc, origin, camera]; CSGGraphics.DrawToAbsolute[dc, VectorEnd, camera]; headPoly _ SVPolygon3d.AddPolyPoint[headPoly, VectorEnd]; headPoly _ SVPolygon3d.AddPolyPoint[headPoly, SVVector3d.Add[VectorEnd, rightBarb]]; headPoly _ SVPolygon3d.AddPolyPoint[headPoly, SVVector3d.Add[VectorEnd, leftBarb]]; CSGGraphics.DrawAreaAbsolute[dc, headPoly, camera]; }; }; DrawLocalVector: PUBLIC PROC [dc: Graphics.Context, v: Vector, origin: Point3d, camera: Camera, localCS: CoordSystem] = { -- assumes v and origin are in localCS coords. vCamera: Vector _ Matrix3d.UpdateVectorWithInverse[localCS.cameraWRTlocal, v]; originCamera: Point3d _ Matrix3d.Update[localCS.wrtCamera, origin]; vCamera _ SVVector3d.Normalize[vCamera]; vCamera _ SVVector3d.Scale[vCamera, 50]; DrawVector[dc, vCamera, originCamera, camera]; }; Draw2dVector: PUBLIC PROC [dc: Graphics.Context, vec: Vector2d, at: Point2d] = { unitVec, vec50: Vector2d; mag: REAL; mag _ RealFns.SqRt[vec[1]*vec[1] + vec[2]*vec[2]]; unitVec[1] _ vec[1]/mag; unitVec[2] _ vec[2]/mag; vec50[1] _ unitVec[1]*50; vec50[2] _ unitVec[2]*50; Graphics.SetCP[dc, at[1], at[2]]; Graphics.DrawTo[dc, at[1]+vec50[1], at[2]+vec50[2]]; }; -- end of Draw2dVector Draw2dCoordSys: PUBLIC PROC [dc: Graphics.Context, origin: Point2d, camera: Camera] = { CSGGraphics.SetCPAbsolute[dc, [-1000, origin[2],0], camera]; CSGGraphics.DrawToAbsolute[dc, [1000, origin[2],0], camera]; CSGGraphics.SetCPAbsolute[dc, [origin[1], -1000,0], camera]; CSGGraphics.DrawToAbsolute[dc, [origin[1], 1000,0], camera]; }; -- assumes Point2d in CAMERA coords DrawX: PUBLIC PROC [dc: Graphics.Context, point: Point2d, camera: Camera] = { halfWidthOfX, halfHeightOfX: REAL; halfWidthOfX _ 10; halfHeightOfX _ 10; CSGGraphics.SetCPAbsolute[dc, [point[1]-halfWidthOfX, point[2]+halfHeightOfX, 0], camera]; CSGGraphics.DrawToAbsolute[dc, [point[1]+halfWidthOfX, point[2]-halfHeightOfX, 0], camera]; CSGGraphics.SetCPAbsolute[dc, [point[1]+halfWidthOfX, point[2]+halfHeightOfX, 0],camera]; CSGGraphics.DrawToAbsolute[dc, [point[1]-halfWidthOfX, point[2]-halfHeightOfX, 0], camera]; }; -- assumes point in CAMERA coords DrawBoundBoxes: PUBLIC PROC [dc: Graphics.Context, tree: CSGTree, camera: Camera] = { DrawNode[dc, tree.son, camera]; }; DrawNode: PRIVATE PROC [dc: Graphics.Context, node: REF ANY, camera: Camera] = { WITH node SELECT FROM prim: Primitive => {mo: MasterObject; SVBoundBox.DrawBoundBox[dc, prim.boundBox, camera.screenCS]; mo _ NARROW[prim.mo]; mo.class.drawSubBoxes[dc, prim, camera.screenCS]; }; comp: Composite => {DrawNode[dc, comp.leftSolid, camera]; DrawNode[dc, comp.rightSolid, camera]; SVBoundBox.DrawBoundBox[dc, comp.boundBox, camera.screenCS]; }; ENDCASE => ERROR; }; -- end of DrawNode END. Κ’– "Mesa" style˜Iprocš¬Οc·œΟk œ žœŒžœžœ\žœ žœ žœ$žœžœžœ"žœžœžœžœJžœ!žœžœžœ"žœžœžœžœžœ žœΟn œžœžœn9œ‡œINœΞ@œŸ œžœžœI+œΞΌœΰ,œžœ žœΘ/œžœ»1œŸœžœžœI+œΐΌœή,œžœ žœΤ/œžœΧŸœžœžœ^0œŸŸ œžœžœYžœύœŸœžœžœΉ$œŸœžœžœZžœŸ"œŸœžœžœbŸœžœžœžœžœžœžœžœνžœžœœžœ˜ώ>—…—€!(