DIRECTORY AtomButtonsTypes, Imager, IO, Rope, SV2d, SV3d, SVBasicTypes, SVModelTypes, SVSceneTypes, ViewerClasses; SVCastRays: CEDAR DEFINITIONS = BEGIN Slice: TYPE = SVSceneTypes.Slice; BoundBox: TYPE = SVBasicTypes.BoundBox; Camera: TYPE = SVModelTypes.Camera; Classification: TYPE = SVSceneTypes.Classification; Color: TYPE = Imager.Color; Composite: TYPE = SVSceneTypes.Composite; CoordSystem: TYPE = SVModelTypes.CoordSystem; FeedbackData: TYPE = AtomButtonsTypes.FeedbackData; LightSourceList: TYPE = SVModelTypes.LightSourceList; Matrix4by4: TYPE = SV3d.Matrix4by4; Point2d: TYPE = SV2d.Point2d; Point3d: TYPE = SV3d.Point3d; Primitive: TYPE = SVSceneTypes.Primitive; Ray: TYPE = SVSceneTypes.Ray; Vector3d: TYPE = SV3d.Vector3d; Viewer: TYPE = ViewerClasses.Viewer; Surface: TYPE = SVSceneTypes.Surface; -- REF ANY; CSGTree: TYPE = SVSceneTypes.CSGTree; PointSetOp: TYPE = SVSceneTypes.PointSetOp; ParameterArray: TYPE = SVSceneTypes.ParameterArray; SurfaceArray: TYPE = SVSceneTypes.SurfaceArray; InOutArray: TYPE = SVSceneTypes.InOutArray; NormalArray: TYPE = SVSceneTypes.NormalArray; PrimitiveArray: TYPE = SVSceneTypes.PrimitiveArray; DrawTree: PROC [tree: CSGTree, lightSources: LightSourceList, camera: Camera, aisRope: Rope.ROPE, bAndWOnly: BOOL, notify: NotifyOfProgressProc _ NoOpNotifyOfProgress, clientData: REF ANY _ NIL, feedback: FeedbackData] RETURNS [success: BOOL, maxRed, maxGreen, maxBlue, maxBlack: NAT]; DrawTreeWithStartLine: PROC [startLine: REAL, tree: CSGTree, lightSources: LightSourceList, camera: Camera, aisRope: Rope.ROPE, bAndWOnly: BOOL, notify: NotifyOfProgressProc _ NoOpNotifyOfProgress, clientData: REF ANY _ NIL, feedback: FeedbackData] RETURNS [success: BOOL, maxRed, maxGreen, maxBlue, maxBlack: NAT]; NotifyOfProgressProc: TYPE = PROC [currentY, minX, minY, maxX, maxY: REAL, clientData: REF ANY _ NIL]; NoOpNotifyOfProgress: NotifyOfProgressProc; SingleRay: PROC [cameraPoint: Point2d, tree: CSGTree, lightSources: LightSourceList, camera: Camera, feedback: FeedbackData, makeStream: BOOL _ FALSE] RETURNS [color: Color]; SingleRay2: PROC [cameraPoint: Point2d, tree: CSGTree, camera: Camera, consolidate: BOOL _ TRUE, feedback: FeedbackData, makeStream: BOOL _ FALSE] RETURNS [class: Classification, rayWorld: Ray]; SortClassByPrimitive: PROC [class: Classification]; NthSurfacePointAndNormal: PROC [class: Classification, rayWorld: Ray, n: NAT] RETURNS [surfacePtWorld: Point3d, normalWorld: Vector3d]; LastOfFirstPointAndNormal: PROC [class: Classification, rayWorld: Ray] RETURNS [surfacePtWorld: Point3d, normalWorld: Vector3d]; LastTopLevelPointAndNormal: PROC [class: Classification, rayWorld: Ray, root: Slice] RETURNS [surfacePtWorld: Point3d, normalWorld: Vector3d]; NthAssemblyAndPrimitive: PROC [class: Classification, n: NAT] RETURNS [assembly: Slice, primitive: Primitive]; LastTopLevelAssemAndPrim: PROC [class: Classification, root: Slice] RETURNS [assembly: Slice, primitive: Primitive]; RayMeetsPlaneOfCoordSystem: PROC [coordSys: CoordSystem, rayWorld: Ray, whichPlane: NAT, depth: REAL _ 0] RETURNS [pointWorld: Point3d, parallel: BOOL]; NthHitData: PROC [class: Classification, n: NAT] RETURNS [hitData: REF ANY]; LastOfFirstHitData: PROC [class: Classification] RETURNS [hitData: REF ANY]; LastTopLevelHitData: PROC [class: Classification, root: Slice] RETURNS [hitData: REF ANY]; RayCast: PROC [cameraPoint: Point2d, worldRay: Ray, node: REF ANY, consolidate: BOOL _ TRUE, feedback: FeedbackData _ NIL, makeStream: BOOL _ FALSE, indent: NAT _ 0] RETURNS [class: Classification]; RayCastBoundingSpheres: PROC [worldRay: Ray, node: REF ANY, consolidate: BOOL _ TRUE, feedback: FeedbackData _ NIL, makeStream: BOOL _ FALSE, indent: NAT _ 0] RETURNS [class: Classification]; RayCastNoBBoxes: PROC [worldRay: Ray, node: REF ANY, consolidate: BOOL _ TRUE, feedback: FeedbackData _ NIL, makeStream: BOOL _ FALSE, indent: NAT _ 0] RETURNS [class: Classification]; HitsTree: PROC [worldRay: Ray, tree: CSGTree] RETURNS [BOOL]; FirstHit: PROC [worldRay: Ray, tree: CSGTree, useBoundSpheres: BOOL, feedback: FeedbackData, makeStream: BOOL _ FALSE, indent: NAT _ 0] RETURNS [hits: BOOL, t: REAL]; GetClassFromPool: PROC RETURNS [class: Classification]; ReturnClassToPool: PROC [class: Classification]; MakeClassAMiss: PROC [class: Classification]; EmptyClass: PROC RETURNS [class: Classification]; WriteStreamComp: PROC [comp: Composite, class: Classification, feedback: FeedbackData, makeStream: BOOL, indent: NAT]; WriteStreamPrim: PROC [prim: Primitive, class: Classification, feedback: FeedbackData, makeStream: BOOL, indent: NAT]; UnionCombine: PROC [leftClass, rightClass: Classification, consolidate: BOOL] RETURNS [combinedClass: Classification]; IntersectionCombine: PROC [leftClass, rightClass: Classification, consolidate: BOOL] RETURNS [combinedClass: Classification]; DifferenceCombine: PROC [leftClass, rightClass: Classification, consolidate: BOOL] RETURNS [combinedClass: Classification]; END. File: SVCastRays.mesa Last edited by Bier on June 1, 1987 10:39:30 am PDT Author: Eric Bier in the summer of 1982 Contents: The ray casting (as opposed to tree building) part of the SVRay package. SVRay.mesa builds the trees maxSceneDepth: NAT = 20; {union, intersection, difference} Generally Useful Procedures In CastRaysImplA The basic ray tracing procedure. Makes a ray tracing of the given CSGTree, according to the specifications in camera. DrawTree calls notify once before starting each line (row) of pixels. Exactly like DrawTree except that only lines with y>startLine are traced. (Useful mostly for debugging when starting the ray trace from the beginning would be too expensive). DrawTree calls a procedure of this type after finishing each scan line. Cast a single ray at the scene from point [x, y] (in CAMERA coordinates on the z = 0 plane). Report the results to the output stream and find the color at that point. Cast a single ray at the scene from the given cameraPoint (point in CAMERA coords on the z = 0 plane). The client must be sure to call CastRays.ReturnClassToPool[class] and SVRay.ReturnRayToPool when he is done with these. The following 4 routines are used along with SingleRay2 to unpack the resulting classification record. In CastRaysImplB Reorders the classification so that all of the intersections corresponding to a particular primitive are grouped together (locally in ascending t value), and primitives are ordered by t value of the first hit on that primitive. Find the surface point and surface normal of the nth primitive hit by the ray. Find the surface point and surface normal, belonging to the first primitive hit by the ray, when the ray last leaves that primitive. Find the surface point and surface normal, belonging to the first top level assembly hit by the ray, when the ray last leaves that top level assembly. Note that the assembly may well be composite (composed of multiple primitives). "Top level" assemblies are direct children of "root". Find the nth primitive hit by the ray and its corresponding displaylist assembly. Find the first top level assembly hit by the ray and the primitive at which the ray last leaves that top level assembly. RayMeetsZConstantPlane: PROC [localRay: Ray, z: REAL] RETURNS [hitPoint: Point3d, parallel: BOOL]; Returns hitPoint in local coordinates. We assume the ray and the z constant plane are in the same coordinate frame. Given a ray in camera coordinates, we find its intersection with the x=depth (or y=depth or z=depth) plane of coordSys. Mostly Used Internally The main ray casting procedure. worldRay must be in WORLD coordinates before this procedure is called. Like RayCast but ignore any bounding boxes which were computed. This is useful if the ray does not originate from the screen (as for computing shadows). Of course, bounding spheres would be useful in this case. Reports true if worldRay hits any object in tree (i.e. if any object is visible at this point). Like HitsTree but returns the parameter value at the first hit, if any. First Hit is used by SVFancyRays for shadows (i.e. to determine which light sources are visible). Pools of Large Records for Recycling. Rearranges class to correspond to a complete miss. Private Procedures (for communication between the several implementation modules) ส%– "cedar" style˜Iheadšœ™Iprocšœ3™3Lšœ'™'Lšœp™pL˜šฯk ˜ LšœœL˜h—L˜Lšœ œ˜L˜Lš˜˜Lšœœ˜!Lšœ œ˜'Lšœœ˜$Lšœœ˜3Lšœœ˜Lšœ œ˜)Lšœ œ˜-Jšœ3˜3Lšœœ ˜5Lšœ œ˜#Lšœ œ˜Lšœ œ˜Lšœ œ˜)Lšœœœ˜Lšœ œ˜Jšœœ˜$Lšœ œ$˜1L˜Lšœ œ˜%L˜Lšœ™L˜šœ œ˜+Lšœ!™!—L˜Lšœœ˜3Lšœœ˜/Lšœ œ˜+Lšœ œ˜-Lšœœ˜3—K™L™L˜šฯnœœNœ œCœœœœ œ'œ˜Lšœพ™พ—šžœœ œNœ œCœœœœ œ%œ˜ปLšœฏ™ฏL˜—L˜Lšžœœœ$œœœœ˜fšœ+˜+L™GL™—š ž œœzœœœ˜ฎLšœง™ง—Lšž œœDœœ&œœœฯuœ˜ย˜Lšœf™fLšœFœ,™wL™J™fJ™—J™J˜šžœœ˜3J™ใJ™—š žœœŸœœ ŸœŸœ ˜‡Jšœ1ฯbœ  œ™N—š žœœŸœœ ŸœŸœ ˜€Jšœ< œ  œ™„—š  œœŸœœ ŸœŸœ ˜ŽJšœ< œ  œก™ž—J˜šžœœ!œ)˜nJšœ  œ  œ;™Q—š œœ&œ)˜tJšœ  œ3  œ™xJ˜—J˜š žœœœœœ™bJšœt™t—LšžœœŸœœ œœŸœœ˜˜˜Lšœw™w—Jš ž œœœœ œœ˜LJš žœœœ œœ˜LJš žœœ&œ œœ˜Z™L™—šžœœ-œœœœœœœ œœ˜ฦLšœg™g—Lšžœœœœœœœœœ œœ˜ฟšžœœœœœœœœœ œœ˜ธL™ิ—L˜šžœœ œœ˜=Lšœ_™_L™—šžœœ/œ&œœ œœœœ˜ฆLšœช™ชL™—K™%Lšžœœœ˜7Lšžœœ˜0šžœœ˜-Lšœ3™3—K™QL™Lšž œœœ˜1LšžœœNœ œ˜vLšžœœNœ œ˜vL˜Lšž œœ6œœ!˜vLšžœœ6œœ!˜}Lšžœœ6œœ!˜{L˜Lšœ˜L˜—…—‚&ณ