<> <> <> DIRECTORY Controls, Draw2d, Draw3d, Imager, Matrix3d, Controls3d, Real, RealFns, Rope, Vector3d, ViewerOps; 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["zum", 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]}; 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[1000.0, 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.ControlVal[hold.lng, vlng]; Controls.ControlVal[hold.lat, vlat]; Controls.ControlVal[hold.mag, vmag]; Controls.ControlVal[hold.dx, 0.0]; Controls.ControlVal[hold.dy, 0.0]; Controls.ControlVal[hold.dz, 0.0]; }; GetView: PUBLIC PROC [w, h: INTEGER, in: Matrix _ NIL] RETURNS [Matrix] ~ { v: ViewPort _ GetViewPort[w, h]; <> 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.ControlVal[vec.xC, vec.v.x]; IF vec.yC # NIL THEN Controls.ControlVal[vec.yC, vec.v.y]; IF vec.zC # NIL THEN Controls.ControlVal[vec.zC, vec.v.z]; } ELSE { IF vec.lngC # NIL THEN Controls.ControlVal[vec.lngC, vec.lng]; IF vec.latC # NIL THEN Controls.ControlVal[vec.latC, vec.lat]; IF vec.magC # NIL THEN Controls.ControlVal[vec.magC, vec.mag]; }; IF c # NIL THEN Controls.ControlVal[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.ControlVal[vec.lngC, vec.lng]; IF vec.latC # NIL THEN Controls.ControlVal[vec.latC, vec.lat]; IF vec.magC # NIL THEN Controls.ControlVal[vec.magC, vec.mag]; IF vec.xC # NIL THEN Controls.ControlVal[vec.xC, vec.v.x]; IF vec.yC # NIL THEN Controls.ControlVal[vec.yC, vec.v.y]; IF vec.zC # NIL THEN Controls.ControlVal[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. ..