<> <> <> <> <<>> DIRECTORY CoordSys, Matrix3d, SV2d, SV3d, SVAssembly, SVCaret, SVInterfaceTypes, SVModelTypes, SVSceneTypes, SVVector3d; SVCaretImpl: CEDAR PROGRAM IMPORTS CoordSys, Matrix3d, SVAssembly, SVVector3d EXPORTS SVCaret = BEGIN CoordSystem: TYPE = SVModelTypes.CoordSystem; Point2d: TYPE = SV2d.Point2d; Point3d: TYPE = SV3d.Point3d; Matrix4by4: TYPE = SV3d.Matrix4by4; Primitive: TYPE = SVSceneTypes.Primitive; Skitter: TYPE = REF SkitterObj; SkitterObj: TYPE = SVSceneTypes.SkitterObj; Slice: TYPE = SVSceneTypes.Slice; SliceDescriptor: TYPE = SVSceneTypes.SliceDescriptor; Vector3d: TYPE = SV3d.Vector3d; Create: PUBLIC PROC RETURNS [skitter: Skitter] = { skitter _ NEW[SkitterObj]; }; Copy: PUBLIC PROC [from: Skitter, to: Skitter] = { to^ _ from^; }; Kill: PUBLIC PROC [skitter: Skitter] = { skitter.alive _ FALSE; }; Exists: PUBLIC PROC [skitter: Skitter] RETURNS [BOOL] = { RETURN[skitter.alive]; }; GetPosition: PUBLIC PROC [skitter: Skitter] RETURNS [skitterWorld: Matrix4by4] = { skitterWorld _ skitter.skitterWorld; }; GetPoint: PUBLIC PROC [skitter: Skitter] RETURNS [origin: Point3d] = { origin _ Matrix3d.OriginOfMatrix[skitter.skitterWorld]; }; SetAssemblyAndPrimitive: PUBLIC PROC [skitter: Skitter, assembly: Slice, primitive: Primitive] = { skitter.attractor _ SVAssembly.NewParts[assembly, NIL, [0,0,0], slice]; skitter.primitive _ primitive; }; SetAttractor: PUBLIC PROC [skitter: Skitter, cameraPt: Point2d, surfacePtWorld: Point3d, normalWorld: Vector3d, attractor: SliceDescriptor] = { skitterWorld: Matrix4by4; IF attractor # NIL THEN { skitterWorld _ MakeAlignedMat[normalWorld, surfacePtWorld, attractor.slice.coordSys]; skitter.attractor _ attractor; skitter.primitive _ NIL; } ELSE { skitterWorld _ Matrix3d.MakeHorizontalMatFromZAxis[normalWorld, surfacePtWorld]; skitter.attractor _ NIL; skitter.primitive _ NIL; }; PositionFromMatrix[skitter, cameraPt, skitterWorld]; }; NoAttractor: PUBLIC PROC [skitter: Skitter] = { skitter.attractor _ NIL; }; GetAttractor: PUBLIC PROC [skitter: Skitter] RETURNS [attractor: SliceDescriptor] = { attractor _ skitter.attractor; }; PositionFromMatrix: PUBLIC PROC [skitter: Skitter, cameraPt: Point2d, skitterWorld: Matrix4by4] = { skitter.alive _ TRUE; skitter.cameraPt _ cameraPt; skitter.skitterWorld _ skitterWorld; }; MakeAlignedMat: PROC [worldNormal: Vector3d, surfacePtInWorld: Point3d, cs: CoordSystem] RETURNS [mat: Matrix4by4] = { <> yAxisOfCS: Vector3d _ Matrix3d.YAxisOfMatrix[CoordSys.WRTWorld[cs]]; xAxis: Vector3d; IF SVVector3d.Parallel[yAxisOfCS, worldNormal] THEN { xAxis _ Matrix3d.XAxisOfMatrix[CoordSys.WRTWorld[cs]]; IF AntiParallel[yAxisOfCS, worldNormal] THEN xAxis _ SVVector3d.Negate[xAxis]; <> } ELSE xAxis _ SVVector3d.CrossProduct[yAxisOfCS, worldNormal]; mat _ Matrix3d.MakeMatFromZandXAxis[worldNormal, xAxis, surfacePtInWorld]; }; AntiParallel: PROC [v1, v2: Vector3d] RETURNS [BOOL] = { RETURN[Sign[v1[1]] = -Sign[v2[1]] OR Sign[v1[2]] = -Sign[v2[2]] OR Sign[v1[3]] = -Sign[v2[3]] ]; }; Sign: PROC [r: REAL] RETURNS [INT] = { IF r = 0.0 THEN RETURN[2]; IF r < 0.0 THEN RETURN[-1] ELSE RETURN[1]; }; END.