4fe03a8923
So I'm reverting. Kent
434 lines
10 KiB
C++
434 lines
10 KiB
C++
/**
|
|
* $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)
|
|
|
|
// defines USE_ODE to choose physics engine
|
|
#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 HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#ifdef USE_ODE
|
|
|
|
#include "KX_OdePhysicsController.h"
|
|
#include "OdePhysicsEnvironment.h"
|
|
#endif //USE_ODE
|
|
|
|
|
|
// USE_SUMO_SOLID is defined in headerfile KX_ConvertPhysicsObject.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 we might not 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
|