/* ----------------------------------------------------------------------------- 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 ObjSliderStr = [ PSLIDER_child : SO3_OBJECT, PSLIDER_parent : SO3_OBJECT, PSLIDER_bCollide : I, PSLIDER_iTargetMode : I, PSLIDER_iSourceMode : I, PSLIDER_contraint : SO3_PHYSICCONTRAINT, PSLIDER_iPosMode : I, PSLIDER_tPosition : [F F F], PSLIDER_tDirection : [F F F], PSLIDER_tLimits : [F F], PSLIDER_bUseLimits : I, PSLIDER_tSpring : [F F], PSLIDER_bUseSpring : I, PSLIDER_fBreakForce : F, PSLIDER_fFriction : F, PSLIDER_bUseMotor : I, PSLIDER_fMotor : F, PSLIDER_bLastLimit : I, PSLIDER_iDebounceTick : I, PSLIDER_iTick : I ]mkObjSliderStr;; fun deleteOb(inst, obstr)= setPluginInstanceCbCameraChange inst nil; SO3PhysicsContraintDestroy obstr.PSLIDER_contraint; setPluginInstanceCbScenePreRender inst nil; 0;; fun cbChangeCamera(inst, viewstr, sessionstr, camera, obstr)= if (camera != V3DgetDefaultCamera c3dXsession) then nil else ( if (!obstr.PSLIDER_iSourceMode) then nil else ( set obstr.PSLIDER_child = V3DgetCameraByType sessionstr camera obstr.PSLIDER_iSourceMode; ); if (!obstr.PSLIDER_iTargetMode) then nil else ( set obstr.PSLIDER_parent = V3DgetCameraByType sessionstr camera obstr.PSLIDER_iTargetMode; ); ); 0;; fun cbContraintPreRender(inst, sessionstr, etime, obstr)= let SO3PhysicsContraintGetSliderForce obstr.PSLIDER_contraint -> [x y z] in ( if (obstr.PSLIDER_fBreakForce <=. 0.0) then nil else ( let (absf x +. absf y +. absf z) /. 3.0 -> avforce in if (avforce <. obstr.PSLIDER_fBreakForce) then nil else ( SO3PhysicsContraintDestroy obstr.PSLIDER_contraint; set obstr.PSLIDER_contraint = nil; setPluginInstanceCbScenePreRender inst nil; SendPluginEvent inst "Broken" nil nil; ); ); SendPluginEvent inst "Force" strcatn (ftoa x)::" "::(ftoa y)::" "::(ftoa z)::nil nil; if (!obstr.PSLIDER_bUseLimits) then nil else ( set obstr.PSLIDER_iTick = obstr.PSLIDER_iTick + (etime / 1000); if ((obstr.PSLIDER_iTick - obstr.PSLIDER_iDebounceTick) < 200) then nil else let obstr.PSLIDER_tLimits -> [tmin tmax] in let SO3PhysicsContraintGetSliderPosition obstr.PSLIDER_contraint -> dist in //let normalizeVectorF obstr.PSLIDER_tDirection -> [dx dy dz] in //let dist *. (dx +. dy +. dz) -> dist in let if ((dist +. 0.01) >=. tmax) then 1 else 0 -> maxlimit in let if ((dist -. 0.01) <=. tmin) then 1 else 0 -> minlimit in let if (minlimit || maxlimit) then 1 else 0 -> hitlimit in ( //addLogMessage ftoa dist; if (maxlimit && !obstr.PSLIDER_bLastLimit) then ( SendPluginEvent inst "In max limit" nil nil; set obstr.PSLIDER_iDebounceTick = obstr.PSLIDER_iTick; set obstr.PSLIDER_bLastLimit = hitlimit; ) else if (minlimit && !obstr.PSLIDER_bLastLimit) then ( SendPluginEvent inst "In min limit" nil nil; set obstr.PSLIDER_iDebounceTick = obstr.PSLIDER_iTick; set obstr.PSLIDER_bLastLimit = hitlimit; ) else if (!hitlimit && obstr.PSLIDER_bLastLimit) then ( SendPluginEvent inst "Out limits" nil nil; set obstr.PSLIDER_iDebounceTick = obstr.PSLIDER_iTick; set obstr.PSLIDER_bLastLimit = hitlimit; ) else nil; ); ); ); 0;; fun cbEnable(inst, from, action, param, reply, obstr)= if (obstr.PSLIDER_contraint != nil) then nil else ( let if obstr.PSLIDER_iPosMode == 0 then SO3ObjectGetGlobalPosition obstr.PSLIDER_child else if obstr.PSLIDER_iPosMode == 1 then SO3ObjectGetGlobalPosition obstr.PSLIDER_parent else obstr.PSLIDER_tPosition -> pos in let SO3MathsQuatGetDirection (SO3ObjectGetGlobalOrientation obstr.PSLIDER_child) obstr.PSLIDER_tDirection -> dir in set obstr.PSLIDER_contraint = SO3PhysicsContraintCreateSlider (V3DgetSession c3dXsession) (SO3SceneNodeGetBody obstr.PSLIDER_child) (SO3SceneNodeGetBody obstr.PSLIDER_parent) pos dir obstr.PSLIDER_bUseLimits obstr.PSLIDER_bUseSpring; if (!obstr.PSLIDER_bUseLimits) then nil else let obstr.PSLIDER_tLimits -> [mint maxt] in SO3PhysicsContraintSetSliderLimits obstr.PSLIDER_contraint mint maxt; if (!obstr.PSLIDER_bUseSpring) then nil else let obstr.PSLIDER_tSpring -> [strength damping] in ( SO3PhysicsContraintSetSliderSpring obstr.PSLIDER_contraint strength damping; ); SO3PhysicsContraintSetSliderFriction obstr.PSLIDER_contraint obstr.PSLIDER_fFriction; if (!obstr.PSLIDER_bUseMotor) then nil else ( SO3PhysicsContraintSetSliderMotorVelocity obstr.PSLIDER_contraint obstr.PSLIDER_fMotor 1.0; SO3PhysicsContraintSetSliderMotorEnable obstr.PSLIDER_contraint 1; ); SO3PhysicsContraintSetCollisionState obstr.PSLIDER_contraint obstr.PSLIDER_bCollide; setPluginInstanceCbScenePreRender inst mkfun4 @cbContraintPreRender obstr; set obstr.PSLIDER_iTick = 0; set obstr.PSLIDER_iDebounceTick = 0; ); 0;; fun cbDisable(inst, from, action, param, reply, obstr)= SO3PhysicsContraintDestroy obstr.PSLIDER_contraint; set obstr.PSLIDER_contraint = nil; setPluginInstanceCbScenePreRender inst nil; 0;; fun cbLock(inst, from, action, param, reply, obstr)= let SO3PhysicsContraintGetSliderPosition obstr.PSLIDER_contraint -> pos in SO3PhysicsContraintSetSliderLimits obstr.PSLIDER_contraint pos pos; 0;; fun cbUnlock(inst, from, action, param, reply, obstr)= let obstr.PSLIDER_tLimits -> [mint maxt] in SO3PhysicsContraintSetSliderLimits obstr.PSLIDER_contraint mint maxt; 0;; fun cbSetLimits(inst, from, action, param, reply, obstr)= let strextr param -> l in let hd l -> p in let (atof (hd p)) -> mint in let if mint == nil then 0.0 else mint -> mint in let atof (hd tl p) -> maxt in let if maxt == nil then 0.0 else maxt -> maxt in if (!obstr.PSLIDER_bUseLimits) then nil else ( set obstr.PSLIDER_tLimits = [mint maxt]; SO3PhysicsContraintSetSliderLimits obstr.PSLIDER_contraint mint maxt; ); 0;; fun cbSetMotor(inst, from, action, param, reply, obstr)= let strextr param -> l in let hd l -> p in let (atof (hd p)) -> velocity in let if velocity == nil then 0.0 else velocity -> velocity in let atof (hd tl p) -> force in let if force == nil then 1.0 else force -> force in ( SO3PhysicsContraintSetSliderMotorVelocity obstr.PSLIDER_contraint velocity force; SO3PhysicsContraintSetSliderMotorEnable obstr.PSLIDER_contraint 1; ); 0;; fun cbStopMotor(inst, from, action, param, reply, obstr)= SO3PhysicsContraintSetSliderMotorEnable obstr.PSLIDER_contraint 0; 0;; fun cbSetBreakForce(inst, from, action, param, reply, obstr)= set obstr.PSLIDER_fBreakForce = atof param; 0;; fun newOb(inst)= let (getPluginInstanceParam inst "object") -> objsource in let (getPluginInstanceParam inst "parent") -> objparent in let atoi (getPluginInstanceParam inst "collide") -> collide in let atoi (getPluginInstanceParam inst "posmode") -> posmode in let atof (getPluginInstanceParam inst "posx") -> fx in let atof (getPluginInstanceParam inst "posy") -> fy in let atof (getPluginInstanceParam inst "posz") -> fz in let [fx fy fz] -> offset in let atof (getPluginInstanceParam inst "dirx") -> dirx in let atof (getPluginInstanceParam inst "diry") -> diry in let atof (getPluginInstanceParam inst "dirz") -> dirz in let [dirx diry dirz] -> dir in let atof (getPluginInstanceParam inst "friction") -> friction in let atoi (getPluginInstanceParam inst "useLimits") -> useLimits in let atof (getPluginInstanceParam inst "mindist") -> mindist in let atof (getPluginInstanceParam inst "maxdist") -> maxdist in let atoi (getPluginInstanceParam inst "useSpring") -> useSpring in let atof (getPluginInstanceParam inst "spstrength") -> spstrength in let atof (getPluginInstanceParam inst "spdamping") -> spdamping in let atof (getPluginInstanceParam inst "breakforce") -> breakforce in let atoi (getPluginInstanceParam inst "useMotor") -> usemotor in let atof (getPluginInstanceParam inst "motor") -> motor in let atoi (getPluginInstanceParam inst "init") -> init in let V3DgetObjectByName c3dXsession objparent -> parent in let V3DgetObjectTypeByName objparent -> iobj1mode in let V3DgetObjectByName c3dXsession objsource -> objsrc in let V3DgetObjectTypeByName objsource -> iobj2mode in let mkObjSliderStr [objsrc parent collide iobj1mode iobj2mode nil posmode offset dir [mindist maxdist] useLimits [spstrength spdamping] useSpring breakforce friction usemotor motor 1 0 0] -> obstr in ( if !iobj1mode && !iobj2mode then nil else setPluginInstanceCbCameraChange inst mkfun5 @cbChangeCamera obstr; if (!init) then nil else cbEnable inst nil nil nil nil obstr; PluginRegisterAction inst "Enable" mkfun6 @cbEnable obstr; PluginRegisterAction inst "Disable" mkfun6 @cbDisable obstr; PluginRegisterAction inst "Lock" mkfun6 @cbLock obstr; PluginRegisterAction inst "Unlock" mkfun6 @cbUnlock obstr; PluginRegisterAction inst "Set motor" mkfun6 @cbSetMotor obstr; PluginRegisterAction inst "Stop motor" mkfun6 @cbStopMotor obstr; PluginRegisterAction inst "Set limits" mkfun6 @cbSetLimits obstr; PluginRegisterAction inst "Set break force" mkfun6 @cbSetBreakForce obstr; setPluginInstanceCbDel inst mkfun2 @deleteOb obstr; ); 0;; fun IniPlug(file)= PlugRegister @newOb nil; setPluginEditor @dynamicedit; 0;;