Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp')
-rw-r--r--source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp427
1 files changed, 427 insertions, 0 deletions
diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
new file mode 100644
index 00000000000..01d02b58132
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
@@ -0,0 +1,427 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#pragma warning (disable : 4786)
+
+#include "KX_ConvertPhysicsObject.h"
+#include "KX_GameObject.h"
+#include "RAS_MeshObject.h"
+#include "KX_Scene.h"
+#include "SYS_System.h"
+
+#include "PHY_Pro.h" //todo cleanup
+#include "KX_ClientObjectInfo.h"
+
+#include "GEN_Map.h"
+#include "GEN_HashedPtr.h"
+
+#include "KX_PhysicsEngineEnums.h"
+#include "PHY_Pro.h"
+
+#include "KX_MotionState.h" // bridge between motionstate and scenegraph node
+#ifdef USE_ODE
+
+#include "KX_OdePhysicsController.h"
+#include "odephysicsenvironment.h"
+#endif //USE_ODE
+
+
+// USE_SUMO_SOLID is defined in headerfile KX_ConvertPhysicsObjects.h
+#ifdef USE_SUMO_SOLID
+
+
+#include "SumoPhysicsEnvironment.h"
+#include "KX_SumoPhysicsController.h"
+
+
+// sumo physics specific
+#include "SM_Object.h"
+#include "SM_FhObject.h"
+#include "SM_Scene.h"
+#include "SM_ClientObjectInfo.h"
+
+#include "KX_SumoPhysicsController.h"
+
+GEN_Map<GEN_HashedPtr,DT_ShapeHandle> map_gamemesh_to_sumoshape;
+
+// forward declarations
+void BL_RegisterSumoObject(KX_GameObject* gameobj,class SM_Scene* sumoScene,DT_SceneHandle solidscene,class SM_Object* sumoObj,const char* matname,bool isDynamic,bool isActor);
+DT_ShapeHandle CreateShapeFromMesh(RAS_MeshObject* meshobj);
+
+
+void KX_ConvertSumoObject( class KX_GameObject* gameobj,
+ class RAS_MeshObject* meshobj,
+ class KX_Scene* kxscene,
+ PHY_ShapeProps* kxshapeprops,
+ PHY_MaterialProps* kxmaterial,
+ struct KX_ObjectProperties* objprop)
+
+
+{
+
+ SM_ShapeProps* smprop = new SM_ShapeProps;
+
+ smprop->m_ang_drag = kxshapeprops->m_ang_drag;
+ smprop->m_do_anisotropic = kxshapeprops->m_do_anisotropic;
+ smprop->m_do_fh = kxshapeprops->m_do_fh;
+ smprop->m_do_rot_fh = kxshapeprops->m_do_rot_fh ;
+ smprop->m_friction_scaling[0] = kxshapeprops->m_friction_scaling[0];
+ smprop->m_friction_scaling[1] = kxshapeprops->m_friction_scaling[1];
+ smprop->m_friction_scaling[2] = kxshapeprops->m_friction_scaling[2];
+ smprop->m_inertia = kxshapeprops->m_inertia;
+ smprop->m_lin_drag = kxshapeprops->m_lin_drag;
+ smprop->m_mass = kxshapeprops->m_mass;
+
+
+ SM_MaterialProps* smmaterial = new SM_MaterialProps;
+
+ smmaterial->m_fh_damping = kxmaterial->m_fh_damping;
+ smmaterial->m_fh_distance = kxmaterial->m_fh_distance;
+ smmaterial->m_fh_normal = kxmaterial->m_fh_normal;
+ smmaterial->m_fh_spring = kxmaterial->m_fh_spring;
+ smmaterial->m_friction = kxmaterial->m_friction;
+ smmaterial->m_restitution = kxmaterial->m_restitution;
+
+ class SumoPhysicsEnvironment* sumoEnv =
+ (SumoPhysicsEnvironment*)kxscene->GetPhysicsEnvironment();
+
+ SM_Scene* sceneptr = sumoEnv->GetSumoScene();
+
+
+
+ SM_Object* sumoObj=NULL;
+
+ if (objprop->m_dyna)
+ {
+
+ DT_ShapeHandle shape = DT_Sphere(0.0);
+
+ if (objprop->m_ghost)
+ {
+
+ sumoObj = new SM_Object(shape,NULL,smprop,NULL);
+ } else
+ {
+ sumoObj = new SM_Object(shape,smmaterial,smprop,NULL);
+ }
+
+ double radius = objprop->m_radius;
+
+ MT_Scalar margin = radius;//0.5;
+ sumoObj->setMargin(margin);
+
+ //if (bRigidBody)
+ //{
+ if (objprop->m_in_active_layer)
+ {
+ DT_AddObject(sumoEnv->GetSolidScene(),
+ sumoObj->getObjectHandle());
+ }
+ //}
+
+ if (objprop->m_angular_rigidbody)
+ {
+ sumoObj->setRigidBody(true);
+ } else
+ {
+ sumoObj->setRigidBody(false);
+ }
+
+ bool isDynamic = true;
+ bool isActor = true;
+
+ BL_RegisterSumoObject(gameobj,sceneptr,sumoEnv->GetSolidScene(),sumoObj,NULL,isDynamic,isActor);
+
+ }
+ else {
+ // non physics object
+ if (meshobj)
+ {
+ int numpolys = meshobj->NumPolygons();
+
+ {
+
+ DT_ShapeHandle complexshape=0;
+
+ if (objprop->m_implicitbox)
+ {
+ complexshape = DT_Box(objprop->m_boundingbox.m_extends[0],objprop->m_boundingbox.m_extends[1],objprop->m_boundingbox.m_extends[2]);
+ } else
+ {
+ if (numpolys>0)
+ {
+ complexshape = CreateShapeFromMesh(meshobj);
+ }
+ }
+
+ if (complexshape)
+ {
+ SM_Object *dynamicParent = NULL;
+
+ if (objprop->m_dynamic_parent)
+ {
+ // problem is how to find the dynamic parent
+ // in the scenegraph
+ KX_SumoPhysicsController* sumoctrl =
+ (KX_SumoPhysicsController*)
+ objprop->m_dynamic_parent->GetPhysicsController();
+
+ if (sumoctrl)
+ {
+ dynamicParent = sumoctrl->GetSumoObject();
+ }
+
+ assert(dynamicParent);
+ }
+
+
+ if (objprop->m_ghost)
+ {
+ sumoObj = new SM_Object(complexshape,NULL,NULL, dynamicParent);
+ } else
+ {
+ sumoObj = new SM_Object(complexshape,smmaterial,NULL, dynamicParent);
+ }
+
+ if (objprop->m_in_active_layer)
+ {
+ DT_AddObject(sumoEnv->GetSolidScene(),
+ sumoObj->getObjectHandle());
+ }
+
+
+ const STR_String& matname=meshobj->GetMaterialName(0);
+
+
+ BL_RegisterSumoObject(gameobj,sceneptr,
+ sumoEnv->GetSolidScene(),sumoObj,
+ matname.ReadPtr(),
+ objprop->m_dyna,
+ objprop->m_isactor);
+
+ }
+ }
+ }
+ }
+
+ // physics object get updated here !
+
+
+ // lazy evaluation because Havok doesn't support scaling !gameobj->UpdateTransform();
+
+ if (objprop->m_in_active_layer && sumoObj)
+ {
+ sceneptr->add(*sumoObj);
+ }
+
+}
+
+
+
+void BL_RegisterSumoObject(KX_GameObject* gameobj,class SM_Scene* sumoScene,DT_SceneHandle solidscene,class SM_Object* sumoObj,const char* matname,bool isDynamic,bool isActor) {
+
+
+
+ //gameobj->SetDynamic(isDynamic);
+
+ PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode());
+
+ // need easy access, not via 'node' etc.
+ KX_SumoPhysicsController* physicscontroller = new KX_SumoPhysicsController(sumoScene,solidscene,sumoObj,motionstate,isDynamic);
+ gameobj->SetPhysicsController(physicscontroller);
+ physicscontroller->setClientInfo(gameobj);
+
+ gameobj->GetSGNode()->AddSGController(physicscontroller);
+
+ //gameobj->GetClientInfo()->m_type = (isActor ? 1 : 0);
+ //gameobj->GetClientInfo()->m_clientobject = gameobj;
+
+ // store materialname in auxinfo, needed for touchsensors
+ //gameobj->GetClientInfo()->m_auxilary_info = (matname? (void*)(matname+2) : NULL);
+
+ physicscontroller->SetObject(gameobj->GetSGNode());
+
+ //gameobj->SetDynamicsScaling(MT_Vector3(1.0, 1.0, 1.0));
+
+};
+
+
+
+DT_ShapeHandle CreateShapeFromMesh(RAS_MeshObject* meshobj)
+{
+
+ DT_ShapeHandle* shapeptr = map_gamemesh_to_sumoshape[GEN_HashedPtr(meshobj)];
+ if (shapeptr)
+ {
+ return *shapeptr;
+ }
+
+ // todo: shared meshes
+ DT_ShapeHandle shape = DT_NewComplexShape();
+ int p=0;
+ int numpolys = meshobj->NumPolygons();
+ if (!numpolys)
+ {
+ return NULL;
+ }
+ int numvalidpolys = 0;
+
+
+
+ for (p=0;p<meshobj->m_triangle_indices.size();p++)
+ {
+ RAS_TriangleIndex& idx = meshobj->m_triangle_indices[p];
+
+ // only add polygons that have the collisionflag set
+ if (idx.m_collider)
+ {
+ DT_Begin();
+ for (int v=0;v<3;v++)
+ {
+ int num = meshobj->m_xyz_index_to_vertex_index_mapping[idx.m_index[v]].size();
+ if (num != 1)
+ {
+ int i=0;
+ }
+ RAS_MatArrayIndex& vertindex = meshobj->m_xyz_index_to_vertex_index_mapping[idx.m_index[v]][0];
+
+ numvalidpolys++;
+
+ {
+ const MT_Point3& pt = meshobj->GetVertex(vertindex.m_array,
+ vertindex.m_index,
+ (RAS_IPolyMaterial*)vertindex.m_matid)->xyz();
+ DT_Vertex(pt[0],pt[1],pt[2]);
+ }
+ }
+ DT_End();
+ }
+ }
+
+ DT_EndComplexShape();
+
+ if (numvalidpolys > 0)
+ {
+ map_gamemesh_to_sumoshape.insert(GEN_HashedPtr(meshobj),shape);
+ return shape;
+ }
+
+ // memleak... todo: delete shape
+ return NULL;
+}
+
+
+void KX_ClearSumoSharedShapes()
+{
+ int numshapes = map_gamemesh_to_sumoshape.size();
+ for (int i=0;i<numshapes ;i++)
+ {
+ DT_ShapeHandle shape = *map_gamemesh_to_sumoshape.at(i);
+ DT_DeleteShape(shape);
+ }
+
+ map_gamemesh_to_sumoshape.clear();
+}
+
+
+
+
+
+#endif //USE_SUMO_SOLID
+
+
+#ifdef USE_ODE
+
+void KX_ConvertODEEngineObject(KX_GameObject* gameobj,
+ RAS_MeshObject* meshobj,
+ KX_Scene* kxscene,
+ struct PHY_ShapeProps* shapeprops,
+ struct PHY_MaterialProps* smmaterial,
+ struct KX_ObjectProperties* objprop)
+{
+ // not yet, future extension :)
+ bool dyna=objprop->m_dyna;
+ bool fullRigidBody= ( objprop->m_dyna && objprop->m_angular_rigidbody) != 0;
+ bool phantom = objprop->m_ghost;
+ class PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode());
+
+ class ODEPhysicsEnvironment* odeEnv =
+ (ODEPhysicsEnvironment*)kxscene->GetPhysicsEnvironment();
+
+ dxSpace* space = odeEnv->GetOdeSpace();
+ dxWorld* world = odeEnv->GetOdeWorld();
+
+ if (!objprop->m_implicitsphere &&
+ MT_fuzzyZero(objprop->m_boundingbox.m_extends[0]) ||
+ MT_fuzzyZero(objprop->m_boundingbox.m_extends[1]) ||
+ MT_fuzzyZero(objprop->m_boundingbox.m_extends[2])
+ )
+ {
+
+ } else
+ {
+
+ KX_OdePhysicsController* physicscontroller =
+ new KX_OdePhysicsController(
+ dyna,
+ fullRigidBody,
+ phantom,
+ motionstate,
+ space,
+ world,
+ shapeprops->m_mass,
+ smmaterial->m_friction,
+ smmaterial->m_restitution,
+ objprop->m_implicitsphere,
+ objprop->m_boundingbox.m_center,
+ objprop->m_boundingbox.m_extends,
+ objprop->m_radius
+ );
+
+ gameobj->SetPhysicsController(physicscontroller);
+ physicscontroller->setClientInfo(gameobj);
+ gameobj->GetSGNode()->AddSGController(physicscontroller);
+
+ bool isActor = objprop->m_isactor;
+ STR_String materialname;
+ if (meshobj)
+ materialname = meshobj->GetMaterialName(0);
+
+ const char* matname = materialname.ReadPtr();
+
+
+ physicscontroller->SetObject(gameobj->GetSGNode());
+
+ }
+}
+
+
+#endif // USE_ODE