<> <> <> <> DIRECTORY CastRays, CoordSys, CSG, CSGGraphics, DisplayList3d, Draw3d, Graphics, IO, Rope, SV2d, SV3d, SVBoundBox, SVHalfSpaces, SVPolygon3d, TFI3d; SVHalfSpacesImpl: PROGRAM IMPORTS CastRays, CSGGraphics, DisplayList3d, Draw3d, IO, SVPolygon3d, TFI3d EXPORTS SVHalfSpaces = BEGIN BoundHedron: TYPE = SVBoundBox.BoundHedron; CoordSystem: TYPE = REF CoordSysObj; CoordSysObj: TYPE = CoordSys.CoordSysObj; Classification: TYPE = REF ClassificationObj; ClassificationObj: TYPE = CastRays.ClassificationObj; LightSourceList: TYPE = DisplayList3d.LightSourceList; Point2d: TYPE = SV2d.Point2d; Ray: TYPE = REF RayObj; RayObj: TYPE = CSG.RayObj; PlanarSurface: TYPE = REF PlanarSurfaceObj; PlanarSurfaceObj: TYPE = DisplayList3d.PlanarSurfaceObj; PlanarSurfaceList: TYPE = DisplayList3d.PlanarSurfaceList; Plane: TYPE = SVPolygon3d.Plane; Point3d: TYPE = SV3d.Point3d; Camera: TYPE = CSGGraphics.Camera; MasterObjectClass: TYPE = REF MasterObjectClassObj; MasterObjectClassObj: TYPE = DisplayList3d.MasterObjectClassObj; MasterObject: TYPE = REF MasterObjectRec; MasterObjectRec: TYPE = DisplayList3d.MasterObjectRec; Primitive: TYPE = CSG.Primitive; Surface: TYPE = REF ANY; Assembly: TYPE = REF AssemblyObj; AssemblyObj: TYPE = DisplayList3d.AssemblyObj; <> HalfSpaceRec: TYPE = REF HalfSpaceRecObj; HalfSpaceRecObj: TYPE = SVHalfSpaces.HalfSpaceRecObj; PlaneSurface: TYPE = REF PlaneSurfaceObj; PlaneSurfaceObj: TYPE = SVHalfSpaces.PlaneSurfaceObj; halfSpaceClass: MasterObjectClass; HalfSpaceBody: PRIVATE PROC RETURNS [halfSpaceRec: HalfSpaceRec] = { halfSpaceRec _ NEW[HalfSpaceRecObj]; halfSpaceRec.gridSide _ 72.0; }; HalfSpaceMakeMasterObject: PUBLIC PROC [name: Rope.ROPE] RETURNS [mo: MasterObject] = { mainBody: HalfSpaceRec _ HalfSpaceBody[]; lineBody: REF ANY _ mainBody; shadeBody: REF ANY _ mainBody; rayCastBody: REF ANY _ HalfSpaceGetRayCastBody[]; mo _ DisplayList3d.CreateMasterObject[name, halfSpaceClass, mainBody, lineBody, shadeBody, rayCastBody]; }; HalfSpaceBoundHedron: PUBLIC PROC [mo: MasterObject] RETURNS [hedron: BoundHedron] = { hedron _ NIL; }; HalfSpaceGetRayCastBody: PRIVATE PROC [] RETURNS [planeS: PlaneSurface] = { planeS _ NEW[PlaneSurfaceObj]; }; HalfSpaceRayCast: PUBLIC PROC [cameraPoint: Point2d, localRay: Ray, masterObject: REF ANY, prim: Primitive] RETURNS [class: Classification] = { mo: MasterObject _ NARROW[masterObject]; RETURN[HalfSpaceCastAux[localRay, NARROW[mo.rayCastBody], prim]]; }; HalfSpaceCastAux: PRIVATE PROC [localRay: Ray, plane: Surface, prim: Primitive] RETURNS [class: Classification] = { <> <> <> <> <> almostZero: REAL _ 1.0e-12; t: REAL; rayStartsOut: BOOL; class _ CastRays.GetClassFromPool[]; IF Abs[localRay.direction[2]] > almostZero THEN { t _ -localRay.basePt[2]/localRay.direction[2]; rayStartsOut _ localRay.basePt[2] >0; IF t > 0 THEN { <> class.count _ 1; class.params[1] _ t; class.surfaces[1] _ plane; class.normals[1] _ [0,1,0]; class.primitives[1] _ prim; IF rayStartsOut THEN { class.classifs[1] _ FALSE; class.classifs[2] _ TRUE; } ELSE { class.classifs[1] _ TRUE; class.classifs[2] _ FALSE; }; } ELSE { <> class.count _ 0; class.classifs[1] _ NOT rayStartsOut; }; } ELSE { <> class.count _ 0; class.classifs[1] _ FALSE; }; }; -- end of HalfSpaceCastAux Abs: PROC [r: REAL] RETURNS [REAL] = { RETURN[IF r >= 0 THEN r ELSE -r]; }; HalfSpaceRayCastNoBBoxes: PUBLIC PROC [localRay: Ray, masterObject: REF ANY, prim: Primitive] RETURNS [class: Classification] = { mo: MasterObject _ NARROW[masterObject]; RETURN[HalfSpaceCastAux[localRay, NARROW[mo.rayCastBody], prim]]; }; HalfSpaceLineDraw: PUBLIC PROC[dc: Graphics.Context, data: REF ANY, camera: Camera, localCS: CoordSystem] = { halfSpaceRec: HalfSpaceRec _ NARROW[data]; gridSide: REAL _ halfSpaceRec.gridSide; plane: Plane _ SVPolygon3d.PlaneFromCoefficients[0,1,0,0]; CSGGraphics.DrawInfiniteLine[dc, [0,0,0], [1,0,0], camera, localCS]; CSGGraphics.DrawInfiniteLine[dc, [0,0,gridSide], [1,0,gridSide], camera, localCS]; CSGGraphics.DrawInfiniteLine[dc, [0,0,-gridSide], [1,0,-gridSide], camera, localCS]; CSGGraphics.DrawInfiniteLine[dc, [0,0,0], [0,0,1], camera, localCS]; CSGGraphics.DrawInfiniteLine[dc, [gridSide,0,0], [gridSide,0,1], camera, localCS]; CSGGraphics.DrawInfiniteLine[dc, [-gridSide,0,0], [-gridSide,0,1], camera, localCS]; CSGGraphics.DrawHorizonOfPlane[dc, plane, camera, localCS]; }; HalfSpaceDrawNormals: PUBLIC PROC[dc: Graphics.Context, data: REF ANY, camera: Camera, localCS: CoordSystem] = { Draw3d.DrawLocalVector[dc, [0,1,0], [0,0,0], camera, localCS]; }; HalfSpaceCountSurf: PUBLIC PROC [masterObject: MasterObject] RETURNS [len: NAT] = { len _ 1; }; HalfSpaceCountVert: PUBLIC PROC [masterObject: MasterObject] RETURNS [len: NAT] = { len _ 0; }; HalfSpaceGetSurf: PUBLIC PROC [assembly: Assembly, camera: CoordSystem] RETURNS [psl: PlanarSurfaceList] = { mo: MasterObject _ NARROW[assembly.object]; midPoint: Point3d _ CSGGraphics.LocalToCamera[[0,0,0], assembly.coordSys]; surface: PlanarSurface; depth: REAL _ midPoint[3]; surface _ NEW[PlanarSurfaceObj _ [ NIL, assembly, mo, [0,1,0], depth]]; psl _ LIST[surface]; }; HalfSpaceDrawSurf: PUBLIC PROC [dc: Graphics.Context, ps: PlanarSurface, lightSources: LightSourceList, camera: Camera] = { localCS: CoordSystem; plane: Plane _ SVPolygon3d.PlaneFromCoefficients[0,1,0,0]; localCS _ ps.assembly.coordSys; CSGGraphics.DrawInfinitePlaneShaded[dc, plane, ps.assembly.artwork, lightSources, camera, localCS]; }; HalfSpaceFileout: PUBLIC PROC [f: IO.STREAM, mo: MasterObject] = { <> f.PutChar[IO.TAB]; f.PutF["data: procedural\n"]; }; HalfSpaceFilein: PUBLIC PROC [f: IO.STREAM, name: Rope.ROPE] RETURNS [mo: MasterObject] = { TFI3d.ReadRope[f, "data: procedural"]; TFI3d.ReadBlank[f]; mo _ HalfSpaceMakeMasterObject[name]; }; Init: PROC = { halfSpace: MasterObject; halfSpaceClass _ DisplayList3d.RegisterMasterObjectClass[ "halfSpace", HalfSpaceFilein, HalfSpaceFileout, HalfSpaceRayCast, HalfSpaceRayCastNoBBoxes, HalfSpaceBoundHedron, DisplayList3d.NoOpPreprocess, HalfSpaceLineDraw, HalfSpaceDrawNormals, HalfSpaceCountSurf, HalfSpaceGetSurf, HalfSpaceDrawSurf, DisplayList3d.NoOpDrawSubBoxes]; halfSpace _ HalfSpaceMakeMasterObject["halfSpace"]; DisplayList3d.RegisterMasterObject[halfSpace]; }; Init[]; END.