/* ----------------------------------------------------------------------------- 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 ObjPhysMatStr = [ OPHYSM_inst : PInstance, OPHYSM_mat1 : SO3_PHYSICMATERIAL, OPHYSM_mat2 : SO3_PHYSICMATERIAL, OPHYSM_sMatName1 : S, OPHYSM_sMatName2 : S, OPHYSM_elasticity : F, OPHYSM_staticFriction : F, OPHYSM_kineticFriction : F, OPHYSM_softness : F, OPHYSM_thickness : F, OPHYSM_collidable : I, OPHYSM_bOverlapped : I, OPHYSM_bIsOverlapped : I, OPHYSM_tContactDefault : [F F F F F I I], OPHYSM_bContactEvent : I, OPHYSM_bContactSpeedEvent : I, OPHYSM_bContactPosition : I, OPHYSM_iLastTick : I ]mkObjPhysMatStr;; fun deleteOb(inst, ophystr)= SO3CbMaterialCollision ophystr.OPHYSM_mat1 ophystr.OPHYSM_mat2 nil nil; SO3CbMaterialOverlapStarted ophystr.OPHYSM_mat1 ophystr.OPHYSM_mat2 nil nil; SO3CbMaterialOverlapEnded ophystr.OPHYSM_mat1 ophystr.OPHYSM_mat2 nil nil; let ophystr.OPHYSM_tContactDefault -> [elasticity staticfriction kineticfriction softness thickness continious collidable] in ( SO3PhysicsMaterialSetDefaultElasticity ophystr.OPHYSM_mat1 ophystr.OPHYSM_mat2 elasticity; SO3PhysicsMaterialSetDefaultFriction ophystr.OPHYSM_mat1 ophystr.OPHYSM_mat2 staticfriction kineticfriction; SO3PhysicsMaterialSetDefaultSoftness ophystr.OPHYSM_mat1 ophystr.OPHYSM_mat2 softness; SO3PhysicsMaterialSetSurfaceThickness ophystr.OPHYSM_mat1 ophystr.OPHYSM_mat2 thickness; SO3PhysicsMaterialSetContiniousCollisionMode ophystr.OPHYSM_mat1 ophystr.OPHYSM_mat2 continious; SO3PhysicsMaterialSetDefaultCollidable ophystr.OPHYSM_mat1 ophystr.OPHYSM_mat2 collidable; ); 0;; fun cbPhysCollision(scene, ophystr, body1, body2, pos, normal, force, normalspeed)= let _tickcount -> tick in if (ophystr.OPHYSM_iLastTick != 0 && (tick - ophystr.OPHYSM_iLastTick) < 17) then nil else ( if (!ophystr.OPHYSM_bContactPosition) then nil else let pos -> [x y z] in SendPluginEvent ophystr.OPHYSM_inst "Contact position" strcatnSep (ftoa x)::(ftoa y)::(ftoa z)::nil " " nil; //let force -> [x y z] in // SendPluginEvent ophystr.OPHYSM_inst "Contact force" strcatnsep (ftoa x)::(ftoa y)::(ftoa z)::nil " " nil; if (!ophystr.OPHYSM_bContactSpeedEvent) then nil else SendPluginEvent ophystr.OPHYSM_inst "Contact speed" ftoa (absf normalspeed) nil; if (!ophystr.OPHYSM_bContactEvent) then nil else SendPluginEvent ophystr.OPHYSM_inst "Contact" nil nil; let pos -> [x y z] in let normal -> [nx ny nz] in let force -> [fx fy fz] in ( cbPlugGeneric 18 SO3ObjectGetName (SO3BodyGetSceneNode body1) strcatn (SO3ObjectGetName (SO3BodyGetSceneNode body2))::"\n"::ophystr.OPHYSM_sMatName1::"\n"::ophystr.OPHYSM_sMatName2::"\n"::(strcatnSep (ftoa x)::(ftoa y)::(ftoa z)::nil " ")::"\n"::(strcatnSep (ftoa nx)::(ftoa ny)::(ftoa nz)::nil " ")::"\n"::(strcatnSep (ftoa fx)::(ftoa fy)::(ftoa fz)::nil " ")::"\n"::(ftoa normalspeed)::nil; cbPlugGeneric 18 SO3ObjectGetName (SO3BodyGetSceneNode body2) strcatn (SO3ObjectGetName (SO3BodyGetSceneNode body1))::"\n"::ophystr.OPHYSM_sMatName1::"\n"::ophystr.OPHYSM_sMatName2::"\n"::(strcatnSep (ftoa x)::(ftoa y)::(ftoa z)::nil " ")::"\n"::(strcatnSep (ftoa nx)::(ftoa ny)::(ftoa nz)::nil " ")::"\n"::(strcatnSep (ftoa fx)::(ftoa fy)::(ftoa fz)::nil " ")::"\n"::(ftoa normalspeed)::nil; ); set ophystr.OPHYSM_iLastTick = _tickcount; ); 0;; fun cbPhysOverlapStarted(scene, ophystr, body1, body2)= SendPluginEvent ophystr.OPHYSM_inst "Overlap started" nil nil; cbPlugGeneric 19 SO3ObjectGetName (SO3BodyGetSceneNode body1) strcatn (SO3ObjectGetName (SO3BodyGetSceneNode body2))::"\n"::ophystr.OPHYSM_sMatName1::"\n"::ophystr.OPHYSM_sMatName2::nil; cbPlugGeneric 19 SO3ObjectGetName (SO3BodyGetSceneNode body2) strcatn (SO3ObjectGetName (SO3BodyGetSceneNode body1))::"\n"::ophystr.OPHYSM_sMatName1::"\n"::ophystr.OPHYSM_sMatName2::nil; 0;; fun cbPhysOverlapEnded(scene, ophystr, body1, body2)= SendPluginEvent ophystr.OPHYSM_inst "Overlap stopped" nil nil; cbPlugGeneric 20 SO3ObjectGetName (SO3BodyGetSceneNode body1) strcatn (SO3ObjectGetName (SO3BodyGetSceneNode body2))::"\n"::ophystr.OPHYSM_sMatName1::"\n"::ophystr.OPHYSM_sMatName2::nil; cbPlugGeneric 20 SO3ObjectGetName (SO3BodyGetSceneNode body2) strcatn (SO3ObjectGetName (SO3BodyGetSceneNode body1))::"\n"::ophystr.OPHYSM_sMatName1::"\n"::ophystr.OPHYSM_sMatName2::nil; 0;; fun cbSetCollidable(inst, from, action, param, reply, ophystr)= if param == nil then nil else SO3PhysicsMaterialSetDefaultCollidable ophystr.OPHYSM_mat1 ophystr.OPHYSM_mat2 (getBooleanFromString param); 0;; fun newOb(inst)= let (getPluginInstanceParam inst "mat1") -> matname1 in let (getPluginInstanceParam inst "mat2") -> matname2 in let atof (getPluginInstanceParam inst "elasticity") -> elasticity in let atof (getPluginInstanceParam inst "staticfriction") -> staticfriction in let atof (getPluginInstanceParam inst "kineticfriction") -> kineticfriction in let atof (getPluginInstanceParam inst "softness") -> softness in let atof (getPluginInstanceParam inst "thickness") -> thickness in let atoi (getPluginInstanceParam inst "collidable") -> collidable in let SO3PhysicsGetMaterial (V3DgetSession c3dXsession) matname1 -> mat1 in let if mat1 == nil then SO3PhysicsMaterialCreate (V3DgetSession c3dXsession) matname1 else mat1 -> mat1 in let SO3PhysicsGetMaterial (V3DgetSession c3dXsession) matname2 -> mat2 in let if mat2 == nil then SO3PhysicsMaterialCreate (V3DgetSession c3dXsession) matname2 else mat2 -> mat2 in let (IsInEditor inst) || IsEventLinked inst "Contact" -> bcontactevent in let (IsInEditor inst) || IsEventLinked inst "Contact speed" -> bcontactspeedevent in let (IsInEditor inst) || IsEventLinked inst "Contact position" -> bcontactposevent in let mkObjPhysMatStr [inst mat1 mat2 matname1 matname2 elasticity staticfriction kineticfriction softness thickness collidable nil nil nil bcontactevent bcontactspeedevent bcontactposevent 0] -> ophystr in ( set ophystr.OPHYSM_tContactDefault = [0.4 0.9 0.5 0.1 0.0 0 1]; SO3PhysicsMaterialSetDefaultElasticity mat1 mat2 elasticity; SO3PhysicsMaterialSetDefaultFriction mat1 mat2 staticfriction kineticfriction; SO3PhysicsMaterialSetDefaultSoftness mat1 mat2 softness; SO3PhysicsMaterialSetSurfaceThickness mat1 mat2 thickness; SO3PhysicsMaterialSetDefaultCollidable mat1 mat2 collidable; SO3CbMaterialCollision mat1 mat2 @cbPhysCollision ophystr; SO3CbMaterialOverlapStarted mat1 mat2 @cbPhysOverlapStarted ophystr; SO3CbMaterialOverlapEnded mat1 mat2 @cbPhysOverlapEnded ophystr; PluginRegisterAction inst "Set collidable" mkfun6 @cbSetCollidable ophystr; setPluginInstanceCbDel inst mkfun2 @deleteOb ophystr; ); 0;; fun IniPlug(file)= PlugRegister @newOb nil; setPluginEditor @dynamicedit; 0;;