/* Trajectory - DMS - Nov 98 - by Sylvain HUET */ /* Trajectory - DMS2 - May 99 - by Patrice FAVRE */ /* modified on the 7th of Jun 99 by Christophe LOREK */ /* Trajectory2 - January 2003 - by Bob Le Gob */ /* Last update: 6th of February 2003 - Bob Le Gob */ typeof class=S;; struct TrajAnim = [TAname:S, TAframerate:I, TAplay:I, TAplayOnce:I, TAtick:I, TAfel:[I r1], TAinit:I] mkTrajAnim;; /******************************************************************************* OptSingleAngle() - Optimizing single position's angle p -> I : Source angle q -> I : Destination original angle <- I : Optimized destination angle *******************************************************************************/ fun OptSingleAngle(p, q) = let (abs (q - p)) -> path1 in let (abs (q + 65536 - p)) -> path2 in let (abs (q - 65536 - p)) -> path3 in let min path1 min path2 path3 -> minpath in if (minpath == path1) then q else if (minpath == path2) then (q + 65536) else (q - 65536);; /******************************************************************************* OptimizeDestinationOrientation() - Optimizing position orientation ap -> I : Source angle a aq -> I : Destination original angle a bp -> I : Source angle b bq -> I : Destination original angle b cp -> I : Source angle c cq -> I : Destination original angle c <- [I I I] : Optimized destination orientation *******************************************************************************/ fun OptimizeDestinationOrientation(ap, aq, bp, bq, cp, cq) = [(OptSingleAngle ap aq) (OptSingleAngle bp bq) (OptSingleAngle cp cq)];; /******************************************************************************* PrepareOptimization2() - Optimizing positions - Second step src -> [Anchor r1] : PositionsList <- [[S [I I I] [I I I] [I I I]] r1] : OpimizedPositionsList *******************************************************************************/ fun PrepareOptimization2(src) = if ((tl src) == nil) then let hd src -> p in match p with ( posAnchor [posp [xp yp zp] [ap bp cp]] -> [posp [xp yp zp] [ap bp cp] [nil nil nil]]::nil ) else let hd src -> p in let hd tl src -> q in match p with ( posAnchor [posp [xp yp zp] [ap bp cp]] -> match q with ( posAnchor [_ _ [aq bq cq]] -> let OptimizeDestinationOrientation ap aq bp bq cp cq -> [aq2 bq2 cq2] in [posp [xp yp zp] [ap bp cp] [aq2 bq2 cq2]]::(PrepareOptimization2 tl src) ) );; /******************************************************************************* PrepareOptimization() - Optimizing positions - First step src -> [[Anchor I [Anchor r1]] r1] : [Linked3dOb ListSize PositionsList] <- [[Anchor I [[S [I I I] [I I I] [I I I]] r1]] r1] : [Linked3dOb ListSize OpimizedPositionsList] *******************************************************************************/ fun PrepareOptimization(src) = let hd src -> [o sz l] in [o sz (PrepareOptimization2 l)]::nil;; /******************************************************************************* cbSlidePos2() - Changing position of the 3D object according to the new frame x -> [Anchor I [S [I I I] [I I I] [I I I]] r1]] : [Linked3dOb listsize optimizedPositionslist] z -> [I I I [I r1] I I] : [TotalFrames CurrentFrame FramesAccumulator FrameEventsList InterpolateFlag InterpolateAnglesFlag] <- I : Not used *******************************************************************************/ fun cbSlidePos2(x, z)= let z -> [lastFrame currentFrame _ _ interpolateFlag flagPosAng] in let x -> [o sz l] in let o -> [h _ _ _] in let (sz * currentFrame / lastFrame) -> i in if interpolateFlag then /* trajectory with interpolation */ let (mod (sz * currentFrame) lastFrame) -> kq in let (lastFrame - kq) -> kp in let (endlist l i) -> [p [q _]] in let p -> [_ [xp yp zp] [ap bp cp] [aq2 bq2 cq2]] in let q -> [_ [xq yq zq] _ _] in ( M3setObjVec session h [(xp*kp+xq*kq)/lastFrame (yp*kp+yq*kq)/lastFrame (zp*kp+zq*kq)/lastFrame]; if flagPosAng then M3setObjAng session h [(ap*kp+aq2*kq)/lastFrame (bp*kp+bq2*kq)/lastFrame (cp*kp+cq2*kq)/lastFrame] else nil; ) else /* trajectory without interpolation */ let (nth_list l i) -> [_ vec ang _] in ( M3setObjVec session h vec; if flagPosAng then M3setObjAng session h ang else nil; );; /******************************************************************************* CheckFrameEvents() - Checking frame events l -> [I r1] : Frame events list fr1 -> I : Previous frame fr2 -> I : Current frame o -> Ob : Current Ob whose trajectory is being checked for frame events <- I : Not used *******************************************************************************/ fun CheckFrameEvents(l, fr1, fr2, o) = if (l == nil) then 0 else let hd l -> fre in if (fre > fr2) then 0 else if ((fre >= fr1) && (fre < fr2)) then ( _DMSevent this (strcatn (ObName o)::".Frame#"::(itoa fre)::nil) nil nil; CheckFrameEvents tl l fr1 fr2 o; ) else CheckFrameEvents tl l fr1 fr2 o;; /******************************************************************************* cbSlidePos() - ObCbAnim callback - Computing new frame o -> Ob : Ob to which the anim is associated z -> [I I I [I r1] I I] : [TotalFrames CurrentFrame FramesAccumulator FrameEventsList InterpolateFlag InterpolateAnglesFlag] a -> TrajAnim : Trajectory beind computed <- I : Not used *******************************************************************************/ fun cbSlidePos(o,z,a)= if a.TAplay then ( if (a.TAtick == nil) then set a.TAtick = _tickcount else nil; let _tickcount -> currenttick in let ((currenttick - a.TAtick) * a.TAframerate) -> timeFrame in let (mod timeFrame 1000) -> accum in let (timeFrame / 1000) -> deltaFrame in let z -> [lastFrame currentFrame accumulator x _ _] in ( set accumulator = accumulator + accum; if (accumulator > 1000) then ( set deltaFrame = deltaFrame + 1; set accumulator = accumulator - 1000; ) else nil; if ((currentFrame + deltaFrame) < (lastFrame - 1)) then ( CheckFrameEvents a.TAfel currentFrame (currentFrame + deltaFrame) o; mutate z <- [_ (currentFrame + deltaFrame) accumulator _ _ _]; set a.TAtick = currenttick; apply_on_list x @cbSlidePos2 z; 0; ) else ( CheckFrameEvents a.TAfel currentFrame lastFrame o; mutate z <- [_ (lastFrame - 1) _ _ _ _]; apply_on_list x @cbSlidePos2 z; set a.TAtick = nil; if a.TAplayOnce then set a.TAplay = 0 else set a.TAplay = 1; mutate z <- [_ 0 0 _ _ _]; 0; ); ); 0; ) else 0; 0;; /******************************************************************************* PrepAnchor() - Retrieving list of positions l -> [Anchor r1] : Anchors list <- [[Anchor r1] [Anchor I [Anchor r1]]] : [nil [Linked3dOb listsize poslist]] *******************************************************************************/ fun PrepAnchor(l)= if (l == nil) then [nil nil] else let l->[a n] in let PrepAnchor n ->[lp lo] in match a with ( objAnchor o -> [nil [o (sizelist lp)-1 lp]::lo]) |(posAnchor _ -> [a::lp lo] );; /******************************************************************************* cbActivate() - Standard callback function for plugin actions o -> Ob : Ob to which the action is associated from -> DMI : Not used action -> S : Action param -> S : Parameter reply -> S : Not used a -> TrajAnim : Trajectory structure associated with Ob <- I : Not used *******************************************************************************/ fun cbActivate(o,from,action,param,reply,a)= if !strcmp action (strcat (ObName o) ".playonce") then ( set a.TAplay = 1; set a.TAplayOnce = 1; set a.TAtick = _tickcount; 0; ) else if !strcmp action (strcat (ObName o) ".playloop") then ( set a.TAplay = 1; set a.TAplayOnce = 0; set a.TAtick = _tickcount; 0; ) else if !strcmp action (strcat (ObName o) ".stop") then ( set a.TAplay = 0; set a.TAtick = nil; 0; ) else nil;; /******************************************************************************* cbComm() - Standard cbcomm callback function for intra plugin messages ui -> UserI : User Instance linked to Ob action -> S : Action param -> S : Parameter a -> TrajAnim : Trajectory structure associated with Ob <- I : Not used *******************************************************************************/ fun cbComm(ui,action,param,a)= if (!strcmp action "playonce") then ( set a.TAplay = 1; set a.TAplayOnce = 1; set a.TAtick = _tickcount; 0; ) else if (!strcmp action "playloop") then ( set a.TAplay = 1; set a.TAplayOnce = 0; set a.TAtick = _tickcount; 0; ) else if (!strcmp action "stop") then ( set a.TAplay = 0; set a.TAtick = nil; 0; ) else if (!strcmp action "noaction") then ( set a.TAplay = a.TAinit; 0; ) else nil;; /******************************************************************************* InsertFrameEvent() - Building frame events list - Sorting list l -> [I r1] : Frame events list fre -> I : New frame event to insert in list <- [I r1] : New frame events list *******************************************************************************/ fun InsertFrameEvent(l, fre) = if (l == nil) then fre::nil else let hd l -> elt in if (elt > fre) then fre::l else elt::(InsertFrameEvent tl l fre);; /******************************************************************************* FrameEventList() - Building frame events list - Building list src -> [[S r1] r1] : List of parameters for the plugin instance dst -> [I r1] : Frame events list to build <- [I r1] : Buildt frame events list *******************************************************************************/ fun FrameEventList(src, dst)= if (src == nil) then dst else let hd src -> [name r] in if !strcmp name "FrameEvent" then let r -> [frameNum _] in FrameEventList tl src InsertFrameEvent dst (atoi frameNum) else FrameEventList tl src dst;; /******************************************************************************* cbNewOb() - New object creation o -> Ob : New Ob <- I : Not used *******************************************************************************/ fun cbNewOb(o)= let UgetParams ObUi o -> lParams in let atoi hd UgetParam ObUi o "Interpolate" -> interpolateFlag in let atoi hd UgetParam ObUi o "Framerate" -> framerate in let atoi hd UgetParam ObUi o "Ini" -> ini in let !atoi hd UgetParam ObUi o "Loop" -> playOnce in let hd UgetParam ObUi o "PosAng" -> PosAng in let atoi hd UgetParam ObUi o "NbFrames" -> nbFrames in let atoi hd UgetParam ObUi o "SrvAnimAutoStart" -> srvAnimAutoStart in let PrepAnchor ObAnchor o -> [_ l] in let PrepareOptimization l -> lOptimized in let if srvAnimAutoStart then 0 else ini -> play in let mkTrajAnim [(ObName o) framerate play playOnce nil (FrameEventList lParams nil) ini] -> ta in ( ObCbAnim o mkfun2 mkfun3 @cbSlidePos ta [nbFrames 0 0 lOptimized interpolateFlag (!strcmpi PosAng "All")]; UcbComm this ObUi o mkfun4 @cbComm ta; ObRegisterAction o (strcatn (ObName o)::".playonce"::nil) mkfun6 @cbActivate ta; ObRegisterAction o (strcatn (ObName o)::".playloop"::nil) mkfun6 @cbActivate ta; ObRegisterAction o (strcatn (ObName o)::".stop"::nil) mkfun6 @cbActivate ta; if srvAnimAutoStart then UsendSrv this (ObUi o) "newclient" (ObName o) else nil; 0; );; /******************************************************************************* IniPlug() - Function called when plugin is initialized file -> S : .plug file <- I : Not used *******************************************************************************/ fun IniPlug(file)= set class = getInfo strextr _getpack _checkpack file "name"; PlugRegister class @cbNewOb nil; 0;;