-- File: CoordSys.mesa
-- Last edited by Bier on January 12, 1983 3:13 pm
-- Author: Eric Bier in June, 1982
-- Contents: Allocation and access to a user-specified set of named coordinate systems

DIRECTORY
 Matrix3d,
 Rope,
 SVVector3d;

CoordSys: DEFINITIONS =
BEGIN

Matrix4by4: TYPE = Matrix3d.Matrix4by4;
Point2d: TYPE = Matrix3d.Point2d;
Point3d: TYPE = Matrix3d.Point3d;
Vector: TYPE = SVVector3d.Vector;

CoordSystem: TYPE = REF CoordSysObj;
CoordSysObj: TYPE = RECORD [
 name: Rope.ROPE,
 mat: Matrix4by4,
 wrtCamera: Matrix4by4,
 wrtWorld: Matrix4by4,
 cameraWRTlocal: Matrix4by4,
 worldWRTlocal: Matrix4by4,
 withRespectTo: CoordSystem];
CoordSysList: TYPE = LIST OF CoordSystem;

InitialCoordSysList: PUBLIC PROC RETURNS [csl: CoordSysList]; -- puts together a CoordSysList with WORLD, and SCREEN in it.

SortCoordSysListByBreadth: PUBLIC PROC [csl: CoordSysList] RETURNS [sortedCsl: CoordSysList];

CreateCoordSys: PROC [name: Rope.ROPE, mat: Matrix4by4, withRespectTo: CoordSystem] RETURNS [newCS: CoordSystem];

FindCoordSysFromName: PROC [name: Rope.ROPE, csl: CoordSysList] RETURNS [cs: CoordSystem];
CoordSysNotFound: SIGNAL;
CoordSysListEmpty: SIGNAL;

FindCoordSysAndNeighborsFromName: PROC [name: Rope.ROPE, csl: CoordSysList] RETURNS [beforeCS, cs, afterCS: CoordSysList];
-- signals CoordSysNotFound if that is the case.

CameraToScreen: PROC [cameraPoint2d: Point2d, screenCoordSys: CoordSystem] RETURNS [screenPoint2d: Point2d];
ScreenToCamera: PUBLIC PROC [screenPoint2d: Point2d, screenCoordSys: CoordSystem] RETURNS [cameraPoint2d: Point2d];

-- getting a generator given a list is very silly. This will probably go away.
GetGenerator: PROC [csl: CoordSysList] RETURNS [g: Generator];
Generator: TYPE = REF GeneratorObj;
GeneratorObj: TYPE = RECORD [currentPtr: LIST OF CoordSystem];
Next: PROC [g: Generator] RETURNS [cs: CoordSystem];

FindInTermsOfWorld: PROC [cs: CoordSystem] RETURNS [mat: Matrix4by4];
FindInTermsOfCamera: PROC [cs: CoordSystem, camera: CoordSystem] RETURNS [mat: Matrix4by4];
TellAboutParent: PROC [cs: CoordSystem];
-- updates the wrtWorld, and wrtCamera fields of cs by premultiplying cs.mat by cs.withRespectTo.wrtWorld and cs.withRespectTo.wrtCamera respectively
FindAinTermsOfB: PROC [a: CoordSystem, b: CoordSystem] RETURNS [mat: Matrix4by4];
-- the above three procs return the relevant matrix with no side effects
FindTranslationOfAinTermsOfB: PROC [a: CoordSystem, b: CoordSystem] RETURNS [displacements: Vector];

TPutAinTermsOfB: PROC [a: CoordSystem, b: CoordSystem] RETURNS [mat: Matrix4by4];
-- finds the matrix and redefines CoordSystem a to be in terms of b from now on.

TPlaceAwrtB: PROC [a: CoordSystem, b: CoordSystem ← NIL, aWRTb: Matrix4by4];
-- places a in WORLD so that the transform from b to a is aWRTb. Updates a with respect to its immediate reference (a.withRespectTo) accordingly.
TPlaceTranslationAwrtB: PROC [a: CoordSystem, b: CoordSystem ← NIL, origin: Point3d];
-- places a in WORLD so that the rotation from a to b remains as it is, but the translation is set to origin. Updates a with respect to its immediate reference (a.withRespectTo) accordingly.

TTranslateAwrtB: PROC [a: CoordSystem, b: CoordSystem ← NIL, tx, ty, tz: REAL];
TXRotateAwrtB: PROC [a: CoordSystem, b: CoordSystem ← NIL, degrees: REAL];
TYRotateAwrtB: PROC [a: CoordSystem, b: CoordSystem ← NIL, degrees: REAL];
TZRotateAwrtB: PROC [a: CoordSystem, b: CoordSystem ← NIL, degrees: REAL];
TAlignAwrtB: PROC [a: CoordSystem, b: CoordSystem ← NIL];
-- rotate A as little as possible to align its three axes parallel to three of the axes of B (though not necessarily the same three).
TAbutAwrtB: PROC [a: CoordSystem, b: CoordSystem ← NIL];
TAbutXAwrtB: PROC [a: CoordSystem, b: CoordSystem ← NIL];
TAbutYAwrtB: PROC [a: CoordSystem, b: CoordSystem ← NIL];
TAbutZAwrtB: PROC [a: CoordSystem, b: CoordSystem ← NIL];

-- these perform the named transform but do not change the coordinate system with respect to which CoordSystem a is defined.
-- when b is NIL, assumes b = WORLD.
-- for local transforms, let b = a.



END.