IMPORTS CastRays, CSGGraphics, Graphics, GraphicsColor, Matrix3d, PriorityQueue, SVTransforms
DisplayList Types
Databases, Scenes, Assemblies, and Lightsources
Database: TYPE = REF DatabaseObj;
DatabaseObj: TYPE = DisplayList3d.DatabaseObj;
Scene: TYPE = REF SceneObj;
SceneObj: TYPE = DisplayList3d.SceneObj;
Assembly: TYPE = REF AssemblyObj;
AssemblyObj: TYPE = DisplayList3d.AssemblyObj;
AssemblyList: TYPE = REF AssemblyListObj;
AssemblyListObj: TYPE = DisplayList3d.AssemblyListObj;
LightSource: TYPE = REF LightSourceObj;
LightSourceObj: TYPE = Shading.LightSourceObj;
LightSourceList: TYPE = Shading.LightSourceList;
Master Object Class Types
MasterObjectClass: TYPE = REF MasterObjectClassObj;
MasterObjectClassObj: TYPE = DisplayList3d.MasterObjectClassObj;
MasterObjectClassList: TYPE = DisplayList3d.MasterObjectClassList;
FileoutProc: TYPE = DisplayList3d.FileoutProc;
FileinProc: TYPE = DisplayList3d.FileinProc;
Master Object Types
MasterObject: TYPE = REF MasterObjectRec;
MasterObjectRec: TYPE = DisplayList3d.MasterObjectRec;
MasterObjectList: TYPE = DisplayList3d.MasterObjectList;
RayCastProc: TYPE = CSG.RayCastProc;
RayCastNoBBoxesProc: TYPE = CSG.RayCastNoBBoxesProc;
PreprocessProc: TYPE = DisplayList3d.PreprocessProc;
LineDrawProc: TYPE = DisplayList3d.LineDrawProc;
NormalsDrawProc: TYPE = DisplayList3d.NormalsDrawProc;
CountPlanarSurfacesProc: TYPE = DisplayList3d.CountPlanarSurfacesProc;
GetPlanarSurfacesProc:
TYPE = DisplayList3d.GetPlanarSurfacesProc;
PlanarSurface: TYPE = REF PlanarSurfaceObj;
PlanarSurfaceObj: TYPE = DisplayList3d.PlanarSurfaceObj;
PlanarSurfaceList: TYPE = DisplayList3d.PlanarSurfaceList;
DrawPlanarSurfaceProc: TYPE = DisplayList3d.DrawPlanarSurfaceProc;
DrawSubBoxesProc: TYPE = DisplayList3d.DrawSubBoxesProc;
Noop Procedures
A master object can use these entries if it doesn't implement one of these procedures
NoOpRayCast:
PUBLIC RayCastProc = {
class ← CastRays.GetClassFromPool[];
CastRays.MakeClassAMiss[class];
};
NoOpRayCastNoBBoxes:
PUBLIC RayCastNoBBoxesProc = {
class ← CastRays.GetClassFromPool[];
CastRays.MakeClassAMiss[class];
};
NoOpPreprocess: PUBLIC PreprocessProc = {}; -- don't preprocess anything
NoOpLineDraw: PUBLIC LineDrawProc = {}; -- don't draw anything
NoOpNormalsDraw: PUBLIC NormalsDrawProc = {}; -- don't draw anything
NoOpCountPlanarSurfaces:
PUBLIC CountPlanarSurfacesProc = {
RETURN[0]};
Say you don't have any
NoOpGetPlanarSurfaces:
PUBLIC GetPlanarSurfacesProc = {
RETURN[
NIL]};
Return the empty list
NoOpDrawPlanarSurface: PUBLIC DrawPlanarSurfaceProc = {}; -- don't draw anything
NoOpDrawSubBoxes: PUBLIC DrawSubBoxesProc = {}; -- don't draw anything
Draw Parts of the Scene Tree
DrawScene:
PUBLIC
PROC [dc: Graphics.Context, scene: Scene, camera: Camera] = {
mark: Graphics.Mark;
SVTransforms.TellAboutCameraAndWorld[scene.assembly, camera, scene];
Clip the picture to the camera's frame
mark ← Graphics.Save[dc];
CSGGraphics.Clip[dc, camera];
SELECT camera.style FROM
wire => DrawWireAssembly[dc, scene.assembly, scene, camera];
shaded => DrawShadedAssembly[dc, scene.assembly, scene, camera];
normals => DrawNormalsAssembly[dc, scene.assembly, scene, camera];
ENDCASE => SIGNAL NotYetImplemented;
Graphics.Restore[dc, mark];
};
NotYetImplemented: PUBLIC SIGNAL = CODE;
DrawAssembly:
PUBLIC
PROC [dc: Graphics.Context, assembly: Assembly, scene: Scene, camera: Camera] = {
SVTransforms.TellAboutCameraAndWorld[assembly, camera, scene];
Clip the picture to the camera's frame
CSGGraphics.Clip[dc, camera];
SELECT camera.style FROM
wire => DrawWireAssembly[dc, assembly, scene, camera];
shaded => DrawShadedAssembly[dc, assembly, scene, camera];
normals => DrawNormalsAssembly[dc, assembly, scene, camera];
ENDCASE => SIGNAL NotYetImplemented;
};
SetColor:
PRIVATE
PROC [dc: Graphics.Context, camera: Camera, color: Color] = {
IF camera.colorFilm THEN Graphics.SetColor[dc, color]
ELSE {
intensity: REAL ← GraphicsColor.ColorToIntensity[color];
Graphics.SetColor[dc, GraphicsColor.IntensityToColor[intensity]]};
};
DrawWireAssembly: PRIVATE PROC [dc: Graphics.Context, assembly: Assembly, scene: Scene, camera: Camera] = {
Graphics.SetColor[dc, GraphicsColor.black];
DrawWireAssembly2[dc, assembly, scene, camera];
};
DrawWireAssembly2: PRIVATE PROC [dc: Graphics.Context, assembly: Assembly, scene: Scene, camera: Camera] = {
lightSources: LightSourceList ← scene.lightSources;
WITH assembly.object SELECT FROM
assems: AssemblyList => {
FOR subassemblies: LIST OF Assembly ← assems.list, subassemblies.rest
UNTIL subassemblies = NIL DO
DrawWireAssembly2[dc: dc, assembly: subassemblies.first, scene: scene, camera: camera];
ENDLOOP;
};
mo: MasterObject => {
-- Graphics.SetColor[dc, assembly.color];
mo.class.lineDraw[dc, mo.lineBody, camera, assembly.coordSys];
};
ENDCASE => ERROR;
};
CountSurfacesInAssemblyList: PRIVATE PROC [asl: AssemblyList] RETURNS [surfCount: NAT] = {
surfCount ← 0;
FOR list: LIST OF Assembly ← asl.list, list.rest UNTIL list = NIL DO
surfCount ← surfCount + CountSurfacesInAssembly[list.first];
ENDLOOP;
};
CountSurfacesInAssembly: PRIVATE PROC [assembly: Assembly] RETURNS [surfCount: NAT] = {
WITH assembly.object SELECT FROM
assems: AssemblyList => surfCount ← CountSurfacesInAssemblyList[assems];
mo: MasterObject => surfCount ← mo.class.countSurf[mo];
ENDCASE => ERROR;
};
PutAssemblyListOnQueue: PRIVATE PROC [asl: AssemblyList, q: PriorityQueue.Ref, cameraCS: CoordSystem] = {
FOR list: LIST OF Assembly ← asl.list, list.rest UNTIL list = NIL DO
PutAssemblyOnQueue[list.first, q, cameraCS];
ENDLOOP;
};
PutAssemblyOnQueue: PRIVATE PROC [assembly: Assembly, q: PriorityQueue.Ref, cameraCS: CoordSystem] = {
thisSurf: PlanarSurface;
cameraNormal: Vector;
WITH assembly.object SELECT FROM
assems: AssemblyList => PutAssemblyListOnQueue[assems, q, cameraCS];
mo: MasterObject => {
surfList: PlanarSurfaceList ← mo.class.getSurf[assembly, cameraCS];
FOR surfList ← surfList, surfList.rest UNTIL surfList = NIL DO
thisSurf ← surfList.first;
cameraNormal ← Matrix3d.UpdateVectorWithInverse[thisSurf.assembly.coordSys.cameraWRTlocal, thisSurf.normal];
thisSurf.normal ← cameraNormal;
-- eliminate most back-facing surfaces at this point by a simple test.
IF thisSurf.normal[3] >0 THEN PriorityQueue.Insert[q,thisSurf];
ENDLOOP;
};
ENDCASE => ERROR;
}; -- end of PutAssemblyOnQueue
DeeperPlanarSurface: SAFE PROC [x,y: PriorityQueue.Item, data: REF ← NIL] RETURNS [BOOL] = TRUSTED {
xS: PlanarSurface ← NARROW[x];
yS: PlanarSurface ← NARROW[y];
RETURN[xS.depth < yS.depth];
};
DrawShadedAssembly:
PRIVATE
PROC [dc: Graphics.Context, assembly: Assembly, scene: Scene, camera: Camera] = {
Get a list of surfaces from each subassembly of "assembly" and draw them with the Painter's Algorithm (back to front)
Count the total number of surfaces and make a priority queue of the appropriate size.
predictedQueueSize: NAT ← CountSurfacesInAssembly[assembly];
surfaceQueue: PriorityQueue.Ref ←
PriorityQueue.Predict[predictedQueueSize, DeeperPlanarSurface];
mo: MasterObject;
thisPlanarSurf: PlanarSurface;
box: Graphics.Box;
mark: Graphics.Mark ← Graphics.Save[dc];
Now put the surfaces on the queue
PutAssemblyOnQueue[assembly, surfaceQueue, camera.coordSys];
Draw a background color
box ← Graphics.GetBounds[dc];
SetColor[dc, camera, scene.backgroundColor];
Graphics.DrawBox[dc, box];
Take them off the queue in order and draw them
FOR i:
NAT
IN[1..PriorityQueue.Size[surfaceQueue]]
DO
thisPlanarSurf ← NARROW[PriorityQueue.Remove[surfaceQueue]];
mo ← thisPlanarSurf.mo;
mo.class.drawSurf[dc, thisPlanarSurf, scene.lightSources, camera];
ENDLOOP;
Graphics.Restore[dc, mark];
};
DrawNormalsAssembly: PROC [dc: Graphics.Context, assembly: Assembly, scene: Scene, camera: Camera] = {
Graphics.SetColor[dc, GraphicsColor.black];
DrawNormalsAssembly2[dc, assembly, scene, camera];
};
DrawNormalsAssembly2: PROC [dc: Graphics.Context, assembly: Assembly, scene: Scene, camera: Camera] = {
lightSources: LightSourceList ← scene.lightSources;
WITH assembly.object SELECT FROM
assems: AssemblyList => {
FOR subassemblies: LIST OF Assembly ← assems.list, subassemblies.rest
UNTIL subassemblies = NIL DO
DrawNormalsAssembly2[dc: dc, assembly: subassemblies.first, scene: scene, camera: camera];
ENDLOOP;
};
mo: MasterObject => {
-- Graphics.SetColor[dc, assembly.color];
mo.class.normalsDraw[dc, mo.shadeBody, camera, assembly.coordSys];
-- surfList: PlanarSurfaceList ← mo.class.getSurf[assembly, camera.coordSys];
-- FOR list: PlanarSurfaceList ← surfList, list.rest UNTIL list = NIL DO
};
ENDCASE => ERROR;
};