<> <> <> DIRECTORY CastRays, CoordSys, CSG, CSGGraphics, DisplayList3d, Graphics, GraphicsColor, Matrix3d, PriorityQueue, Shading, SV2d, SVPolygon3d, SVTransforms, SVVector3d; DisplayList3dImplB: PROGRAM IMPORTS CastRays, CSGGraphics, Graphics, GraphicsColor, Matrix3d, PriorityQueue, SVTransforms EXPORTS DisplayList3d = BEGIN <> Camera: TYPE = CSGGraphics.Camera; Classification: TYPE = REF ClassificationObj; ClassificationObj: TYPE = CSG.ClassificationObj; Color: TYPE = GraphicsColor.Color; CoordSysList: TYPE = CoordSys.CoordSysList; CoordSysObj: TYPE = CoordSys.CoordSysObj; CoordSystem: TYPE = REF CoordSysObj; CSGTree: TYPE = REF CSGTreeObj; CSGTreeObj: TYPE = CSG.CSGTreeObj; Matrix4by4: TYPE = Matrix3d.Matrix4by4; Point2d: TYPE = SV2d.Point2d; Point3d: TYPE = Matrix3d.Point3d; PointSetOp: TYPE = CSG.PointSetOp; -- {union, intersection, difference} Poly3d: TYPE = SVPolygon3d.Poly3d; Primitive: TYPE = REF PrimitiveObj; PrimitiveObj: TYPE = CSG.PrimitiveObj; Ray: TYPE = REF RayObj; RayObj: TYPE = CSG.RayObj; Vector: TYPE = SVVector3d.Vector; <> <> 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; <> MasterObjectClass: TYPE = REF MasterObjectClassObj; MasterObjectClassObj: TYPE = DisplayList3d.MasterObjectClassObj; MasterObjectClassList: TYPE = DisplayList3d.MasterObjectClassList; FileoutProc: TYPE = DisplayList3d.FileoutProc; FileinProc: TYPE = DisplayList3d.FileinProc; <> 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; <> <> 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]}; <> NoOpGetPlanarSurfaces: PUBLIC GetPlanarSurfacesProc = {RETURN[NIL]}; <> NoOpDrawPlanarSurface: PUBLIC DrawPlanarSurfaceProc = {}; -- don't draw anything NoOpDrawSubBoxes: PUBLIC DrawSubBoxesProc = {}; -- don't draw anything <> DrawScene: PUBLIC PROC [dc: Graphics.Context, scene: Scene, camera: Camera] = { mark: Graphics.Mark; SVTransforms.TellAboutCameraAndWorld[scene.assembly, camera, scene]; <> 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]; <> 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] = { <> <> predictedQueueSize: NAT _ CountSurfacesInAssembly[assembly]; surfaceQueue: PriorityQueue.Ref _ PriorityQueue.Predict[predictedQueueSize, DeeperPlanarSurface]; mo: MasterObject; thisPlanarSurf: PlanarSurface; box: Graphics.Box; mark: Graphics.Mark _ Graphics.Save[dc]; <> PutAssemblyOnQueue[assembly, surfaceQueue, camera.coordSys]; <> box _ Graphics.GetBounds[dc]; SetColor[dc, camera, scene.backgroundColor]; Graphics.DrawBox[dc, box]; <> 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; }; END.