/* ----------------------------------------------------------------------------- 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 ObjPhysBodyStr = [ PBODY_inst : PInstance, PBODY_obj : SO3_OBJECT, PBODY_iCameraMode : I, PBODY_initpos : [[F F F] [F F F F]], PBODY_mode : I, PBODY_bCancelGravity : I, PBODY_bAutoFreeze : I, PBODY_bUpJoint : I, PBODY_tFluid : [I F], PBODY_state : I, PBODY_bVelolicty : I, PBODY_bOmega : I, PBODY_bContact : I, PBODY_bRayIn : I, PBODY_bRayOut : I, PBODY_bOverlapStart : I, PBODY_bOverlapStop : I, PBODY_bGrabed : I, PBODY_bUngrabed : I ]mkObjPhysBodyStr;; fun deleteOb(inst, objbodystr)= let SO3SceneNodeGetBody objbodystr.PBODY_obj -> body in let objbodystr.PBODY_tFluid -> [isfluid vol] in ( setPluginInstanceCbPostRender inst nil; setPluginInstanceCbCameraChange inst nil; SO3BodyDestroyBasicJointUpVector body; SO3BodySetAutoSleep body 1; SO3BodySetGravityEnable body 1; SO3BodySetFluid body isfluid; SO3BodySetFluidVolumeRatio body vol; SO3BodySetIgnoreCollision body 0; set objbodystr.PBODY_obj = nil; set objbodystr.PBODY_iCameraMode = 0; set objbodystr.PBODY_initpos = nil; set objbodystr.PBODY_tFluid = nil; ); 0;; fun cbGetPostRender(inst, viewstr, objbodystr)= let SO3SceneNodeGetBody objbodystr.PBODY_obj -> body in if body == nil then nil else let SO3BodyGetVelocity body -> [vx vy vz] in let if objbodystr.PBODY_mode then SO3ObjectGetDerivedDirectionAxis objbodystr.PBODY_obj [vx vy vz] else [vx vy vz] -> [vx vy vz] in let SO3BodyGetOmega body -> [ox oy oz] in let if objbodystr.PBODY_mode then SO3ObjectGetDerivedDirectionAxis objbodystr.PBODY_obj [ox oy oz] else [ox oy oz] -> [ox oy oz] in ( if (!objbodystr.PBODY_bVelolicty) then nil else SendPluginEvent inst "Velocity" strbuild ((ftoa vx)::(ftoa vy)::(ftoa vz)::nil)::nil nil; if (!objbodystr.PBODY_bOmega) then nil else SendPluginEvent inst "Omega" strbuild ((ftoa ox)::(ftoa oy)::(ftoa oz)::nil)::nil nil; if ((absf vx) >=. 0.001 || (absf vy) >=. 0.001 || (absf vz) >=. 0.001 || (absf ox) >=. 0.001 || (absf oy) >=. 0.001 || (absf oz) >=. 0.001) then ( if objbodystr.PBODY_state == 1 then nil else ( set objbodystr.PBODY_state = 1; SendPluginEvent inst "Has motion" nil nil; ); ) else ( if objbodystr.PBODY_state == 0 then nil else ( set objbodystr.PBODY_state = 0; SendPluginEvent inst "Has no motion" nil nil; ); ); ); 0;; fun cbSetWorldEnable(inst, from, action, param, reply, objbodystr)= if (param == nil) then nil else V3DphysEnablePhysic c3dXsession (getBooleanFromString param); 0;; fun cbResetWorld(inst, from, action, param, reply, objbodystr)= V3DphysResetPhysic c3dXsession; 0;; fun cbSetWorldGravity(inst, from, action, param, reply, objbodystr)= if (atof param) == nil then nil else let hd strextr param -> lp in let atof hd lp -> px in let atof hd tl lp -> py in let atof hd tl tl lp -> pz in V3DphysSetGravity c3dXsession [px py pz]; 0;; fun cbSetEnable(inst, from, action, param, reply, objbodystr)= if param == nil then nil else let SO3SceneNodeGetBody objbodystr.PBODY_obj -> body in if (getBooleanFromString param) != 1 then ( SO3BodySetIgnoreCollision body 1; SO3BodySetVelocity body [0.0 0.0 0.0]; SO3BodySetFreeze body 1; ) else ( SO3BodySetIgnoreCollision body 0; SO3BodySetFreeze body 0; ); 0;; fun cbSetFluid(inst, from, action, param, reply, objbodystr)= if param == nil then nil else let SO3SceneNodeGetBody objbodystr.PBODY_obj -> body in let (getBooleanFromString param) -> state in ( SO3BodySetFluid body state; ); 0;; fun cbSetFluidVolume(inst, from, action, param, reply, objbodystr)= if param == nil then nil else let SO3SceneNodeGetBody objbodystr.PBODY_obj -> body in let atof param -> val in ( SO3BodySetFluidVolumeRatio body val; ); 0;; fun cbSetMass(inst, from, action, param, reply, objbodystr)= let SO3SceneNodeGetBody objbodystr.PBODY_obj -> body in SO3BodySetMass body if (atof param) == nil then 0.0 else (atof param); 0;; fun cbAddImpulse(inst, from, action, param, reply, objbodystr)= let SO3SceneNodeGetBody objbodystr.PBODY_obj -> body in let hd strextr param -> lp in let hd tl strextr param -> op in let [(if (atof hd lp) == nil then 0.0 else (atof hd lp)) (if (atof hd tl lp) == nil then 0.0 else (atof hd tl lp)) (if (atof hd tl tl lp) == nil then 0.0 else (atof hd tl tl lp))] -> [x y z] in let if objbodystr.PBODY_mode then SO3ObjectGetDerivedDirectionAxis objbodystr.PBODY_obj [x y z] else [x y z] -> [x y z] in let SO3ObjectGetGlobalPosition objbodystr.PBODY_obj -> [px py pz] in let [(if (atof hd op) == nil then px else px +. (atof hd op)) (if (atof hd tl op) == nil then py else py +. (atof hd tl op)) (if (atof hd tl tl op) == nil then pz else pz +. (atof hd tl tl op))] -> [ox oy oz] in let if objbodystr.PBODY_mode then SO3ObjectGetDerivedDirectionAxis objbodystr.PBODY_obj [ox oy oz] else [ox oy oz] -> [ox oy oz] in SO3BodyAddImpulse body [x y z] [ox oy oz]; 0;; fun cbSetOmega(inst, from, action, param, reply, objbodystr)= let SO3SceneNodeGetBody objbodystr.PBODY_obj -> body in let hd strextr param -> lp in let [(if (atof hd lp) == nil then 0.0 else (atof hd lp)) (if (atof hd tl lp) == nil then 0.0 else (atof hd tl lp)) (if (atof hd tl tl lp) == nil then 0.0 else (atof hd tl tl lp))] -> [x y z] in let if objbodystr.PBODY_mode then SO3ObjectGetDerivedDirectionAxis objbodystr.PBODY_obj [x y z] else [x y z] -> [x y z] in SO3BodySetOmega body [x y z]; 0;; fun cbSetVelocity(inst, from, action, param, reply, objbodystr)= let SO3SceneNodeGetBody objbodystr.PBODY_obj -> body in let hd strextr param -> lp in let [(if (atof hd lp) == nil then 0.0 else (atof hd lp)) (if (atof hd tl lp) == nil then 0.0 else (atof hd tl lp)) (if (atof hd tl tl lp) == nil then 0.0 else (atof hd tl tl lp))] -> [x y z] in let if objbodystr.PBODY_mode then SO3ObjectGetDerivedDirectionAxis objbodystr.PBODY_obj [x y z] else [x y z] -> [x y z] in SO3BodySetVelocity body [x y z]; 0;; fun cbAddVelocity(inst, from, action, param, reply, objbodystr)= let SO3SceneNodeGetBody objbodystr.PBODY_obj -> body in let hd strextr param -> lp in let [(if (atof hd lp) == nil then 0.0 else (atof hd lp)) (if (atof hd tl lp) == nil then 0.0 else (atof hd tl lp)) (if (atof hd tl tl lp) == nil then 0.0 else (atof hd tl tl lp))] -> [x y z] in let if objbodystr.PBODY_mode then SO3ObjectGetDerivedDirectionAxis objbodystr.PBODY_obj [x y z] else [x y z] -> [x y z] in let SO3BodyGetVelocity body -> [vx vy vz] in SO3BodySetVelocity body [x +. vx y +. vy z +. vz]; 0;; fun cbSetForce(inst, from, action, param, reply, objbodystr)= let SO3SceneNodeGetBody objbodystr.PBODY_obj -> body in let hd strextr param -> lp in let [(if (atof hd lp) == nil then 0.0 else (atof hd lp)) (if (atof hd tl lp) == nil then 0.0 else (atof hd tl lp)) (if (atof hd tl tl lp) == nil then 0.0 else (atof hd tl tl lp))] -> [x y z] in let if objbodystr.PBODY_mode then SO3ObjectGetDerivedDirectionAxis objbodystr.PBODY_obj [x y z] else [x y z] -> [x y z] in SO3BodySetForce body [x y z]; 0;; fun cbAddForce(inst, from, action, param, reply, objbodystr)= let SO3SceneNodeGetBody objbodystr.PBODY_obj -> body in let hd strextr param -> lp in let [(if (atof hd lp) == nil then 0.0 else (atof hd lp)) (if (atof hd tl lp) == nil then 0.0 else (atof hd tl lp)) (if (atof hd tl tl lp) == nil then 0.0 else (atof hd tl tl lp))] -> [x y z] in if objbodystr.PBODY_mode then SO3BodyAddLocalForce body [x y z] else SO3BodyAddForce body [x y z]; 0;; fun cbSetTorque(inst, from, action, param, reply, objbodystr)= let SO3SceneNodeGetBody objbodystr.PBODY_obj -> body in let hd strextr param -> lp in let [(if (atof hd lp) == nil then 0.0 else (atof hd lp)) (if (atof hd tl lp) == nil then 0.0 else (atof hd tl lp)) (if (atof hd tl tl lp) == nil then 0.0 else (atof hd tl tl lp))] -> [x y z] in let if objbodystr.PBODY_mode then SO3ObjectGetDerivedDirectionAxis objbodystr.PBODY_obj [x y z] else [x y z] -> [x y z] in SO3BodySetTorque body [x y z]; 0;; fun cbAddTorque(inst, from, action, param, reply, objbodystr)= let SO3SceneNodeGetBody objbodystr.PBODY_obj -> body in let hd strextr param -> lp in let [(if (atof hd lp) == nil then 0.0 else (atof hd lp)) (if (atof hd tl lp) == nil then 0.0 else (atof hd tl lp)) (if (atof hd tl tl lp) == nil then 0.0 else (atof hd tl tl lp))] -> [x y z] in let if objbodystr.PBODY_mode then SO3ObjectGetDerivedDirectionAxis objbodystr.PBODY_obj [x y z] else [x y z] -> [x y z] in SO3BodyAddTorque body [x y z]; 0;; fun cbSetConstantForce(inst, from, action, param, reply, objbodystr)= let SO3SceneNodeGetBody objbodystr.PBODY_obj -> body in let hd strextr param -> lp in let [(if (atof hd lp) == nil then 0.0 else (atof hd lp)) (if (atof hd tl lp) == nil then 0.0 else (atof hd tl lp)) (if (atof hd tl tl lp) == nil then 0.0 else (atof hd tl tl lp))] -> [x y z] in let if objbodystr.PBODY_mode then SO3ObjectGetDerivedDirectionAxis objbodystr.PBODY_obj [x y z] else [x y z] -> [x y z] in SO3BodySetConstantForce body [x y z]; 0;; fun cbAddConstantForce(inst, from, action, param, reply, objbodystr)= let SO3SceneNodeGetBody objbodystr.PBODY_obj -> body in let hd strextr param -> lp in let [(if (atof hd lp) == nil then 0.0 else (atof hd lp)) (if (atof hd tl lp) == nil then 0.0 else (atof hd tl lp)) (if (atof hd tl tl lp) == nil then 0.0 else (atof hd tl tl lp))] -> [x y z] in let if objbodystr.PBODY_mode then SO3ObjectGetDerivedDirectionAxis objbodystr.PBODY_obj [x y z] else [x y z] -> [x y z] in SO3BodyAddConstantForce body [x y z]; 0;; fun cbSetConstantTorque(inst, from, action, param, reply, objbodystr)= let SO3SceneNodeGetBody objbodystr.PBODY_obj -> body in let hd strextr param -> lp in let [(if (atof hd lp) == nil then 0.0 else (atof hd lp)) (if (atof hd tl lp) == nil then 0.0 else (atof hd tl lp)) (if (atof hd tl tl lp) == nil then 0.0 else (atof hd tl tl lp))] -> [x y z] in let if objbodystr.PBODY_mode then SO3ObjectGetDerivedDirectionAxis objbodystr.PBODY_obj [x y z] else [x y z] -> [x y z] in SO3BodySetConstantTorque body [x y z]; 0;; fun cbAddConstantTorque(inst, from, action, param, reply, objbodystr)= let SO3SceneNodeGetBody objbodystr.PBODY_obj -> body in let hd strextr param -> lp in let [(if (atof hd lp) == nil then 0.0 else (atof hd lp)) (if (atof hd tl lp) == nil then 0.0 else (atof hd tl lp)) (if (atof hd tl tl lp) == nil then 0.0 else (atof hd tl tl lp))] -> [x y z] in let if objbodystr.PBODY_mode then SO3ObjectGetDerivedDirectionAxis objbodystr.PBODY_obj [x y z] else [x y z] -> [x y z] in SO3BodyAddConstantTorque body [x y z]; 0;; fun cbAutoFreezeBody(inst, from, action, param, reply, objbodystr)= let if (param) == nil then 1 else (getBooleanFromString param) -> state in let SO3SceneNodeGetBody objbodystr.PBODY_obj -> body in if body == nil then nil else SO3BodySetAutoSleep body state; 0;; fun cbResetBody(inst, from, action, param, reply, objbodystr)= let SO3SceneNodeGetBody objbodystr.PBODY_obj -> body in let objbodystr.PBODY_initpos -> [pos quat] in if body == nil then nil else ( SO3BodySetVelocity body [0.0 0.0 0.0]; SO3BodySetOmega body [0.0 0.0 0.0]; SO3BodySetTorque body [0.0 0.0 0.0]; SO3BodySetConstantTorque body [0.0 0.0 0.0]; SO3BodySetConstantForce body [0.0 0.0 0.0]; SO3BodySetForce body [0.0 0.0 0.0]; SO3ObjectSetPosition objbodystr.PBODY_obj pos; SO3ObjectSetOrientation objbodystr.PBODY_obj quat; ); 0;; fun cbChangeCamera(inst, viewstr, sessionstr, camera, objbodystr)= if (camera != V3DgetDefaultCamera c3dXsession) then nil else let objbodystr.PBODY_obj -> oldson in let V3DgetCameraByType sessionstr camera objbodystr.PBODY_iCameraMode -> father in let SO3ObjectGetPosition father -> cpos in let SO3ObjectGetOrientation father -> cquat in ( set objbodystr.PBODY_obj = father; let objbodystr.PBODY_initpos -> [pos quat] in ( SO3ObjectSetPosition oldson pos; SO3ObjectSetOrientation oldson quat; ); set objbodystr.PBODY_initpos = [cpos cquat]; ); 0;; fun cbGeneric(inst, type, value, param, objbodystr)= let (SO3ObjectGetName objbodystr.PBODY_obj) -> objname in if (strcmpi objname value) then nil else ( if (type == 16) then if (!objbodystr.PBODY_bRayIn) then nil else SendPluginEvent objbodystr.PBODY_inst "Ray intersect in" param nil else if (type == 17) then if (!objbodystr.PBODY_bRayOut) then nil else SendPluginEvent objbodystr.PBODY_inst "Ray intersect out" param nil else if (type == 18) then if (!objbodystr.PBODY_bContact) then nil else SendPluginEvent objbodystr.PBODY_inst "Contact" param nil else if (type == 19) then if (!objbodystr.PBODY_bOverlapStart) then nil else SendPluginEvent objbodystr.PBODY_inst "Overlap started" param nil else if (type == 20) then if (!objbodystr.PBODY_bOverlapStop) then nil else SendPluginEvent objbodystr.PBODY_inst "Overlap stopped" param nil else if (type == 21) then if (!objbodystr.PBODY_bGrabed) then nil else SendPluginEvent objbodystr.PBODY_inst "Grabed" param nil else if (type == 22) then if (!objbodystr.PBODY_bUngrabed) then nil else SendPluginEvent objbodystr.PBODY_inst "Ungrabed" param nil else nil; ); 0;; fun cbSetObject(inst, from, action, param, reply, objbodystr)= deleteOb inst objbodystr; let V3DgetObjectByName c3dXsession param -> objsrc in let V3DgetObjectTypeByName param -> icammode in let SO3ObjectGetPosition objsrc -> cpos in let SO3ObjectGetOrientation objsrc -> cquat in let SO3SceneNodeGetBody objsrc -> body in let SO3BodyGetFluid body -> isfluid in let SO3BodyGetFluidVolumeRatio body -> vol in ( set objbodystr.PBODY_obj = objsrc; set objbodystr.PBODY_iCameraMode = icammode; set objbodystr.PBODY_initpos = [cpos cquat]; set objbodystr.PBODY_tFluid = [isfluid vol]; if icammode == 0 then nil else setPluginInstanceCbCameraChange inst mkfun5 @cbChangeCamera objbodystr; if !(objbodystr.PBODY_bUpJoint) then nil else SO3BodyCreateBasicJointUpVector body [0.0 1.0 0.0]; if (!objbodystr.PBODY_bCancelGravity) then nil else SO3BodySetGravityEnable body 0; SO3BodySetAutoSleep body objbodystr.PBODY_bAutoFreeze; SendPluginEvent inst "Object setted" nil nil; ); 0;; fun cbApplyObject(inst, from, action, param, reply, objbodystr)= let V3DgetObjectByName c3dXsession param -> objsrc in let V3DgetObjectTypeByName param -> icammode in let SO3SceneNodeGetBody objbodystr.PBODY_obj -> srcbody in let SO3ObjectGetPosition objsrc -> cpos in let SO3ObjectGetOrientation objsrc -> cquat in let SO3SceneNodeGetBody objsrc -> body in ( if !(objbodystr.PBODY_bUpJoint) then nil else SO3BodyCreateBasicJointUpVector body [0.0 1.0 0.0]; if (!objbodystr.PBODY_bCancelGravity) then nil else SO3BodySetGravityEnable body 0; SO3BodySetAutoSleep body objbodystr.PBODY_bAutoFreeze; SO3BodySetConstantForce body SO3BodyGetConstantForce srcbody; SO3BodySetConstantTorque body SO3BodyGetConstantTorque srcbody; ); 0;; fun cbSetGravityState(inst, from, action, param, reply, objbodystr)= let getBooleanFromString param -> state in let SO3SceneNodeGetBody objbodystr.PBODY_obj -> body in SO3BodySetGravityEnable body state; 0;; fun newOb(inst)= let (getPluginInstanceParam inst "object") -> objname in let atoi (getPluginInstanceParam inst "mode") -> mode in let atoi (getPluginInstanceParam inst "upjoint") -> upjoint in let atoi (getPluginInstanceParam inst "autofreeze") -> autofreeze in let if (autofreeze == nil) then 1 else autofreeze -> autofreeze in let atoi (getPluginInstanceParam inst "cancelgravity") -> cancelgravity in let if (cancelgravity == nil) then 0 else cancelgravity -> cancelgravity in let V3DgetObjectByName c3dXsession objname -> objsrc in let V3DgetObjectTypeByName objname -> icammode in let SO3ObjectGetPosition objsrc -> cpos in let SO3ObjectGetOrientation objsrc -> cquat in let SO3SceneNodeGetBody objsrc -> body in let SO3BodyGetFluid body -> isfluid in let SO3BodyGetFluidVolumeRatio body -> vol in let (IsInEditor inst) || IsEventLinked inst "Velocity" -> bVel in let (IsInEditor inst) || IsEventLinked inst "Omega" -> bOmega in let (IsInEditor inst) || IsEventLinked inst "Contact" -> bContact in let (IsInEditor inst) || IsEventLinked inst "Ray intersect in" -> bRayIn in let (IsInEditor inst) || IsEventLinked inst "Ray intersect out" -> bRayOut in let (IsInEditor inst) || IsEventLinked inst "Overlap started" -> bOverlapStart in let (IsInEditor inst) || IsEventLinked inst "Overlap stopped" -> bOverlapStop in let (IsInEditor inst) || IsEventLinked inst "Grabed" -> bGrabed in let (IsInEditor inst) || IsEventLinked inst "Ungrabed" -> bUngrabed in let mkObjPhysBodyStr [inst objsrc icammode [cpos cquat] mode cancelgravity autofreeze upjoint [isfluid vol] 0 bVel bOmega bContact bRayIn bRayOut bOverlapStart bOverlapStop bGrabed bUngrabed] -> objbodystr in ( if icammode == 0 then nil else setPluginInstanceCbCameraChange inst mkfun5 @cbChangeCamera objbodystr; if !upjoint then nil else SO3BodyCreateBasicJointUpVector body [0.0 1.0 0.0]; if (!cancelgravity) then nil else SO3BodySetGravityEnable body 0; if (!bContact && !bRayIn && !bRayOut && !bOverlapStart && !bOverlapStop && !bGrabed && !bUngrabed) then nil else setPluginInstanceCbGeneric inst mkfun5 @cbGeneric objbodystr; SO3BodySetAutoSleep body autofreeze; PluginRegisterAction inst "Reset body" mkfun6 @cbResetBody objbodystr; PluginRegisterAction inst "Set omega" mkfun6 @cbSetOmega objbodystr; PluginRegisterAction inst "Set velocity" mkfun6 @cbSetVelocity objbodystr; PluginRegisterAction inst "Add velocity" mkfun6 @cbAddVelocity objbodystr; PluginRegisterAction inst "Set force" mkfun6 @cbSetForce objbodystr; PluginRegisterAction inst "Add force" mkfun6 @cbAddForce objbodystr; PluginRegisterAction inst "Set torque" mkfun6 @cbSetTorque objbodystr; PluginRegisterAction inst "Add torque" mkfun6 @cbAddTorque objbodystr; PluginRegisterAction inst "Set constant force" mkfun6 @cbSetConstantForce objbodystr; PluginRegisterAction inst "Add constant force" mkfun6 @cbAddConstantForce objbodystr; PluginRegisterAction inst "Set constant torque" mkfun6 @cbSetConstantTorque objbodystr; PluginRegisterAction inst "Add constant torque" mkfun6 @cbAddConstantTorque objbodystr; PluginRegisterAction inst "Set gravity state" mkfun6 @cbSetGravityState objbodystr; PluginRegisterAction inst "Set world enable" mkfun6 @cbSetWorldEnable objbodystr; PluginRegisterAction inst "Reset world" mkfun6 @cbResetWorld objbodystr; PluginRegisterAction inst "Add impulse" mkfun6 @cbAddImpulse objbodystr; PluginRegisterAction inst "Set world gravity" mkfun6 @cbSetWorldGravity objbodystr; PluginRegisterAction inst "Set enable" mkfun6 @cbSetEnable objbodystr; PluginRegisterAction inst "Set mass" mkfun6 @cbSetMass objbodystr; PluginRegisterAction inst "Set auto freeze" mkfun6 @cbAutoFreezeBody objbodystr; PluginRegisterAction inst "Set fluid" mkfun6 @cbSetFluid objbodystr; PluginRegisterAction inst "Set fluid volume ratio" mkfun6 @cbSetFluidVolume objbodystr; PluginRegisterAction inst "Set object" mkfun6 @cbSetObject objbodystr; PluginRegisterAction inst "Apply on object" mkfun6 @cbApplyObject objbodystr; setPluginInstanceCbPostRender inst mkfun3 @cbGetPostRender objbodystr; setPluginInstanceCbDel inst mkfun2 @deleteOb objbodystr; ); 0;; fun IniPlug(file)= PlugRegister @newOb nil; setPluginEditor @dynamicedit; 0;;