/* ----------------------------------------------------------------------------- This source file is part of OpenSpace3D For the latest info, see http://www.openspace3d.com Copyright (c) 2012 I-maginer This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, or go to http://www.gnu.org/copyleft/lesser.txt ----------------------------------------------------------------------------- */ struct PlugAnim = [ PANIM_inst : PInstance, PANIM_anim : V3Danim, PANIM_fWeight : F, PANIM_fSpeed : F, PANIM_bLoop : I, PANIM_bSkipFrame : I, PANIM_bState : I, PANIM_fLastPos : F, PANIM_tPos : [F F], PANIM_lEvents : [[F S] r1], PANIM_iCurEvent : I ]mkPlugAnim;; typeof lPlugAnims = [PlugAnim r1];; fun addPlugAnim(panimstr)= set lPlugAnims = panimstr::lPlugAnims; 0;; fun removePlugAnim(panimstr)= set lPlugAnims = remove_from_list lPlugAnims panimstr; 0;; fun stopSamePlugAnim(animstr)= let sizelist lPlugAnims -> size in let 0 -> i in while (i < size) do ( let nth_list lPlugAnims i -> panimstr in if ((panimstr.PANIM_anim != animstr) || !panimstr.PANIM_bState) then nil else ( V3DstopAnimation panimstr.PANIM_anim; setPluginInstanceCbScenePostRender panimstr.PANIM_inst nil; setPluginInstanceCbScenePreRender2 panimstr.PANIM_inst nil; ); set i = i + 1; ); 0;; fun deleteOb(inst, panimstr)= removePlugAnim panimstr; setPluginInstanceCbScenePreRender inst nil; setPluginInstanceCbScenePreRender2 inst nil; setPluginInstanceCbScenePostRender inst nil; V3DstopAnimation panimstr.PANIM_anim; V3DsetAnimationPosition panimstr.PANIM_anim 0.0; V3DenableAnimation panimstr.PANIM_anim 0; 0;; fun cbGetAnimPosEvents(inst, view3d, etime, panimstr)= if !(V3DgetAnimationEnable panimstr.PANIM_anim) then nil else let SO3AnimationGetTimePosition panimstr.PANIM_anim.V3D_anim -> pos in let panimstr.PANIM_tPos -> [stpos endpos] in ( if pos == panimstr.PANIM_fLastPos then nil else ( let sizelist panimstr.PANIM_lEvents -> size in let 0 -> i in while i < size do ( let nth_list panimstr.PANIM_lEvents i -> [epos evt] in if panimstr.PANIM_fLastPos == nil then if ((pos >=. epos) && panimstr.PANIM_fSpeed >. 0.0) || ((pos <=. epos) && panimstr.PANIM_fSpeed <. 0.0) then SendPluginEvent inst evt nil nil else nil else if ((pos >=. epos && panimstr.PANIM_fLastPos <. epos) && panimstr.PANIM_fSpeed >. 0.0) || ((pos <=. epos && panimstr.PANIM_fLastPos >. epos) && panimstr.PANIM_fSpeed <. 0.0) then SendPluginEvent inst evt nil nil else nil; set i = i + 1; ); if V3DgetAnimationLoop panimstr.PANIM_anim then nil else if (pos +. 0.00001) <. endpos then nil else SendPluginEvent inst "Ended" nil nil; ); set panimstr.PANIM_fLastPos = pos; ); 0;; fun cbClipAnimPos(inst, view3d, etime, panimstr)= let SO3AnimationGetTimePosition panimstr.PANIM_anim.V3D_anim -> pos in let panimstr.PANIM_tPos -> [stpos endpos] in ( if pos <=. endpos then nil else ( if panimstr.PANIM_bLoop && stpos != 0.0 then ( V3DsetAnimationPosition panimstr.PANIM_anim stpos; 0; ) else ( V3DsetAnimationPosition panimstr.PANIM_anim endpos; 0; ); ); ); 0;; fun cbGetAnimPos(inst, view3d, etime, panimstr)= let SO3AnimationGetTimePosition panimstr.PANIM_anim.V3D_anim -> pos in let panimstr.PANIM_tPos -> [stpos endpos] in ( if (pos +. 0.00001) <. endpos then nil else ( let V3DgetAnimationLoop panimstr.PANIM_anim -> loop in if loop then nil else ( setPluginInstanceCbScenePostRender inst nil; setPluginInstanceCbScenePreRender2 inst nil; //call the frame event before disable the animation cbGetAnimPosEvents inst view3d etime panimstr; set panimstr.PANIM_fLastPos = nil; V3DstopAnimation panimstr.PANIM_anim; set panimstr.PANIM_bState = 0; 0; ) ); ); 0;; /* fun cbGetAnimPos(inst, view3d, etime, panimstr)= let SO3AnimationGetTimePosition panimstr.PANIM_anim.V3D_anim -> pos in let panimstr.PANIM_tPos -> [stpos endpos] in if (pos == panimstr.PANIM_fLastPos) then nil else ( if (!panimstr.PANIM_anim.V3D_bAnimState) then nil else ( let sizelist panimstr.PANIM_lEvents -> size in let 0 -> i in while i < size do ( let nth_list panimstr.PANIM_lEvents i -> [epos evt] in if ((((epos <=. pos) && (panimstr.PANIM_fSpeed >. 0.0)) && ((i > panimstr.PANIM_iCurEvent) || (panimstr.PANIM_iCurEvent == nil))) || (((epos >=. pos) && (panimstr.PANIM_fSpeed <. 0.0)) && ((i < panimstr.PANIM_iCurEvent) || (panimstr.PANIM_iCurEvent == nil)))) then ( set panimstr.PANIM_iCurEvent = i; SendPluginEvent inst evt nil nil; ) else nil; set i = i + 1; ); ); if ((pos >=. endpos) || ((pos <. panimstr.PANIM_fLastPos) && (panimstr.PANIM_fSpeed >. 0.0)) || ((pos >. panimstr.PANIM_fLastPos) && (panimstr.PANIM_fSpeed <. 0.0))) then ( if !panimstr.PANIM_bLoop then ( V3DstopAnimation panimstr.PANIM_anim; SendPluginEvent inst "Ended" nil nil; set panimstr.PANIM_iCurEvent = nil; ) else ( if stpos == 0.0 then nil else ( V3DsetAnimationPosition panimstr.PANIM_anim stpos; 0; ); set panimstr.PANIM_iCurEvent = nil; ); ) else nil; set panimstr.PANIM_fLastPos = pos; ); 0;; */ fun cbPlayAnim(inst, from, action, param, rep, panimstr) = let panimstr.PANIM_tPos -> [stpos endpos] in let V3DgetAnimationPosition panimstr.PANIM_anim -> cpos in ( stopSamePlugAnim panimstr.PANIM_anim; V3DpauseAnimation panimstr.PANIM_anim; V3DanimationSetSkipFrame panimstr.PANIM_anim panimstr.PANIM_bSkipFrame; V3DsetAnimationSpeed panimstr.PANIM_anim panimstr.PANIM_fSpeed; V3DsetAnimationLoop panimstr.PANIM_anim if stpos != 0.0 then 0 else panimstr.PANIM_bLoop; V3DsetAnimationWeight panimstr.PANIM_anim panimstr.PANIM_fWeight; if cpos <. endpos && cpos >. stpos then ( V3DplayAnimation panimstr.PANIM_anim; 0; ) else ( let if (panimstr.PANIM_fSpeed >. 0.0) then stpos else endpos -> npos in ( V3DsetAnimationPosition panimstr.PANIM_anim npos; V3DplayAnimationFromPos panimstr.PANIM_anim npos; ); set panimstr.PANIM_fLastPos = nil; 0; ); ); //addLogMessage ftoa V3DgetAnimationPosition panimstr.PANIM_anim; set panimstr.PANIM_bState = 1; setPluginInstanceCbScenePostRender inst mkfun4 @cbGetAnimPos panimstr; setPluginInstanceCbScenePreRender2 inst mkfun4 @cbClipAnimPos panimstr; 0;; fun cbPauseAnim(inst, from, action, param, rep, panimstr) = setPluginInstanceCbScenePostRender inst nil; setPluginInstanceCbScenePreRender2 inst nil; V3DpauseAnimation panimstr.PANIM_anim; set panimstr.PANIM_bState = 0; 0;; fun cbStopAnim(inst, from, action, param, rep, panimstr) = setPluginInstanceCbScenePostRender inst nil; setPluginInstanceCbScenePreRender2 inst nil; V3DstopAnimation panimstr.PANIM_anim; set panimstr.PANIM_bState = 0; set panimstr.PANIM_fLastPos = nil; 0;; fun cbLoopAnim(inst, from, action, param, rep, panimstr) = if param == nil then nil else ( set panimstr.PANIM_bLoop = atoi param; let panimstr.PANIM_tPos -> [stpos endpos] in V3DsetAnimationLoop panimstr.PANIM_anim if stpos != 0.0 then 0 else atoi param; ); 0;; fun cbSpeedAnim(inst, from, action, param, rep, panimstr) = if param == nil then nil else ( set panimstr.PANIM_fSpeed = atof param; V3DsetAnimationSpeed panimstr.PANIM_anim (atof param); ); 0;; fun cbWeightAnim(inst, from, action, param, rep, panimstr) = if param == nil then nil else ( set panimstr.PANIM_fWeight = atof param; V3DsetAnimationWeight panimstr.PANIM_anim atof param; ); 0;; fun cbTimeAnim(inst, from, action, param, rep, panimstr) = if param == nil then nil else ( V3DsetAnimationPosition panimstr.PANIM_anim atof param; set panimstr.PANIM_fLastPos = atof param; //addLogMessage strcat "set pos :" ftoa V3DgetAnimationPosition panimstr.PANIM_anim; ); 0;; fun cbResetAnim(inst, from, action, param, rep, panimstr) = let panimstr.PANIM_tPos -> [stpos endpos] in ( V3DresetAnimation panimstr.PANIM_anim; V3DsetAnimationPosition panimstr.PANIM_anim stpos; V3DsetAnimationSpeed panimstr.PANIM_anim panimstr.PANIM_fSpeed; V3DsetAnimationWeight panimstr.PANIM_anim panimstr.PANIM_fWeight; V3DsetAnimationLoop panimstr.PANIM_anim if stpos != 0.0 then 0 else panimstr.PANIM_bLoop; set panimstr.PANIM_fLastPos = nil; ); 0;; fun sortAnimPos(p1, p2)= let p1 -> [f1 _] in let p2 -> [f2 _] in f1 <=. f2;; fun newOb(inst)= let (getPluginInstanceParam inst "anim") -> animname in let atof (getPluginInstanceParam inst "weight") -> weight in let if weight == nil then 1.0 else weight -> weight in let atof (getPluginInstanceParam inst "speed") -> speed in let if speed == nil then 1.0 else speed -> speed in let atoi (getPluginInstanceParam inst "loop") -> loop in let if loop == nil then 0 else loop -> loop in let atoi (getPluginInstanceParam inst "skipframe") -> skipframe in let if skipframe == nil then 1 else skipframe -> skipframe in let atoi (getPluginInstanceParam inst "enable") -> enable in let if enable == nil then 0 else enable -> enable in let V3DgetAnimationByName c3dXsession animname -> animstr in let if animstr == nil then 1.0 else V3DgetAnimationLength animstr -> length in let atof (getPluginInstanceParam inst "startpos") -> startpos in let if startpos == nil then 0.0 else startpos -> startpos in let atof (getPluginInstanceParam inst "endpos") -> endpos in let if endpos == nil then length else endpos -> endpos in let mkPlugAnim [inst animstr weight speed loop skipframe enable nil [startpos endpos] nil nil] -> panimstr in ( addPlugAnim panimstr; // Stop anim if enabled by editor V3DstopAnimation animstr; V3DenableAnimation animstr 1; V3DsetAnimationLoop animstr if startpos != 0.0 then 0 else loop; setPluginInstanceCbScenePreRender panimstr.PANIM_inst mkfun4 @cbGetAnimPosEvents panimstr; let getPluginInstanceUserEvents inst -> levent in let sizelist levent -> size in let 0 -> i in while i < size do ( let nth_list levent i -> evt in let atof (hd hd (strextr evt)) -> pos in ( set panimstr.PANIM_lEvents = lcat panimstr.PANIM_lEvents [pos evt]::nil; ); set i = i + 1; ); set panimstr.PANIM_lEvents = sortlist panimstr.PANIM_lEvents @sortAnimPos; if !enable then nil else cbPlayAnim inst nil nil nil nil panimstr; PluginRegisterAction inst "Play" mkfun6 @cbPlayAnim panimstr; PluginRegisterAction inst "Pause" mkfun6 @cbPauseAnim panimstr; PluginRegisterAction inst "Stop" mkfun6 @cbStopAnim panimstr; PluginRegisterAction inst "Set loop" mkfun6 @cbLoopAnim panimstr; PluginRegisterAction inst "Set speed" mkfun6 @cbSpeedAnim panimstr; PluginRegisterAction inst "Set weight" mkfun6 @cbWeightAnim panimstr; PluginRegisterAction inst "Set position" mkfun6 @cbTimeAnim panimstr; PluginRegisterAction inst "Reset" mkfun6 @cbResetAnim panimstr; setPluginInstanceCbDel inst mkfun2 @deleteOb panimstr; ); 0;; fun IniPlug(file)= PlugRegister @newOb nil; setPluginEditor @dynamicedit; 0;;