Controls3dImpl:
CEDAR
PROGRAM
IMPORTS Controls, Draw2d, Draw3d, Matrix3d, Real, RealFns, Rope, Vector3d, ViewerOps
EXPORTS Controls3d
~ BEGIN
OPEN Controls3d;
ControlType: TYPE ~ Controls.ControlType;
ControlList: TYPE ~ Controls.ControlList;
cameraMatrix: Matrix3d.Matrix;
InitCamera:
PUBLIC
PROC [pan, tilt, roll:
REAL ← 0.0, zoom:
REAL ← 1.0, dx, dy, dz:
REAL ← 0.0, fov:
REAL ← 40.0, proc: ControlProc ←
NIL, data:
REF
ANY ←
NIL, cam: Camera ←
NIL]
RETURNS [Camera] ~ {
c: Camera ← IF cam # NIL THEN cam ELSE NEW[CameraRec];
c.pan ← Controls.NewControl["pan", circ, , 0.0, 360.0, pan, , , , proc, data];
c.tilt ← Controls.NewControl["tilt", circ, , 0.0, 360.0, tilt, , , , proc, data];
c.roll ← Controls.NewControl["roll", circ, , 0.0, 360.0, roll, , , , proc, data];
c.zoom ← Controls.NewControl["zoom", vert, , 0.0, 40.0, zoom, , , , proc, data];
c.dx ← Controls.NewControl["dx", vert, , -10.0, 10.0, dx, , , , proc, data];
c.dy ← Controls.NewControl["dy", vert, , -10.0, 10.0, dy, , , , proc, data];
c.dz ← Controls.NewControl["dz", vert, , -10.0, 10.0, dz, , , , proc, data];
c.fov ← Controls.NewControl["fov", vert, , 0.0, 100.0, fov, , , , proc, data];
SetCamera[c];
RETURN[c];
};
GetCamera: PUBLIC PROC RETURNS [Matrix] ~ {RETURN[cameraMatrix]};
GetCameraNoFOV:
PUBLIC
PROC [pan, tilt, roll, dx, dy, dz:
REAL ← 0.0, zoom:
REAL ← 1.0]
RETURNS [m: Matrix] ~ {
m ← Matrix3d.Identity[];
m ← Matrix3d.LocalTranslate[m, [dx, dy, dz], m];
m ← Matrix3d.LocalScale[m, zoom, m];
m ← Matrix3d.LocalRotate[m, [0.0, 1.0, 0.0], pan,,, m];
m ← Matrix3d.LocalRotate[m, [0.0, 0.0, 1.0], tilt,,, m];
m ← Matrix3d.LocalRotate[m, [1.0, 0.0, 0.0], roll,,, m];
};
SetCamera:
PUBLIC
PROC [c: Camera] ~ {
SetCameraVals[c.pan.val, c.tilt.val, c.roll.val, c.zoom.val, c.dx.val, c.dy.val, c.dz.val, c.fov.val];
};
SetCameraVals:
PUBLIC
PROC [pan, tilt, roll:
REAL ← 0., zoom:
REAL ← 1., dx, dy, dz, fov:
REAL ← 0.] ~ {
cameraMatrix ←
IF fov = 0.0
THEN Matrix3d.Identity[cameraMatrix]
ELSE Matrix3d.MakePerspective[0.1, 0.0, fov, cameraMatrix];
cameraMatrix ← Matrix3d.LocalTranslate[cameraMatrix, [dx, dy, dz], cameraMatrix];
cameraMatrix ← Matrix3d.LocalScale[cameraMatrix, zoom, cameraMatrix];
cameraMatrix ← Matrix3d.LocalRotate[cameraMatrix, [0.0, 1.0, 0.0], pan,,, cameraMatrix];
cameraMatrix ← Matrix3d.LocalRotate[cameraMatrix, [0.0, 0.0, 1.0], tilt,,, cameraMatrix];
cameraMatrix ← Matrix3d.LocalRotate[cameraMatrix, [1.0, 0.0, 0.0], roll,,, cameraMatrix];
};
InitHold:
PUBLIC PROC [proc: ControlProc ←
NIL, data:
REF
ANY ←
NIL, hold: Hold ←
NIL]
RETURNS [Hold] ~ {
h: Hold ← IF hold # NIL THEN hold ELSE NEW[HoldRec];
h.dx ← Controls.NewControl["ptx", vert, , -1.0, 1.0, 0.0, , , , proc, data];
h.dy ← Controls.NewControl["pty", vert, , -1.0, 1.0, 0.0, , , , proc, data];
h.dz ← Controls.NewControl["ptz", vert, , -1.0, 1.0, 0.0, , , , proc, data];
h.lng ← Controls.NewControl["lng", circ, , 0.0, 360.0, 0.0, , , , proc, data];
h.lat ← Controls.NewControl["lat", circ, , 0.0, 360.0, 0.0, , , , proc, data];
h.mag ← Controls.NewControl["mag", vert, , -2.0, 2.0, 0.0, , , , proc, data];
RETURN[h];
};
FocusHold:
PUBLIC
PROC [tan: Triple, hold: Controls3d.Hold] ~ {
vlng, vlat, vmag: REAL;
[[vlng, vlat, vmag]] ← Vector3d.PolarFromCartesian[tan];
Controls.SetControlVal[hold.lng, vlng];
Controls.SetControlVal[hold.lat, vlat];
Controls.SetControlVal[hold.mag, vmag];
Controls.SetControlVal[hold.dx, 0.0];
Controls.SetControlVal[hold.dy, 0.0];
Controls.SetControlVal[hold.dz, 0.0];
};
GetView:
PUBLIC
PROC [w, h:
INTEGER, in: Matrix ←
NIL]
RETURNS [Matrix] ~ {
v: ViewPort ← GetViewPort[w, h];
Translate and scale to viewport; don't scale z so can compare z with w for near clipping:
RETURN[
Matrix3d.Translate[
Matrix3d.DiffScale[cameraMatrix, [v.xs, v.ys, 1.0]],
[v.xo, v.yo, 0.0],
in]];
};
InitPix:
PUBLIC
PROC [context: Context, w, h:
INTEGER, in: Matrix ←
NIL]
RETURNS [Matrix] ~ {
Draw2d.ClearContext[context, 0, 0, w, h];
RETURN[GetView[w, h, in]];
};
GetViewPort:
PUBLIC PROC [w, h:
INTEGER]
RETURNS [ViewPort] ~ {
xo: INTEGER ← w/2;
yo: INTEGER ← h/2;
s: REAL ← 0.9*Real.Round[MIN[xo, yo]];
RETURN[[xo, yo, s, s]];
};
ShowVec:
PUBLIC PROC [vec: VecData, context: Context, view: Matrix] ~ {
Draw3d.V[vec.v, vec.name, context, view];
};
PTControl:
PROC [name:
ROPE ← NIL, type: ControlType, trunc:
BOOL ← FALSE, min, max, init:
REAL, proc: ControlProc, data:
REF
ANY]
RETURNS [ControlData] ~ {
RETURN[Controls.NewControl[name, type, , min, max, init, trunc, , , proc, data]];
};
InitScal:
PUBLIC
PROC [name:
ROPE ←
NIL, type: ControlType, trunc:
BOOL ←
FALSE, min, max, init:
REAL]
RETURNS [ScalData] ~ {
scal: ScalData ← NEW[ScalDataRec ← [name: name, val: init]];
scal.C ← PTControl[name, type, trunc, min, max, init, NIL, scal];
RETURN[scal];
};
ComputeVec:
PUBLIC
PROC [vec: VecData, x, y, z:
REAL, polar:
BOOL ←
FALSE] ~ {
IF polar
THEN {
cosmag: REAL ← RealFns.CosDeg[y]*z;
vec.lng ← x; vec.lat ← y; vec.mag ← z;
vec.v.x ← cosmag*RealFns.CosDeg[vec.lng];
vec.v.z ← cosmag*RealFns.SinDeg[vec.lng];
vec.v.y ← z*RealFns.SinDeg[vec.lat];
}
ELSE {
xzSum: REAL ← x*x+z*z;
vec.v ← [x, y, z];
vec.lng ← RealFns.ArcTanDeg[z, x];
vec.lat ← RealFns.ArcTanDeg[y, Real.SqRt[xzSum]];
IF vec.lat < 0.0 THEN vec.lat ← 360.0+vec.lat;
vec.mag ← Real.SqRt[xzSum+y*y];
};
};
InitVec:
PUBLIC
PROC [name:
ROPE ←
NIL, v: Triple ← [0.0, 0.0, 0.0], polar, cartesian:
BOOL ←
TRUE, min:
REAL ← -5.0, max:
REAL ← 5.0]
RETURNS [VecData] ~ {
vec: VecData ← NEW[VecDataRec ← [name: name]];
ComputeVec[vec, v.x, v.y, v.z];
IF polar
THEN {
vec.lngC ← PTControl[Rope.Concat[name, ": lng"], circ, , 360.0, 0.0, vec.lng, Lng, vec];
vec.latC ← PTControl["lat", circ, FALSE, 360.0, 0.0, vec.lat, Lat, vec];
vec.magC ← PTControl["mag", vert, FALSE, -5.0, 5.0, vec.mag, Mag, vec];
};
IF cartesian
THEN {
vec.xC ← PTControl["x", vert, FALSE, min, max, vec.v.x, X, vec];
vec.yC ← PTControl["y", vert, FALSE, min, max, vec.v.y, Y, vec];
vec.zC ← PTControl["z", vert, FALSE, min, max, vec.v.z, Z, vec];
};
RETURN[vec];
};
SetVec:
PUBLIC
PROC [vec: VecData, x, y, z:
REAL, polar:
BOOL ←
FALSE, c: Controls.ControlData ←
NIL, val:
REAL] ~ {
ComputeVec[vec, x, y, z, polar];
IF polar
THEN {
IF vec.xC # NIL THEN Controls.SetControlVal[vec.xC, vec.v.x];
IF vec.yC # NIL THEN Controls.SetControlVal[vec.yC, vec.v.y];
IF vec.zC # NIL THEN Controls.SetControlVal[vec.zC, vec.v.z];
}
ELSE {
IF vec.lngC # NIL THEN Controls.SetControlVal[vec.lngC, vec.lng];
IF vec.latC # NIL THEN Controls.SetControlVal[vec.latC, vec.lat];
IF vec.magC # NIL THEN Controls.SetControlVal[vec.magC, vec.mag];
};
IF c # NIL THEN Controls.SetControlVal[c, val];
};
PaintControls:
PUBLIC
PROC [c1, c2, c3, c4, c5, c6: Controls.ControlData ←
NIL] ~ {
IF c1 # NIL THEN ViewerOps.PaintViewer[c1.viewer, client, FALSE, c1];
IF c2 # NIL THEN ViewerOps.PaintViewer[c2.viewer, client, FALSE, c2];
IF c3 # NIL THEN ViewerOps.PaintViewer[c3.viewer, client, FALSE, c2];
IF c4 # NIL THEN ViewerOps.PaintViewer[c3.viewer, client, FALSE, c2];
IF c5 # NIL THEN ViewerOps.PaintViewer[c3.viewer, client, FALSE, c2];
IF c6 # NIL THEN ViewerOps.PaintViewer[c3.viewer, client, FALSE, c2];
};
ReviseVec:
PUBLIC PROC [vec: VecData, val:
REAL, type: CoordType] ~ {
SELECT type
FROM
lng => SetVec[vec, val, vec.lat, vec.mag, TRUE, vec.lngC, val];
lat => SetVec[vec, vec.lng, val, vec.mag, TRUE, vec.latC, val];
mag => SetVec[vec, vec.lng, vec.lat, val, TRUE, vec.magC, val];
x => SetVec[vec, val, vec.v.y, vec.v.z, FALSE, vec.xC, val];
y => SetVec[vec, vec.v.x, val, vec.v.z, FALSE, vec.yC, val];
z => SetVec[vec, vec.v.x, vec.v.y, val, FALSE, vec.zC, val];
ENDCASE => NULL;
};
ResetVec:
PUBLIC
PROC [vec: Controls3d.VecData, p: Triple, polar:
BOOL ←
FALSE] ~ {
ComputeVec[vec, p.x, p.y, p.z, polar];
IF vec.lngC # NIL THEN Controls.SetControlVal[vec.lngC, vec.lng];
IF vec.latC # NIL THEN Controls.SetControlVal[vec.latC, vec.lat];
IF vec.magC # NIL THEN Controls.SetControlVal[vec.magC, vec.mag];
IF vec.xC # NIL THEN Controls.SetControlVal[vec.xC, vec.v.x];
IF vec.yC # NIL THEN Controls.SetControlVal[vec.yC, vec.v.y];
IF vec.zC # NIL THEN Controls.SetControlVal[vec.zC, vec.v.z];
};
Lng: ControlProc ~ {ReviseVec[NARROW[control.data, VecData], control.val, lng]};
Lat: ControlProc ~ {ReviseVec[NARROW[control.data, VecData], control.val, lat]};
Mag: ControlProc ~ {ReviseVec[NARROW[control.data, VecData], control.val, mag]};
X: ControlProc ~ {ReviseVec[NARROW[control.data, VecData], control.val, x]};
Y: ControlProc ~ {ReviseVec[NARROW[control.data, VecData], control.val, y]};
Z: ControlProc ~ {ReviseVec[NARROW[control.data, VecData], control.val, z]};
END.
..