Copyright (C) 1994, Digital Equipment Corp.
Digital Internal Use Only
Created on Mon Feb 14 16:01:56 PST 1994 by najork
MODULE*************************************************************************** Module body ***************************************************************************OrthoCameraGO EXPORTSOrthoCameraGO ,OrthoCameraGOProxy ; IMPORT CameraGO, CameraGOPrivate, GO, GOPrivate, GraphicsBase, GraphicsBasePrivate, Matrix4, Mth, Point3, PointProp, PointPropPrivate, Prop, RealProp, RealPropPrivate, TransformPropPrivate; PROCEDURENew (from, to, up : Point3.T; height : REAL) : T = VAR cam := NEW (T).init (); BEGIN cam.setProp (CameraGO.From.bind (PointProp.NewConst (from))); cam.setProp (CameraGO.To.bind (PointProp.NewConst (to))); cam.setProp (CameraGO.Up.bind (PointProp.NewConst (up))); cam.setProp (Height.bind (RealProp.NewConst (height))); RETURN cam; END New; REVEAL T = Public BRANDED OBJECT lookat : Matrix4.T; aspect : REAL; height : REAL; OVERRIDES init := Init; draw := Draw; view := View; damageIfDependent := DamageIfDependent; END; PROCEDUREInit (self : T) : T = BEGIN EVAL CameraGO.T.init (self); IF MkProxyT # NIL AND self.proxy = NIL THEN MkProxyT (self); END; RETURN self; END Init; PROCEDUREDamageIfDependent (self : T; pn : Prop.Name) = BEGIN IF pn = CameraGO.From OR pn = CameraGO.To OR pn = CameraGO.Up OR pn = CameraGO.Aspect OR pn = Height OR pn = GO.Transform THEN self.damaged := TRUE; END; END DamageIfDependent; PROCEDUREDraw (self : T; state : GraphicsBase.T) = BEGIN IF self.damaged THEN state.push (self); WITH tm = GO.Transform.getState (state), from = Matrix4.TransformPoint3 (tm, CameraGO.From.getState (state)), to = Matrix4.TransformPoint3 (tm, CameraGO.To.getState (state)), up = Matrix4.TransformPoint3 (tm, CameraGO.Up.getState (state)) DO self.lookat := Matrix4.LookatViewMatrix (from, to, up); self.flag := TRUE; self.aspect := CameraGO.Aspect.getState (state); self.height := Height.getState (state); self.damaged := FALSE; END; (* If the transformation state contains a non-uniform matrix, the viewing parallelepiped might be distorted. In this case, it is not possible to determine a correct value for height ... *) state.pop (self); END; END Draw; PROCEDUREView (self : T; state : GraphicsBase.T) = VAR near : REAL; far : REAL; BEGIN self.flag := FALSE; (*** map the bounding sphere into viewing coordinates ***) WITH bs = state.getBoundingVolume(), tm = self.lookat, center = Point3.T { tm[0][0] * bs.center.x + tm[0][1] * bs.center.y + tm[0][2] * bs.center.z + tm[0][3], tm[1][0] * bs.center.x + tm[1][1] * bs.center.y + tm[1][2] * bs.center.z + tm[1][3], tm[2][0] * bs.center.x + tm[2][1] * bs.center.y + tm[2][2] * bs.center.z + tm[2][3]}, radius = bs.radius * Mth.sqrt (tm[0][0] * tm[0][0] + tm[1][0] * tm[1][0] + tm[2][0] * tm[2][0]) DO near := center.z + radius; far := center.z - radius; (* Handle singularity "near = far" *) IF near = far THEN near := near + 0.01; far := far - 0.01; END; END; (*** Set the viewing and projection transformations. ***) state.setViewProjTransform (self.lookat, Matrix4.OrthoProjMatrix (self.height, self.aspect, near, far)); END View;
BEGIN Height := NEW (RealProp.Name).init (10.0); END OrthoCameraGO.