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/Physics/Bullet')
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.cpp726
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.h59
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp230
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h24
4 files changed, 580 insertions, 459 deletions
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
index 44c4e284e7c..8ea2b4f299d 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
@@ -39,7 +39,6 @@ subject to the following restrictions:
#include "LinearMath/btConvexHull.h"
#include "BulletCollision/Gimpact/btGImpactShape.h"
-
#include "BulletSoftBody/btSoftRigidDynamicsWorld.h"
#include "DNA_mesh_types.h"
@@ -65,7 +64,6 @@ extern bool gDisableDeactivation;
float gLinearSleepingTreshold;
float gAngularSleepingTreshold;
-
BlenderBulletCharacterController::BlenderBulletCharacterController(btMotionState *motionState, btPairCachingGhostObject *ghost, btConvexShape* shape, float stepHeight)
: btKinematicCharacterController(ghost,shape,stepHeight,2),
m_motionState(motionState),
@@ -118,6 +116,18 @@ const btVector3& BlenderBulletCharacterController::getWalkDirection()
return m_walkDirection;
}
+bool CleanPairCallback::processOverlap(btBroadphasePair &pair)
+{
+ if ((pair.m_pProxy0 == m_cleanProxy) || (pair.m_pProxy1 == m_cleanProxy)) {
+ m_pairCache->cleanOverlappingPair(pair, m_dispatcher);
+ CcdPhysicsController *ctrl0 = (CcdPhysicsController*)(((btCollisionObject*)pair.m_pProxy0->m_clientObject)->getUserPointer());
+ CcdPhysicsController *ctrl1 = (CcdPhysicsController*)(((btCollisionObject*)pair.m_pProxy1->m_clientObject)->getUserPointer());
+ ctrl0->GetCollisionObject()->activate(false);
+ ctrl1->GetCollisionObject()->activate(false);
+ }
+ return false;
+}
+
CcdPhysicsController::CcdPhysicsController (const CcdConstructionInfo& ci)
:m_cci(ci)
{
@@ -588,20 +598,13 @@ void CcdPhysicsController::CreateRigidbody()
static void DeleteBulletShape(btCollisionShape* shape, bool free)
{
- if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
- {
- // shapes based on meshes use an interface that contains the vertices.
- btTriangleMeshShape* meshShape = static_cast<btTriangleMeshShape*>(shape);
- btStridingMeshInterface* meshInterface = meshShape->getMeshInterface();
- if (meshInterface)
- delete meshInterface;
- }
- else if (shape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE)
- {
- btGImpactMeshShape* meshShape = static_cast<btGImpactMeshShape*>(shape);
- btStridingMeshInterface* meshInterface = meshShape->getMeshInterface();
- if (meshInterface)
- delete meshInterface;
+ if (shape->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE) {
+ /* If we use Bullet scaled shape (btScaledBvhTriangleMeshShape) we have to
+ * free the child of the unscaled shape (btTriangleMeshShape) here.
+ */
+ btTriangleMeshShape *meshShape = ((btScaledBvhTriangleMeshShape *)shape)->getChildShape();
+ if (meshShape)
+ delete meshShape;
}
if (free) {
delete shape;
@@ -634,48 +637,41 @@ bool CcdPhysicsController::DeleteControllerShape( )
bool CcdPhysicsController::ReplaceControllerShape(btCollisionShape *newShape)
{
-
- /* Note, deleting the previous collision shape must be done already */
- /* if (m_collisionShape) DeleteControllerShape(); */
+ if (m_collisionShape)
+ DeleteControllerShape();
+
+ // If newShape is NULL it means to create a new Bullet shape.
+ if (!newShape)
+ newShape = m_shapeInfo->CreateBulletShape(m_cci.m_margin, m_cci.m_bGimpact, !m_cci.m_bSoft);
m_object->setCollisionShape(newShape);
- m_collisionShape= newShape;
- m_cci.m_collisionShape= newShape;
-
- if (GetSoftBody()) {
+ m_collisionShape = newShape;
+ m_cci.m_collisionShape = newShape;
+
+ btSoftBody *softBody = GetSoftBody();
+ if (softBody) {
+ btSoftRigidDynamicsWorld *world = GetPhysicsEnvironment()->GetDynamicsWorld();
+ // remove the old softBody
+ world->removeSoftBody(softBody);
+
// soft body must be recreated
- m_cci.m_physicsEnv->RemoveCcdPhysicsController(this);
delete m_object;
m_object = NULL;
// force complete reinitialization
m_softbodyMappingDone = false;
m_prototypeTransformInitialized = false;
m_softBodyTransformInitialized = false;
+
CreateSoftbody();
assert(m_object);
- // reinsert the new body
- m_cci.m_physicsEnv->AddCcdPhysicsController(this);
- }
-
- /* Copied from CcdPhysicsEnvironment::addCcdPhysicsController() */
-
- /* without this, an object can rest on the old physics mesh
- * and not move to account for the physics mesh, even with 'nosleep' */
- btSoftRigidDynamicsWorld* dw= GetPhysicsEnvironment()->GetDynamicsWorld();
- btCollisionObjectArray &obarr= dw->getCollisionObjectArray();
- btCollisionObject *ob;
- btBroadphaseProxy* proxy;
-
- for (int i= 0; i < obarr.size(); i++) {
- ob= obarr[i];
- if (ob->getCollisionShape() == newShape) {
- proxy = ob->getBroadphaseHandle();
-
- if (proxy)
- dw->getPairCache()->cleanProxyFromPairs(proxy,dw->getDispatcher());
- }
+
+ btSoftBody *newSoftBody = GetSoftBody();
+ // set the user
+ newSoftBody->setUserPointer(this);
+ // add the new softbody
+ world->addSoftBody(newSoftBody);
}
-
+
return true;
}
@@ -850,36 +846,6 @@ void CcdPhysicsController::PostProcessReplica(class PHY_IMotionState* motionsta
m_cci.m_physicsEnv->AddCcdPhysicsController(this);
-/* SM_Object* dynaparent=0;
- SumoPhysicsController* sumoparentctrl = (SumoPhysicsController* )parentctrl;
-
- if (sumoparentctrl)
- {
- dynaparent = sumoparentctrl->GetSumoObject();
- }
-
- SM_Object* orgsumoobject = m_sumoObj;
-
-
- m_sumoObj = new SM_Object(
- orgsumoobject->getShapeHandle(),
- orgsumoobject->getMaterialProps(),
- orgsumoobject->getShapeProps(),
- dynaparent);
-
- m_sumoObj->setRigidBody(orgsumoobject->isRigidBody());
-
- m_sumoObj->setMargin(orgsumoobject->getMargin());
- m_sumoObj->setPosition(orgsumoobject->getPosition());
- m_sumoObj->setOrientation(orgsumoobject->getOrientation());
- //if it is a dyna, register for a callback
- m_sumoObj->registerCallback(*this);
-
- m_sumoScene->add(* (m_sumoObj));
- */
-
-
-
}
void CcdPhysicsController::SetPhysicsEnvironment(class PHY_IPhysicsEnvironment *env)
@@ -1082,6 +1048,25 @@ void CcdPhysicsController::ResolveCombinedVelocities(float linvelX,float linvel
{
}
+void CcdPhysicsController::RefreshCollisions()
+{
+ // the object is in an inactive layer so it's useless to update it and can cause problems
+ if (!GetPhysicsEnvironment()->IsActiveCcdPhysicsController(this))
+ return;
+
+ btSoftRigidDynamicsWorld *dw = GetPhysicsEnvironment()->GetDynamicsWorld();
+ btBroadphaseProxy *proxy = m_object->getBroadphaseHandle();
+ btDispatcher *dispatcher = dw->getDispatcher();
+ btOverlappingPairCache *pairCache = dw->getPairCache();
+
+ CleanPairCallback cleanPairs(proxy, pairCache, dispatcher);
+ pairCache->processAllOverlappingPairs(&cleanPairs, dispatcher);
+
+ // Forcibly recreate the physics object
+ btBroadphaseProxy* handle = m_object->getBroadphaseHandle();
+ GetPhysicsEnvironment()->UpdateCcdPhysicsController(this, GetMass(), m_object->getCollisionFlags(), handle->m_collisionFilterGroup, handle->m_collisionFilterMask);
+}
+
void CcdPhysicsController::SuspendDynamics(bool ghost)
{
btRigidBody *body = GetRigidBody();
@@ -1546,8 +1531,7 @@ void CcdPhysicsController::AddCompoundChild(PHY_IPhysicsController* child)
const btCollisionShape* childShape = childBody->getCollisionShape();
if (!rootShape ||
!childShape ||
- rootShape->getShapeType() != COMPOUND_SHAPE_PROXYTYPE ||
- childShape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
+ rootShape->getShapeType() != COMPOUND_SHAPE_PROXYTYPE)
return;
btCompoundShape* compoundShape = (btCompoundShape*)rootShape;
// compute relative transformation between parent and child
@@ -1597,7 +1581,7 @@ void CcdPhysicsController::AddCompoundChild(PHY_IPhysicsController* child)
// must update the broadphase cache,
GetPhysicsEnvironment()->RefreshCcdPhysicsController(this);
// remove the children
- GetPhysicsEnvironment()->DisableCcdPhysicsController(childCtrl);
+ GetPhysicsEnvironment()->RemoveCcdPhysicsController(childCtrl);
}
/* Reverse function of the above, it will remove a shape from a compound shape
@@ -1653,7 +1637,7 @@ void CcdPhysicsController::RemoveCompoundChild(PHY_IPhysicsController* child)
// must update the broadphase cache,
GetPhysicsEnvironment()->RefreshCcdPhysicsController(this);
// reactivate the children
- GetPhysicsEnvironment()->EnableCcdPhysicsController(childCtrl);
+ GetPhysicsEnvironment()->AddCcdPhysicsController(childCtrl);
}
PHY_IPhysicsController* CcdPhysicsController::GetReplica()
@@ -1713,33 +1697,50 @@ PHY_IPhysicsController* CcdPhysicsController::GetReplicaForSensors()
* 2) from_gameobj - creates the phys mesh from the DerivedMesh where possible, else the RAS_MeshObject
* 3) this - update the phys mesh from DerivedMesh or RAS_MeshObject
*
- * Most of the logic behind this is in shapeInfo->UpdateMesh(...)
+ * Most of the logic behind this is in m_shapeInfo->UpdateMesh(...)
*/
bool CcdPhysicsController::ReinstancePhysicsShape(KX_GameObject *from_gameobj, RAS_MeshObject *from_meshobj)
{
- CcdShapeConstructionInfo *shapeInfo;
-
- shapeInfo = this->GetShapeInfo();
-
- if (shapeInfo->m_shapeType != PHY_SHAPE_MESH/* || spc->GetSoftBody()*/)
+ if (m_shapeInfo->m_shapeType != PHY_SHAPE_MESH)
return false;
- this->DeleteControllerShape();
-
- if (from_gameobj==NULL && from_meshobj==NULL)
- from_gameobj = KX_GameObject::GetClientObject((KX_ClientObjectInfo*)this->GetNewClientInfo());
+ if (!from_gameobj && !from_meshobj)
+ from_gameobj = KX_GameObject::GetClientObject((KX_ClientObjectInfo*)GetNewClientInfo());
/* updates the arrays used for making the new bullet mesh */
- shapeInfo->UpdateMesh(from_gameobj, from_meshobj);
+ m_shapeInfo->UpdateMesh(from_gameobj, from_meshobj);
/* create the new bullet mesh */
- CcdConstructionInfo& cci = this->GetConstructionInfo();
- btCollisionShape* bm= shapeInfo->CreateBulletShape(cci.m_margin, cci.m_bGimpact, !cci.m_bSoft);
+ GetPhysicsEnvironment()->UpdateCcdPhysicsControllerShape(m_shapeInfo);
- this->ReplaceControllerShape(bm);
return true;
}
+void CcdPhysicsController::ReplicateConstraints(KX_GameObject *replica, std::vector<KX_GameObject*> constobj)
+{
+ if (replica->GetConstraints().size() == 0 || !replica->GetPhysicsController())
+ return;
+
+ PHY_IPhysicsEnvironment *physEnv = GetPhysicsEnvironment();
+
+ vector<bRigidBodyJointConstraint*> constraints = replica->GetConstraints();
+ vector<bRigidBodyJointConstraint*>::iterator consit;
+
+ /* Object could have some constraints, iterate over all of theme to ensure that every constraint is recreated. */
+ for (consit = constraints.begin(); consit != constraints.end(); ++consit) {
+ /* Try to find the constraint targets in the list of group objects. */
+ bRigidBodyJointConstraint *dat = (*consit);
+ vector<KX_GameObject*>::iterator memit;
+ for (memit = constobj.begin(); memit != constobj.end(); ++memit) {
+ KX_GameObject *member = (*memit);
+ /* If the group member is the actual target for the constraint. */
+ if (dat->tar->id.name + 2 == member->GetName() && member->GetPhysicsController())
+ physEnv->SetupObjectConstraints(replica, member, dat);
+ }
+ }
+
+}
+
///////////////////////////////////////////////////////////
///A small utility class, DefaultMotionState
///
@@ -1821,7 +1822,7 @@ CcdShapeConstructionInfo* CcdShapeConstructionInfo::FindMesh(RAS_MeshObject* mes
return NULL;
}
-bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm, bool polytope)
+bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject *meshobj, DerivedMesh *dm, bool polytope)
{
int numpolys, numverts;
@@ -1833,7 +1834,7 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm,
bool free_dm = false;
// No mesh object or mesh has no polys
- if (!meshobj || meshobj->HasColliderPolygon()==false) {
+ if (!meshobj || !meshobj->HasColliderPolygon()) {
m_vertexArray.clear();
m_polygonIndexArray.clear();
m_triFaceArray.clear();
@@ -1856,80 +1857,83 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm,
/* double lookup */
const int *index_mf_to_mpoly = (const int *)dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
const int *index_mp_to_orig = (const int *)dm->getPolyDataArray(dm, CD_ORIGINDEX);
- if (index_mf_to_mpoly == NULL) {
+ if (!index_mf_to_mpoly) {
index_mp_to_orig = NULL;
}
m_shapeType = (polytope) ? PHY_SHAPE_POLYTOPE : PHY_SHAPE_MESH;
/* Convert blender geometry into bullet mesh, need these vars for mapping */
- vector<bool> vert_tag_array(numverts, false);
- unsigned int tot_bt_verts= 0;
+ std::vector<bool> vert_tag_array(numverts, false);
+ unsigned int tot_bt_verts = 0;
- if (polytope)
- {
+ if (polytope) {
// Tag verts we're using
- for (int p2=0; p2<numpolys; p2++)
- {
- MFace* mf = &mface[p2];
+ for (int p2 = 0; p2 < numpolys; p2++) {
+ MFace *mf = &mface[p2];
const int origi = index_mf_to_mpoly ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, p2) : p2;
- RAS_Polygon* poly = meshobj->GetPolygon(origi);
+ RAS_Polygon *poly = meshobj->GetPolygon(origi);
// only add polygons that have the collision flag set
- if (poly->IsCollider())
- {
- if (vert_tag_array[mf->v1] == false) {vert_tag_array[mf->v1] = true; tot_bt_verts++;}
- if (vert_tag_array[mf->v2] == false) {vert_tag_array[mf->v2] = true; tot_bt_verts++;}
- if (vert_tag_array[mf->v3] == false) {vert_tag_array[mf->v3] = true; tot_bt_verts++;}
- if (mf->v4 && vert_tag_array[mf->v4] == false) {vert_tag_array[mf->v4] = true; tot_bt_verts++;}
+ if (poly->IsCollider()) {
+ if (!vert_tag_array[mf->v1]) {
+ vert_tag_array[mf->v1] = true;
+ tot_bt_verts++;
+ }
+ if (!vert_tag_array[mf->v2]) {
+ vert_tag_array[mf->v2] = true;
+ tot_bt_verts++;
+ }
+ if (!vert_tag_array[mf->v3]) {
+ vert_tag_array[mf->v3] = true;
+ tot_bt_verts++;
+ }
+ if (mf->v4 && !vert_tag_array[mf->v4]) {
+ vert_tag_array[mf->v4] = true;
+ tot_bt_verts++;
+ }
}
}
-
+
/* Can happen with ngons */
if (!tot_bt_verts) {
goto cleanup_empty_mesh;
}
- m_vertexArray.resize(tot_bt_verts*3);
+ m_vertexArray.resize(tot_bt_verts * 3);
- btScalar *bt= &m_vertexArray[0];
+ btScalar *bt = &m_vertexArray[0];
- for (int p2=0; p2<numpolys; p2++)
- {
- MFace* mf = &mface[p2];
+ for (int p2 = 0; p2 < numpolys; p2++) {
+ MFace *mf = &mface[p2];
const int origi = index_mf_to_mpoly ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, p2) : p2;
- RAS_Polygon* poly= meshobj->GetPolygon(origi);
+ RAS_Polygon *poly = meshobj->GetPolygon(origi);
// only add polygons that have the collisionflag set
- if (poly->IsCollider())
- {
- if (vert_tag_array[mf->v1]==true)
- {
- const float* vtx = mvert[mf->v1].co;
+ if (poly->IsCollider()) {
+ if (vert_tag_array[mf->v1]) {
+ const float *vtx = mvert[mf->v1].co;
vert_tag_array[mf->v1] = false;
*bt++ = vtx[0];
*bt++ = vtx[1];
*bt++ = vtx[2];
}
- if (vert_tag_array[mf->v2]==true)
- {
- const float* vtx = mvert[mf->v2].co;
+ if (vert_tag_array[mf->v2]) {
+ const float *vtx = mvert[mf->v2].co;
vert_tag_array[mf->v2] = false;
*bt++ = vtx[0];
*bt++ = vtx[1];
*bt++ = vtx[2];
}
- if (vert_tag_array[mf->v3]==true)
- {
- const float* vtx = mvert[mf->v3].co;
+ if (vert_tag_array[mf->v3]) {
+ const float *vtx = mvert[mf->v3].co;
vert_tag_array[mf->v3] = false;
*bt++ = vtx[0];
*bt++ = vtx[1];
*bt++ = vtx[2];
}
- if (mf->v4 && vert_tag_array[mf->v4]==true)
- {
- const float* vtx = mvert[mf->v4].co;
+ if (mf->v4 && vert_tag_array[mf->v4]) {
+ const float *vtx = mvert[mf->v4].co;
vert_tag_array[mf->v4] = false;
*bt++ = vtx[0];
*bt++ = vtx[1];
@@ -1939,28 +1943,38 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm,
}
}
else {
- unsigned int tot_bt_tris= 0;
- vector<int> vert_remap_array(numverts, 0);
-
+ unsigned int tot_bt_tris = 0;
+ std::vector<int> vert_remap_array(numverts, 0);
+
// Tag verts we're using
- for (int p2=0; p2<numpolys; p2++)
- {
- MFace* mf = &mface[p2];
+ for (int p2 = 0; p2 < numpolys; p2++) {
+ MFace *mf = &mface[p2];
const int origi = index_mf_to_mpoly ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, p2) : p2;
- RAS_Polygon* poly= meshobj->GetPolygon(origi);
+ RAS_Polygon *poly = meshobj->GetPolygon(origi);
// only add polygons that have the collision flag set
- if (poly->IsCollider())
- {
- if (vert_tag_array[mf->v1]==false)
- {vert_tag_array[mf->v1] = true;vert_remap_array[mf->v1] = tot_bt_verts;tot_bt_verts++;}
- if (vert_tag_array[mf->v2]==false)
- {vert_tag_array[mf->v2] = true;vert_remap_array[mf->v2] = tot_bt_verts;tot_bt_verts++;}
- if (vert_tag_array[mf->v3]==false)
- {vert_tag_array[mf->v3] = true;vert_remap_array[mf->v3] = tot_bt_verts;tot_bt_verts++;}
- if (mf->v4 && vert_tag_array[mf->v4]==false)
- {vert_tag_array[mf->v4] = true;vert_remap_array[mf->v4] = tot_bt_verts;tot_bt_verts++;}
- tot_bt_tris += (mf->v4 ? 2:1); /* a quad or a tri */
+ if (poly->IsCollider()) {
+ if (!vert_tag_array[mf->v1]) {
+ vert_tag_array[mf->v1] = true;
+ vert_remap_array[mf->v1] = tot_bt_verts;
+ tot_bt_verts++;
+ }
+ if (!vert_tag_array[mf->v2]) {
+ vert_tag_array[mf->v2] = true;
+ vert_remap_array[mf->v2] = tot_bt_verts;
+ tot_bt_verts++;
+ }
+ if (!vert_tag_array[mf->v3]) {
+ vert_tag_array[mf->v3] = true;
+ vert_remap_array[mf->v3] = tot_bt_verts;
+ tot_bt_verts++;
+ }
+ if (mf->v4 && !vert_tag_array[mf->v4]) {
+ vert_tag_array[mf->v4] = true;
+ vert_remap_array[mf->v4] = tot_bt_verts;
+ tot_bt_verts++;
+ }
+ tot_bt_tris += (mf->v4 ? 2 : 1); /* a quad or a tri */
}
}
@@ -1969,43 +1983,39 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm,
goto cleanup_empty_mesh;
}
- m_vertexArray.resize(tot_bt_verts*3);
+ m_vertexArray.resize(tot_bt_verts * 3);
m_polygonIndexArray.resize(tot_bt_tris);
- m_triFaceArray.resize(tot_bt_tris*3);
- btScalar *bt= &m_vertexArray[0];
- int *poly_index_pt= &m_polygonIndexArray[0];
- int *tri_pt= &m_triFaceArray[0];
+ m_triFaceArray.resize(tot_bt_tris * 3);
+ btScalar *bt = &m_vertexArray[0];
+ int *poly_index_pt = &m_polygonIndexArray[0];
+ int *tri_pt = &m_triFaceArray[0];
UVco *uv_pt = NULL;
- if (tface)
- {
- m_triFaceUVcoArray.resize(tot_bt_tris*3);
+ if (tface) {
+ m_triFaceUVcoArray.resize(tot_bt_tris * 3);
uv_pt = &m_triFaceUVcoArray[0];
- }
- else
+ }
+ else
m_triFaceUVcoArray.clear();
- for (int p2=0; p2<numpolys; p2++)
- {
- MFace* mf = &mface[p2];
- MTFace* tf = (tface) ? &tface[p2] : NULL;
+ for (int p2 = 0; p2 < numpolys; p2++) {
+ MFace *mf = &mface[p2];
+ MTFace *tf = (tface) ? &tface[p2] : NULL;
const int origi = index_mf_to_mpoly ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, p2) : p2;
- RAS_Polygon* poly= meshobj->GetPolygon(origi);
+ RAS_Polygon *poly = meshobj->GetPolygon(origi);
// only add polygons that have the collisionflag set
- if (poly->IsCollider())
- {
- MVert *v1= &mvert[mf->v1];
- MVert *v2= &mvert[mf->v2];
- MVert *v3= &mvert[mf->v3];
+ if (poly->IsCollider()) {
+ MVert *v1 = &mvert[mf->v1];
+ MVert *v2 = &mvert[mf->v2];
+ MVert *v3 = &mvert[mf->v3];
// the face indices
tri_pt[0] = vert_remap_array[mf->v1];
tri_pt[1] = vert_remap_array[mf->v2];
tri_pt[2] = vert_remap_array[mf->v3];
- tri_pt= tri_pt+3;
- if (tf)
- {
+ tri_pt = tri_pt + 3;
+ if (tf) {
uv_pt[0].uv[0] = tf->uv[0][0];
uv_pt[0].uv[1] = tf->uv[0][1];
uv_pt[1].uv[0] = tf->uv[1][0];
@@ -2020,19 +2030,19 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm,
poly_index_pt++;
// the vertex location
- if (vert_tag_array[mf->v1]==true) { /* *** v1 *** */
+ if (vert_tag_array[mf->v1]) { /* *** v1 *** */
vert_tag_array[mf->v1] = false;
*bt++ = v1->co[0];
*bt++ = v1->co[1];
*bt++ = v1->co[2];
}
- if (vert_tag_array[mf->v2]==true) { /* *** v2 *** */
+ if (vert_tag_array[mf->v2]) { /* *** v2 *** */
vert_tag_array[mf->v2] = false;
*bt++ = v2->co[0];
*bt++ = v2->co[1];
*bt++ = v2->co[2];
}
- if (vert_tag_array[mf->v3]==true) { /* *** v3 *** */
+ if (vert_tag_array[mf->v3]) { /* *** v3 *** */
vert_tag_array[mf->v3] = false;
*bt++ = v3->co[0];
*bt++ = v3->co[1];
@@ -2041,12 +2051,12 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm,
if (mf->v4)
{
- MVert *v4= &mvert[mf->v4];
+ MVert *v4 = &mvert[mf->v4];
tri_pt[0] = vert_remap_array[mf->v1];
tri_pt[1] = vert_remap_array[mf->v3];
tri_pt[2] = vert_remap_array[mf->v4];
- tri_pt= tri_pt+3;
+ tri_pt = tri_pt + 3;
if (tf)
{
uv_pt[0].uv[0] = tf->uv[0][0];
@@ -2063,7 +2073,7 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm,
poly_index_pt++;
// the vertex location
- if (vert_tag_array[mf->v4] == true) { /* *** v4 *** */
+ if (vert_tag_array[mf->v4]) { /* *** v4 *** */
vert_tag_array[mf->v4] = false;
*bt++ = v4->co[0];
*bt++ = v4->co[1];
@@ -2077,27 +2087,27 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm,
/* If this ever gets confusing, print out an OBJ file for debugging */
#if 0
printf("# vert count %d\n", m_vertexArray.size());
- for (i=0; i<m_vertexArray.size(); i+=1) {
+ for (i = 0; i < m_vertexArray.size(); i += 1) {
printf("v %.6f %.6f %.6f\n", m_vertexArray[i].x(), m_vertexArray[i].y(), m_vertexArray[i].z());
}
printf("# face count %d\n", m_triFaceArray.size());
- for (i=0; i<m_triFaceArray.size(); i+=3) {
- printf("f %d %d %d\n", m_triFaceArray[i]+1, m_triFaceArray[i+1]+1, m_triFaceArray[i+2]+1);
+ for (i = 0; i < m_triFaceArray.size(); i += 3) {
+ printf("f %d %d %d\n", m_triFaceArray[i] + 1, m_triFaceArray[i + 1] + 1, m_triFaceArray[i + 2] + 1);
}
#endif
}
#if 0
- if (validpolys==false)
+ if (validpolys == false)
{
// should not happen
m_shapeType = PHY_SHAPE_NONE;
return false;
}
#endif
-
+
m_meshObject = meshobj;
if (free_dm) {
dm->release(dm);
@@ -2105,10 +2115,9 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm,
}
// sharing only on static mesh at present, if you change that, you must also change in FindMesh
- if (!polytope && !dm)
- {
+ if (!polytope && !dm) {
// triangle shape can be shared, store the mesh object in the map
- m_meshShapeMap.insert(std::pair<RAS_MeshObject*,CcdShapeConstructionInfo*>(meshobj,this));
+ m_meshShapeMap.insert(std::pair<RAS_MeshObject *, CcdShapeConstructionInfo *>(meshobj, this));
}
return true;
@@ -2131,51 +2140,50 @@ cleanup_empty_mesh:
/* Updates the arrays used by CreateBulletShape(),
* take care that recalcLocalAabb() runs after CreateBulletShape is called.
* */
-bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject* gameobj, class RAS_MeshObject* meshobj)
+bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject *gameobj, class RAS_MeshObject *meshobj)
{
int numpolys;
int numverts;
- unsigned int tot_bt_tris= 0;
- unsigned int tot_bt_verts= 0;
+ unsigned int tot_bt_tris = 0;
+ unsigned int tot_bt_verts = 0;
int i, j;
int v_orig;
/* Use for looping over verts in a face as a try or 2 tris */
- const int quad_verts[7]= {0,1,2, 0,2,3, -1};
- const int tri_verts[4]= {0,1,2, -1};
+ const int quad_verts[7] = {0, 1, 2, 0, 2, 3, -1};
+ const int tri_verts[4] = {0, 1, 2, -1};
const int *fv_pt;
- if (gameobj==NULL && meshobj==NULL)
+ if (!gameobj && !meshobj)
return false;
-
+
if (m_shapeType != PHY_SHAPE_MESH)
return false;
- RAS_Deformer *deformer= gameobj ? gameobj->GetDeformer():NULL;
- DerivedMesh* dm = NULL;
+ RAS_Deformer *deformer = gameobj ? gameobj->GetDeformer() : NULL;
+ DerivedMesh *dm = NULL;
if (deformer)
dm = deformer->GetPhysicsMesh();
-
+
/* get the mesh from the object if not defined */
- if (meshobj==NULL) {
-
+ if (!meshobj) {
/* modifier mesh */
if (dm)
- meshobj= deformer->GetRasMesh();
-
+ meshobj = deformer->GetRasMesh();
+
/* game object first mesh */
- if (meshobj==NULL) {
+ if (!meshobj) {
if (gameobj->GetMeshCount() > 0) {
- meshobj= gameobj->GetMesh(0);
+ meshobj = gameobj->GetMesh(0);
}
}
}
-
- if (dm && deformer->GetRasMesh() == meshobj)
- { /*
+
+ if (dm && deformer->GetRasMesh() == meshobj) {
+ /*
* Derived Mesh Update
*
* */
@@ -2187,41 +2195,38 @@ bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject* gameobj, class RA
/* double lookup */
const int *index_mf_to_mpoly = (const int *)dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
- const int *index_mp_to_orig = (const int *)dm->getPolyDataArray(dm, CD_ORIGINDEX);
- if (index_mf_to_mpoly == NULL) {
+ const int *index_mp_to_orig = (const int *)dm->getPolyDataArray(dm, CD_ORIGINDEX);
+ if (!index_mf_to_mpoly) {
index_mp_to_orig = NULL;
}
MFace *mf;
MVert *mv;
- int flen;
-
- if (CustomData_has_layer(&dm->faceData, CD_MTFACE))
- {
+ if (CustomData_has_layer(&dm->faceData, CD_MTFACE)) {
MTFace *tface = (MTFace *)dm->getTessFaceDataArray(dm, CD_MTFACE);
MTFace *tf;
- vector<bool> vert_tag_array(numverts, false);
- vector<int> vert_remap_array(numverts, 0);
+ std::vector<bool> vert_tag_array(numverts, false);
+ std::vector<int> vert_remap_array(numverts, 0);
+
+ for (mf = mface, tf = tface, i = 0; i < numpolys; mf++, tf++, i++) {
+ if (tf->mode & TF_DYNAMIC) {
+ int flen;
- for (mf= mface, tf= tface, i=0; i < numpolys; mf++, tf++, i++) {
- if (tf->mode & TF_DYNAMIC)
- {
if (mf->v4) {
- tot_bt_tris+= 2;
- flen= 4;
- } else {
+ tot_bt_tris += 2;
+ flen = 4;
+ }
+ else {
tot_bt_tris++;
- flen= 3;
+ flen = 3;
}
- for (j=0; j<flen; j++)
- {
+ for (j = 0; j < flen; j++) {
v_orig = (*(&mf->v1 + j));
- if (vert_tag_array[v_orig]==false)
- {
+ if (!vert_tag_array[v_orig]) {
vert_tag_array[v_orig] = true;
vert_remap_array[v_orig] = tot_bt_verts;
tot_bt_verts++;
@@ -2230,42 +2235,38 @@ bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject* gameobj, class RA
}
}
- m_vertexArray.resize(tot_bt_verts*3);
- btScalar *bt= &m_vertexArray[0];
+ m_vertexArray.resize(tot_bt_verts * 3);
+ btScalar *bt = &m_vertexArray[0];
- m_triFaceArray.resize(tot_bt_tris*3);
- int *tri_pt= &m_triFaceArray[0];
+ m_triFaceArray.resize(tot_bt_tris * 3);
+ int *tri_pt = &m_triFaceArray[0];
- m_triFaceUVcoArray.resize(tot_bt_tris*3);
- UVco *uv_pt= &m_triFaceUVcoArray[0];
+ m_triFaceUVcoArray.resize(tot_bt_tris * 3);
+ UVco *uv_pt = &m_triFaceUVcoArray[0];
m_polygonIndexArray.resize(tot_bt_tris);
- int *poly_index_pt= &m_polygonIndexArray[0];
+ int *poly_index_pt = &m_polygonIndexArray[0];
- for (mf= mface, tf= tface, i=0; i < numpolys; mf++, tf++, i++)
- {
- if (tf->mode & TF_DYNAMIC)
- {
+ for (mf = mface, tf = tface, i = 0; i < numpolys; mf++, tf++, i++) {
+ if (tf->mode & TF_DYNAMIC) {
int origi = index_mf_to_mpoly ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i) : i;
if (mf->v4) {
- fv_pt= quad_verts;
+ fv_pt = quad_verts;
*poly_index_pt++ = origi;
*poly_index_pt++ = origi;
- flen= 4;
- } else {
- fv_pt= tri_verts;
+ }
+ else {
+ fv_pt = tri_verts;
*poly_index_pt++ = origi;
- flen= 3;
}
- for (; *fv_pt > -1; fv_pt++)
- {
+ for (; *fv_pt > -1; fv_pt++) {
v_orig = (*(&mf->v1 + (*fv_pt)));
if (vert_tag_array[v_orig])
{
- mv= mvert + v_orig;
+ mv = mvert + v_orig;
*bt++ = mv->co[0];
*bt++ = mv->co[1];
*bt++ = mv->co[2];
@@ -2283,37 +2284,37 @@ bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject* gameobj, class RA
else {
/* no need for a vertex mapping. simple/fast */
- tot_bt_verts= numverts;
+ tot_bt_verts = numverts;
- for (mf= mface, i=0; i < numpolys; mf++, i++) {
- tot_bt_tris += (mf->v4 ? 2:1);
+ for (mf = mface, i = 0; i < numpolys; mf++, i++) {
+ tot_bt_tris += (mf->v4 ? 2 : 1);
}
- m_vertexArray.resize(tot_bt_verts*3);
- btScalar *bt= &m_vertexArray[0];
+ m_vertexArray.resize(tot_bt_verts * 3);
+ btScalar *bt = &m_vertexArray[0];
- m_triFaceArray.resize(tot_bt_tris*3);
- int *tri_pt= &m_triFaceArray[0];
+ m_triFaceArray.resize(tot_bt_tris * 3);
+ int *tri_pt = &m_triFaceArray[0];
m_polygonIndexArray.resize(tot_bt_tris);
- int *poly_index_pt= &m_polygonIndexArray[0];
+ int *poly_index_pt = &m_polygonIndexArray[0];
m_triFaceUVcoArray.clear();
- for (mv= mvert, i=0; i < numverts; mv++, i++) {
+ for (mv = mvert, i = 0; i < numverts; mv++, i++) {
*bt++ = mv->co[0]; *bt++ = mv->co[1]; *bt++ = mv->co[2];
}
- for (mf= mface, i=0; i < numpolys; mf++, i++) {
+ for (mf = mface, i = 0; i < numpolys; mf++, i++) {
int origi = index_mf_to_mpoly ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i) : i;
if (mf->v4) {
- fv_pt= quad_verts;
+ fv_pt = quad_verts;
*poly_index_pt++ = origi;
*poly_index_pt++ = origi;
}
else {
- fv_pt= tri_verts;
+ fv_pt = tri_verts;
*poly_index_pt++ = origi;
}
@@ -2322,51 +2323,46 @@ bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject* gameobj, class RA
}
}
}
- else { /*
- * RAS Mesh Update
- *
- * */
-
+ else { /*
+ * RAS Mesh Update
+ *
+ * */
/* Note!, gameobj can be NULL here */
/* transverts are only used for deformed RAS_Meshes, the RAS_TexVert data
* is too hard to get at, see below for details */
- float (*transverts)[3] = NULL;
- int transverts_tot= 0; /* with deformed meshes - should always be greater than the max orginal index, or we get crashes */
+ float(*transverts)[3] = NULL;
+ int transverts_tot = 0; /* with deformed meshes - should always be greater than the max orginal index, or we get crashes */
if (deformer) {
/* map locations from the deformed array
*
* Could call deformer->Update(); but rely on redraw updating.
* */
- transverts= deformer->GetTransVerts(&transverts_tot);
+ transverts = deformer->GetTransVerts(&transverts_tot);
}
// Tag verts we're using
- numpolys= meshobj->NumPolygons();
- numverts= meshobj->m_sharedvertex_map.size();
+ numpolys = meshobj->NumPolygons();
+ numverts = meshobj->m_sharedvertex_map.size();
const float *xyz;
- vector<bool> vert_tag_array(numverts, false);
- vector<int> vert_remap_array(numverts, 0);
+ std::vector<bool> vert_tag_array(numverts, false);
+ std::vector<int> vert_remap_array(numverts, 0);
- for (int p=0; p<numpolys; p++)
- {
- RAS_Polygon* poly= meshobj->GetPolygon(p);
- if (poly->IsCollider())
- {
- for (i=0; i < poly->VertexCount(); i++)
- {
- v_orig= poly->GetVertex(i)->getOrigIndex();
- if (vert_tag_array[v_orig]==false)
- {
+ for (int p = 0; p < numpolys; p++) {
+ RAS_Polygon *poly = meshobj->GetPolygon(p);
+ if (poly->IsCollider()) {
+ for (i = 0; i < poly->VertexCount(); i++) {
+ v_orig = poly->GetVertex(i)->getOrigIndex();
+ if (!vert_tag_array[v_orig]) {
vert_tag_array[v_orig] = true;
vert_remap_array[v_orig] = tot_bt_verts;
tot_bt_verts++;
}
}
- tot_bt_tris += (poly->VertexCount()==4 ? 2:1);
+ tot_bt_tris += (poly->VertexCount() == 4 ? 2 : 1);
}
}
@@ -2374,32 +2370,29 @@ bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject* gameobj, class RA
if (tot_bt_tris == 0 || tot_bt_verts == 0)
return false;
- m_vertexArray.resize(tot_bt_verts*3);
- btScalar *bt= &m_vertexArray[0];
+ m_vertexArray.resize(tot_bt_verts * 3);
+ btScalar *bt = &m_vertexArray[0];
- m_triFaceArray.resize(tot_bt_tris*3);
- int *tri_pt= &m_triFaceArray[0];
+ m_triFaceArray.resize(tot_bt_tris * 3);
+ int *tri_pt = &m_triFaceArray[0];
/* cant be used for anything useful in this case, since we don't rely on the original mesh
* will just be an array like pythons range(tot_bt_tris) */
m_polygonIndexArray.resize(tot_bt_tris);
- for (int p=0; p<numpolys; p++)
- {
- RAS_Polygon* poly= meshobj->GetPolygon(p);
+ int p = 0;
+ int t = 0;
+ while (t < tot_bt_tris) {
+ RAS_Polygon *poly = meshobj->GetPolygon(p);
- if (poly->IsCollider())
- {
+ if (poly->IsCollider()) {
/* quad or tri loop */
- fv_pt= (poly->VertexCount()==3 ? tri_verts:quad_verts);
+ fv_pt = (poly->VertexCount() == 3 ? tri_verts : quad_verts);
- for (; *fv_pt > -1; fv_pt++)
- {
- v_orig= poly->GetVertex(*fv_pt)->getOrigIndex();
-
- if (vert_tag_array[v_orig])
- {
+ for (; *fv_pt > -1; fv_pt++) {
+ v_orig = poly->GetVertex(*fv_pt)->getOrigIndex();
+ if (vert_tag_array[v_orig]) {
if (transverts) {
/* deformed mesh, using RAS_TexVert locations would be too troublesome
* because they are use the gameob as a hash in the material slot */
@@ -2409,55 +2402,60 @@ bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject* gameobj, class RA
}
else {
/* static mesh python may have modified */
- xyz= meshobj->GetVertexLocation( v_orig );
+ xyz = meshobj->GetVertexLocation(v_orig);
*bt++ = xyz[0];
*bt++ = xyz[1];
*bt++ = xyz[2];
}
-
vert_tag_array[v_orig] = false;
}
-
*tri_pt++ = vert_remap_array[v_orig];
}
}
-
- m_polygonIndexArray[p] = p; /* dumb counting */
+ // first triangle
+ m_polygonIndexArray[t] = p;
+
+ // if the poly is a quad we transform it in two triangles
+ if (poly->VertexCount() == 4) {
+ t++;
+ // second triangle
+ m_polygonIndexArray[t] = p;
+ }
+ t++;
+ p++;
}
}
-
+
#if 0
/* needs #include <cstdio> */
printf("# vert count %d\n", m_vertexArray.size());
- for (int i=0; i<m_vertexArray.size(); i+=3) {
- printf("v %.6f %.6f %.6f\n", m_vertexArray[i], m_vertexArray[i+1], m_vertexArray[i+2]);
+ for (int i = 0; i < m_vertexArray.size(); i += 3) {
+ printf("v %.6f %.6f %.6f\n", m_vertexArray[i], m_vertexArray[i + 1], m_vertexArray[i + 2]);
}
printf("# face count %d\n", m_triFaceArray.size());
- for (int i=0; i<m_triFaceArray.size(); i+=3) {
- printf("f %d %d %d\n", m_triFaceArray[i]+1, m_triFaceArray[i+1]+1, m_triFaceArray[i+2]+1);
+ for (int i = 0; i < m_triFaceArray.size(); i += 3) {
+ printf("f %d %d %d\n", m_triFaceArray[i] + 1, m_triFaceArray[i + 1] + 1, m_triFaceArray[i + 2] + 1);
}
#endif
- /* force recreation of the m_unscaledShape.
+ /* force recreation of the m_triangleIndexVertexArray.
* If this has multiple users we cant delete */
- if (m_unscaledShape) {
- // don't free now so it can re-allocate under the same location and not break pointers.
- // DeleteBulletShape(m_unscaledShape);
- m_forceReInstance= true;
+ if (m_triangleIndexVertexArray) {
+ m_forceReInstance = true;
}
// Make sure to also replace the mesh in the shape map! Otherwise we leave dangling references when we free.
// Note, this whole business could cause issues with shared meshes. If we update one mesh, do we replace
// them all?
- std::map<RAS_MeshObject*,CcdShapeConstructionInfo*>::iterator mit = m_meshShapeMap.find(m_meshObject);
+ std::map<RAS_MeshObject *, CcdShapeConstructionInfo *>::iterator mit = m_meshShapeMap.find(m_meshObject);
if (mit != m_meshShapeMap.end()) {
m_meshShapeMap.erase(mit);
m_meshShapeMap[meshobj] = this;
}
- m_meshObject= meshobj;
-
+ m_meshObject = meshobj;
+
if (dm) {
dm->needsFree = 1;
dm->release(dm);
@@ -2465,8 +2463,6 @@ bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject* gameobj, class RA
return true;
}
-
-
bool CcdShapeConstructionInfo::SetProxy(CcdShapeConstructionInfo* shapeInfo)
{
if (shapeInfo == NULL)
@@ -2529,74 +2525,61 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape(btScalar margin, b
// 9 multiplications/additions and one function call for each triangle that passes the mid phase filtering
// One possible optimization is to use directly the btBvhTriangleMeshShape when the scale is 1,1,1
// and btScaledBvhTriangleMeshShape otherwise.
- if (useGimpact)
- {
- btTriangleIndexVertexArray* indexVertexArrays = new btTriangleIndexVertexArray(
+ if (useGimpact) {
+ if (!m_triangleIndexVertexArray || m_forceReInstance) {
+ if (m_triangleIndexVertexArray)
+ delete m_triangleIndexVertexArray;
+
+ m_triangleIndexVertexArray = new btTriangleIndexVertexArray(
m_polygonIndexArray.size(),
- &m_triFaceArray[0],
- 3*sizeof(int),
- m_vertexArray.size()/3,
+ m_triFaceArray.data(),
+ 3 * sizeof(int),
+ m_vertexArray.size() / 3,
&m_vertexArray[0],
- 3*sizeof(btScalar)
- );
- btGImpactMeshShape* gimpactShape = new btGImpactMeshShape(indexVertexArrays);
- gimpactShape->setMargin(margin);
- gimpactShape->updateBound();
- collisionShape = gimpactShape;
-
-
- } else
- {
- if (!m_unscaledShape || m_forceReInstance)
- {
-
- btTriangleIndexVertexArray* indexVertexArrays = 0;
+ 3 * sizeof(btScalar));
+ m_forceReInstance = false;
+ }
+ btGImpactMeshShape *gimpactShape = new btGImpactMeshShape(m_triangleIndexVertexArray);
+ gimpactShape->setMargin(margin);
+ gimpactShape->updateBound();
+ collisionShape = gimpactShape;
+ }
+ else {
+ if (!m_triangleIndexVertexArray || m_forceReInstance) {
///enable welding, only for the objects that need it (such as soft bodies)
- if (0.f != m_weldingThreshold1)
- {
- btTriangleMesh* collisionMeshData = new btTriangleMesh(true,false);
+ if (0.0f != m_weldingThreshold1) {
+ btTriangleMesh *collisionMeshData = new btTriangleMesh(true, false);
collisionMeshData->m_weldingThreshold = m_weldingThreshold1;
- bool removeDuplicateVertices=true;
+ bool removeDuplicateVertices = true;
// m_vertexArray not in multiple of 3 anymore, use m_triFaceArray
- for (unsigned int i=0; i<m_triFaceArray.size(); i+=3) {
- btScalar *bt = &m_vertexArray[3*m_triFaceArray[i]];
+ for (unsigned int i = 0; i < m_triFaceArray.size(); i += 3) {
+ btScalar *bt = &m_vertexArray[3 * m_triFaceArray[i]];
btVector3 v1(bt[0], bt[1], bt[2]);
- bt = &m_vertexArray[3*m_triFaceArray[i+1]];
+ bt = &m_vertexArray[3 * m_triFaceArray[i + 1]];
btVector3 v2(bt[0], bt[1], bt[2]);
- bt = &m_vertexArray[3*m_triFaceArray[i+2]];
+ bt = &m_vertexArray[3 * m_triFaceArray[i + 2]];
btVector3 v3(bt[0], bt[1], bt[2]);
collisionMeshData->addTriangle(v1, v2, v3, removeDuplicateVertices);
}
- indexVertexArrays = collisionMeshData;
-
- } else
- {
- indexVertexArrays = new btTriangleIndexVertexArray(
+ m_triangleIndexVertexArray = collisionMeshData;
+ }
+ else {
+ m_triangleIndexVertexArray = new btTriangleIndexVertexArray(
m_polygonIndexArray.size(),
- &m_triFaceArray[0],
- 3*sizeof(int),
- m_vertexArray.size()/3,
+ m_triFaceArray.data(),
+ 3 * sizeof(int),
+ m_vertexArray.size() / 3,
&m_vertexArray[0],
- 3*sizeof(btScalar));
- }
-
- // this shape will be shared and not deleted until shapeInfo is deleted
-
- // for UpdateMesh, reuse the last memory location so instancing wont crash.
- if (m_unscaledShape) {
- DeleteBulletShape(m_unscaledShape, false);
- m_unscaledShape->~btBvhTriangleMeshShape();
- m_unscaledShape = new(m_unscaledShape) btBvhTriangleMeshShape( indexVertexArrays, true, useBvh );
- } else {
- m_unscaledShape = new btBvhTriangleMeshShape( indexVertexArrays, true, useBvh );
+ 3 * sizeof(btScalar));
}
- m_forceReInstance= false;
- } else if (useBvh && m_unscaledShape->getOptimizedBvh() == NULL) {
- // the existing unscaledShape was not build with Bvh, do it now
- m_unscaledShape->buildOptimizedBvh();
+
+ m_forceReInstance = false;
}
- collisionShape = new btScaledBvhTriangleMeshShape(m_unscaledShape, btVector3(1.0f,1.0f,1.0f));
+
+ btBvhTriangleMeshShape *unscaledShape = new btBvhTriangleMeshShape(m_triangleIndexVertexArray, true, useBvh);
+ unscaledShape->setMargin(margin);
+ collisionShape = new btScaledBvhTriangleMeshShape(unscaledShape, btVector3(1.0f, 1.0f, 1.0f));
collisionShape->setMargin(margin);
}
break;
@@ -2638,10 +2621,9 @@ CcdShapeConstructionInfo::~CcdShapeConstructionInfo()
(*sit)->Release();
}
m_shapeArray.clear();
- if (m_unscaledShape)
- {
- DeleteBulletShape(m_unscaledShape, true);
- }
+
+ if (m_triangleIndexVertexArray)
+ delete m_triangleIndexVertexArray;
m_vertexArray.clear();
if (m_shapeType == PHY_SHAPE_MESH && m_meshObject != NULL)
{
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
index de40624d7bb..b1d38763fbb 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
@@ -79,7 +79,7 @@ public:
m_userData(NULL),
m_refCount(1),
m_meshObject(NULL),
- m_unscaledShape(NULL),
+ m_triangleIndexVertexArray(NULL),
m_forceReInstance(false),
m_weldingThreshold1(0.f),
m_shapeProxy(NULL)
@@ -110,10 +110,11 @@ public:
void AddShape(CcdShapeConstructionInfo* shapeInfo);
- btTriangleMeshShape* GetMeshShape(void)
+ btStridingMeshInterface *GetMeshInterface()
{
- return (m_unscaledShape);
+ return m_triangleIndexVertexArray;
}
+
CcdShapeConstructionInfo* GetChildShape(int i)
{
if (i < 0 || i >= (int)m_shapeArray.size())
@@ -195,8 +196,8 @@ protected:
int m_refCount; // this class is shared between replicas
// keep track of users so that we can release it
RAS_MeshObject* m_meshObject; // Keep a pointer to the original mesh
- btBvhTriangleMeshShape* m_unscaledShape;// holds the shared unscale BVH mesh shape,
- // the actual shape is of type btScaledBvhTriangleMeshShape
+ // The list of vertexes and indexes for the triangle mesh, shared between Bullet shape.
+ btTriangleIndexVertexArray *m_triangleIndexVertexArray;
std::vector<CcdShapeConstructionInfo*> m_shapeArray; // for compound shapes
bool m_forceReInstance; //use gimpact for concave dynamic/moving collision detection
float m_weldingThreshold1; //welding closeby vertices together can improve softbody stability etc.
@@ -447,6 +448,23 @@ public:
#endif
};
+class CleanPairCallback : public btOverlapCallback
+{
+ btBroadphaseProxy *m_cleanProxy;
+ btOverlappingPairCache *m_pairCache;
+ btDispatcher *m_dispatcher;
+
+public:
+ CleanPairCallback(btBroadphaseProxy *cleanProxy, btOverlappingPairCache *pairCache, btDispatcher *dispatcher)
+ :m_cleanProxy(cleanProxy),
+ m_pairCache(pairCache),
+ m_dispatcher(dispatcher)
+ {
+ }
+
+ virtual bool processOverlap(btBroadphasePair &pair);
+};
+
///CcdPhysicsController is a physics object that supports continuous collision detection and time of impact based physics resolution.
class CcdPhysicsController : public PHY_IPhysicsController
{
@@ -498,6 +516,11 @@ protected:
return (--m_registerCount == 0) ? true : false;
}
+ bool Registered() const
+ {
+ return (m_registerCount != 0);
+ }
+
void addCcdConstraintRef(btTypedConstraint* c);
void removeCcdConstraintRef(btTypedConstraint* c);
btTypedConstraint* getCcdConstraintRef(int index);
@@ -513,7 +536,15 @@ protected:
CcdPhysicsController (const CcdConstructionInfo& ci);
+ /**
+ * Delete the current Bullet shape used in the rigid body.
+ */
bool DeleteControllerShape();
+
+ /**
+ * Delete the old Bullet shape and set the new Bullet shape : newShape
+ * \param newShape The new Bullet shape to set, if is NULL we create a new Bullet shape
+ */
bool ReplaceControllerShape(btCollisionShape *newShape);
virtual ~CcdPhysicsController();
@@ -598,7 +629,7 @@ protected:
virtual void ResolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ);
-
+ virtual void RefreshCollisions();
virtual void SuspendDynamics(bool ghost);
virtual void RestoreDynamics();
@@ -626,8 +657,12 @@ protected:
virtual void CalcXform() {}
virtual void SetMargin(float margin)
{
- if (m_collisionShape)
- m_collisionShape->setMargin(btScalar(margin));
+ if (m_collisionShape) {
+ m_collisionShape->setMargin(margin);
+ // if the shape use a unscaled shape we have also to set the correct margin in it
+ if (m_collisionShape->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE)
+ ((btScaledBvhTriangleMeshShape *)m_collisionShape)->getChildShape()->setMargin(margin);
+ }
}
virtual float GetMargin() const
{
@@ -712,6 +747,11 @@ protected:
return GetConstructionInfo().m_bDyna;
}
+ virtual bool IsSuspended() const
+ {
+ return m_suspended;
+ }
+
virtual bool IsCompound()
{
return GetConstructionInfo().m_shapeInfo->m_shapeType == PHY_SHAPE_COMPOUND;
@@ -719,6 +759,9 @@ protected:
virtual bool ReinstancePhysicsShape(KX_GameObject *from_gameobj, RAS_MeshObject* from_meshobj);
+ /* Method to replicate rigid body joint contraints for group instances. */
+ virtual void ReplicateConstraints(KX_GameObject *gameobj, std::vector<KX_GameObject*> constobj);
+
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GE:CcdPhysicsController")
#endif
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
index ac74029fbe3..3670d79a01e 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
@@ -461,6 +461,19 @@ m_scalingPropagated(false)
void CcdPhysicsEnvironment::AddCcdPhysicsController(CcdPhysicsController* ctrl)
{
+ // the controller is already added we do nothing
+ if (!m_controllers.insert(ctrl).second) {
+ return;
+ }
+
+ /* In the case of compound child controller (see also RemoveCcdPhysicsController)
+ * we add the controller to the trigger controlers list : m_triggerControllers
+ * if it use collision callbacks.
+ */
+ if (ctrl->Registered()) {
+ m_triggerControllers.insert(ctrl);
+ }
+
btRigidBody* body = ctrl->GetRigidBody();
btCollisionObject* obj = ctrl->GetCollisionObject();
@@ -469,8 +482,6 @@ void CcdPhysicsEnvironment::AddCcdPhysicsController(CcdPhysicsController* ctrl)
if (body)
body->setGravity( m_gravity );
- m_controllers.insert(ctrl);
-
if (body)
{
//use explicit group/filter for finer control over collision in bullet => near/radar sensor
@@ -505,10 +516,32 @@ void CcdPhysicsEnvironment::AddCcdPhysicsController(CcdPhysicsController* ctrl)
bool CcdPhysicsEnvironment::RemoveCcdPhysicsController(CcdPhysicsController* ctrl)
{
+ // if the physics controller is already removed we do nothing
+ if (!m_controllers.erase(ctrl)) {
+ return false;
+ }
+
+ /* In the case of compound child controller which use collision callbacks
+ * we remove it from the m_triggerControllers list but leave m_registerCount
+ * to know in AddCcdPhysicsController if we have to add it in m_triggerControllers
+ * and to avoid an useless added in RequestCollisionCallback, indeed we can't register
+ * more than one time a controller.
+ */
+ if (ctrl->Registered()) {
+ m_triggerControllers.erase(ctrl);
+ }
+
//also remove constraint
btRigidBody* body = ctrl->GetRigidBody();
if (body)
{
+ btBroadphaseProxy *proxy = ctrl->GetCollisionObject()->getBroadphaseHandle();
+ btDispatcher *dispatcher = m_dynamicsWorld->getDispatcher();
+ btOverlappingPairCache *pairCache = m_dynamicsWorld->getPairCache();
+
+ CleanPairCallback cleanPairs(proxy, pairCache, dispatcher);
+ pairCache->processAllOverlappingPairs(&cleanPairs, dispatcher);
+
for (int i = ctrl->getNumCcdConstraintRefs() - 1; i >= 0; i--)
{
btTypedConstraint* con = ctrl->getCcdConstraintRef(i);
@@ -548,13 +581,8 @@ bool CcdPhysicsEnvironment::RemoveCcdPhysicsController(CcdPhysicsController* ctr
}
}
}
- if (ctrl->m_registerCount != 0)
- printf("Warning: removing controller with non-zero m_registerCount: %d\n", ctrl->m_registerCount);
-
- //remove it from the triggers
- m_triggerControllers.erase(ctrl);
- return (m_controllers.erase(ctrl) != 0);
+ return true;
}
void CcdPhysicsEnvironment::UpdateCcdPhysicsController(CcdPhysicsController* ctrl, btScalar newMass, int newCollisionFlags, short int newCollisionGroup, short int newCollisionMask)
@@ -562,6 +590,7 @@ void CcdPhysicsEnvironment::UpdateCcdPhysicsController(CcdPhysicsController* ctr
// this function is used when the collisionning group of a controller is changed
// remove and add the collistioning object
btRigidBody* body = ctrl->GetRigidBody();
+ btSoftBody *softBody = ctrl->GetSoftBody();
btCollisionObject* obj = ctrl->GetCollisionObject();
if (obj)
{
@@ -575,6 +604,9 @@ void CcdPhysicsEnvironment::UpdateCcdPhysicsController(CcdPhysicsController* ctr
body->setMassProps(newMass, inertia);
m_dynamicsWorld->addRigidBody(body, newCollisionGroup, newCollisionMask);
}
+ else if (softBody) {
+ m_dynamicsWorld->addSoftBody(softBody);
+ }
else {
m_dynamicsWorld->addCollisionObject(obj, newCollisionGroup, newCollisionMask);
}
@@ -586,43 +618,6 @@ void CcdPhysicsEnvironment::UpdateCcdPhysicsController(CcdPhysicsController* ctr
ctrl->m_cci.m_collisionFlags = newCollisionFlags;
}
-void CcdPhysicsEnvironment::EnableCcdPhysicsController(CcdPhysicsController* ctrl)
-{
- if (m_controllers.insert(ctrl).second)
- {
- btCollisionObject* obj = ctrl->GetCollisionObject();
- obj->setUserPointer(ctrl);
- // update the position of the object from the user
- if (ctrl->GetMotionState())
- {
- btTransform xform = CcdPhysicsController::GetTransformFromMotionState(ctrl->GetMotionState());
- ctrl->SetCenterOfMassTransform(xform);
- }
- m_dynamicsWorld->addCollisionObject(obj,
- ctrl->GetCollisionFilterGroup(), ctrl->GetCollisionFilterMask());
- }
-}
-
-void CcdPhysicsEnvironment::DisableCcdPhysicsController(CcdPhysicsController* ctrl)
-{
- if (m_controllers.erase(ctrl))
- {
- btRigidBody* body = ctrl->GetRigidBody();
- if (body)
- {
- m_dynamicsWorld->removeRigidBody(body);
- } else
- {
- if (ctrl->GetSoftBody())
- {
- } else
- {
- m_dynamicsWorld->removeCollisionObject(ctrl->GetCollisionObject());
- }
- }
- }
-}
-
void CcdPhysicsEnvironment::RefreshCcdPhysicsController(CcdPhysicsController* ctrl)
{
btCollisionObject* obj = ctrl->GetCollisionObject();
@@ -636,6 +631,11 @@ void CcdPhysicsEnvironment::RefreshCcdPhysicsController(CcdPhysicsController* ct
}
}
+bool CcdPhysicsEnvironment::IsActiveCcdPhysicsController(CcdPhysicsController *ctrl)
+{
+ return (m_controllers.find(ctrl) != m_controllers.end());
+}
+
void CcdPhysicsEnvironment::AddCcdGraphicController(CcdGraphicController* ctrl)
{
if (m_cullingTree && !ctrl->GetBroadphaseHandle())
@@ -671,6 +671,19 @@ void CcdPhysicsEnvironment::RemoveCcdGraphicController(CcdGraphicController* ctr
}
}
+void CcdPhysicsEnvironment::UpdateCcdPhysicsControllerShape(CcdShapeConstructionInfo *shapeInfo)
+{
+ for (std::set<CcdPhysicsController *>::iterator it = m_controllers.begin(); it != m_controllers.end(); ++it) {
+ CcdPhysicsController *ctrl = *it;
+
+ if (ctrl->GetShapeInfo() != shapeInfo)
+ continue;
+
+ ctrl->ReplaceControllerShape(NULL);
+ RefreshCcdPhysicsController(ctrl);
+ }
+}
+
void CcdPhysicsEnvironment::BeginFrame()
{
@@ -752,8 +765,8 @@ public:
void CcdPhysicsEnvironment::ProcessFhSprings(double curTime,float interval)
{
std::set<CcdPhysicsController*>::iterator it;
- // dynamic of Fh spring is based on a timestep of 1/60
- int numIter = (int)(interval*60.0001f);
+ // Add epsilon to the tick rate for numerical stability
+ int numIter = (int)(interval*(KX_KetsjiEngine::GetTicRate() + 0.001f));
for (it=m_controllers.begin(); it!=m_controllers.end(); it++)
{
@@ -1156,17 +1169,8 @@ static bool GetHitTriangle(btCollisionShape* shape, CcdShapeConstructionInfo* sh
int indexstride;
int numfaces;
PHY_ScalarType indicestype;
- btStridingMeshInterface* meshInterface = NULL;
- btTriangleMeshShape* triangleShape = shapeInfo->GetMeshShape();
+ btStridingMeshInterface* meshInterface = shapeInfo->GetMeshInterface();
- if (triangleShape)
- meshInterface = triangleShape->getMeshInterface();
- else
- {
- // other possibility is gImpact
- if (shape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE)
- meshInterface = (static_cast<btGImpactMeshShape*>(shape))->getMeshInterface();
- }
if (!meshInterface)
return false;
@@ -2188,15 +2192,8 @@ btTypedConstraint* CcdPhysicsEnvironment::GetConstraintById(int constraintId)
void CcdPhysicsEnvironment::AddSensor(PHY_IPhysicsController* ctrl)
{
-
CcdPhysicsController* ctrl1 = (CcdPhysicsController* )ctrl;
- // addSensor() is a "light" function for bullet because it is used
- // dynamically when the sensor is activated. Use enableCcdPhysicsController() instead
- //if (m_controllers.insert(ctrl1).second)
- //{
- // addCcdPhysicsController(ctrl1);
- //}
- EnableCcdPhysicsController(ctrl1);
+ AddCcdPhysicsController(ctrl1);
}
bool CcdPhysicsEnvironment::RemoveCollisionCallback(PHY_IPhysicsController* ctrl)
@@ -2211,7 +2208,7 @@ bool CcdPhysicsEnvironment::RemoveCollisionCallback(PHY_IPhysicsController* ctrl
void CcdPhysicsEnvironment::RemoveSensor(PHY_IPhysicsController* ctrl)
{
- DisableCcdPhysicsController((CcdPhysicsController*)ctrl);
+ RemoveCcdPhysicsController((CcdPhysicsController*)ctrl);
}
void CcdPhysicsEnvironment::AddTouchCallback(int response_class, PHY_ResponseCallback callback, void *user)
@@ -2644,9 +2641,6 @@ int CcdPhysicsEnvironment::CreateConstraint(class PHY_IPhysicsController* ctrl
if (!rb0)
return 0;
- // If either of the controllers is missing, we can't do anything.
- if (!c0 || !c1) return 0;
-
btVector3 pivotInB = rb1 ? rb1->getCenterOfMassTransform().inverse()(rb0->getCenterOfMassTransform()(pivotInA)) :
rb0->getCenterOfMassTransform() * pivotInA;
btVector3 axisInA(axisX,axisY,axisZ);
@@ -2658,6 +2652,8 @@ int CcdPhysicsEnvironment::CreateConstraint(class PHY_IPhysicsController* ctrl
{
case PHY_POINT2POINT_CONSTRAINT:
{
+ // If either of the controllers is missing, we can't do anything.
+ if (!c0 || !c1) return 0;
btPoint2PointConstraint* p2p = 0;
@@ -2686,6 +2682,9 @@ int CcdPhysicsEnvironment::CreateConstraint(class PHY_IPhysicsController* ctrl
case PHY_GENERIC_6DOF_CONSTRAINT:
{
+ // If either of the controllers is missing, we can't do anything.
+ if (!c0 || !c1) return 0;
+
btGeneric6DofConstraint* genericConstraint = 0;
if (rb1)
@@ -2739,7 +2738,7 @@ int CcdPhysicsEnvironment::CreateConstraint(class PHY_IPhysicsController* ctrl
*rb0,s_fixedObject2,
frameInA,frameInB,useReferenceFrameA);
}
-
+
if (genericConstraint)
{
//m_constraints.push_back(genericConstraint);
@@ -2756,6 +2755,9 @@ int CcdPhysicsEnvironment::CreateConstraint(class PHY_IPhysicsController* ctrl
}
case PHY_CONE_TWIST_CONSTRAINT:
{
+ // If either of the controllers is missing, we can't do anything.
+ if (!c0 || !c1) return 0;
+
btConeTwistConstraint* coneTwistContraint = 0;
@@ -2807,7 +2809,7 @@ int CcdPhysicsEnvironment::CreateConstraint(class PHY_IPhysicsController* ctrl
*rb0,s_fixedObject2,
frameInA,frameInB);
}
-
+
if (coneTwistContraint)
{
//m_constraints.push_back(genericConstraint);
@@ -2830,6 +2832,9 @@ int CcdPhysicsEnvironment::CreateConstraint(class PHY_IPhysicsController* ctrl
case PHY_LINEHINGE_CONSTRAINT:
{
+ // If either of the controllers is missing, we can't do anything.
+ if (!c0 || !c1) return 0;
+
btHingeConstraint* hinge = 0;
if (rb1)
@@ -3517,20 +3522,23 @@ void CcdPhysicsEnvironment::ConvertObject(KX_GameObject *gameobj, RAS_MeshObject
if (isbulletdyna)
gameobj->SetRecordAnimation(true);
+ physicscontroller->SetNewClientInfo(gameobj->getClientInfo());
+
// don't add automatically sensor object, they are added when a collision sensor is registered
if (!isbulletsensor && (blenderobject->lay & activeLayerBitInfo) != 0)
{
this->AddCcdPhysicsController( physicscontroller);
}
- physicscontroller->SetNewClientInfo(gameobj->getClientInfo());
+
{
btRigidBody* rbody = physicscontroller->GetRigidBody();
if (rbody)
{
+ rbody->setLinearFactor(ci.m_linearFactor);
+
if (isbulletrigidbody)
{
- rbody->setLinearFactor(ci.m_linearFactor);
rbody->setAngularFactor(ci.m_angularFactor);
}
@@ -3591,3 +3599,79 @@ void CcdPhysicsEnvironment::ConvertObject(KX_GameObject *gameobj, RAS_MeshObject
}
#endif
}
+
+
+void CcdPhysicsEnvironment::SetupObjectConstraints(KX_GameObject *obj_src, KX_GameObject *obj_dest,
+ bRigidBodyJointConstraint *dat)
+{
+ PHY_IPhysicsController *phy_src = obj_src->GetPhysicsController();
+ PHY_IPhysicsController *phy_dest = obj_dest->GetPhysicsController();
+ PHY_IPhysicsEnvironment *phys_env = obj_src->GetScene()->GetPhysicsEnvironment();
+
+ /* We need to pass a full constraint frame, not just axis. */
+ MT_Matrix3x3 localCFrame(MT_Vector3(dat->axX,dat->axY,dat->axZ));
+ MT_Vector3 axis0 = localCFrame.getColumn(0);
+ MT_Vector3 axis1 = localCFrame.getColumn(1);
+ MT_Vector3 axis2 = localCFrame.getColumn(2);
+ MT_Vector3 scale = obj_src->NodeGetWorldScaling();
+
+ /* Apply not only the pivot and axis values, but also take scale into count
+ * this is not working well, if only one or two axis are scaled, but works ok on
+ * homogeneous scaling. */
+ int constraintId = phys_env->CreateConstraint(
+ phy_src, phy_dest, (PHY_ConstraintType)dat->type,
+ (float)(dat->pivX * scale.x()), (float)(dat->pivY * scale.y()), (float)(dat->pivZ * scale.z()),
+ (float)(axis0.x() * scale.x()), (float)(axis0.y() * scale.y()), (float)(axis0.z() * scale.z()),
+ (float)(axis1.x() * scale.x()), (float)(axis1.y() * scale.y()), (float)(axis1.z() * scale.z()),
+ (float)(axis2.x() * scale.x()), (float)(axis2.y() * scale.y()), (float)(axis2.z() * scale.z()),
+ dat->flag);
+
+ /* PHY_POINT2POINT_CONSTRAINT = 1,
+ * PHY_LINEHINGE_CONSTRAINT = 2,
+ * PHY_ANGULAR_CONSTRAINT = 3,
+ * PHY_CONE_TWIST_CONSTRAINT = 4,
+ * PHY_VEHICLE_CONSTRAINT = 11,
+ * PHY_GENERIC_6DOF_CONSTRAINT = 12 */
+
+ if (!constraintId)
+ return;
+
+ int dof = 0;
+ int dof_max = 0;
+ int dofbit = 0;
+
+ switch (dat->type) {
+ /* Set all the limits for generic 6DOF constraint. */
+ case PHY_GENERIC_6DOF_CONSTRAINT:
+ dof_max = 6;
+ dofbit = 1;
+ break;
+ /* Set XYZ angular limits for cone twist constraint. */
+ case PHY_CONE_TWIST_CONSTRAINT:
+ dof = 3;
+ dof_max = 6;
+ dofbit = 1 << 3;
+ break;
+ /* Set only X angular limits for line hinge and angular constraint. */
+ case PHY_LINEHINGE_CONSTRAINT:
+ case PHY_ANGULAR_CONSTRAINT:
+ dof = 3;
+ dof_max = 4;
+ dofbit = 1 << 3;
+ break;
+ default:
+ break;
+ }
+
+ for (; dof < dof_max; dof++) {
+ if (dat->flag & dofbit) {
+ phys_env->SetConstraintParam(constraintId, dof, dat->minLimit[dof], dat->maxLimit[dof]);
+ }
+ else {
+ /* minLimit > maxLimit means free (no limit) for this degree of freedom. */
+ phys_env->SetConstraintParam(constraintId, dof, 1.0f, -1.0f);
+ }
+ dofbit <<= 1;
+ }
+
+}
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
index ff8a3f4f9f9..94aea215478 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
@@ -22,6 +22,8 @@ subject to the following restrictions:
#define __CCDPHYSICSENVIRONMENT_H__
#include "PHY_IPhysicsEnvironment.h"
+#include "KX_KetsjiEngine.h"
+
#include <vector>
#include <set>
#include <map>
@@ -52,6 +54,7 @@ class btOverlappingPairCache;
class btIDebugDraw;
class PHY_IVehicle;
class CcdOverlapFilterCallBack;
+class CcdShapeConstructionInfo;
/** CcdPhysicsEnvironment is an experimental mainloop for physics simulation using optional continuous collision detection.
* Physics Environment takes care of stepping the simulation and is a container for physics entities.
@@ -131,8 +134,7 @@ protected:
virtual void SetFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep)
{
- //based on DEFAULT_PHYSICS_TIC_RATE of 60 hertz
- SetNumTimeSubSteps((int)(fixedTimeStep / 60.f));
+ SetNumTimeSubSteps((int)(fixedTimeStep / KX_KetsjiEngine::GetTicRate()));
}
//returns 0.f if no fixed timestep is used
@@ -220,16 +222,22 @@ protected:
void UpdateCcdPhysicsController(CcdPhysicsController* ctrl, btScalar newMass, int newCollisionFlags, short int newCollisionGroup, short int newCollisionMask);
- void DisableCcdPhysicsController(CcdPhysicsController* ctrl);
-
- void EnableCcdPhysicsController(CcdPhysicsController* ctrl);
-
void RefreshCcdPhysicsController(CcdPhysicsController* ctrl);
+ bool IsActiveCcdPhysicsController(CcdPhysicsController *ctrl);
+
void AddCcdGraphicController(CcdGraphicController* ctrl);
void RemoveCcdGraphicController(CcdGraphicController* ctrl);
+ /**
+ * Update all physics controllers shape which use the same shape construction info.
+ * Call RecreateControllerShape on controllers which use the same shape
+ * construction info that argument shapeInfo.
+ * You need to call this function when the shape construction info changed.
+ */
+ void UpdateCcdPhysicsControllerShape(CcdShapeConstructionInfo *shapeInfo);
+
btBroadphaseInterface* GetBroadphase();
btDbvtBroadphase* GetCullingTree() { return m_cullingTree; }
@@ -274,6 +282,10 @@ protected:
bool isCompoundChild,
bool hasCompoundChildren);
+ /* Set the rigid body joints constraints values for converted objects and replicated group instances. */
+ virtual void SetupObjectConstraints(KX_GameObject *obj_src, KX_GameObject *obj_dest,
+ bRigidBodyJointConstraint *dat);
+
protected: