DIRECTORY Atom USING [ GetPropFromList, PropList, PutPropOnList ], Real USING [ Fix, Float ], Rope USING [ ROPE ], G3dMatrix USING [ Transform, MakeRotate ], G3dSpline USING [ CoeffsSequence, Interpolate, InterpolateCyclic, Position ], ThreeDBasics USING [ Context, Error, Pair, PairSequence, ShapeInstance, ShapeProc, Triple, TripleSequence, VertexInfoProc ], SceneUtilities USING [ FindShape ], Animation3D USING [ ViewProc ]; Animation3DImpl: CEDAR PROGRAM IMPORTS Atom, G3dMatrix, G3dSpline, Real, SceneUtilities, ThreeDBasics EXPORTS Animation3D ~ BEGIN Context: TYPE ~ ThreeDBasics.Context; Pair: TYPE ~ ThreeDBasics.Pair; PairSequence: TYPE ~ ThreeDBasics.PairSequence; Triple: TYPE ~ ThreeDBasics.Triple; -- RECORD [ x, y, z: REAL]; TripleSequence: TYPE ~ ThreeDBasics.TripleSequence; ShapeInstance: TYPE ~ ThreeDBasics.ShapeInstance; ViewProc: TYPE ~ Animation3D.ViewProc; LORA: TYPE ~ LIST OF REF ANY; GetProp: PROC [propList: Atom.PropList, prop: REF ANY] RETURNS [REF ANY] ~ Atom.GetPropFromList; PutProp: PROC [propList: Atom.PropList, prop: REF ANY, val: REF ANY] RETURNS [Atom.PropList] ~ Atom.PutPropOnList; MoveEyePointInOrbit: PUBLIC PROC[ context: REF Context, eyePt, lookingAt, axis, base: Triple, displayProc: ViewProc, framesPerRev: NAT, startAt, endAt: NAT _ 0 ] ~ { theta: REAL _ 360. / framesPerRev; currentEyePt: Triple; FOR i: NAT IN [startAt .. endAt] DO IF context.stopMe^ THEN RETURN[]; currentEyePt _ G3dMatrix.Transform[ eyePt, G3dMatrix.MakeRotate[ axis: axis, theta: theta * i, base: base ] ]; context.frameNumber _ i; displayProc[ context, currentEyePt, lookingAt, context.frameNumber ]; ENDLOOP; context.frameNumber _ 0; }; MoveCtrOfInterestInOrbit: PUBLIC PROC[ context: REF Context, eyePt, lookingAt, axis, base: Triple, displayProc: ViewProc, framesPerRev: NAT, startAt, endAt: NAT _ 0 ] ~ { theta: REAL _ 360. / framesPerRev; currentLookingAt: Triple; FOR i: NAT IN [startAt .. endAt] DO IF context.stopMe^ THEN RETURN[]; currentLookingAt _ G3dMatrix.Transform[ lookingAt, G3dMatrix.MakeRotate[ axis: axis, theta: theta * i, base: base ] ]; context.frameNumber _ i; displayProc[ context, eyePt, currentLookingAt, context.frameNumber ]; ENDLOOP; context.frameNumber _ 0; }; MoveOnLine: PUBLIC PROC[ context: REF Context, eyePt, lookingAt, toEyePt, toLookingAt: Triple, displayProc: ViewProc, framesOnLine: NAT, startAt, endAt: NAT _ 0 ] ~ { currentEyePt, currentLookingAt: Triple; FOR i: NAT IN [startAt .. endAt] DO IF context.stopMe^ THEN RETURN[]; currentEyePt.x _ eyePt.x + (toEyePt.x - eyePt.x) * i / (framesOnLine-1); currentEyePt.y _ eyePt.y + (toEyePt.y - eyePt.y) * i / (framesOnLine-1); currentEyePt.z _ eyePt.z + (toEyePt.z - eyePt.z) * i / (framesOnLine-1); currentLookingAt.x _ lookingAt.x + (toLookingAt.x - lookingAt.x) * i / (framesOnLine-1); currentLookingAt.y _ lookingAt.y + (toLookingAt.y - lookingAt.y) * i /(framesOnLine-1); currentLookingAt.z _ lookingAt.z + (toLookingAt.z - lookingAt.z) * i / (framesOnLine-1); context.frameNumber _ i; displayProc[ context, currentEyePt, currentLookingAt, context.frameNumber ]; ENDLOOP; context.frameNumber _ 0; }; MoveOnOpenCurve: PUBLIC PROC[ context: REF Context, eyePts, lookingAts: REF TripleSequence, displayProc: ViewProc, framesOnCurve: NAT, startAt, endAt: NAT _ 0 ] ~ { currentEyePt, currentLookingAt: REF TripleSequence; epCoeffs: G3dSpline.CoeffsSequence _ G3dSpline.Interpolate[eyePts]; ciCoeffs: G3dSpline.CoeffsSequence _ G3dSpline.Interpolate[lookingAts]; currentEyePt _ ExpandCurve[epCoeffs, framesOnCurve]; currentLookingAt _ ExpandCurve[ciCoeffs, framesOnCurve]; IF context.stopMe^ THEN RETURN[]; FOR i: NAT IN [startAt .. endAt] DO j: NAT _ i MOD framesOnCurve; context.frameNumber _ i; displayProc[ context, currentEyePt[j], currentLookingAt[j], context.frameNumber ]; ENDLOOP; context.frameNumber _ 0; }; MoveOnClosedCurve: PUBLIC PROC[ context: REF Context, eyePts, lookingAts: REF TripleSequence, displayProc: ViewProc, framesOnCurve: NAT, startAt, endAt: NAT _ 0 ] ~ { currentEyePt, currentLookingAt: REF TripleSequence; epCoeffs: G3dSpline.CoeffsSequence _ G3dSpline.InterpolateCyclic[eyePts]; ciCoeffs: G3dSpline.CoeffsSequence _ G3dSpline.InterpolateCyclic[lookingAts]; currentEyePt _ ExpandCurve[epCoeffs, framesOnCurve]; currentLookingAt _ ExpandCurve[ciCoeffs, framesOnCurve]; FOR i: NAT IN [startAt .. endAt] DO j: NAT _ i MOD framesOnCurve; IF context.stopMe^ THEN RETURN[]; context.frameNumber _ i; displayProc[ context, currentEyePt[j], currentLookingAt[j], context.frameNumber ]; ENDLOOP; context.frameNumber _ 0; }; ExpandCurve: PROC[coeffs: G3dSpline.CoeffsSequence, numFrames: NAT] RETURNS[REF TripleSequence] ~ { points: REF TripleSequence _ NEW[TripleSequence[numFrames]]; framesPerSeg: REAL _ Real.Float[numFrames - 1] / (coeffs.length); FOR i: NAT IN [0..numFrames - 1) DO t: REAL _ i / framesPerSeg; -- distance, in segments, along curve seg: NAT _ Real.Fix[t]; -- segment t _ t - seg; -- position in segment points[i] _ G3dSpline.Position[coeffs[seg], t]; ENDLOOP; points[numFrames - 1] _ G3dSpline.Position[coeffs[coeffs.length - 1], 1.0]; points.length _ numFrames; RETURN[points]; }; ShowOpenCurve: PUBLIC PROC[ context: Context, eyePts, lookingAts: REF TripleSequence, numFrames: NAT, startAt: NAT _ 0 ] ~ { SIGNAL ThreeDBasics.Error[[$Unimplemented, "Sorry, ask Frank for an implementation"]]; }; ShowClosedCurve: PUBLIC PROC[ context: Context, eyePts, lookingAts: REF TripleSequence, numFrames: NAT, startAt: NAT _ 0 ] ~ { SIGNAL ThreeDBasics.Error[[$Unimplemented, "Sorry, ask Frank for an implementation"]]; }; ShowOrbit: PUBLIC PROC[ context: Context, startPt, axis, base: Triple, framesPerRev: NAT ] ~ { SIGNAL ThreeDBasics.Error[[$Unimplemented, "Sorry, ask Frank for an implementation"]]; }; SetTxtrTranslation: PUBLIC PROC[ context: REF Context, shapeName: Rope.ROPE, translation: Pair, frames: NAT ] ~{ shape: REF ShapeInstance _ SceneUtilities.FindShape[context, shapeName]; translation.x _ translation.x / frames; translation.y _ translation.y / frames; shape.shadingProps _ PutProp[ shape.shadingProps, $TxtrTranslation, NEW[Pair _ translation] ]; shape.shadingClass.loadVtxAux _ LoadTranslatedTxtrCoords; }; LoadTranslatedTxtrCoords: ThreeDBasics.VertexInfoProc ~ { -- load aux field in vtx frameNumber: NAT _ context.frameNumber; shape: REF ShapeInstance _ NARROW[ Atom.GetPropFromList[vtx.props, $Shape] ]; txtrIncr: REF Pair _ NARROW[GetProp[shape.shadingProps, $TxtrTranslation] ]; vtxAux: REF Pair _ NEW[Pair]; WITH data SELECT FROM input: LORA => { auxInfo: REF PairSequence _ NARROW[ input.first ]; index: INTEGER _ NARROW[ input.rest.first, REF INTEGER ]^; vtxAux.x _ auxInfo[index].x + txtrIncr.x * frameNumber; -- texture coords vtxAux.y _ auxInfo[index].y + txtrIncr.y * frameNumber; }; txtr: REF Pair => { vtxAux.x _ txtr.x + txtrIncr.x * frameNumber; vtxAux.y _ txtr.y + txtrIncr.y * frameNumber; }; ENDCASE => SIGNAL ThreeDBasics.Error[[$Unimplemented, "Unrecognized type"]]; vtx.aux _ vtxAux; RETURN[ vtx ]; }; SetShapeInterpolation: PUBLIC PROC[ context: REF Context, shapeName: Rope.ROPE, begin, end: REF ShapeInstance, frames: NAT ] ~{ shape: REF ShapeInstance _ SceneUtilities.FindShape[context, shapeName]; shape.shadingProps _ PutProp[ shape.shadingProps, $ShapeLerp, NEW[LORA _ LIST[ begin, end, NEW[ NAT _ frames] ] ] ]; shape.class.doBeforeFrame _ CONS[LerpShape, shape.class.doBeforeFrame]; }; LerpShape: ThreeDBasics.ShapeProc ~ { frameNumber: NAT _ context.frameNumber; list: LORA _ NARROW[GetProp[shape.shadingProps, $ShapeLerp] ]; begin: REF ShapeInstance _ NARROW[list.first]; end: REF ShapeInstance _ NARROW[list.rest.first]; lastFrame: NAT _ NARROW[list.rest.rest.first, REF NAT]^; alpha: REAL _ 1.0 * frameNumber / lastFrame; FOR i: NAT IN [0..shape.vertex.length) DO shape.vertex[i].x _ begin.vertex[i].x + alpha * (end.vertex[i].x -begin.vertex[i].x); shape.vertex[i].y _ begin.vertex[i].y + alpha * (end.vertex[i].y -begin.vertex[i].y); shape.vertex[i].z _ begin.vertex[i].z + alpha * (end.vertex[i].z -begin.vertex[i].z); ENDLOOP; FOR i: NAT IN [0..shape.shade.length) DO shape.shade[i].r _ begin.shade[i].r + alpha * (end.shade[i].r -begin.shade[i].r); shape.shade[i].g _ begin.shade[i].g + alpha * (end.shade[i].g -begin.shade[i].g); shape.shade[i].b _ begin.shade[i].b + alpha * (end.shade[i].b -begin.shade[i].b); ENDLOOP; shape.shadingInValid _ TRUE; RETURN[shape]; }; SetShapeManipulation: PUBLIC PROC[ context: REF Context, shapeName: Rope.ROPE, prop, propVal: REF ANY, proc: ThreeDBasics.ShapeProc ] ~ { shape: REF ShapeInstance _ SceneUtilities.FindShape[context, shapeName]; shape.shadingProps _ PutProp[ shape.shadingProps, prop, propVal ]; shape.class.doBeforeFrame _ CONS[ proc, NIL ]; }; AddShapeManipulation: PUBLIC PROC[ context: REF Context, shapeName: Rope.ROPE, prop, propVal: REF ANY, proc: ThreeDBasics.ShapeProc ] ~ { shape: REF ShapeInstance _ SceneUtilities.FindShape[context, shapeName]; shape.shadingProps _ PutProp[ shape.shadingProps, prop, propVal ]; shape.class.doBeforeFrame _ CONS[ proc, shape.class.doBeforeFrame ]; }; END. ”Animation3DImpl.mesa Copyright c 1984 by Xerox Corporation. All rights reserved. Last Edited by: Crow, February 8, 1988 5:03:07 pm PST Bloomenthal, September 14, 1988 1:05:33 pm PDT Basic Types Renamed Procedures Procedures for Animation Call display procedure Call display procedure Procedures for Viewing Trajectories Adds description of path to data for current scene, will be displayed just like any other shape. "Trajectory" is name given to resulting ShapeInstance. Procedures for Texture Animation Sets up translation by [translation.x, translation.y] over "frames" frames PROC[ context: REF Context, vtx: REF VertexInfo, data: REF ANY _ NIL ] RETURNS[REF VertexInfo]; Procedures for Shape Interpolation Sets up translation by [translation.x, translation.y] over "frames" frames PROC[context: REF Context, shape: REF ShapeInstance, data: REF ANY _ NIL] RETURNS[REF ShapeInstance] Translates texture coordinates over sequence of frames Procedure for Registering Shape Manipulation Procedures for Animation Way of registering procedure to be called to modify shape before each frame Way of registering procedure to be called to modify shape before each frame สd˜Ihead™šœ ฯmœ1™˜OJšœ žœs˜†Jšœžœ˜$Jšœ žœ˜!—J˜—head2šœžœž˜Iašžœ>˜Fšžœ ˜J˜—šœž˜J˜——šฯb ™ Jšœ žœ˜%Jšœžœ˜Jšœžœ˜/Jšœžœฯc˜EJšœžœ˜3Jšœžœ˜1Jšœ žœ˜'Jš žœžœžœžœžœžœ˜J˜—šŸ™Jšฯnœžœ!žœžœžœžœžœ.˜uJšกœžœ!žœžœžœžœž œ&˜x—™š กœžœžœ žœžœžœ ˜ัJšœžœ˜#J˜šžœžœžœž˜#Nšžœžœžœ˜!˜#J˜˜J˜ J˜J˜ J˜—J˜Jš ™—J˜J˜EJšžœ˜—J˜J˜—š กœžœžœ žœŠžœ%žœ ˜๒Jšœžœ˜#J˜šžœžœžœž˜#Nšžœžœžœ˜!˜'J˜ ˜J˜ J˜J˜ J˜—J˜Jš ™—J˜J˜EJšžœ˜—J˜J˜—š ก œžœžœ žœ~žœžœ ˜ลJ˜'šžœžœžœž˜#Nšžœžœžœ˜!J˜HJ˜HJ˜HJ˜XJ˜WJ˜XJ˜J˜LJšžœ˜—J˜J˜J˜—šกœžœžœ žœ,žœXžœžœ ˜ำJšœ žœ˜3J˜CJ˜GJ˜4J˜8Nšžœžœžœ˜!šžœžœžœž˜#Jšœžœžœ˜J˜J˜RJšžœ˜—J˜N˜N˜—šกœžœžœ žœ-žœTžœžœ ˜าJšœ žœ˜3J˜IJ˜MJ˜4J˜8šžœžœžœž˜#Jšœžœžœ˜Nšžœžœžœ˜!J˜J˜RJšžœ˜—J˜N˜N˜—š ก œžœ.žœ žœžœ˜kJšœžœžœ˜˜HJ˜'J˜'˜Jšœ&žœ˜>J˜—J˜9J˜—defaultšกœ" ˜RJšžœ žœžœžœžœžœžœžœ ™_Jšœ žœ˜'Jšœžœžœ,˜NJšœ žœžœ1˜LNšœžœžœ˜šžœžœž˜šœžœ˜Jšœ žœžœ˜2Nš œžœžœžœžœ˜:Nšœ= ˜NN˜7N˜—šœžœ ˜N˜1N˜/N˜—Nšžœžœ;˜L—O˜Ošžœ˜O˜——™"šกœžœžœ žœžœžœžœ˜ŒJ™JJšœžœ>˜H˜J˜ Jš žœžœžœžœžœ˜4J˜—Jšœžœ'˜GJ˜—šก œ˜%Jšžœ žœžœžœžœžœžœžœ™dJ™6Jšœ žœ˜'Jšœžœžœ+˜>Jšœžœžœ ˜.Jšœžœžœ˜1Jš œ žœžœžœžœ˜8Jšœžœ!˜,šžœžœžœž˜)J˜UJ˜UJ˜UJšžœ˜—šžœžœžœž˜(J˜QJ˜QJ˜QJšžœ˜—Jšœžœ˜Jšžœ˜J˜——™Ešกœžœžœ žœžœžœžœ2˜ฅJ™KJšœžœ>˜HJ˜BJšœžœžœ˜.J˜—šกœžœžœ žœžœžœžœ2˜ฅJ™KJšœžœ>˜HJ˜BJšœžœ$˜DJ˜——Jšžœ˜—…—%>26