SVCaretImpl.mesa
Copyright © 1987 by Xerox Corporation. All rights reserved.
Last edited by Bier on May 22, 1987 3:58:24 pm PDT
Contents: Routines for placing the skitter in a Gargoyle3D scene.
DIRECTORY
SVCoordSys, SVMatrix3d, SV2d, SV3d, SVAssembly, SVCaret, SVInterfaceTypes, SVModelTypes, SVSceneTypes, SVVector3d;
SVCaretImpl:
CEDAR
PROGRAM
IMPORTS SVCoordSys, SVMatrix3d, SVAssembly, SVVector3d
EXPORTS SVCaret =
BEGIN
AlignmentObject: TYPE = SVSceneTypes.AlignmentObject;
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;
skitter.attractor ← NIL;
};
Exists:
PUBLIC
PROC [skitter: Skitter]
RETURNS [
BOOL] = {
RETURN[skitter.alive];
};
GetPosition:
PUBLIC
PROC [skitter: Skitter]
RETURNS [skitter
World: Matrix4by4] = {
skitterWorld ← skitter.skitterWorld;
};
GetPoint:
PUBLIC
PROC [skitter: Skitter]
RETURNS [origin: Point3d] = {
origin ← SVMatrix3d.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, surfacePt
World: Point3d, normal
World: Vector3d, attractor: AlignmentObject] = {
skitterWorld: Matrix4by4;
IF attractor #
NIL
AND
ISTYPE[attractor, SliceDescriptor]
THEN {
sliceD: SliceDescriptor ← NARROW[attractor];
skitterWorld ← MakeAlignedMat[normalWorld, surfacePtWorld, sliceD.slice.coordSys];
skitter.attractor ← attractor;
skitter.primitive ← NIL;
}
ELSE {
skitterWorld ← SVMatrix3d.MakeHorizontalMatFromZAxis[normalWorld, surfacePtWorld];
skitter.attractor ← attractor;
skitter.primitive ← NIL;
};
PositionFromMatrix[skitter, cameraPt, skitterWorld];
};
NoAttractor:
PUBLIC
PROC [skitter: Skitter] = {
skitter.attractor ← NIL;
};
GetAttractor:
PUBLIC
PROC [skitter: Skitter]
RETURNS [attractor: AlignmentObject] = {
attractor ← skitter.attractor;
};
PositionFromMatrix:
PUBLIC
PROC [skitter: Skitter, cameraPt: Point2d, skitter
World: Matrix4by4] = {
skitter.alive ← TRUE;
skitter.cameraPt ← cameraPt;
skitter.skitterWorld ← skitterWorld;
};
MakeAlignedMat:
PROC [worldNormal: Vector3d, surfacePtInWorld: Point3d, cs: CoordSystem]
RETURNS [mat: Matrix4by4] = {
Create a Matrix4by4 with origin at surfacePtInWorld whose z axis is parallel to worldNormal and whose x zxis is orthogonal to both worldNormal and the y axis of cs in WORLD coordinates. Assume that cs.wrtWorld is accurate
yAxisOfCS: Vector3d ← SVMatrix3d.YAxisOfMatrix[SVCoordSys.WRTWorld[cs]];
xAxis: Vector3d;
IF SVVector3d.Parallel[yAxisOfCS, worldNormal]
THEN {
xAxis ← SVMatrix3d.XAxisOfMatrix[SVCoordSys.WRTWorld[cs]];
IF AntiParallel[yAxisOfCS, worldNormal] THEN xAxis ← SVVector3d.Negate[xAxis];
Allows positioning code to distinguish between top surfaces and bottom surfaces.
}
ELSE xAxis ← SVVector3d.CrossProduct[yAxisOfCS, worldNormal];
mat ← SVMatrix3d.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.