/* 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: 4th of February 2003 - Bob Le Gob */ typeof class=S;; struct TrajAnim = [TAname:S, TAframerate:I, TAplaystop:I, TAlooponce:I, TAinterpoflag:I, TAtick:I, TAfel:[I r1]] mkTrajAnim;; /* Angles optimization */ fun BLG_OptSingleAng(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);; fun BLG_OptimizeDestinationsAngle(ap, aq, bp, bq, cp, cq) = [(BLG_OptSingleAng ap aq) (BLG_OptSingleAng bp bq) (BLG_OptSingleAng cp cq)];; fun BLG_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 BLG_OptimizeDestinationsAngle ap aq bp bq cp cq -> [aq2 bq2 cq2] in [posp [xp yp zp] [ap bp cp] [aq2 bq2 cq2]]::(BLG_PrepareOptimization2 tl src) ) );; fun BLG_PrepareOptimization(src) = let hd src -> [o sz l] in [o sz (BLG_PrepareOptimization2 l)]::nil;; /* Changing position of the 3D object according to the new frame */ fun slidepos2(x,param)= let param -> [z interpoflag prevframe] in if interpoflag then /* trajectory with interpolation */ let x->[o sz l] in let z->[lastframe currentframe _ _ flagPosAng] in let o->[h _ _ _] in let sz*currentframe/lastframe -> i in 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 x->[o sz l] in let z->[lastframe currentframe _ _ flagPosAng] in let o->[h _ _ _] in let sz*currentframe/lastframe -> i in let nth_list l i -> [_ vec ang _] in ( M3setObjVec session h vec; if flagPosAng then M3setObjAng session h ang else nil; );; /* Checking frame events */ 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;; /* Computing new frame */ fun slidepos(o,z,a)= if a.TAplaystop 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 let currentframe -> prevframe 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 @slidepos2 [z a.TAinterpoflag prevframe]; 0; ) else ( CheckFrameEvents a.TAfel currentframe lastframe o; mutate z<-[_ (lastframe - 1) _ _ _]; apply_on_list x @slidepos2 [z a.TAinterpoflag prevframe]; set a.TAtick = nil; if a.TAlooponce then set a.TAplaystop = 0 else set a.TAplaystop = 1; mutate z<-[_ 0 0 _ _]; 0; ); ); 0; ) else 0; 0;; /* Retrieving list of positions */ fun prepanch(l)= if l==nil then [nil nil] else let l->[a n] in let prepanch n ->[lp lo] in match a with (objAnchor o -> [nil [o (sizelist lp)-1 lp]::lo]) |(posAnchor _ -> [a::lp lo]);; /* activate() */ fun activate(o,from,action,param,reply,a)= if !strcmp action (strcat (ObName o) ".playonce") then (set a.TAplaystop = 1; set a.TAlooponce = 1; set a.TAtick = _tickcount; 0) else if !strcmp action (strcat (ObName o) ".playloop") then (set a.TAplaystop = 1; set a.TAlooponce = 0; set a.TAtick = _tickcount; 0) else if !strcmp action (strcat (ObName o) ".stop") then (set a.TAplaystop = 0; set a.TAtick = nil; 0) else nil;; /* cbcomm() */ fun cbcomm(ui,action,param,a)= if !strcmp action "playonce" then (set a.TAplaystop = 1; set a.TAlooponce = 1; set a.TAtick = _tickcount; 0) else if !strcmp action "playloop" then (set a.TAplaystop = 1; set a.TAlooponce = 0; set a.TAtick = _tickcount; 0) else if !strcmp action "stop" then (set a.TAplaystop = 0; set a.TAtick = nil; 0) else nil;; /* Building sorted list of frame events */ 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);; 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;; /* newOb() */ fun newOb(o)= let UgetParams ObUi o -> paramlist 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" -> looponce 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 prepanch ObAnchor o -> [_ l] in let BLG_PrepareOptimization l -> BLG_l in let mkTrajAnim [(ObName o) framerate ini looponce interpolateflag nil (FrameEventList paramlist nil)] -> ta in ( ObCbAnim o mkfun2 mkfun3 @slidepos ta [nbframes 0 0 BLG_l (!strcmpi PosAng "All")]; UcbComm this ObUi o mkfun4 @cbcomm ta; ObRegisterAction o (strcatn (ObName o)::".playonce"::nil) mkfun6 @activate ta; ObRegisterAction o (strcatn (ObName o)::".playloop"::nil) mkfun6 @activate ta; ObRegisterAction o (strcatn (ObName o)::".stop"::nil) mkfun6 @activate ta; if srvAnimAutoStart then UsendSrv this (ObUi o) "newclient" (ObName o) else nil; 0; );; /* IniPlug() */ fun IniPlug(file)= set class=getInfo strextr _getpack _checkpack file "name"; PlugRegister class @newOb nil; 0;;