/* ----------------------------------------------------------------------------- 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 ObjBallAndSocketStr = [ PBALLASOCKET_child : SO3_OBJECT, PBALLASOCKET_parent : SO3_OBJECT, PBALLASOCKET_bCollide : I, PBALLASOCKET_iTargetMode : I, PBALLASOCKET_iSourceMode : I, PBALLASOCKET_contraint : SO3_PHYSICCONTRAINT, PBALLASOCKET_iPosMode : I, PBALLASOCKET_tPosition : [F F F], PBALLASOCKET_tLimits : [F F F], PBALLASOCKET_bUseLimits : I, PBALLASOCKET_fBreakForce : F ]mkObjBallAndSocketStr;; fun deleteOb(inst, obstr)= setPluginInstanceCbCameraChange inst nil; SO3PhysicsContraintDestroy obstr.PBALLASOCKET_contraint; setPluginInstanceCbScenePreRender inst nil; 0;; fun cbChangeCamera(inst, viewstr, sessionstr, camera, obstr)= if (camera != V3DgetDefaultCamera c3dXsession) then nil else ( if (!obstr.PBALLASOCKET_iSourceMode) then nil else ( set obstr.PBALLASOCKET_child = V3DgetCameraByType sessionstr camera obstr.PBALLASOCKET_iSourceMode; ); if (!obstr.PBALLASOCKET_iTargetMode) then nil else ( set obstr.PBALLASOCKET_parent = V3DgetCameraByType sessionstr camera obstr.PBALLASOCKET_iTargetMode; ); ); 0;; fun cbBallPreRender(inst, sessionstr, etime, obstr)= let SO3PhysicsContraintGetBallAndSocketForce obstr.PBALLASOCKET_contraint -> [x y z] in ( if (obstr.PBALLASOCKET_fBreakForce <=. 0.0) then nil else ( let (absf x +. absf y +. absf z) /. 3.0 -> avforce in if (avforce <. obstr.PBALLASOCKET_fBreakForce) then nil else ( SO3PhysicsContraintDestroy obstr.PBALLASOCKET_contraint; set obstr.PBALLASOCKET_contraint = nil; setPluginInstanceCbScenePreRender inst nil; SendPluginEvent inst "Broken" nil nil; ); ); SendPluginEvent inst "Force" strcatn (ftoa x)::" "::(ftoa y)::" "::(ftoa z)::nil nil; ); 0;; fun cbEnable(inst, from, action, param, reply, obstr)= if (obstr.PBALLASOCKET_contraint != nil) then nil else ( let if obstr.PBALLASOCKET_iPosMode == 0 then SO3ObjectGetGlobalPosition obstr.PBALLASOCKET_child else if obstr.PBALLASOCKET_iPosMode == 1 then SO3ObjectGetGlobalPosition obstr.PBALLASOCKET_parent else obstr.PBALLASOCKET_tPosition -> pos in set obstr.PBALLASOCKET_contraint = SO3PhysicsContraintCreateBallAndSocket (V3DgetSession c3dXsession) (SO3SceneNodeGetBody obstr.PBALLASOCKET_child) (SO3SceneNodeGetBody obstr.PBALLASOCKET_parent) pos obstr.PBALLASOCKET_bUseLimits; if (!obstr.PBALLASOCKET_bUseLimits) then nil else let obstr.PBALLASOCKET_tLimits -> [cone mint maxt] in SO3PhysicsContraintSetBallAndSocketLimits obstr.PBALLASOCKET_contraint (SO3MathsDegreeToRadian cone) (SO3MathsDegreeToRadian mint) (SO3MathsDegreeToRadian maxt); SO3PhysicsContraintSetCollisionState obstr.PBALLASOCKET_contraint obstr.PBALLASOCKET_bCollide; setPluginInstanceCbScenePreRender inst mkfun4 @cbBallPreRender obstr; ); 0;; fun cbDisable(inst, from, action, param, reply, obstr)= SO3PhysicsContraintDestroy obstr.PBALLASOCKET_contraint; set obstr.PBALLASOCKET_contraint = nil; setPluginInstanceCbScenePreRender inst nil; 0;; fun cbSetBreakForce(inst, from, action, param, reply, obstr)= set obstr.PBALLASOCKET_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 atoi (getPluginInstanceParam inst "useLimits") -> useLimits in let atof (getPluginInstanceParam inst "coneangle") -> coneangle in let atof (getPluginInstanceParam inst "mintwist") -> mintwist in let atof (getPluginInstanceParam inst "maxtwist") -> maxtwist in let atof (getPluginInstanceParam inst "breakforce") -> breakforce 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 mkObjBallAndSocketStr [objsrc parent collide iobj1mode iobj2mode nil posmode offset [coneangle mintwist maxtwist] useLimits breakforce] -> 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 "Set break force" mkfun6 @cbSetBreakForce obstr; setPluginInstanceCbDel inst mkfun2 @deleteOb obstr; ); 0;; fun IniPlug(file)= PlugRegister @newOb nil; setPluginEditor @dynamicedit; 0;;