/* ----------------------------------------------------------------------------- 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 PlugExplode = [ EXP_inst : PInstance, EXP_shell : SO3_OBJECT, EXP_iShellMode : I, EXP_fMaxScale : [F F F], EXP_lRef : [[SO3_OBJECT [[F F F] [F F F]]] r1], EXP_fSpeed : F, EXP_fCoef : F, EXP_bState : I ]mkPlugExplode;; fun deleteOb(inst, obstr)= setPluginInstanceCbCameraChange inst nil; setPluginInstanceCbScenePreRender inst nil; while (obstr.EXP_lRef != nil) do ( let hd obstr.EXP_lRef -> [obj [pos off]] in SO3ObjectSetPosition obj pos; set obstr.EXP_lRef = tl obstr.EXP_lRef; ); 0;; fun saveSonsPosition(l, obstr, sons)= if l == nil then nil else let hd l -> obj in ( let SO3ObjectGetPosition obj -> pos in let SO3ObjectGetGlobalPosition obstr.EXP_shell -> gposref in let SO3ObjectGetWorldBoundingBoxInfo obj 0 -> [_ bc _] in let quatInverse SO3ObjectGetGlobalOrientation SO3ObjectGetParent obj -> gquat in let SO3ObjectGetGlobalScale obj -> gscale in let multiplyVectorF obstr.EXP_fMaxScale (subVectorF bc gposref) -> off in let divideVectorF (SO3MathsQuatGetDirection gquat off) gscale -> off in let if (off == nil) then [0.0 0.0 0.0] else off -> off in set obstr.EXP_lRef = [obj [pos off]]::obstr.EXP_lRef; if (!sons) then nil else saveSonsPosition (SO3ObjectGetChildren obj) obstr sons; saveSonsPosition (tl l) obstr sons; ); 0;; fun scaleSonsPosition(l, obstr, coef, sons)= if l == nil then nil else let hd l -> obj in ( let switch obstr.EXP_lRef obj -> [pos off] in let addVectorF pos (multiplyVectorF [coef coef coef] off) -> offsc in //let addVectorF (multiplyVectorF pos (addVectorF [1.0 1.0 1.0] scale)) (multiplyVectorF scale off) -> offsc in SO3ObjectSetPosition obj offsc; if (!sons) then nil else scaleSonsPosition (SO3ObjectGetChildren obj) obstr coef sons; scaleSonsPosition (tl l) obstr coef sons; ); 0;; fun cbExplodePreRender(inst, sessionstr, etime, obstr)= let (itof etime) /. 1000000.0 -> ftime in let ftime *. 100.0 -> nbframe in let if (obstr.EXP_bState == 1) then obstr.EXP_fSpeed else (-. obstr.EXP_fSpeed) -> speed in let if ((obstr.EXP_fCoef +. (speed *. nbframe)) >. 1.0) then 1.0 else if ((obstr.EXP_fCoef +. (speed *. nbframe)) <. 0.0) then 0.0 else (obstr.EXP_fCoef +. (speed *. nbframe)) -> coef in if ((obstr.EXP_bState == 1) && (coef == 1.0)) || ((obstr.EXP_bState == 0) && (coef == 0.0)) then ( scaleSonsPosition (SO3ObjectGetChildren obstr.EXP_shell) obstr coef 1; set obstr.EXP_fCoef = coef; setPluginInstanceCbScenePreRender inst nil; SendPluginEvent obstr.EXP_inst "End" nil nil; 0; ) else ( scaleSonsPosition (SO3ObjectGetChildren obstr.EXP_shell) obstr coef 1; set obstr.EXP_fCoef = coef; 0; ); 0;; fun enableExplode(inst, from, action, param, rep, obstr)= if (obstr.EXP_bState == 1) then nil else ( set obstr.EXP_bState = 1; setPluginInstanceCbScenePreRender inst mkfun4 @cbExplodePreRender obstr; ); 0;; fun disableExplode(inst, from, action, param, rep, obstr)= if (obstr.EXP_bState == 0) then nil else ( set obstr.EXP_bState = 0; setPluginInstanceCbScenePreRender inst mkfun4 @cbExplodePreRender obstr; ); 0;; fun cbSetScale(inst, from, action, param, rep, obstr)= let hd strextr param -> lsvec in let if (atof (hd lsvec)) == nil then 0.0 else (atof (hd lsvec)) -> x in let if (atof (hd tl lsvec)) == nil then 0.0 else (atof (hd tl lsvec)) -> y in let if (atof (hd tl tl lsvec)) == nil then 0.0 else (atof (hd tl tl lsvec)) -> z in set obstr.EXP_fMaxScale = [x y z]; while (obstr.EXP_lRef != nil) do ( let hd obstr.EXP_lRef -> [obj [pos off]] in SO3ObjectSetPosition obj pos; set obstr.EXP_lRef = tl obstr.EXP_lRef; ); saveSonsPosition obstr.EXP_shell::nil obstr 1; set obstr.EXP_bState = 0; set obstr.EXP_fCoef = 0.0; 0;; fun cbSetCoef(inst, from, action, param, rep, obstr)= let atof param -> coef in set obstr.EXP_fCoef = coef; set obstr.EXP_bState = 2; setPluginInstanceCbScenePreRender inst nil; scaleSonsPosition (SO3ObjectGetChildren obstr.EXP_shell) obstr obstr.EXP_fCoef 1; 0;; fun cbChangeCamera(inst, viewstr, sessionstr, camera, obstr)= let V3DgetCameraByType sessionstr camera obstr.EXP_iShellMode -> nfather in ( set obstr.EXP_shell = nfather; ); 0;; fun cbSetObject(inst, from, action, param, reply, obstr)= if param == nil then nil else let V3DgetObjectByName c3dXsession param -> father in let V3DgetObjectTypeByName param -> iobjmode in ( set obstr.EXP_bState = 0; set obstr.EXP_fCoef = 0.0; setPluginInstanceCbScenePreRender inst nil; while (obstr.EXP_lRef != nil) do ( let hd obstr.EXP_lRef -> [obj [pos off]] in SO3ObjectSetPosition obj pos; set obstr.EXP_lRef = tl obstr.EXP_lRef; ); set obstr.EXP_shell = father; set obstr.EXP_iShellMode = iobjmode; saveSonsPosition obstr.EXP_shell::nil obstr 1; if !iobjmode then nil else setPluginInstanceCbCameraChange inst mkfun5 @cbChangeCamera obstr; ); 0;; fun newOb(inst)= let (getPluginInstanceParam inst "object") -> objname in let atoi (getPluginInstanceParam inst "enable") -> enable in let atof (getPluginInstanceParam inst "scalex") -> scalex in let atof (getPluginInstanceParam inst "scaley") -> scaley in let atof (getPluginInstanceParam inst "scalez") -> scalez in let atof (getPluginInstanceParam inst "speed") -> speed in let if speed == nil then 0.01 else speed /. 100.0 -> speed in let V3DgetObjectByName c3dXsession objname -> obj in let V3DgetObjectTypeByName objname -> iobjmode in let mkPlugExplode [inst obj iobjmode [scalex scaley scalez] nil speed 0.0 0] -> obstr in ( saveSonsPosition obstr.EXP_shell::nil obstr 1; PluginRegisterAction inst "Set scale" mkfun6 @cbSetScale obstr; PluginRegisterAction inst "Set coef" mkfun6 @cbSetCoef obstr; PluginRegisterAction inst "Explode" mkfun6 @enableExplode obstr; PluginRegisterAction inst "Fold" mkfun6 @disableExplode obstr; PluginRegisterAction inst "Set object" mkfun6 @cbSetObject obstr; if !iobjmode then nil else setPluginInstanceCbCameraChange inst mkfun5 @cbChangeCamera obstr; setPluginInstanceCbDel inst mkfun2 @deleteOb obstr; ); 0;; fun IniPlug(file)= PlugRegister @newOb nil; setPluginEditor @dynamicedit; 0;;