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. ΠFile: SVHalfSpacesImpl.mesa Author: Eric Bier on August 12, 1983 1:58 pm Last edited by Bier: August 16, 1983 10:31 am Contents: Implementation of the half-space object class BASIC SHAPES Do one ray-plane intersection test. The half space ends at the xz plane (i.e. the plane with equation y = 0. Ray parameterization is R = p + t*d. For y, this is: y[t] = p[2]+t*d[2]. If d has no y component, this has no solution. Otherwise, we find t = -p[2]/d[2]. Check to see which side of the plane the ray originates on. Check to see that t is positive. The ray hits the plane. The plane is behind the ray. Ray is functionally parallel to the plane. Count a complete miss. HalfSpaces can be recovered from scratch. Κͺ˜Ihead™J™,J™-J™8šΟk ˜ Iprocšœ ˜ Lšœ ˜ Lšœ˜Lšœ ˜ Lšœ˜J˜J˜ Jšœ˜Lšœ˜Lšœ˜L˜Lšœ ˜ Lšœ ˜ L˜ Lšœ˜—šœ˜Jšœ/œ˜LJšœ˜—šœ˜Lšœ œ˜+Lšœ œœ ˜$Lšœ œ˜)Lšœœœ˜.Lšœœ˜5Lšœœ!˜6Lšœ œ˜Lšœœœ˜Lšœœœ˜Lšœœœ˜+Lšœœ"˜8Lšœœ#˜:Lšœœ˜ Lšœ œ˜Lšœœ˜"Lšœœœ˜3Lšœœ&˜@Lšœœœ˜)Lšœœ!˜6Lšœ œœ ˜ Lšœ œœœ˜Lšœ œœ ˜!Lšœ œ˜/—šœ ™ Lšœœœ˜)Lšœœ!˜6Lšœœœ˜)Lšœœ!˜6Lšœ#˜#šΟn œœœœ!˜DLšœœ˜$Lšœ˜Lšœ˜—L˜š žœœœ œœ˜WLšœ)˜)Lšœ œœ ˜Lšœ œœ ˜Lšœ œœ˜1Lšœh˜hLšœ˜—L˜šžœœœœ˜VLšœ œ˜ Lšœ˜—L˜šžœœœœ˜KLšœ œ˜Lšœ˜—L˜š žœœœ5œœœ˜Lšœœ˜(Lšœœ˜ALšœ˜—šžœœœ2œ˜sL™#L™HLšœΟbœŸœŸœ™5L™L™±Lšœ œ ˜Lšœœ˜Lšœœ˜Lšœ$˜$L˜šœ)œ˜1Lšœ.˜.Lšœ%˜%šœœ˜™L˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜—šœœ˜Lšœœ˜Lšœœ˜L˜—šœ˜Lšœœ˜Lšœœ˜L˜—L˜—šœ˜L™L˜Lšœœ˜&L˜—L˜—šœ˜L™BL˜Lšœœ˜L˜—LšœΟcœ˜—š žœœœœœ˜&Lšœœœœ˜!L˜—L˜š žœœœœœœ˜Lšœœ˜(Lšœœ˜ALšœ˜—L˜š žœœœœœ+˜mLšœœ˜*Lšœ œ˜'L˜:LšœD˜DLšœR˜RLšœT˜TLšœD˜DLšœR˜RLšœT˜TLšœ;˜;Lšœ˜—š žœœœœœ+˜pLšœ>˜>Lšœ˜—š žœœœœœ˜SLšœ˜Lšœ˜—š žœœœœœ˜SLšœ˜Lšœ˜—šžœœœ+œ˜lLšœœ˜+LšœJ˜JLšœ˜Lšœœ˜šœ œ˜"Lšœ!˜$—Lšœœ ˜Lšœ˜—šžœœœ]˜{Lšœ˜Lšœ:˜:Lšœ˜Lšœc˜cLšœ˜—L˜š žœœœœœ˜BLšœ)™)Lšœ œœ˜Lšœ˜Lšœ˜—šžœœœœœ œœ˜[Lšœ&˜&Lšœ˜Lšœ%˜%Lšœ˜—šžœœ˜Lšœ˜L˜Lšœ9˜9Lšœ ˜ Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ!˜!Lšœ3˜3Lšœ.˜.L˜L˜—Lšœ˜—L˜Jšœ˜J˜—…—Z"Τ