/* ----------------------------------------------------------------------------- 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 ----------------------------------------------------------------------------- */ /************************************************** Ogre 3D Newton physics library Version: 1.0 Author: Bastien BOURINEAU Last update: 16.12.2008 **************************************************/ // arch : SO3_PA_DEFAULT SO3_PA_MEDIUM SO3_PA_BEST // solver : SO3_SM_EXACT 1 2 4 8 // friction : SO3_FM_EXACT SO3_FM_ADAPTATIVE struct V3Dphysics = [ V3DPHYS_iFps : I, V3DPHYS_iArchMode : I, V3DPHYS_iSolverMode : I, V3DPHYS_iFrictionMode : I, V3DPHYS_bEnable : I ] mkV3Dphysics;; proto V3DphysCreateBodyEllipsoid = fun [SO3_OBJECT [F F F]] SO3_PHYSICBODY;; proto V3DphysCreateBodyBox = fun [SO3_OBJECT [F F F]] SO3_PHYSICBODY;; //proto V3DphysCreateBodyFluid = fun [SO3_OBJECT] SO3_PHYSICBODY;; fun V3DphysEnablePhysic(sessionstr, state)= if (sessionstr.V3D_physics.V3DPHYS_bEnable == 1 && state == 1) then nil else ( set sessionstr.V3D_physics.V3DPHYS_bEnable = state; SO3WorldSetEnabled (V3DgetSession sessionstr) state; ); 0;; fun V3DphysResetPhysic(sessionstr)= SO3WorldReset (V3DgetSession sessionstr); 0;; fun V3DphysGetState(sessionstr)= sessionstr.V3D_physics.V3DPHYS_bEnable;; // deprecated fun V3DphysSetWorld(sessionstr, vec)= 0;; // deprecated fun V3DphysGetWorld(sessionstr)= [0.0 0.0 0.0];; fun V3DphysSetFps(sessionstr, fps)= if fps == nil then nil else ( set sessionstr.V3D_physics.V3DPHYS_iFps = fps; SO3WorldSetFPS (V3DgetSession sessionstr) sessionstr.V3D_physics.V3DPHYS_iFps; ); 0;; fun V3DphysGetFps(sessionstr)= sessionstr.V3D_physics.V3DPHYS_iFps;; fun V3DphysSetGravity(sessionstr, g)= SO3WorldSetGravity (V3DgetSession sessionstr) (multiplyVectorF g [(itof iGlobalUnit) (itof iGlobalUnit) (itof iGlobalUnit)]); 0;; fun V3DphysGetGravity(sessionstr)= divideVectorF (SO3WorldGetGravity (V3DgetSession sessionstr)) [(itof iGlobalUnit) (itof iGlobalUnit) (itof iGlobalUnit)];; /*fun V3DphysSetArchitectureMode(sessionstr, mode)= if mode == nil then nil else ( set sessionstr.V3D_physics.V3DPHYS_iArchMode = mode; SO3WorldSetPlateformArchitecture (V3DgetSession sessionstr) sessionstr.V3D_physics.V3DPHYS_iArchMode; ); 0;; fun V3DphysGetArchitectureMode(sessionstr)= sessionstr.V3D_physics.V3DPHYS_iArchMode;; fun V3DphysGetArchitectureModeName(sessionstr)= let [SO3_PA_DEFAULT "default"]::[SO3_PA_MEDIUM "medium"]::[SO3_PA_BEST "best"]::nil -> l in switch l (V3DphysGetArchitectureMode sessionstr);; fun V3DphysSetArchitectureModeByName(sessionstr, smode)= let ["default" SO3_PA_DEFAULT]::["medium" SO3_PA_MEDIUM]::["best" SO3_PA_BEST]::nil -> l in V3DphysSetArchitectureMode sessionstr (switchstri l smode);; */ fun V3DphysSetSolverMode(sessionstr, mode)= let if mode == nil then 1 else mode -> mode in ( set sessionstr.V3D_physics.V3DPHYS_iSolverMode = mode; SO3WorldSetSolverModel (V3DgetSession sessionstr) sessionstr.V3D_physics.V3DPHYS_iSolverMode; ); 0;; fun V3DphysGetSolverMode(sessionstr)= sessionstr.V3D_physics.V3DPHYS_iSolverMode;; fun V3DphysGetSolverModeName(sessionstr)= let [SO3_SM_EXACT "exact"]::[1 "iterative one passes"]::[2 "iterative two passes"]::[4 "iterative four passes"]::[8 "iterative eight passes"]::nil -> l in switch l (V3DphysGetSolverMode sessionstr);; fun V3DphysSetSolverModeByName(sessionstr, smode)= let ["exact" SO3_SM_EXACT]::["iterative one passes" 1]::["iterative two passes" 2]::["iterative four passes" 4]::["iterative eight passes" 8]::nil -> l in V3DphysSetSolverMode sessionstr (switchstri l smode);; /* fun V3DphysSetFluidProperties(sessionstr, body, p)= let p -> [density viscosity accviscosity] in SO3BodySetFluidProperties (V3DgetSession sessionstr) body density viscosity accviscosity; 0;; */ fun V3DgetDefaultMaterial(sessionstr)= let SO3PhysicsGetMaterial (V3DgetSession sessionstr) "default" -> mat in if (mat == nil) then SO3PhysicsMaterialCreate (V3DgetSession sessionstr) "default" else mat;; fun V3DgetAvatarMaterial(sessionstr)= let SO3PhysicsGetMaterial (V3DgetSession sessionstr) "avatar" -> matav in if (matav != nil) then matav else let V3DgetDefaultMaterial sessionstr -> matdef in ( set matav = SO3PhysicsMaterialCreate (V3DgetSession sessionstr) "avatar"; SO3PhysicsMaterialSetDefaultElasticity matdef matav 0.0; SO3PhysicsMaterialSetDefaultSoftness matdef matav 0.0; SO3PhysicsMaterialSetSurfaceThickness matdef matav 0.01; SO3PhysicsMaterialSetContiniousCollisionMode matdef matav 1; SO3PhysicsMaterialSetDefaultCollidable matdef matav 1; matav; );; fun V3DphysSetBodyMaterial(sessionstr, body, matname)= let if ((matname == nil) || (!strcmp "" (strtrim matname))) then "default" else matname -> matname in let SO3PhysicsGetMaterial (V3DgetSession sessionstr) matname -> mat in let if mat == nil then SO3PhysicsMaterialCreate (V3DgetSession sessionstr) matname else mat -> mat in ( SO3BodySetMaterial body mat; mat; );; fun V3DphysCreateMaterialOnNode(sessionstr, node)= let SO3ObjectGetName node -> name in let SO3SceneNodeGetBody node -> body in if (body == nil) then nil else let SO3PhysicsMaterialCreate (V3DgetSession sessionstr) strcat name "_physmat" -> mat in ( SO3BodySetMaterial body mat; mat; );; fun V3DphysGetUniformBoundingBox(node)= if ((SO3ObjectGetType node) != SO3_TYPE_ENTITY) then [0.1 0.1 0.1] else ( let SO3ObjectGetGlobalScale node -> oscale in ( SO3ObjectSetGlobalScale node [1.0 1.0 1.0]; let SO3ObjectGetBoundingBoxInfo node 0 -> [bsize _ _] in ( SO3ObjectSetGlobalScale node oscale; bsize ) ) );; fun V3DphysCreateBodyEllipsoid(node, vec)= let if vec == nil then V3DphysGetUniformBoundingBox node else vec -> [x y z] in let [(if x <=. 0.0 then 0.01 else x/.2.0) (if y <=. 0.0 then 0.01 else y/.2.0) (if z <=. 0.0 then 0.01 else z/.2.0)] -> vec in SO3BodyCreateEllipsoid node vec;; fun V3DphysCreateBodyBox(node, vec)= let if vec == nil then V3DphysGetUniformBoundingBox node else vec -> [x y z] in let [(if x <=. 0.0 then 0.01 else x) (if y <=. 0.0 then 0.01 else y) (if z <=. 0.0 then 0.01 else z)] -> vec in SO3BodyCreateBox node vec;; fun V3DphysCreateBodyCylinder(node, vec)= let if vec == nil then V3DphysGetUniformBoundingBox node else vec -> [x y z] in let [(if x <=. 0.0 then 0.01 else x) (if y <=. 0.0 then 0.01 else y) (if z <=. 0.0 then 0.01 else z)] -> [x y z] in SO3BodyCreateCylinder node (x /. 2.0) y;; fun V3DphysCreateBodyChamferCylinder(node, vec)= let if vec == nil then V3DphysGetUniformBoundingBox node else vec -> [x y z] in let [(if x <=. 0.0 then 0.01 else x) (if y <=. 0.0 then 0.01 else y) (if z <=. 0.0 then 0.01 else z)] -> [x y z] in SO3BodyCreateChamferCylinder node (x /. 2.0) y;; fun V3DphysCreateBodyCapsule(node, vec)= let if vec == nil then V3DphysGetUniformBoundingBox node else vec -> [x y z] in let [(if x <=. 0.0 then 0.01 else x) (if y <=. 0.0 then 0.01 else y) (if z <=. 0.0 then 0.01 else z)] -> [x y z] in SO3BodyCreateCapsule node (x /. 2.0) y;; fun V3DphysCreateBodyCone(node, vec)= let if vec == nil then V3DphysGetUniformBoundingBox node else vec -> [x y z] in let [(if x <=. 0.0 then 0.01 else x) (if y <=. 0.0 then 0.01 else y) (if z <=. 0.0 then 0.01 else z)] -> [x y z] in SO3BodyCreateCone node (x /. 2.0) y;; fun V3DphysCreateBodyPyramid(node, vec)= let if vec == nil then V3DphysGetUniformBoundingBox node else vec -> [x y z] in let [(if x <=. 0.0 then 0.01 else x) (if y <=. 0.0 then 0.01 else y) (if z <=. 0.0 then 0.01 else z)] -> vec in SO3BodyCreatePyramid node vec;; fun V3DphysCreateBodyEllipsoidExt(node, vec, offsetp, offseta)= let if vec == nil then V3DphysGetUniformBoundingBox node else vec -> [x y z] in let [(if x <=. 0.0 then 0.01 else x/.2.0) (if y <=. 0.0 then 0.01 else y/.2.0) (if z <=. 0.0 then 0.01 else z/.2.0)] -> vec in let offseta -> [ax ay az] in let if (offseta != nil) then SO3MathsEulerYXZToQuat [SO3MathsDegreeToRadian ax SO3MathsDegreeToRadian ay SO3MathsDegreeToRadian az] else nil -> offsetq in SO3BodyCreateEllipsoidExt node vec offsetp offsetq;; fun V3DphysCreateBodyBoxExt(node, vec, offsetp, offseta)= let if vec == nil then V3DphysGetUniformBoundingBox node else vec -> [x y z] in let [(if x <=. 0.0 then 0.01 else x) (if y <=. 0.0 then 0.01 else y) (if z <=. 0.0 then 0.01 else z)] -> vec in let offseta -> [ax ay az] in let if (offseta != nil) then SO3MathsEulerYXZToQuat [SO3MathsDegreeToRadian ax SO3MathsDegreeToRadian ay SO3MathsDegreeToRadian az] else nil -> offsetq in SO3BodyCreateBoxExt node vec offsetp offsetq;; fun V3DphysCreateBodyCylinderExt(node, vec, offsetp, offseta)= let if vec == nil then V3DphysGetUniformBoundingBox node else vec -> [x y z] in let [(if x <=. 0.0 then 0.01 else x) (if y <=. 0.0 then 0.01 else y) (if z <=. 0.0 then 0.01 else z)] -> [x y z] in let offseta -> [ax ay az] in let if (offseta != nil) then SO3MathsEulerYXZToQuat [SO3MathsDegreeToRadian ax SO3MathsDegreeToRadian ay SO3MathsDegreeToRadian az] else nil -> offsetq in SO3BodyCreateCylinderExt node (x /. 2.0) y offsetp offsetq;; fun V3DphysCreateBodyChamferCylinderExt(node, vec, offsetp, offseta)= let if vec == nil then V3DphysGetUniformBoundingBox node else vec -> [x y z] in let [(if x <=. 0.0 then 0.01 else x) (if y <=. 0.0 then 0.01 else y) (if z <=. 0.0 then 0.01 else z)] -> [x y z] in let offseta -> [ax ay az] in let if (offseta != nil) then SO3MathsEulerYXZToQuat [SO3MathsDegreeToRadian ax SO3MathsDegreeToRadian ay SO3MathsDegreeToRadian az] else nil -> offsetq in SO3BodyCreateChamferCylinderExt node (x /. 2.0) y offsetp offsetq;; fun V3DphysCreateBodyCapsuleExt(node, vec, offsetp, offseta)= let if vec == nil then V3DphysGetUniformBoundingBox node else vec -> [x y z] in let [(if x <=. 0.0 then 0.01 else x) (if y <=. 0.0 then 0.01 else y) (if z <=. 0.0 then 0.01 else z)] -> [x y z] in let offseta -> [ax ay az] in let if (offseta != nil) then SO3MathsEulerYXZToQuat [SO3MathsDegreeToRadian ax SO3MathsDegreeToRadian ay SO3MathsDegreeToRadian az] else nil -> offsetq in SO3BodyCreateCapsuleExt node (x /. 2.0) y offsetp offsetq;; fun V3DphysCreateBodyConeExt(node, vec, offsetp, offseta)= let if vec == nil then V3DphysGetUniformBoundingBox node else vec -> [x y z] in let [(if x <=. 0.0 then 0.01 else x) (if y <=. 0.0 then 0.01 else y) (if z <=. 0.0 then 0.01 else z)] -> [x y z] in let offseta -> [ax ay az] in let if (offseta != nil) then SO3MathsEulerYXZToQuat [SO3MathsDegreeToRadian ax SO3MathsDegreeToRadian ay SO3MathsDegreeToRadian az] else nil -> offsetq in SO3BodyCreateConeExt node (x /. 2.0) y offsetp offsetq;; fun V3DphysCreateBodyPyramidExt(node, vec, offsetp, offseta)= let if vec == nil then V3DphysGetUniformBoundingBox node else vec -> [x y z] in let [(if x <=. 0.0 then 0.01 else x) (if y <=. 0.0 then 0.01 else y) (if z <=. 0.0 then 0.01 else z)] -> vec in let offseta -> [ax ay az] in let if (offseta != nil) then SO3MathsEulerYXZToQuat [SO3MathsDegreeToRadian ax SO3MathsDegreeToRadian ay SO3MathsDegreeToRadian az] else nil -> offsetq in SO3BodyCreatePyramidExt node vec offsetp offsetq;; fun V3DphysSetMaterialProperties(material, bcoll, bcontcoll, staticfriction, kineticfriction, elasticity, softness)= 0;; fun V3DphysEnableBody(body, state)= SO3BodySetIgnoreCollision body !state; SO3BodySetVelocity body [0.0 0.0 0.0]; SO3BodySetOmega body [0.0 0.0 0.0]; SO3BodySetFreeze body !state; SO3BodySetGravityEnable body state; SO3BodySetSimulation body state; 0;; fun V3DphysFreezeBody(body, mode)= let if !mode == 0 then 0 else 1 -> state in SO3BodySetFreeze body state; 0;; fun V3DphysGetBodyState(body, mode)= SO3BodyGetSimulation body;; fun V3DphysShowDebug(sessionstr, state)= SO3WorldShowLines (V3DgetSession sessionstr) state; 0;; fun V3DphysCreate(sessionstr)= let mkV3Dphysics [nil nil nil nil nil] -> physstr in //SO3_PA_DEFAULT SO3_SM_EXACT SO3_FM_EXACT ( set sessionstr.V3D_physics = physstr; //V3DphysSetArchitectureMode sessionstr SO3_PA_DEFAULT; V3DphysSetSolverMode sessionstr 1; V3DphysSetFps sessionstr 120; V3DphysSetGravity sessionstr [0.0 (-.9.81) 0.0]; V3DphysEnablePhysic sessionstr 0; //V3DphysShowDebug sessionstr 1; ); 0;; fun V3DphysDestroy(sessionstr)= V3DphysEnablePhysic sessionstr 0; set sessionstr.V3D_physics = nil; 0;; fun V3DphysReset(sessionstr)= V3DphysDestroy sessionstr; V3DphysCreate sessionstr; 0;;