File: CoordFrames.tioga
Last Edited by: Bier, June 18, 1984 1:41:21 pm PDT
Coordinate Frames, Cameras, Interaction and Caching:
A New Coordinate Frame Package for Solidviews
Issues
A coordinate frame package must:
1) Be Simple.
2) Be Robust
3) Be Powerful.
4) Be Fast.
5) Support Instancing.
6) Support Multiple Views.
The Solidviews coordinate frame package was designed to support the above goals. Several main design questions arose:
1) Which parts of the Solidviews data structures are viewpoint dependent (and thus should be associated with a particular window (viewer)?
Which are viewpoint independent but scene dependent and so should be associated with a Solidviews scene?
Which are viewpoint independent and scene independent and so should be associated with the edittool or a global frame?
2) Which matrix operations should be done on the fly and which results should be cached? Where should they be cached?
3) What sort of objects should the user be allowed to scale unevenly?
The Data Structures
The data structures which are related to the Solidviews display list and coordinate frame hierarchy are:
1) CoordSystem nodes:
CoordSystem: TYPE = REF CoordSysObj;
CoordSysObj: TYPE = RECORD [
name: Rope.ROPE,
mat: Matrix4by4,
wrtCamera: Matrix4by4,
wrtWorld: Matrix4by4,
cameraWRTlocal: Matrix4by4,
worldWRTlocal: Matrix4by4,
withRespectTo: CoordSystem];
CoordSysList: TYPE = LIST OF CoordSystem;
A CoordSystem has a name, a pointer to its parent "withRespectTo", a pointer to a number of children: "CoordSysList", and space for caching 5 matrices including CP, CCAMERA, CWORLD, CAMERAC, and WORLDC. Where are these various matrices used? See Appendix A.
2) Cameras:
Camera: TYPE = REF CameraObj;
CameraObj: TYPE = RECORD [
viewName: Rope.ROPE,
coordSys: CoordSystem,
screenCS: CoordSystem,
resolution: REAL,     -- ray tracing resolution
focalLength: REAL,
projection: Projection,    -- perspective or orthogonal
frame: FrameBox,     -- the outermost ray tracing box.
clippingPlanes: LIST OF Plane,  -- planes in the coordinates of this camera.
visibleAssemblies: LIST OF Rope.ROPE -- a list of subtree roots.
style: DrawStyle,     -- wireframe, shaded, etc.
colorFilm: BOOL,
quality: QualityMode,
abort: BOOLFALSE,
useBoundBoxes: BOOLFALSE]; -- IF FALSE then use bounding spheres
Summary: A camera has a name such as "Front" or "UpRight". Its coordSys is a son of WORLD. screenCS is a son of NIL. It describes the relative translation between CAMERA coordinates and CedarGraphics coordinates.
The screenCS is created by SVViewerImpl at viewer creation time. Oddly, it is past from camera to camera at CameraFromFileCamera time, instead of being stored with the viewer data.
3) Assembly
Assembly: TYPE = REF AssemblyObj;
AssemblyObj: TYPE = RECORD [
 name: Rope.ROPE,
 coordSys: CoordSystem,
 artwork: Artwork,
 scalars: Vector,
 visible: BOOL,
 isTool: BOOL,
 object: REF ANY -- a MasterObject or an assembly list
 ];
Each assembly refers to a coordSys. The scalars are included in coordSysParent but are kept separate for when the user wants to edit the assembly with the Edit! command.
4) Primitive
Primitive: TYPE = REF PrimitiveObj;
PrimitiveObj: TYPE = RECORD [
name: Rope.ROPE,
artwork: Artwork,
assembly: REF ANY, -- a DisplayList3d.Assembly. REF ANY avoids compilation dependencies.
mo: REF ANY, -- should be MasterObject but oh the compilation dependencies!
rayCast: RayCastProc,
rayCastNoBBoxes: RayCastNoBBoxesProc,
rayCastBoundingSpheres: RayCastBoundingSpheresProc,
primWRTAssembly: CoordSystem,
scalars: Vector,
worldWRTPrim: Matrix4by4,
primWRTWorld: Matrix4by4,
hints: REF ANY, -- each object type may wish to store helpful information here
boundBox: BoundBox,
boundSphere: BoundSphere,
boundHedron: BoundHedron,
inverted: BOOL, -- is this shape to be subtracted?
currentRay: Ray,
rayStepX: Ray];
primWRTAssembly is a CoordSystem. It is the same as assembly.coordSys.
worldWRTPrim, and primWRTWorld are inverses. They are the same as assembly.coordSys.wrtWorld and assembly.coordSys.worldWRTlocal.
5) Composite
Composite: TYPE = REF CompositeObj;
CompositeObj: TYPE = RECORD [
name: Rope.ROPE,
operation: PointSetOp,
leftSolid: REF ANY,
rightSolid: REF ANY,
boundBox: BoundBox,
boundSphere: BoundSphere];
Note that composites know nothing about coordinate frames and have no pointers to the assembly data structure. This could be changed if needed, since each composite is associated with a single composite assembly (though each composite assembly may be associated with many Composites).
6) Viewer Data
ViewerPictureData: TYPE = REF ViewerPictureDataObj;
ViewerPictureDataObj: TYPE = RECORD [
proc: PROC [dc: Graphics.Context],
scene: Scene,-- the collection of 3d objects we are looking at
tree: CSGTree,-- for efficiency we will occasional cache the (viewpoint dependent) ray tracing tree
camera: Camera, -- our point of view
baseCS: CoordSystem,-- ****
mode: InteractionMode,
viewerToolData: ViewerToolData-- a back pointer
];
InteractionMode: TYPE = {select, cast};
Viewpoint Dependence
Appendix A: Where the Cached matrices are used.
.wrtCamera
SVBoundSphere.BoundSphereFromBoundHedron computes all boundhedron points in CAMERA coordinates.
CSGGraphics.LocalToCamera converts any given point to CAMERA coordinates.
SVViewerUser.DrawOneCS draws cs.wrtCamera.
SVEditUser.ListCoordSystems puts wrtCamera out onto the stream.
.wrtWorld
CSGGraphics.LocalToWorld converts any given point to WORLD coordinates.
SVPrimitive.FromAssembly copies assem.coordSys.wrtWorld into prim.primWRTWorld.
SVViewerInput.MakeAlignedMat assumes that the selection's parent.wrtWorld is accurate.
SVViewerInput.EndMoveeSelection and EndBackMoveeSelection store moveeSelection.coordSys.wrtWorld.
SVEditUser.SetTargetSelection and SetMoveeSelection use targetSelection.coordSys.withRespectTo.wrtWorld to compute targetSelectionParent.
SVEditUser.ExtendMovee stores moveeSelection.coordSys.wrtWorld in the final movee.
.cameraWRTlocal
CSGGraphics.DrawHorizonOfPlane needs this inverse to compute the plane in CAMERA coordinates.
DisplayList3dImplB.PutAssemblyOnQueue uses thisSurf.assembly.coordSys.cameraWRTlocal to compute the surface normal in CAMERA coordinates. CAMERA coordinates are used so that a back-facing (heuristic) test is easy.
.worldWRTlocal
CSGGraphics.VectorToWorld uses localCS.worldWRTlocal.
General
Draw3d.DrawLocalVector converts the vector origin to CAMERA coordinates using wrtCamera and converts the direction with cameraWRTlocal.
CoordSys.TellAboutParent updates wrtWorld wrtCamera worldWRTlocal cameraWRTlocal (i.e. everything but mat).
SVTransforms.TellAboutCameraAndWorld1 updates .wrtCamera .wrtWorld .cameraWRTlocal and .worldWRTlocal for primitive assemblies, and updates .wrtWorld for the Camera itself.
SVTransforms.TellAboutCameraAndWorld updates .wrtCamera .wrtWorld .cameraWRTlocal and .worldWRTlocal for all assemblies in the tree, and updates .wrtWorld for the Camera itself.
CSGGraphics.DrawArea uses .wrtWorld to update polygon vertices. It uses .cameraWRTlocal to convert the surface normal to CAMERA, and .worldWRTlocal to convert the surface normal to WORLD.
CSGGraphics.DrawAreaNormalAbsolute uses .wrtWorld to update polygon vertices. It uses the .worldWRTlocal of the Camera to convert the surface normal to WORLD. CSGGraphics.DrawAreaNormalAbsolute in turn is used in SweepGeometryImpl.DrawPlanarSurfaceLinearSweep since the camera normals are computed when the planar surface is being sorted.
Appendix B: Implementation notes.
When implementing general operations such as IncTransf, AbsTransf, TugTransf, I had to give up the efficiency of the special Matrix3d operations such as Scale, RotateAboutYAxis, and so forth. Furthermore, Scaling operations are difficult because they currently require changing information in the assembly record.