DIRECTORY AtomButtonsTypes, CastRays, CoordSys, CSG, DisplayListToTree, IO, Matrix3d, Preprocess3d, Real, SV2d, SV3d, SVGravity, SVLines3d, SVModelTypes, SVRayTypes, SVScene, SVSceneTypes; SVGravityImpl: CEDAR PROGRAM IMPORTS CastRays, CoordSys, CSG, DisplayListToTree, Matrix3d, Preprocess3d, SVLines3d, SVScene EXPORTS SVGravity = BEGIN Assembly: TYPE = SVSceneTypes.Assembly; Camera: TYPE = SVSceneTypes.Camera; Classification: TYPE = SVRayTypes.Classification; CSGTree: TYPE = SVRayTypes.CSGTree; FeedbackData: TYPE = AtomButtonsTypes.FeedbackData; Matrix4by4: TYPE = SV3d.Matrix4by4; Point2d: TYPE = SV2d.Point2d; Point3d: TYPE = SV3d.Point3d; PointAndDone: TYPE = SVSceneTypes.PointAndDone; PointGenerator: TYPE = SVSceneTypes.PointGenerator; Primitive: TYPE = SVRayTypes.Primitive; Ray: TYPE = SVRayTypes.Ray; Scene: TYPE = SVSceneTypes.Scene; SearchDepth: TYPE = SVRayTypes.SearchDepth; Shape: TYPE = SVSceneTypes.Shape; Vector3d: TYPE = SV3d.Vector3d; Line3d: TYPE = SV3d.Line3d; MasterObject: TYPE = SVSceneTypes.MasterObject; MasterObjectDescriptor: TYPE = SVSceneTypes.MasterObjectDescriptor; MasterObjectDescriptorObj: TYPE = SVSceneTypes.MasterObjectDescriptorObj; PointsOrSurfaces: PUBLIC PROC [cameraPoint: Point2d, camera: Camera, scene: Scene, tree: CSGTree, criticalR: REAL, searchDepth: SearchDepth] RETURNS [surfacePtWORLD: Point3d, normalWORLD: Vector3d, assembly: Assembly] = { pointsPtWORLD: Point3d; pointsNormalWORLD: Vector3d; pointsAssembly: Assembly; parallel: BOOL; rayWORLD: Ray _ GetWorldRayFromCameraPoint[cameraPoint, camera]; -- from pool [surfacePtWORLD, normalWORLD, assembly] _ RayAtSurfaces[rayWORLD, cameraPoint, camera, scene, tree, criticalR, searchDepth]; [pointsPtWORLD, pointsNormalWORLD, pointsAssembly] _ RayAtPoints[rayWORLD, scene, camera, criticalR]; IF WithinTolerance[pointsPtWORLD, rayWORLD, criticalR] THEN { surfacePtWORLD _ pointsPtWORLD; IF pointsAssembly # assembly THEN { normalWORLD _ pointsNormalWORLD; assembly _ pointsAssembly; }; }; IF assembly = NIL THEN { [surfacePtWORLD, normalWORLD, parallel] _ RayMeetsCentralCameraPlane[cameraPoint, camera]; }; CSG.ReturnRayToPool[rayWORLD]; }; LineFromRay: PROC [ray: Ray] RETURNS [line: Line3d] = { basePt: Point3d; direction: Vector3d; [basePt, direction] _ CSG.GetWorldRay[ray]; line _ SVLines3d.LineFromPointAndVector[basePt, direction]; }; WithinTolerance: PROC [point: Point3d, rayWORLD: Ray, criticalR: REAL] RETURNS [BOOL] = { line: Line3d; dist: REAL; line _ LineFromRay[rayWORLD]; dist _ SVLines3d.DistancePointToLine[point, line]; RETURN[dist <= criticalR]; }; GetWorldRayFromCameraPoint: PROC [cameraPoint: Point2d, camera: Camera] RETURNS [rayWORLD: Ray] = { rayCamera: Ray; cameraWORLD: Matrix4by4 _ CoordSys.FindInTermsOfWorld[camera.coordSys]; rayCamera _ CSG.GetRayFromPool[]; CSG.StuffCameraRay[rayCamera, cameraPoint, camera]; rayWORLD _ CSG.TransformRayToWorld[rayCamera, cameraWORLD]; -- allocates ray from pool CSG.ReturnRayToPool[rayCamera]; }; RayAtSurfaces: PROC [rayWorld: Ray, cameraPoint: Point2d, camera: Camera, scene: Scene, tree: CSGTree, criticalR: REAL, searchDepth: SearchDepth] RETURNS [surfacePtWorld: Point3d, normalWorld: Vector3d, assembly: Assembly] = { class: Classification; primitive: Primitive; IF tree.outOfDate THEN { tree _ DisplayListToTree.AssemblyToTree[scene.assembly, scene, camera, tree]; [] _ Preprocess3d.PreprocessForInteraction[tree, camera]; tree.outOfDate _ FALSE; }; class _ SingleRay[rayWorld, cameraPoint, tree, TRUE, NIL]; -- from pool [assembly, primitive] _ AssemblyAndPrimitiveAtSearchDepth[class, searchDepth, scene.assembly]; IF class.count > 0 THEN [surfacePtWorld, normalWorld] _ SurfacePointAndNormalAtSearchDepth[class, rayWorld, searchDepth, scene.assembly]; CastRays.ReturnClassToPool[class]; }; AssemblyAndPrimitiveAtSearchDepth: PROC [class: Classification, searchDepth: SearchDepth, root: Assembly] RETURNS [assembly: Assembly, primitive: Primitive] = { SELECT searchDepth FROM first => [assembly, primitive] _ CastRays.NthAssemblyAndPrimitive[class, 1]; lastOfFirst => [assembly, primitive] _ CastRays.NthAssemblyAndPrimitive[class, 1]; last => [assembly, primitive] _ CastRays.NthAssemblyAndPrimitive[class, class.count]; lastOfLevel1 => [assembly, primitive] _ CastRays.LastTopLevelAssemAndPrim[class, root]; ENDCASE => ERROR; }; SurfacePointAndNormalAtSearchDepth: PROC [class: Classification, rayWorld: Ray, searchDepth: SearchDepth, root: Assembly] RETURNS [surfacePtWorld: Point3d, normalWorld: Vector3d] = { SELECT searchDepth FROM first => [surfacePtWorld, normalWorld] _ CastRays.NthSurfacePointAndNormal[class, rayWorld, 1]; lastOfFirst => [surfacePtWorld, normalWorld] _ CastRays.LastOfFirstPointAndNormal[class, rayWorld]; last => IF class.count = 0 THEN ERROR ELSE [surfacePtWorld, normalWorld] _ CastRays.NthSurfacePointAndNormal[class, rayWorld, class.count]; lastOfLevel1 => [surfacePtWorld, normalWorld] _ CastRays.LastTopLevelPointAndNormal[class, rayWorld, root]; ENDCASE => ERROR; }; SingleRay: PUBLIC PROC [rayWorld: Ray, cameraPoint: Point2d, tree: CSGTree, consolidate: BOOL _ TRUE, feedback: FeedbackData, makeStream: BOOL _ FALSE] RETURNS [class: Classification] = { topNode: REF ANY _ tree.son; class _ CastRays.RayCast[cameraPoint, rayWorld, topNode, consolidate, feedback, makeStream, 0]; }; -- end of SingleRay RayAtPoints: PROC [ray: Ray, scene: Scene, camera: Camera, criticalR: REAL] RETURNS [bestPoint: Point3d, bestNormal: Vector3d, bestAssembly: Assembly] = { primList: LIST OF Assembly _ SVScene.ListOfPrimAssemblies[scene.assembly, scene]; line3d: Line3d; bestDist, thisDist: REAL; pointWORLD: Point3d; pointGen: PointGenerator; shape: Shape; assembly: Assembly; mo: MasterObject; moWORLD: Matrix4by4; moD: MasterObjectDescriptor; line3d _ LineFromRay[ray]; bestDist _ Real.LargestNumber; bestAssembly _ NIL; FOR list: LIST OF Assembly _ primList, list.rest UNTIL list = NIL DO assembly _ list.first; shape _ NARROW[assembly.shape]; mo _ shape.mo; moWORLD _ CoordSys.FindInTermsOfWorld[shape.coordSys]; moD _ NEW[MasterObjectDescriptorObj _ [mo, NIL]]; pointGen _ mo.class.pointsInDescriptor[moD]; FOR pointAndDone: PointAndDone _ mo.class.nextPoint[pointGen], mo.class.nextPoint[pointGen] UNTIL pointAndDone.done = TRUE DO pointWORLD _ Matrix3d.Update[pointAndDone.point, moWORLD]; thisDist _ SVLines3d.DistancePointToLine[pointWORLD, line3d]; IF thisDist < bestDist THEN { bestDist _ thisDist; bestPoint _ pointWORLD; bestAssembly _ assembly; }; ENDLOOP; ENDLOOP; bestNormal _ Matrix3d.ZAxisOfMatrix[CoordSys.FindInTermsOfWorld[camera.coordSys]]; }; RayMeetsCameraPlane: PROC [cameraPoint: Point2d, depth: REAL, camera: Camera] RETURNS [planePtCamera: Point3d, parallel: BOOL] = { rayWorld: Ray; worldCamera: Matrix4by4; planePtWorld: Point3d; rayWorld _ CSG.GetRayFromPool[]; CSG.StuffWorldRayFromCamera[rayWorld, cameraPoint, camera]; [planePtWorld, parallel] _ CastRays.RayMeetsPlaneOfCoordSystem[camera.coordSys, rayWorld, 3, depth]; worldCamera _ CoordSys.FindAInTermsOfB[camera.coordSys.parent, camera.coordSys]; planePtCamera _ Matrix3d.Update[planePtWorld, worldCamera]; CSG.ReturnRayToPool[rayWorld]; }; RayMeetsCentralCameraPlane: PROC [cameraPoint: Point2d, camera: Camera] RETURNS [pointWORLD: Point3d, normalWORLD: Vector3d, parallel: BOOL] = { worldCAMERA: Matrix4by4 _ CoordSys.FindWorldInTermsOf[camera.coordSys]; originCAMERA: Point3d _ Matrix3d.OriginOfMatrix[worldCAMERA]; depth: REAL _ originCAMERA[3]; rayWorld: Ray; rayWorld _ CSG.GetRayFromPool[]; CSG.StuffWorldRayFromCamera[rayWorld, cameraPoint, camera]; [pointWORLD, parallel] _ CastRays.RayMeetsPlaneOfCoordSystem[camera.coordSys, rayWorld, 3, depth]; normalWORLD _ Matrix3d.ZAxisOfMatrix[CoordSys.FindInTermsOfWorld[camera.coordSys]]; CSG.ReturnRayToPool[rayWorld]; }; END. ζSVGravityImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Last edited by Bier on February 17, 1987 11:19:15 pm PST Contents: Routines to snap the skitter to faces, segments, and points in the scene. Κ@˜J˜Icodešœ™Kšœ Οmœ1™˜ZK˜—Kšžœ œ˜K˜K˜—K˜šŸ œžœ žœ˜7Kšœ˜Kšœ˜Kšœžœ˜+Kšœ;˜;K˜K˜—š Ÿœžœ œžœžœžœ˜YKšœ ˜ Kšœžœ˜ Kšœ œ˜Kšœ2˜2Kšžœ˜K˜K˜—šŸœžœ(žœ œ ˜cIprocšœ œ˜Lšœ œ<˜GLšœ œžœ˜!Lšžœ œ˜3Lš œ œžœ œ œΟc˜VLšžœ œ˜K˜K˜—šŸ œžœ œUžœžœ  œ œ#˜βJšœ˜Jšœ˜šžœžœ˜JšœM˜MJšœ9˜9Jšœžœ˜J˜J˜—Jšœ/žœžœ’ ˜GJšœ^˜^šžœž˜Jšœ  œ œ1 œ˜qJ˜—Jšœ"˜"K˜K˜—šΠbnŸ œžœCžœ/˜ Jšžœ ž˜Jšœ*‘œ ˜LJšœ0‘œ ˜RJšœ)‘œ˜UJšœ1‘œ˜WJšžœžœ˜J˜J˜—š £Ÿ œžœ œ1žœ  œ œ˜ΆJšžœ ž˜šœ˜Jš œ  œ œ ‘œ  œ˜V—šœ˜Jš œ  œ œ ‘œ  œ˜T—šœ˜Jšžœžœž˜Jš žœ  œ œ ‘œ  œ˜e—šœ˜Jš œ  œ œ ‘œ  œ˜[—Jšžœžœ˜J˜J˜—šŸ œžœžœ œ9žœžœ&žœžœžœ˜»Lšœ žœžœ ˜Lšœ) œ1˜_Lšœ’˜—K˜šŸ œžœ5žœžœG˜šKšœ žœžœ@˜QKšœ˜Kšœžœ˜Kšœ œ ˜Kšœ˜Kšœ ˜ Kšœ˜Kšœ˜Kšœ œ ˜Kšœ˜K˜Kšœ˜Kšœ˜Kšœžœ˜š žœžœžœ žœžœž˜DKšœ˜Kšœžœ˜Kšœ˜Kšœ œ/˜6Kšœžœ"žœ˜1Kšœ,˜,šžœYžœžœž˜}Kšœ œ) œ˜:Kšœ. œ ˜=šžœžœ˜Kšœ˜Kšœ œ˜Kšœ˜K˜—Kšžœ˜—Kšžœ˜—KšœR˜RK˜K˜—K˜š Ÿœžœžœžœ  œžœ˜‚Jšœ œ˜Jšœ œ ˜Jšœ œ ˜Jšœ œžœ˜ Jšžœ œ˜;Jšœ œF œ ˜dJšœ œE˜PJšœ œ œ œ˜;Jšžœ œ˜J˜J˜—š Ÿœžœ(žœ œ œžœ˜Kšœ œ<˜GKšœ œ) œ˜=Kšœžœ  œ˜Jšœ œ˜Jšœ œžœ˜ Jšžœ œ˜;Jšœ œF œ ˜bKšœ œH˜SJšžœ œ˜K˜—K˜Kšžœ˜K˜J˜—…—|'’