Blender V2.61 - r43446
|
00001 00004 /* 00005 Bullet Continuous Collision Detection and Physics Library 00006 Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ 00007 00008 This software is provided 'as-is', without any express or implied warranty. 00009 In no event will the authors be held liable for any damages arising from the use of this software. 00010 Permission is granted to anyone to use this software for any purpose, 00011 including commercial applications, and to alter it and redistribute it freely, 00012 subject to the following restrictions: 00013 00014 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 00015 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 00016 3. This notice may not be removed or altered from any source distribution. 00017 */ 00018 00019 #ifndef WIN32 00020 #include <stdint.h> 00021 #endif 00022 00023 #include "CcdPhysicsController.h" 00024 #include "btBulletDynamicsCommon.h" 00025 #include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h" 00026 00027 #include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h" 00028 00029 #include "PHY_IMotionState.h" 00030 #include "CcdPhysicsEnvironment.h" 00031 #include "RAS_MeshObject.h" 00032 #include "KX_GameObject.h" 00033 00034 #include "BulletSoftBody/btSoftBody.h" 00035 #include "BulletSoftBody//btSoftBodyInternals.h" 00036 #include "BulletSoftBody/btSoftBodyHelpers.h" 00037 #include "LinearMath/btConvexHull.h" 00038 #include "BulletCollision/Gimpact/btGImpactShape.h" 00039 #include "BulletCollision/Gimpact/btGImpactShape.h" 00040 00041 00042 #include "BulletSoftBody/btSoftRigidDynamicsWorld.h" 00043 00044 #include "DNA_mesh_types.h" 00045 #include "DNA_meshdata_types.h" 00046 00047 extern "C"{ 00048 #include "BKE_cdderivedmesh.h" 00049 } 00050 00051 class BP_Proxy; 00052 00054 00055 //'temporarily' global variables 00056 //float gDeactivationTime = 2.f; 00057 //bool gDisableDeactivation = false; 00058 extern float gDeactivationTime; 00059 extern bool gDisableDeactivation; 00060 00061 00062 float gLinearSleepingTreshold = 0.8f; 00063 float gAngularSleepingTreshold = 1.0f; 00064 00065 00066 btVector3 startVel(0,0,0);//-10000); 00067 00068 CcdPhysicsController::CcdPhysicsController (const CcdConstructionInfo& ci) 00069 :m_cci(ci) 00070 { 00071 m_prototypeTransformInitialized = false; 00072 m_softbodyMappingDone = false; 00073 m_collisionDelay = 0; 00074 m_newClientInfo = 0; 00075 m_registerCount = 0; 00076 m_softBodyTransformInitialized = false; 00077 m_parentCtrl = 0; 00078 // copy pointers locally to allow smart release 00079 m_MotionState = ci.m_MotionState; 00080 m_collisionShape = ci.m_collisionShape; 00081 // apply scaling before creating rigid body 00082 m_collisionShape->setLocalScaling(m_cci.m_scaling); 00083 if (m_cci.m_mass) 00084 m_collisionShape->calculateLocalInertia(m_cci.m_mass, m_cci.m_localInertiaTensor); 00085 // shape info is shared, increment ref count 00086 m_shapeInfo = ci.m_shapeInfo; 00087 if (m_shapeInfo) 00088 m_shapeInfo->AddRef(); 00089 00090 m_bulletMotionState = 0; 00091 00092 00093 CreateRigidbody(); 00094 00095 00097 /*#ifdef WIN32 00098 if (GetRigidBody() && !GetRigidBody()->isStaticObject()) 00099 GetRigidBody()->setLinearVelocity(startVel); 00100 #endif*/ 00101 00102 } 00103 00104 btTransform& CcdPhysicsController::GetTransformFromMotionState(PHY_IMotionState* motionState) 00105 { 00106 static btTransform trans; 00107 btVector3 tmp; 00108 motionState->getWorldPosition(tmp.m_floats[0], tmp.m_floats[1], tmp.m_floats[2]); 00109 trans.setOrigin(tmp); 00110 00111 float ori[12]; 00112 motionState->getWorldOrientation(ori); 00113 trans.getBasis().setFromOpenGLSubMatrix(ori); 00114 //btQuaternion orn; 00115 //motionState->getWorldOrientation(orn[0],orn[1],orn[2],orn[3]); 00116 //trans.setRotation(orn); 00117 return trans; 00118 00119 } 00120 00121 class BlenderBulletMotionState : public btMotionState 00122 { 00123 PHY_IMotionState* m_blenderMotionState; 00124 00125 public: 00126 00127 BlenderBulletMotionState(PHY_IMotionState* bms) 00128 :m_blenderMotionState(bms) 00129 { 00130 00131 } 00132 00133 void getWorldTransform(btTransform& worldTrans ) const 00134 { 00135 btVector3 pos; 00136 float ori[12]; 00137 00138 m_blenderMotionState->getWorldPosition(pos.m_floats[0],pos.m_floats[1],pos.m_floats[2]); 00139 m_blenderMotionState->getWorldOrientation(ori); 00140 worldTrans.setOrigin(pos); 00141 worldTrans.getBasis().setFromOpenGLSubMatrix(ori); 00142 } 00143 00144 void setWorldTransform(const btTransform& worldTrans) 00145 { 00146 m_blenderMotionState->setWorldPosition(worldTrans.getOrigin().getX(),worldTrans.getOrigin().getY(),worldTrans.getOrigin().getZ()); 00147 btQuaternion rotQuat = worldTrans.getRotation(); 00148 m_blenderMotionState->setWorldOrientation(rotQuat[0],rotQuat[1],rotQuat[2],rotQuat[3]); 00149 m_blenderMotionState->calculateWorldTransformations(); 00150 } 00151 00152 }; 00153 00154 00155 btRigidBody* CcdPhysicsController::GetRigidBody() 00156 { 00157 return btRigidBody::upcast(m_object); 00158 } 00159 btCollisionObject* CcdPhysicsController::GetCollisionObject() 00160 { 00161 return m_object; 00162 } 00163 btSoftBody* CcdPhysicsController::GetSoftBody() 00164 { 00165 return btSoftBody::upcast(m_object); 00166 } 00167 00168 #include "BulletSoftBody/btSoftBodyHelpers.h" 00169 00170 00171 bool CcdPhysicsController::CreateSoftbody() 00172 { 00173 int shapeType = m_cci.m_collisionShape ? m_cci.m_collisionShape->getShapeType() : 0; 00174 00175 //disable soft body until first sneak preview is ready 00176 if (!m_cci.m_bSoft || !m_cci.m_collisionShape || 00177 ((shapeType != CONVEX_HULL_SHAPE_PROXYTYPE)&& 00178 (shapeType != TRIANGLE_MESH_SHAPE_PROXYTYPE) && 00179 (shapeType != SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE))) 00180 { 00181 return false; 00182 } 00183 00184 btRigidBody::btRigidBodyConstructionInfo rbci(m_cci.m_mass,m_bulletMotionState,m_collisionShape,m_cci.m_localInertiaTensor * m_cci.m_inertiaFactor); 00185 rbci.m_linearDamping = m_cci.m_linearDamping; 00186 rbci.m_angularDamping = m_cci.m_angularDamping; 00187 rbci.m_friction = m_cci.m_friction; 00188 rbci.m_restitution = m_cci.m_restitution; 00189 00190 btVector3 p(0,0,0);// = getOrigin(); 00191 //btSoftBody* psb=btSoftBodyHelpers::CreateRope(worldInfo, btVector3(-10,0,i*0.25),btVector3(10,0,i*0.25), 16,1+2); 00192 btSoftBody* psb = 0; 00193 btSoftBodyWorldInfo& worldInfo = m_cci.m_physicsEnv->getDynamicsWorld()->getWorldInfo(); 00194 00195 if (m_cci.m_collisionShape->getShapeType() == CONVEX_HULL_SHAPE_PROXYTYPE) 00196 { 00197 btConvexHullShape* convexHull = (btConvexHullShape* )m_cci.m_collisionShape; 00198 { 00199 int nvertices = convexHull->getNumPoints(); 00200 const btVector3* vertices = convexHull->getPoints(); 00201 00202 HullDesc hdsc(QF_TRIANGLES,nvertices,vertices); 00203 HullResult hres; 00204 HullLibrary hlib;/*??*/ 00205 hdsc.mMaxVertices=nvertices; 00206 hlib.CreateConvexHull(hdsc,hres); 00207 00208 psb=new btSoftBody(&worldInfo,(int)hres.mNumOutputVertices, 00209 &hres.m_OutputVertices[0],0); 00210 for(int i=0;i<(int)hres.mNumFaces;++i) 00211 { 00212 const int idx[]={ hres.m_Indices[i*3+0], 00213 hres.m_Indices[i*3+1], 00214 hres.m_Indices[i*3+2]}; 00215 if(idx[0]<idx[1]) psb->appendLink( idx[0],idx[1]); 00216 if(idx[1]<idx[2]) psb->appendLink( idx[1],idx[2]); 00217 if(idx[2]<idx[0]) psb->appendLink( idx[2],idx[0]); 00218 psb->appendFace(idx[0],idx[1],idx[2]); 00219 } 00220 hlib.ReleaseResult(hres); 00221 } 00222 } else 00223 { 00224 int numtris = 0; 00225 if (m_cci.m_collisionShape->getShapeType() ==SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE) 00226 { 00227 btScaledBvhTriangleMeshShape* scaledtrimeshshape = (btScaledBvhTriangleMeshShape*) m_cci.m_collisionShape; 00228 btBvhTriangleMeshShape* trimeshshape = scaledtrimeshshape->getChildShape(); 00229 00231 if (trimeshshape->getMeshInterface()->getNumSubParts()==1) 00232 { 00233 unsigned char* vertexBase; 00234 PHY_ScalarType vertexType; 00235 int numverts; 00236 int vertexstride; 00237 unsigned char* indexbase; 00238 int indexstride; 00239 PHY_ScalarType indexType; 00240 trimeshshape->getMeshInterface()->getLockedVertexIndexBase(&vertexBase,numverts,vertexType,vertexstride,&indexbase,indexstride,numtris,indexType); 00241 00242 psb = btSoftBodyHelpers::CreateFromTriMesh(worldInfo,(const btScalar*)vertexBase,(const int*)indexbase,numtris,false); 00243 } 00244 } else 00245 { 00246 btTriangleMeshShape* trimeshshape = (btTriangleMeshShape*) m_cci.m_collisionShape; 00248 if (trimeshshape->getMeshInterface()->getNumSubParts()==1) 00249 { 00250 unsigned char* vertexBase; 00251 PHY_ScalarType vertexType; 00252 int numverts; 00253 int vertexstride; 00254 unsigned char* indexbase; 00255 int indexstride; 00256 PHY_ScalarType indexType; 00257 trimeshshape->getMeshInterface()->getLockedVertexIndexBase(&vertexBase,numverts,vertexType,vertexstride,&indexbase,indexstride,numtris,indexType); 00258 00259 psb = btSoftBodyHelpers::CreateFromTriMesh(worldInfo,(const btScalar*)vertexBase,(const int*)indexbase,numtris,false); 00260 } 00261 } 00262 // store face tag so that we can find our original face when doing ray casting 00263 btSoftBody::Face* ft; 00264 int i; 00265 for (i=0, ft=&psb->m_faces[0]; i<numtris; ++i, ++ft) 00266 { 00267 // Hack!! use m_tag to store the face number, normally it is a pointer 00268 // add 1 to make sure it is never 0 00269 ft->m_tag = (void*)((uintptr_t)(i+1)); 00270 } 00271 } 00272 if (m_cci.m_margin > 0.f) 00273 { 00274 psb->getCollisionShape()->setMargin(m_cci.m_margin); 00275 psb->updateBounds(); 00276 } 00277 m_object = psb; 00278 00279 //btSoftBody::Material* pm=psb->appendMaterial(); 00280 btSoftBody::Material* pm=psb->m_materials[0]; 00281 pm->m_kLST = m_cci.m_soft_linStiff; 00282 pm->m_kAST = m_cci.m_soft_angStiff; 00283 pm->m_kVST = m_cci.m_soft_volume; 00284 psb->m_cfg.collisions = 0; 00285 00286 if (m_cci.m_soft_collisionflags & CCD_BSB_COL_CL_RS) 00287 { 00288 psb->m_cfg.collisions += btSoftBody::fCollision::CL_RS; 00289 } else 00290 { 00291 psb->m_cfg.collisions += btSoftBody::fCollision::SDF_RS; 00292 } 00293 if (m_cci.m_soft_collisionflags & CCD_BSB_COL_CL_SS) 00294 { 00295 psb->m_cfg.collisions += btSoftBody::fCollision::CL_SS; 00296 } else 00297 { 00298 psb->m_cfg.collisions += btSoftBody::fCollision::VF_SS; 00299 } 00300 00301 00302 psb->m_cfg.kSRHR_CL = m_cci.m_soft_kSRHR_CL; /* Soft vs rigid hardness [0,1] (cluster only) */ 00303 psb->m_cfg.kSKHR_CL = m_cci.m_soft_kSKHR_CL; /* Soft vs kinetic hardness [0,1] (cluster only) */ 00304 psb->m_cfg.kSSHR_CL = m_cci.m_soft_kSSHR_CL; /* Soft vs soft hardness [0,1] (cluster only) */ 00305 psb->m_cfg.kSR_SPLT_CL = m_cci.m_soft_kSR_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */ 00306 00307 psb->m_cfg.kSK_SPLT_CL = m_cci.m_soft_kSK_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */ 00308 psb->m_cfg.kSS_SPLT_CL = m_cci.m_soft_kSS_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */ 00309 psb->m_cfg.kVCF = m_cci.m_soft_kVCF; /* Velocities correction factor (Baumgarte) */ 00310 psb->m_cfg.kDP = m_cci.m_soft_kDP; /* Damping coefficient [0,1] */ 00311 00312 psb->m_cfg.kDG = m_cci.m_soft_kDG; /* Drag coefficient [0,+inf] */ 00313 psb->m_cfg.kLF = m_cci.m_soft_kLF; /* Lift coefficient [0,+inf] */ 00314 psb->m_cfg.kPR = m_cci.m_soft_kPR; /* Pressure coefficient [-inf,+inf] */ 00315 psb->m_cfg.kVC = m_cci.m_soft_kVC; /* Volume conversation coefficient [0,+inf] */ 00316 00317 psb->m_cfg.kDF = m_cci.m_soft_kDF; /* Dynamic friction coefficient [0,1] */ 00318 psb->m_cfg.kMT = m_cci.m_soft_kMT; /* Pose matching coefficient [0,1] */ 00319 psb->m_cfg.kCHR = m_cci.m_soft_kCHR; /* Rigid contacts hardness [0,1] */ 00320 psb->m_cfg.kKHR = m_cci.m_soft_kKHR; /* Kinetic contacts hardness [0,1] */ 00321 00322 psb->m_cfg.kSHR = m_cci.m_soft_kSHR; /* Soft contacts hardness [0,1] */ 00323 psb->m_cfg.kAHR = m_cci.m_soft_kAHR; /* Anchors hardness [0,1] */ 00324 00325 if (m_cci.m_gamesoftFlag & CCD_BSB_BENDING_CONSTRAINTS)//OB_SB_GOAL) 00326 { 00327 psb->generateBendingConstraints(2,pm); 00328 } 00329 00330 psb->m_cfg.piterations = m_cci.m_soft_piterations; 00331 psb->m_cfg.viterations = m_cci.m_soft_viterations; 00332 psb->m_cfg.diterations = m_cci.m_soft_diterations; 00333 psb->m_cfg.citerations = m_cci.m_soft_citerations; 00334 00335 if (m_cci.m_gamesoftFlag & CCD_BSB_SHAPE_MATCHING)//OB_SB_GOAL) 00336 { 00337 psb->setPose(false,true);// 00338 } else 00339 { 00340 psb->setPose(true,false); 00341 } 00342 00343 psb->randomizeConstraints(); 00344 00345 if (m_cci.m_soft_collisionflags & (CCD_BSB_COL_CL_RS+CCD_BSB_COL_CL_SS)) 00346 { 00347 psb->generateClusters(m_cci.m_soft_numclusteriterations); 00348 } 00349 00350 psb->setTotalMass(m_cci.m_mass); 00351 00352 psb->setCollisionFlags(0); 00353 00355 { 00356 RAS_MeshObject* rasMesh= GetShapeInfo()->GetMesh(); 00357 00358 if (rasMesh && !m_softbodyMappingDone) 00359 { 00360 //printf("apply\n"); 00361 RAS_MeshSlot::iterator it; 00362 RAS_MeshMaterial *mmat; 00363 RAS_MeshSlot *slot; 00364 size_t i; 00365 00366 //for each material 00367 for (int m=0;m<rasMesh->NumMaterials();m++) 00368 { 00369 mmat = rasMesh->GetMeshMaterial(m); 00370 00371 slot = mmat->m_baseslot; 00372 for(slot->begin(it); !slot->end(it); slot->next(it)) 00373 { 00374 int index = 0; 00375 for(i=it.startvertex; i<it.endvertex; i++,index++) 00376 { 00377 RAS_TexVert* vertex = &it.vertex[i]; 00378 //search closest index, and store it in vertex 00379 vertex->setSoftBodyIndex(0); 00380 btScalar maxDistSqr = 1e30; 00381 btSoftBody::tNodeArray& nodes(psb->m_nodes); 00382 btVector3 xyz = btVector3(vertex->getXYZ()[0],vertex->getXYZ()[1],vertex->getXYZ()[2]); 00383 for (int n=0;n<nodes.size();n++) 00384 { 00385 btScalar distSqr = (nodes[n].m_x - xyz).length2(); 00386 if (distSqr<maxDistSqr) 00387 { 00388 maxDistSqr = distSqr; 00389 00390 vertex->setSoftBodyIndex(n); 00391 } 00392 } 00393 } 00394 } 00395 } 00396 } 00397 } 00398 m_softbodyMappingDone = true; 00399 00400 btTransform startTrans; 00401 rbci.m_motionState->getWorldTransform(startTrans); 00402 00403 m_MotionState->setWorldPosition(startTrans.getOrigin().getX(),startTrans.getOrigin().getY(),startTrans.getOrigin().getZ()); 00404 m_MotionState->setWorldOrientation(0,0,0,1); 00405 00406 if (!m_prototypeTransformInitialized) 00407 { 00408 m_prototypeTransformInitialized = true; 00409 m_softBodyTransformInitialized = true; 00410 psb->transform(startTrans); 00411 } 00412 m_object->setCollisionFlags(m_object->getCollisionFlags() | m_cci.m_collisionFlags); 00413 if (m_cci.m_do_anisotropic) 00414 m_object->setAnisotropicFriction(m_cci.m_anisotropicFriction); 00415 return true; 00416 } 00417 00418 00419 void CcdPhysicsController::CreateRigidbody() 00420 { 00421 00422 //btTransform trans = GetTransformFromMotionState(m_MotionState); 00423 m_bulletMotionState = new BlenderBulletMotionState(m_MotionState); 00424 00426 if (CreateSoftbody()) 00427 // soft body created, done 00428 return; 00429 00430 //create a rgid collision object 00431 btRigidBody::btRigidBodyConstructionInfo rbci(m_cci.m_mass,m_bulletMotionState,m_collisionShape,m_cci.m_localInertiaTensor * m_cci.m_inertiaFactor); 00432 rbci.m_linearDamping = m_cci.m_linearDamping; 00433 rbci.m_angularDamping = m_cci.m_angularDamping; 00434 rbci.m_friction = m_cci.m_friction; 00435 rbci.m_restitution = m_cci.m_restitution; 00436 m_object = new btRigidBody(rbci); 00437 00438 // 00439 // init the rigidbody properly 00440 // 00441 00442 //setMassProps this also sets collisionFlags 00443 //convert collision flags! 00444 //special case: a near/radar sensor controller should not be defined static or it will 00445 //generate loads of static-static collision messages on the console 00446 if (m_cci.m_bSensor) 00447 { 00448 // reset the flags that have been set so far 00449 GetCollisionObject()->setCollisionFlags(0); 00450 // sensor must never go to sleep: they need to detect continously 00451 GetCollisionObject()->setActivationState(DISABLE_DEACTIVATION); 00452 } 00453 GetCollisionObject()->setCollisionFlags(m_object->getCollisionFlags() | m_cci.m_collisionFlags); 00454 btRigidBody* body = GetRigidBody(); 00455 00456 if (body) 00457 { 00458 body->setGravity( m_cci.m_gravity); 00459 body->setDamping(m_cci.m_linearDamping, m_cci.m_angularDamping); 00460 00461 if (!m_cci.m_bRigid) 00462 { 00463 body->setAngularFactor(0.f); 00464 } 00465 body->setContactProcessingThreshold(m_cci.m_contactProcessingThreshold); 00466 00467 } 00468 if (m_object && m_cci.m_do_anisotropic) 00469 { 00470 m_object->setAnisotropicFriction(m_cci.m_anisotropicFriction); 00471 } 00472 00473 } 00474 00475 static void DeleteBulletShape(btCollisionShape* shape, bool free) 00476 { 00477 if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) 00478 { 00479 // shapes based on meshes use an interface that contains the vertices. 00480 btTriangleMeshShape* meshShape = static_cast<btTriangleMeshShape*>(shape); 00481 btStridingMeshInterface* meshInterface = meshShape->getMeshInterface(); 00482 if (meshInterface) 00483 delete meshInterface; 00484 } 00485 if(free) { 00486 delete shape; 00487 } 00488 } 00489 00490 bool CcdPhysicsController::DeleteControllerShape( ) 00491 { 00492 if (m_collisionShape) 00493 { 00494 // collision shape is always unique to the controller, can delete it here 00495 if (m_collisionShape->isCompound()) 00496 { 00497 // bullet does not delete the child shape, must do it here 00498 btCompoundShape* compoundShape = (btCompoundShape*)m_collisionShape; 00499 int numChild = compoundShape->getNumChildShapes(); 00500 for (int i=numChild-1 ; i >= 0; i--) 00501 { 00502 btCollisionShape* childShape = compoundShape->getChildShape(i); 00503 DeleteBulletShape(childShape, true); 00504 } 00505 } 00506 DeleteBulletShape(m_collisionShape, true); 00507 00508 return true; 00509 } 00510 00511 return false; 00512 } 00513 00514 bool CcdPhysicsController::ReplaceControllerShape(btCollisionShape *newShape) 00515 { 00516 00517 /* Note, deleting the previous collision shape must be done already */ 00518 /* if (m_collisionShape) DeleteControllerShape(); */ 00519 00520 m_object->setCollisionShape(newShape); 00521 m_collisionShape= newShape; 00522 m_cci.m_collisionShape= newShape; 00523 00524 if (GetSoftBody()) { 00525 // soft body must be recreated 00526 m_cci.m_physicsEnv->removeCcdPhysicsController(this); 00527 delete m_object; 00528 m_object = NULL; 00529 // force complete reinitialization 00530 m_softbodyMappingDone = false; 00531 m_prototypeTransformInitialized = false; 00532 m_softBodyTransformInitialized = false; 00533 CreateSoftbody(); 00534 assert(m_object); 00535 // reinsert the new body 00536 m_cci.m_physicsEnv->addCcdPhysicsController(this); 00537 } 00538 00539 /* Copied from CcdPhysicsEnvironment::addCcdPhysicsController() */ 00540 00541 /* without this, an object can rest on the old physics mesh 00542 * and not move to account for the physics mesh, even with 'nosleep' */ 00543 btSoftRigidDynamicsWorld* dw= GetPhysicsEnvironment()->getDynamicsWorld(); 00544 btCollisionObjectArray &obarr= dw->getCollisionObjectArray(); 00545 btCollisionObject *ob; 00546 btBroadphaseProxy* proxy; 00547 00548 for(int i= 0; i < obarr.size(); i++) { 00549 ob= obarr[i]; 00550 if (ob->getCollisionShape() == newShape) { 00551 proxy = ob->getBroadphaseHandle(); 00552 00553 if(proxy) 00554 dw->getPairCache()->cleanProxyFromPairs(proxy,dw->getDispatcher()); 00555 } 00556 } 00557 00558 return true; 00559 } 00560 00561 CcdPhysicsController::~CcdPhysicsController() 00562 { 00563 //will be reference counted, due to sharing 00564 if (m_cci.m_physicsEnv) 00565 m_cci.m_physicsEnv->removeCcdPhysicsController(this); 00566 00567 if (m_MotionState) 00568 delete m_MotionState; 00569 if (m_bulletMotionState) 00570 delete m_bulletMotionState; 00571 delete m_object; 00572 00573 DeleteControllerShape(); 00574 00575 if (m_shapeInfo) 00576 { 00577 m_shapeInfo->Release(); 00578 } 00579 } 00580 00581 00585 bool CcdPhysicsController::SynchronizeMotionStates(float time) 00586 { 00587 //sync non-static to motionstate, and static from motionstate (todo: add kinematic etc.) 00588 00589 btSoftBody* sb = GetSoftBody(); 00590 if (sb) 00591 { 00592 if (sb->m_pose.m_bframe) 00593 { 00594 btVector3 worldPos = sb->m_pose.m_com; 00595 btQuaternion worldquat; 00596 btMatrix3x3 trs = sb->m_pose.m_rot*sb->m_pose.m_scl; 00597 trs.getRotation(worldquat); 00598 m_MotionState->setWorldPosition(worldPos[0],worldPos[1],worldPos[2]); 00599 m_MotionState->setWorldOrientation(worldquat[0],worldquat[1],worldquat[2],worldquat[3]); 00600 } 00601 else 00602 { 00603 btVector3 aabbMin,aabbMax; 00604 sb->getAabb(aabbMin,aabbMax); 00605 btVector3 worldPos = (aabbMax+aabbMin)*0.5f; 00606 m_MotionState->setWorldPosition(worldPos[0],worldPos[1],worldPos[2]); 00607 } 00608 m_MotionState->calculateWorldTransformations(); 00609 return true; 00610 } 00611 00612 btRigidBody* body = GetRigidBody(); 00613 00614 if (body && !body->isStaticObject()) 00615 { 00616 00617 if ((m_cci.m_clamp_vel_max>0.0) || (m_cci.m_clamp_vel_min>0.0)) 00618 { 00619 const btVector3& linvel = body->getLinearVelocity(); 00620 float len= linvel.length(); 00621 00622 if((m_cci.m_clamp_vel_max>0.0) && (len > m_cci.m_clamp_vel_max)) 00623 body->setLinearVelocity(linvel * (m_cci.m_clamp_vel_max / len)); 00624 00625 else if ((m_cci.m_clamp_vel_min>0.0) && btFuzzyZero(len)==0 && (len < m_cci.m_clamp_vel_min)) 00626 body->setLinearVelocity(linvel * (m_cci.m_clamp_vel_min / len)); 00627 } 00628 00629 const btTransform& xform = body->getCenterOfMassTransform(); 00630 const btMatrix3x3& worldOri = xform.getBasis(); 00631 const btVector3& worldPos = xform.getOrigin(); 00632 float ori[12]; 00633 worldOri.getOpenGLSubMatrix(ori); 00634 m_MotionState->setWorldOrientation(ori); 00635 m_MotionState->setWorldPosition(worldPos[0],worldPos[1],worldPos[2]); 00636 m_MotionState->calculateWorldTransformations(); 00637 00638 float scale[3]; 00639 m_MotionState->getWorldScaling(scale[0],scale[1],scale[2]); 00640 btVector3 scaling(scale[0],scale[1],scale[2]); 00641 GetCollisionShape()->setLocalScaling(scaling); 00642 } else 00643 { 00644 btVector3 worldPos; 00645 btQuaternion worldquat; 00646 00647 /* m_MotionState->getWorldPosition(worldPos[0],worldPos[1],worldPos[2]); 00648 m_MotionState->getWorldOrientation(worldquat[0],worldquat[1],worldquat[2],worldquat[3]); 00649 btTransform oldTrans = m_body->getCenterOfMassTransform(); 00650 btTransform newTrans(worldquat,worldPos); 00651 00652 SetCenterOfMassTransform(newTrans); 00653 //need to keep track of previous position for friction effects... 00654 00655 m_MotionState->calculateWorldTransformations(); 00656 */ 00657 float scale[3]; 00658 m_MotionState->getWorldScaling(scale[0],scale[1],scale[2]); 00659 btVector3 scaling(scale[0],scale[1],scale[2]); 00660 GetCollisionShape()->setLocalScaling(scaling); 00661 } 00662 return true; 00663 00664 } 00665 00670 void CcdPhysicsController::WriteMotionStateToDynamics(bool nondynaonly) 00671 { 00672 btTransform& xform = CcdPhysicsController::GetTransformFromMotionState(m_MotionState); 00673 SetCenterOfMassTransform(xform); 00674 } 00675 00676 void CcdPhysicsController::WriteDynamicsToMotionState() 00677 { 00678 } 00679 // controller replication 00680 void CcdPhysicsController::PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl) 00681 { 00682 00683 m_softBodyTransformInitialized=false; 00684 m_MotionState = motionstate; 00685 m_registerCount = 0; 00686 m_collisionShape = NULL; 00687 00688 // always create a new shape to avoid scaling bug 00689 if (m_shapeInfo) 00690 { 00691 m_shapeInfo->AddRef(); 00692 m_collisionShape = m_shapeInfo->CreateBulletShape(m_cci.m_margin, m_cci.m_bGimpact, !m_cci.m_bSoft); 00693 00694 if (m_collisionShape) 00695 { 00696 // new shape has no scaling, apply initial scaling 00697 //m_collisionShape->setMargin(m_cci.m_margin); 00698 m_collisionShape->setLocalScaling(m_cci.m_scaling); 00699 00700 if (m_cci.m_mass) 00701 m_collisionShape->calculateLocalInertia(m_cci.m_mass, m_cci.m_localInertiaTensor); 00702 } 00703 } 00704 00705 // load some characterists that are not 00706 btRigidBody* oldbody = GetRigidBody(); 00707 m_object = 0; 00708 CreateRigidbody(); 00709 btRigidBody* body = GetRigidBody(); 00710 if (body) 00711 { 00712 if (m_cci.m_mass) 00713 { 00714 body->setMassProps(m_cci.m_mass, m_cci.m_localInertiaTensor * m_cci.m_inertiaFactor); 00715 } 00716 00717 if (oldbody) 00718 { 00719 body->setLinearFactor(oldbody->getLinearFactor()); 00720 body->setAngularFactor(oldbody->getAngularFactor()); 00721 if (oldbody->getActivationState() == DISABLE_DEACTIVATION) 00722 body->setActivationState(DISABLE_DEACTIVATION); 00723 } 00724 } 00725 // sensor object are added when needed 00726 if (!m_cci.m_bSensor) 00727 m_cci.m_physicsEnv->addCcdPhysicsController(this); 00728 00729 00730 /* SM_Object* dynaparent=0; 00731 SumoPhysicsController* sumoparentctrl = (SumoPhysicsController* )parentctrl; 00732 00733 if (sumoparentctrl) 00734 { 00735 dynaparent = sumoparentctrl->GetSumoObject(); 00736 } 00737 00738 SM_Object* orgsumoobject = m_sumoObj; 00739 00740 00741 m_sumoObj = new SM_Object( 00742 orgsumoobject->getShapeHandle(), 00743 orgsumoobject->getMaterialProps(), 00744 orgsumoobject->getShapeProps(), 00745 dynaparent); 00746 00747 m_sumoObj->setRigidBody(orgsumoobject->isRigidBody()); 00748 00749 m_sumoObj->setMargin(orgsumoobject->getMargin()); 00750 m_sumoObj->setPosition(orgsumoobject->getPosition()); 00751 m_sumoObj->setOrientation(orgsumoobject->getOrientation()); 00752 //if it is a dyna, register for a callback 00753 m_sumoObj->registerCallback(*this); 00754 00755 m_sumoScene->add(* (m_sumoObj)); 00756 */ 00757 00758 00759 00760 } 00761 00762 void CcdPhysicsController::SetPhysicsEnvironment(class PHY_IPhysicsEnvironment *env) 00763 { 00764 // can safely assume CCD environment 00765 CcdPhysicsEnvironment *physicsEnv = static_cast<CcdPhysicsEnvironment*>(env); 00766 00767 if (m_cci.m_physicsEnv != physicsEnv) 00768 { 00769 // since the environment is changing, we must also move the controler to the 00770 // new environment. Note that we don't handle sensor explicitly: this 00771 // function can be called on sensor but only when they are not registered 00772 if (m_cci.m_physicsEnv->removeCcdPhysicsController(this)) 00773 { 00774 physicsEnv->addCcdPhysicsController(this); 00775 } 00776 m_cci.m_physicsEnv = physicsEnv; 00777 } 00778 } 00779 00780 void CcdPhysicsController::SetCenterOfMassTransform(btTransform& xform) 00781 { 00782 btRigidBody* body = GetRigidBody(); 00783 if (body) 00784 { 00785 body->setCenterOfMassTransform(xform); 00786 } else 00787 { 00788 //either collision object or soft body? 00789 if (GetSoftBody()) 00790 { 00791 00792 } else 00793 { 00794 00795 if (m_object->isStaticOrKinematicObject()) 00796 { 00797 m_object->setInterpolationWorldTransform(m_object->getWorldTransform()); 00798 } else 00799 { 00800 m_object->setInterpolationWorldTransform(xform); 00801 } 00802 if (body) 00803 { 00804 body->setInterpolationLinearVelocity(body->getLinearVelocity()); 00805 body->setInterpolationAngularVelocity(body->getAngularVelocity()); 00806 body->updateInertiaTensor(); 00807 } 00808 m_object->setWorldTransform(xform); 00809 } 00810 } 00811 } 00812 00813 // kinematic methods 00814 void CcdPhysicsController::RelativeTranslate(float dlocX,float dlocY,float dlocZ,bool local) 00815 { 00816 if (m_object) 00817 { 00818 m_object->activate(true); 00819 if (m_object->isStaticObject()) 00820 { 00821 if (!m_cci.m_bSensor) 00822 m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); 00823 // kinematic object should not set the transform, it disturbs the velocity interpolation 00824 return; 00825 } 00826 00827 // btRigidBody* body = GetRigidBody(); // not used anymore 00828 00829 btVector3 dloc(dlocX,dlocY,dlocZ); 00830 btTransform xform = m_object->getWorldTransform(); 00831 00832 if (local) 00833 { 00834 dloc = xform.getBasis()*dloc; 00835 } 00836 00837 xform.setOrigin(xform.getOrigin() + dloc); 00838 SetCenterOfMassTransform(xform); 00839 } 00840 00841 } 00842 00843 void CcdPhysicsController::RelativeRotate(const float rotval[9],bool local) 00844 { 00845 if (m_object) 00846 { 00847 m_object->activate(true); 00848 if (m_object->isStaticObject()) 00849 { 00850 if (!m_cci.m_bSensor) 00851 m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); 00852 // kinematic object should not set the transform, it disturbs the velocity interpolation 00853 return; 00854 } 00855 00856 btMatrix3x3 drotmat( rotval[0],rotval[4],rotval[8], 00857 rotval[1],rotval[5],rotval[9], 00858 rotval[2],rotval[6],rotval[10]); 00859 00860 00861 btMatrix3x3 currentOrn; 00862 GetWorldOrientation(currentOrn); 00863 00864 btTransform xform = m_object->getWorldTransform(); 00865 00866 xform.setBasis(xform.getBasis()*(local ? 00867 drotmat : (currentOrn.inverse() * drotmat * currentOrn))); 00868 00869 SetCenterOfMassTransform(xform); 00870 } 00871 } 00872 00873 00874 void CcdPhysicsController::GetWorldOrientation(btMatrix3x3& mat) 00875 { 00876 float ori[12]; 00877 m_MotionState->getWorldOrientation(ori); 00878 mat.setFromOpenGLSubMatrix(ori); 00879 } 00880 00881 void CcdPhysicsController::getOrientation(float &quatImag0,float &quatImag1,float &quatImag2,float &quatReal) 00882 { 00883 btQuaternion q = m_object->getWorldTransform().getRotation(); 00884 quatImag0 = q[0]; 00885 quatImag1 = q[1]; 00886 quatImag2 = q[2]; 00887 quatReal = q[3]; 00888 } 00889 void CcdPhysicsController::setOrientation(float quatImag0,float quatImag1,float quatImag2,float quatReal) 00890 { 00891 if (m_object) 00892 { 00893 m_object->activate(true); 00894 if (m_object->isStaticObject()) 00895 { 00896 if (!m_cci.m_bSensor) 00897 m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); 00898 // kinematic object should not set the transform, it disturbs the velocity interpolation 00899 return; 00900 } 00901 // not required 00902 //m_MotionState->setWorldOrientation(quatImag0,quatImag1,quatImag2,quatReal); 00903 btTransform xform = m_object->getWorldTransform(); 00904 xform.setRotation(btQuaternion(quatImag0,quatImag1,quatImag2,quatReal)); 00905 SetCenterOfMassTransform(xform); 00906 // not required 00907 //m_bulletMotionState->setWorldTransform(xform); 00908 00909 00910 00911 } 00912 00913 } 00914 00915 void CcdPhysicsController::setWorldOrientation(const btMatrix3x3& orn) 00916 { 00917 if (m_object) 00918 { 00919 m_object->activate(true); 00920 if (m_object->isStaticObject() && !m_cci.m_bSensor) 00921 { 00922 m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); 00923 } 00924 // not required 00925 //m_MotionState->setWorldOrientation(quatImag0,quatImag1,quatImag2,quatReal); 00926 btTransform xform = m_object->getWorldTransform(); 00927 xform.setBasis(orn); 00928 SetCenterOfMassTransform(xform); 00929 // not required 00930 //m_bulletMotionState->setWorldTransform(xform); 00931 //only once! 00932 if (!m_softBodyTransformInitialized && GetSoftBody()) 00933 { 00934 m_softbodyStartTrans.setBasis(orn); 00935 xform.setOrigin(m_softbodyStartTrans.getOrigin()); 00936 GetSoftBody()->transform(xform); 00937 m_softBodyTransformInitialized = true; 00938 } 00939 00940 } 00941 00942 } 00943 00944 void CcdPhysicsController::setPosition(float posX,float posY,float posZ) 00945 { 00946 if (m_object) 00947 { 00948 m_object->activate(true); 00949 if (m_object->isStaticObject()) 00950 { 00951 if (!m_cci.m_bSensor) 00952 m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); 00953 // kinematic object should not set the transform, it disturbs the velocity interpolation 00954 return; 00955 } 00956 // not required, this function is only used to update the physic controller 00957 //m_MotionState->setWorldPosition(posX,posY,posZ); 00958 btTransform xform = m_object->getWorldTransform(); 00959 xform.setOrigin(btVector3(posX,posY,posZ)); 00960 SetCenterOfMassTransform(xform); 00961 if (!m_softBodyTransformInitialized) 00962 m_softbodyStartTrans.setOrigin(xform.getOrigin()); 00963 // not required 00964 //m_bulletMotionState->setWorldTransform(xform); 00965 } 00966 } 00967 00968 void CcdPhysicsController::forceWorldTransform(const btMatrix3x3& mat, const btVector3& pos) 00969 { 00970 if (m_object) 00971 { 00972 btTransform& xform = m_object->getWorldTransform(); 00973 xform.setBasis(mat); 00974 xform.setOrigin(pos); 00975 } 00976 } 00977 00978 00979 void CcdPhysicsController::resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ) 00980 { 00981 } 00982 00983 void CcdPhysicsController::getPosition(PHY__Vector3& pos) const 00984 { 00985 const btTransform& xform = m_object->getWorldTransform(); 00986 pos[0] = xform.getOrigin().x(); 00987 pos[1] = xform.getOrigin().y(); 00988 pos[2] = xform.getOrigin().z(); 00989 } 00990 00991 void CcdPhysicsController::setScaling(float scaleX,float scaleY,float scaleZ) 00992 { 00993 if (!btFuzzyZero(m_cci.m_scaling.x()-scaleX) || 00994 !btFuzzyZero(m_cci.m_scaling.y()-scaleY) || 00995 !btFuzzyZero(m_cci.m_scaling.z()-scaleZ)) 00996 { 00997 m_cci.m_scaling = btVector3(scaleX,scaleY,scaleZ); 00998 00999 if (m_object && m_object->getCollisionShape()) 01000 { 01001 m_object->activate(true); // without this, sleeping objects scale wont be applied in bullet if python changes the scale - Campbell. 01002 m_object->getCollisionShape()->setLocalScaling(m_cci.m_scaling); 01003 01004 //printf("no inertia recalc for fixed objects with mass=0\n"); 01005 btRigidBody* body = GetRigidBody(); 01006 if (body && m_cci.m_mass) 01007 { 01008 body->getCollisionShape()->calculateLocalInertia(m_cci.m_mass, m_cci.m_localInertiaTensor); 01009 body->setMassProps(m_cci.m_mass, m_cci.m_localInertiaTensor * m_cci.m_inertiaFactor); 01010 } 01011 01012 } 01013 } 01014 } 01015 01016 // physics methods 01017 void CcdPhysicsController::ApplyTorque(float torqueX,float torqueY,float torqueZ,bool local) 01018 { 01019 btVector3 torque(torqueX,torqueY,torqueZ); 01020 btTransform xform = m_object->getWorldTransform(); 01021 01022 01023 if (m_object && torque.length2() > (SIMD_EPSILON*SIMD_EPSILON)) 01024 { 01025 btRigidBody* body = GetRigidBody(); 01026 m_object->activate(); 01027 if (m_object->isStaticObject()) 01028 { 01029 if (!m_cci.m_bSensor) 01030 m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); 01031 return; 01032 } 01033 if (local) 01034 { 01035 torque = xform.getBasis()*torque; 01036 } 01037 if (body) 01038 { 01039 if (m_cci.m_bRigid) 01040 { 01041 body->applyTorque(torque); 01042 } 01043 else 01044 { 01045 //workaround for incompatibility between 'DYNAMIC' game object, and angular factor 01046 //a DYNAMIC object has some inconsistency: it has no angular effect due to collisions, but still has torque 01047 const btVector3& angFac = body->getAngularFactor(); 01048 btVector3 tmpFac(1,1,1); 01049 body->setAngularFactor(tmpFac); 01050 body->applyTorque(torque); 01051 body->setAngularFactor(angFac); 01052 } 01053 } 01054 } 01055 } 01056 01057 void CcdPhysicsController::ApplyForce(float forceX,float forceY,float forceZ,bool local) 01058 { 01059 btVector3 force(forceX,forceY,forceZ); 01060 01061 01062 if (m_object && force.length2() > (SIMD_EPSILON*SIMD_EPSILON)) 01063 { 01064 m_object->activate(); 01065 if (m_object->isStaticObject()) 01066 { 01067 if (!m_cci.m_bSensor) 01068 m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); 01069 return; 01070 } 01071 btTransform xform = m_object->getWorldTransform(); 01072 01073 if (local) 01074 { 01075 force = xform.getBasis()*force; 01076 } 01077 btRigidBody* body = GetRigidBody(); 01078 if (body) 01079 body->applyCentralForce(force); 01080 btSoftBody* soft = GetSoftBody(); 01081 if (soft) 01082 { 01083 // the force is applied on each node, must reduce it in the same extend 01084 if (soft->m_nodes.size() > 0) 01085 force /= soft->m_nodes.size(); 01086 soft->addForce(force); 01087 } 01088 } 01089 } 01090 void CcdPhysicsController::SetAngularVelocity(float ang_velX,float ang_velY,float ang_velZ,bool local) 01091 { 01092 btVector3 angvel(ang_velX,ang_velY,ang_velZ); 01093 if (m_object && angvel.length2() > (SIMD_EPSILON*SIMD_EPSILON)) 01094 { 01095 m_object->activate(true); 01096 if (m_object->isStaticObject()) 01097 { 01098 if (!m_cci.m_bSensor) 01099 m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); 01100 return; 01101 } 01102 btTransform xform = m_object->getWorldTransform(); 01103 if (local) 01104 { 01105 angvel = xform.getBasis()*angvel; 01106 } 01107 btRigidBody* body = GetRigidBody(); 01108 if (body) 01109 body->setAngularVelocity(angvel); 01110 } 01111 01112 } 01113 void CcdPhysicsController::SetLinearVelocity(float lin_velX,float lin_velY,float lin_velZ,bool local) 01114 { 01115 01116 btVector3 linVel(lin_velX,lin_velY,lin_velZ); 01117 if (m_object/* && linVel.length2() > (SIMD_EPSILON*SIMD_EPSILON)*/) 01118 { 01119 m_object->activate(true); 01120 if (m_object->isStaticObject()) 01121 { 01122 if (!m_cci.m_bSensor) 01123 m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); 01124 return; 01125 } 01126 01127 btSoftBody* soft = GetSoftBody(); 01128 if (soft) 01129 { 01130 if (local) 01131 { 01132 linVel = m_softbodyStartTrans.getBasis()*linVel; 01133 } 01134 soft->setVelocity(linVel); 01135 } else 01136 { 01137 btTransform xform = m_object->getWorldTransform(); 01138 if (local) 01139 { 01140 linVel = xform.getBasis()*linVel; 01141 } 01142 btRigidBody* body = GetRigidBody(); 01143 if (body) 01144 body->setLinearVelocity(linVel); 01145 } 01146 } 01147 } 01148 void CcdPhysicsController::applyImpulse(float attachX,float attachY,float attachZ, float impulseX,float impulseY,float impulseZ) 01149 { 01150 btVector3 impulse(impulseX,impulseY,impulseZ); 01151 01152 if (m_object && impulse.length2() > (SIMD_EPSILON*SIMD_EPSILON)) 01153 { 01154 m_object->activate(); 01155 if (m_object->isStaticObject()) 01156 { 01157 if (!m_cci.m_bSensor) 01158 m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); 01159 return; 01160 } 01161 01162 btVector3 pos(attachX,attachY,attachZ); 01163 btRigidBody* body = GetRigidBody(); 01164 if (body) 01165 body->applyImpulse(impulse,pos); 01166 01167 } 01168 01169 } 01170 void CcdPhysicsController::SetActive(bool active) 01171 { 01172 } 01173 // reading out information from physics 01174 void CcdPhysicsController::GetLinearVelocity(float& linvX,float& linvY,float& linvZ) 01175 { 01176 btRigidBody* body = GetRigidBody(); 01177 if (body) 01178 { 01179 const btVector3& linvel = body->getLinearVelocity(); 01180 linvX = linvel.x(); 01181 linvY = linvel.y(); 01182 linvZ = linvel.z(); 01183 } else 01184 { 01185 linvX = 0.f; 01186 linvY = 0.f; 01187 linvZ = 0.f; 01188 } 01189 01190 } 01191 01192 void CcdPhysicsController::GetAngularVelocity(float& angVelX,float& angVelY,float& angVelZ) 01193 { 01194 btRigidBody* body = GetRigidBody(); 01195 if (body) 01196 { 01197 const btVector3& angvel= body->getAngularVelocity(); 01198 angVelX = angvel.x(); 01199 angVelY = angvel.y(); 01200 angVelZ = angvel.z(); 01201 } else 01202 { 01203 angVelX = 0.f; 01204 angVelY = 0.f; 01205 angVelZ = 0.f; 01206 } 01207 } 01208 01209 void CcdPhysicsController::GetVelocity(const float posX,const float posY,const float posZ,float& linvX,float& linvY,float& linvZ) 01210 { 01211 btVector3 pos(posX,posY,posZ); 01212 btRigidBody* body = GetRigidBody(); 01213 if (body) 01214 { 01215 btVector3 linvel = body->getVelocityInLocalPoint(pos); 01216 linvX = linvel.x(); 01217 linvY = linvel.y(); 01218 linvZ = linvel.z(); 01219 } else 01220 { 01221 linvX = 0.f; 01222 linvY = 0.f; 01223 linvZ = 0.f; 01224 } 01225 } 01226 void CcdPhysicsController::getReactionForce(float& forceX,float& forceY,float& forceZ) 01227 { 01228 } 01229 01230 // dyna's that are rigidbody are free in orientation, dyna's with non-rigidbody are restricted 01231 void CcdPhysicsController::setRigidBody(bool rigid) 01232 { 01233 if (!rigid) 01234 { 01235 btRigidBody* body = GetRigidBody(); 01236 if (body) 01237 { 01238 //fake it for now 01239 btVector3 inertia = body->getInvInertiaDiagLocal(); 01240 inertia[1] = 0.f; 01241 body->setInvInertiaDiagLocal(inertia); 01242 body->updateInertiaTensor(); 01243 } 01244 } 01245 } 01246 01247 // clientinfo for raycasts for example 01248 void* CcdPhysicsController::getNewClientInfo() 01249 { 01250 return m_newClientInfo; 01251 } 01252 void CcdPhysicsController::setNewClientInfo(void* clientinfo) 01253 { 01254 m_newClientInfo = clientinfo; 01255 } 01256 01257 01258 void CcdPhysicsController::UpdateDeactivation(float timeStep) 01259 { 01260 btRigidBody* body = GetRigidBody(); 01261 if (body) 01262 { 01263 body->updateDeactivation( timeStep); 01264 } 01265 } 01266 01267 bool CcdPhysicsController::wantsSleeping() 01268 { 01269 btRigidBody* body = GetRigidBody(); 01270 if (body) 01271 { 01272 return body->wantsSleeping(); 01273 } 01274 //check it out 01275 return true; 01276 } 01277 01278 PHY_IPhysicsController* CcdPhysicsController::GetReplica() 01279 { 01280 // This is used only to replicate Near and Radar sensor controllers 01281 // The replication of object physics controller is done in KX_BulletPhysicsController::GetReplica() 01282 CcdConstructionInfo cinfo = m_cci; 01283 if (m_shapeInfo) 01284 { 01285 // This situation does not normally happen 01286 cinfo.m_collisionShape = m_shapeInfo->CreateBulletShape(m_cci.m_margin, m_cci.m_bGimpact, !m_cci.m_bSoft); 01287 } 01288 else if (m_collisionShape) 01289 { 01290 switch (m_collisionShape->getShapeType()) 01291 { 01292 case SPHERE_SHAPE_PROXYTYPE: 01293 { 01294 btSphereShape* orgShape = (btSphereShape*)m_collisionShape; 01295 cinfo.m_collisionShape = new btSphereShape(*orgShape); 01296 break; 01297 } 01298 01299 case CONE_SHAPE_PROXYTYPE: 01300 { 01301 btConeShape* orgShape = (btConeShape*)m_collisionShape; 01302 cinfo.m_collisionShape = new btConeShape(*orgShape); 01303 break; 01304 } 01305 01306 default: 01307 { 01308 return 0; 01309 } 01310 } 01311 } 01312 01313 cinfo.m_MotionState = new DefaultMotionState(); 01314 cinfo.m_shapeInfo = m_shapeInfo; 01315 01316 CcdPhysicsController* replica = new CcdPhysicsController(cinfo); 01317 return replica; 01318 } 01319 01324 01325 DefaultMotionState::DefaultMotionState() 01326 { 01327 m_worldTransform.setIdentity(); 01328 m_localScaling.setValue(1.f,1.f,1.f); 01329 } 01330 01331 01332 DefaultMotionState::~DefaultMotionState() 01333 { 01334 01335 } 01336 01337 void DefaultMotionState::getWorldPosition(float& posX,float& posY,float& posZ) 01338 { 01339 posX = m_worldTransform.getOrigin().x(); 01340 posY = m_worldTransform.getOrigin().y(); 01341 posZ = m_worldTransform.getOrigin().z(); 01342 } 01343 01344 void DefaultMotionState::getWorldScaling(float& scaleX,float& scaleY,float& scaleZ) 01345 { 01346 scaleX = m_localScaling.getX(); 01347 scaleY = m_localScaling.getY(); 01348 scaleZ = m_localScaling.getZ(); 01349 } 01350 01351 void DefaultMotionState::getWorldOrientation(float& quatIma0,float& quatIma1,float& quatIma2,float& quatReal) 01352 { 01353 btQuaternion quat = m_worldTransform.getRotation(); 01354 quatIma0 = quat.x(); 01355 quatIma1 = quat.y(); 01356 quatIma2 = quat.z(); 01357 quatReal = quat[3]; 01358 } 01359 01360 void DefaultMotionState::getWorldOrientation(float* ori) 01361 { 01362 m_worldTransform.getBasis().getOpenGLSubMatrix(ori); 01363 } 01364 01365 void DefaultMotionState::setWorldOrientation(const float* ori) 01366 { 01367 m_worldTransform.getBasis().setFromOpenGLSubMatrix(ori); 01368 } 01369 void DefaultMotionState::setWorldPosition(float posX,float posY,float posZ) 01370 { 01371 btVector3 pos(posX,posY,posZ); 01372 m_worldTransform.setOrigin( pos ); 01373 } 01374 01375 void DefaultMotionState::setWorldOrientation(float quatIma0,float quatIma1,float quatIma2,float quatReal) 01376 { 01377 btQuaternion orn(quatIma0,quatIma1,quatIma2,quatReal); 01378 m_worldTransform.setRotation( orn ); 01379 } 01380 01381 void DefaultMotionState::calculateWorldTransformations() 01382 { 01383 01384 } 01385 01386 // Shape constructor 01387 std::map<RAS_MeshObject*, CcdShapeConstructionInfo*> CcdShapeConstructionInfo::m_meshShapeMap; 01388 01389 CcdShapeConstructionInfo* CcdShapeConstructionInfo::FindMesh(RAS_MeshObject* mesh, struct DerivedMesh* dm, bool polytope) 01390 { 01391 if (polytope || dm) 01392 // not yet supported 01393 return NULL; 01394 01395 std::map<RAS_MeshObject*,CcdShapeConstructionInfo*>::const_iterator mit = m_meshShapeMap.find(mesh); 01396 if (mit != m_meshShapeMap.end()) 01397 return mit->second; 01398 return NULL; 01399 } 01400 01401 bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm, bool polytope) 01402 { 01403 int numpolys, numverts; 01404 01405 // assume no shape information 01406 // no support for dynamic change of shape yet 01407 assert(IsUnused()); 01408 m_shapeType = PHY_SHAPE_NONE; 01409 m_meshObject = NULL; 01410 bool free_dm = false; 01411 01412 // No mesh object or mesh has no polys 01413 if (!meshobj || meshobj->HasColliderPolygon()==false) { 01414 m_vertexArray.clear(); 01415 m_polygonIndexArray.clear(); 01416 m_triFaceArray.clear(); 01417 m_triFaceUVcoArray.clear(); 01418 return false; 01419 } 01420 01421 if (!dm) { 01422 free_dm = true; 01423 dm = CDDM_from_mesh(meshobj->GetMesh(), NULL); 01424 } 01425 01426 MVert *mvert = dm->getVertArray(dm); 01427 MFace *mface = dm->getFaceArray(dm); 01428 numpolys = dm->getNumFaces(dm); 01429 numverts = dm->getNumVerts(dm); 01430 int* index = (int*)dm->getFaceDataArray(dm, CD_ORIGINDEX); 01431 MTFace *tface = (MTFace *)dm->getFaceDataArray(dm, CD_MTFACE); 01432 01433 m_shapeType = (polytope) ? PHY_SHAPE_POLYTOPE : PHY_SHAPE_MESH; 01434 01435 /* Convert blender geometry into bullet mesh, need these vars for mapping */ 01436 vector<bool> vert_tag_array(numverts, false); 01437 unsigned int tot_bt_verts= 0; 01438 01439 if (polytope) 01440 { 01441 // Tag verts we're using 01442 for (int p2=0; p2<numpolys; p2++) 01443 { 01444 MFace* mf = &mface[p2]; 01445 RAS_Polygon* poly = meshobj->GetPolygon((index)? index[p2]: p2); 01446 01447 // only add polygons that have the collision flag set 01448 if (poly->IsCollider()) 01449 { 01450 if (vert_tag_array[mf->v1]==false) {vert_tag_array[mf->v1]= true;tot_bt_verts++;} 01451 if (vert_tag_array[mf->v2]==false) {vert_tag_array[mf->v2]= true;tot_bt_verts++;} 01452 if (vert_tag_array[mf->v3]==false) {vert_tag_array[mf->v3]= true;tot_bt_verts++;} 01453 if (mf->v4 && vert_tag_array[mf->v4]==false) {vert_tag_array[mf->v4]= true;tot_bt_verts++;} 01454 } 01455 } 01456 01457 m_vertexArray.resize(tot_bt_verts*3); 01458 01459 btScalar *bt= &m_vertexArray[0]; 01460 01461 for (int p2=0; p2<numpolys; p2++) 01462 { 01463 MFace* mf = &mface[p2]; 01464 RAS_Polygon* poly= meshobj->GetPolygon((index)? index[p2]: p2); 01465 01466 // only add polygons that have the collisionflag set 01467 if (poly->IsCollider()) 01468 { 01469 if (vert_tag_array[mf->v1]==true) 01470 { 01471 const float* vtx = mvert[mf->v1].co; 01472 vert_tag_array[mf->v1]= false; 01473 *bt++ = vtx[0]; 01474 *bt++ = vtx[1]; 01475 *bt++ = vtx[2]; 01476 } 01477 if (vert_tag_array[mf->v2]==true) 01478 { 01479 const float* vtx = mvert[mf->v2].co; 01480 vert_tag_array[mf->v2]= false; 01481 *bt++ = vtx[0]; 01482 *bt++ = vtx[1]; 01483 *bt++ = vtx[2]; 01484 } 01485 if (vert_tag_array[mf->v3]==true) 01486 { 01487 const float* vtx = mvert[mf->v3].co; 01488 vert_tag_array[mf->v3]= false; 01489 *bt++ = vtx[0]; 01490 *bt++ = vtx[1]; 01491 *bt++ = vtx[2]; 01492 } 01493 if (mf->v4 && vert_tag_array[mf->v4]==true) 01494 { 01495 const float* vtx = mvert[mf->v4].co; 01496 vert_tag_array[mf->v4]= false; 01497 *bt++ = vtx[0]; 01498 *bt++ = vtx[1]; 01499 *bt++ = vtx[2]; 01500 } 01501 } 01502 } 01503 } 01504 else { 01505 unsigned int tot_bt_tris= 0; 01506 vector<int> vert_remap_array(numverts, 0); 01507 01508 // Tag verts we're using 01509 for (int p2=0; p2<numpolys; p2++) 01510 { 01511 MFace* mf = &mface[p2]; 01512 RAS_Polygon* poly= meshobj->GetPolygon((index)? index[p2]: p2); 01513 01514 // only add polygons that have the collision flag set 01515 if (poly->IsCollider()) 01516 { 01517 if (vert_tag_array[mf->v1]==false) 01518 {vert_tag_array[mf->v1]= true;vert_remap_array[mf->v1]= tot_bt_verts;tot_bt_verts++;} 01519 if (vert_tag_array[mf->v2]==false) 01520 {vert_tag_array[mf->v2]= true;vert_remap_array[mf->v2]= tot_bt_verts;tot_bt_verts++;} 01521 if (vert_tag_array[mf->v3]==false) 01522 {vert_tag_array[mf->v3]= true;vert_remap_array[mf->v3]= tot_bt_verts;tot_bt_verts++;} 01523 if (mf->v4 && vert_tag_array[mf->v4]==false) 01524 {vert_tag_array[mf->v4]= true;vert_remap_array[mf->v4]= tot_bt_verts;tot_bt_verts++;} 01525 tot_bt_tris += (mf->v4 ? 2:1); /* a quad or a tri */ 01526 } 01527 } 01528 01529 m_vertexArray.resize(tot_bt_verts*3); 01530 m_polygonIndexArray.resize(tot_bt_tris); 01531 m_triFaceArray.resize(tot_bt_tris*3); 01532 btScalar *bt= &m_vertexArray[0]; 01533 int *poly_index_pt= &m_polygonIndexArray[0]; 01534 int *tri_pt= &m_triFaceArray[0]; 01535 01536 UVco *uv_pt = NULL; 01537 if (tface) 01538 { 01539 m_triFaceUVcoArray.resize(tot_bt_tris*3); 01540 uv_pt = &m_triFaceUVcoArray[0]; 01541 } 01542 else 01543 m_triFaceUVcoArray.clear(); 01544 01545 for (int p2=0; p2<numpolys; p2++) 01546 { 01547 MFace* mf = &mface[p2]; 01548 MTFace* tf = (tface) ? &tface[p2] : NULL; 01549 RAS_Polygon* poly= meshobj->GetPolygon((index)? index[p2]: p2); 01550 01551 // only add polygons that have the collisionflag set 01552 if (poly->IsCollider()) 01553 { 01554 MVert *v1= &mvert[mf->v1]; 01555 MVert *v2= &mvert[mf->v2]; 01556 MVert *v3= &mvert[mf->v3]; 01557 01558 // the face indicies 01559 tri_pt[0]= vert_remap_array[mf->v1]; 01560 tri_pt[1]= vert_remap_array[mf->v2]; 01561 tri_pt[2]= vert_remap_array[mf->v3]; 01562 tri_pt= tri_pt+3; 01563 if (tf) 01564 { 01565 uv_pt[0].uv[0] = tf->uv[0][0]; 01566 uv_pt[0].uv[1] = tf->uv[0][1]; 01567 uv_pt[1].uv[0] = tf->uv[1][0]; 01568 uv_pt[1].uv[1] = tf->uv[1][1]; 01569 uv_pt[2].uv[0] = tf->uv[2][0]; 01570 uv_pt[2].uv[1] = tf->uv[2][1]; 01571 uv_pt += 3; 01572 } 01573 01574 // m_polygonIndexArray 01575 *poly_index_pt= (index)? index[p2]: p2; 01576 poly_index_pt++; 01577 01578 // the vertex location 01579 if (vert_tag_array[mf->v1]==true) { /* *** v1 *** */ 01580 vert_tag_array[mf->v1]= false; 01581 *bt++ = v1->co[0]; 01582 *bt++ = v1->co[1]; 01583 *bt++ = v1->co[2]; 01584 } 01585 if (vert_tag_array[mf->v2]==true) { /* *** v2 *** */ 01586 vert_tag_array[mf->v2]= false; 01587 *bt++ = v2->co[0]; 01588 *bt++ = v2->co[1]; 01589 *bt++ = v2->co[2]; 01590 } 01591 if (vert_tag_array[mf->v3]==true) { /* *** v3 *** */ 01592 vert_tag_array[mf->v3]= false; 01593 *bt++ = v3->co[0]; 01594 *bt++ = v3->co[1]; 01595 *bt++ = v3->co[2]; 01596 } 01597 01598 if (mf->v4) 01599 { 01600 MVert *v4= &mvert[mf->v4]; 01601 01602 tri_pt[0]= vert_remap_array[mf->v1]; 01603 tri_pt[1]= vert_remap_array[mf->v3]; 01604 tri_pt[2]= vert_remap_array[mf->v4]; 01605 tri_pt= tri_pt+3; 01606 if (tf) 01607 { 01608 uv_pt[0].uv[0] = tf->uv[0][0]; 01609 uv_pt[0].uv[1] = tf->uv[0][1]; 01610 uv_pt[1].uv[0] = tf->uv[2][0]; 01611 uv_pt[1].uv[1] = tf->uv[2][1]; 01612 uv_pt[2].uv[0] = tf->uv[3][0]; 01613 uv_pt[2].uv[1] = tf->uv[3][1]; 01614 uv_pt += 3; 01615 } 01616 01617 // m_polygonIndexArray 01618 *poly_index_pt= (index)? index[p2]: p2; 01619 poly_index_pt++; 01620 01621 // the vertex location 01622 if (vert_tag_array[mf->v4]==true) { /* *** v4 *** */ 01623 vert_tag_array[mf->v4]= false; 01624 *bt++ = v4->co[0]; 01625 *bt++ = v4->co[1]; 01626 *bt++ = v4->co[2]; 01627 } 01628 } 01629 } 01630 } 01631 01632 01633 /* If this ever gets confusing, print out an OBJ file for debugging */ 01634 #if 0 01635 printf("# vert count %d\n", m_vertexArray.size()); 01636 for(i=0; i<m_vertexArray.size(); i+=1) { 01637 printf("v %.6f %.6f %.6f\n", m_vertexArray[i].x(), m_vertexArray[i].y(), m_vertexArray[i].z()); 01638 } 01639 01640 printf("# face count %d\n", m_triFaceArray.size()); 01641 for(i=0; i<m_triFaceArray.size(); i+=3) { 01642 printf("f %d %d %d\n", m_triFaceArray[i]+1, m_triFaceArray[i+1]+1, m_triFaceArray[i+2]+1); 01643 } 01644 #endif 01645 01646 } 01647 01648 #if 0 01649 if (validpolys==false) 01650 { 01651 // should not happen 01652 m_shapeType = PHY_SHAPE_NONE; 01653 return false; 01654 } 01655 #endif 01656 01657 m_meshObject = meshobj; 01658 if (free_dm) { 01659 dm->release(dm); 01660 dm = NULL; 01661 } 01662 01663 // sharing only on static mesh at present, if you change that, you must also change in FindMesh 01664 if (!polytope && !dm) 01665 { 01666 // triangle shape can be shared, store the mesh object in the map 01667 m_meshShapeMap.insert(std::pair<RAS_MeshObject*,CcdShapeConstructionInfo*>(meshobj,this)); 01668 } 01669 return true; 01670 } 01671 01672 #include <cstdio> 01673 01674 /* Updates the arrays used by CreateBulletShape(), 01675 * take care that recalcLocalAabb() runs after CreateBulletShape is called. 01676 * */ 01677 bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject* gameobj, class RAS_MeshObject* meshobj) 01678 { 01679 int numpolys; 01680 int numverts; 01681 01682 unsigned int tot_bt_tris= 0; 01683 unsigned int tot_bt_verts= 0; 01684 01685 int i, j; 01686 int v_orig; 01687 01688 /* Use for looping over verts in a face as a try or 2 tris */ 01689 const int quad_verts[7]= {0,1,2, 0,2,3, -1}; 01690 const int tri_verts[4]= {0,1,2, -1}; 01691 const int *fv_pt; 01692 01693 if(gameobj==NULL && meshobj==NULL) 01694 return false; 01695 01696 if(m_shapeType != PHY_SHAPE_MESH) 01697 return false; 01698 01699 RAS_Deformer *deformer= gameobj ? gameobj->GetDeformer():NULL; 01700 DerivedMesh* dm = NULL; 01701 01702 if (deformer) 01703 dm = deformer->GetPhysicsMesh(); 01704 01705 /* get the mesh from the object if not defined */ 01706 if(meshobj==NULL) { 01707 01708 /* modifier mesh */ 01709 if(dm) 01710 meshobj= deformer->GetRasMesh(); 01711 01712 /* game object first mesh */ 01713 if(meshobj==NULL) { 01714 if(gameobj->GetMeshCount() > 0) { 01715 meshobj= gameobj->GetMesh(0); 01716 } 01717 } 01718 } 01719 01720 if(dm && deformer->GetRasMesh() == meshobj) 01721 { /* 01722 * Derived Mesh Update 01723 * 01724 * */ 01725 01726 MVert *mvert = dm->getVertArray(dm); 01727 MFace *mface = dm->getFaceArray(dm); 01728 numpolys = dm->getNumFaces(dm); 01729 numverts = dm->getNumVerts(dm); 01730 int* index = (int*)dm->getFaceDataArray(dm, CD_ORIGINDEX); 01731 01732 MFace *mf; 01733 MVert *mv; 01734 01735 int flen; 01736 01737 if(CustomData_has_layer(&dm->faceData, CD_MTFACE)) 01738 { 01739 MTFace *tface = (MTFace *)dm->getFaceDataArray(dm, CD_MTFACE); 01740 MTFace *tf; 01741 01742 vector<bool> vert_tag_array(numverts, false); 01743 vector<int> vert_remap_array(numverts, 0); 01744 01745 for(mf= mface, tf= tface, i=0; i < numpolys; mf++, tf++, i++) { 01746 if(tf->mode & TF_DYNAMIC) 01747 { 01748 if(mf->v4) { 01749 tot_bt_tris+= 2; 01750 flen= 4; 01751 } else { 01752 tot_bt_tris++; 01753 flen= 3; 01754 } 01755 01756 for(j=0; j<flen; j++) 01757 { 01758 v_orig = (*(&mf->v1 + j)); 01759 01760 if(vert_tag_array[v_orig]==false) 01761 { 01762 vert_tag_array[v_orig]= true; 01763 vert_remap_array[v_orig]= tot_bt_verts; 01764 tot_bt_verts++; 01765 } 01766 } 01767 } 01768 } 01769 01770 m_vertexArray.resize(tot_bt_verts*3); 01771 btScalar *bt= &m_vertexArray[0]; 01772 01773 m_triFaceArray.resize(tot_bt_tris*3); 01774 int *tri_pt= &m_triFaceArray[0]; 01775 01776 m_triFaceUVcoArray.resize(tot_bt_tris*3); 01777 UVco *uv_pt= &m_triFaceUVcoArray[0]; 01778 01779 m_polygonIndexArray.resize(tot_bt_tris); 01780 int *poly_index_pt= &m_polygonIndexArray[0]; 01781 01782 for(mf= mface, tf= tface, i=0; i < numpolys; mf++, tf++, i++) 01783 { 01784 if(tf->mode & TF_DYNAMIC) 01785 { 01786 int origi = (index)? index[i]: i; 01787 01788 if(mf->v4) { 01789 fv_pt= quad_verts; 01790 *poly_index_pt++ = origi; 01791 *poly_index_pt++ = origi; 01792 flen= 4; 01793 } else { 01794 fv_pt= tri_verts; 01795 *poly_index_pt++ = origi; 01796 flen= 3; 01797 } 01798 01799 for(; *fv_pt > -1; fv_pt++) 01800 { 01801 v_orig = (*(&mf->v1 + (*fv_pt))); 01802 01803 if(vert_tag_array[v_orig]) 01804 { 01805 mv= mvert + v_orig; 01806 *bt++ = mv->co[0]; 01807 *bt++ = mv->co[1]; 01808 *bt++ = mv->co[2]; 01809 01810 vert_tag_array[v_orig]= false; 01811 } 01812 *tri_pt++ = vert_remap_array[v_orig]; 01813 uv_pt->uv[0] = tf->uv[*fv_pt][0]; 01814 uv_pt->uv[1] = tf->uv[*fv_pt][1]; 01815 uv_pt++; 01816 } 01817 } 01818 } 01819 } 01820 else { 01821 /* no need for a vertex mapping. simple/fast */ 01822 01823 tot_bt_verts= numverts; 01824 01825 for(mf= mface, i=0; i < numpolys; mf++, i++) { 01826 tot_bt_tris += (mf->v4 ? 2:1); 01827 } 01828 01829 m_vertexArray.resize(tot_bt_verts*3); 01830 btScalar *bt= &m_vertexArray[0]; 01831 01832 m_triFaceArray.resize(tot_bt_tris*3); 01833 int *tri_pt= &m_triFaceArray[0]; 01834 01835 m_polygonIndexArray.resize(tot_bt_tris); 01836 int *poly_index_pt= &m_polygonIndexArray[0]; 01837 01838 m_triFaceUVcoArray.clear(); 01839 01840 for(mv= mvert, i=0; i < numverts; mv++, i++) { 01841 *bt++ = mv->co[0]; *bt++ = mv->co[1]; *bt++ = mv->co[2]; 01842 } 01843 01844 for(mf= mface, i=0; i < numpolys; mf++, i++) { 01845 int origi = (index)? index[i]: i; 01846 01847 if(mf->v4) { 01848 fv_pt= quad_verts; 01849 *poly_index_pt++ = origi; 01850 *poly_index_pt++ = origi; 01851 } 01852 else { 01853 fv_pt= tri_verts; 01854 *poly_index_pt++ = origi; 01855 } 01856 01857 for(; *fv_pt > -1; fv_pt++) 01858 *tri_pt++ = (*(&mf->v1 + (*fv_pt))); 01859 } 01860 } 01861 } 01862 else { /* 01863 * RAS Mesh Update 01864 * 01865 * */ 01866 01867 /* Note!, gameobj can be NULL here */ 01868 01869 /* transverts are only used for deformed RAS_Meshes, the RAS_TexVert data 01870 * is too hard to get at, see below for details */ 01871 float (*transverts)[3]= NULL; 01872 int transverts_tot= 0; /* with deformed meshes - should always be greater then the max orginal index, or we get crashes */ 01873 01874 if(deformer) { 01875 /* map locations from the deformed array 01876 * 01877 * Could call deformer->Update(); but rely on redraw updating. 01878 * */ 01879 transverts= deformer->GetTransVerts(&transverts_tot); 01880 } 01881 01882 // Tag verts we're using 01883 numpolys= meshobj->NumPolygons(); 01884 numverts= meshobj->m_sharedvertex_map.size(); 01885 const float *xyz; 01886 01887 01888 vector<bool> vert_tag_array(numverts, false); 01889 vector<int> vert_remap_array(numverts, 0); 01890 01891 for(int p=0; p<numpolys; p++) 01892 { 01893 RAS_Polygon* poly= meshobj->GetPolygon(p); 01894 if (poly->IsCollider()) 01895 { 01896 for(i=0; i < poly->VertexCount(); i++) 01897 { 01898 v_orig= poly->GetVertex(i)->getOrigIndex(); 01899 if(vert_tag_array[v_orig]==false) 01900 { 01901 vert_tag_array[v_orig]= true; 01902 vert_remap_array[v_orig]= tot_bt_verts; 01903 tot_bt_verts++; 01904 } 01905 } 01906 tot_bt_tris += (poly->VertexCount()==4 ? 2:1); 01907 } 01908 } 01909 01910 m_vertexArray.resize(tot_bt_verts*3); 01911 btScalar *bt= &m_vertexArray[0]; 01912 01913 m_triFaceArray.resize(tot_bt_tris*3); 01914 int *tri_pt= &m_triFaceArray[0]; 01915 01916 /* cant be used for anything useful in this case, since we dont rely on the original mesh 01917 * will just be an array like pythons range(tot_bt_tris) */ 01918 m_polygonIndexArray.resize(tot_bt_tris); 01919 01920 01921 for(int p=0; p<numpolys; p++) 01922 { 01923 RAS_Polygon* poly= meshobj->GetPolygon(p); 01924 01925 if (poly->IsCollider()) 01926 { 01927 /* quad or tri loop */ 01928 fv_pt= (poly->VertexCount()==3 ? tri_verts:quad_verts); 01929 01930 for(; *fv_pt > -1; fv_pt++) 01931 { 01932 v_orig= poly->GetVertex(*fv_pt)->getOrigIndex(); 01933 01934 if(vert_tag_array[v_orig]) 01935 { 01936 if(transverts) { 01937 /* deformed mesh, using RAS_TexVert locations would be too troublesome 01938 * because they are use the gameob as a hash in the material slot */ 01939 *bt++ = transverts[v_orig][0]; 01940 *bt++ = transverts[v_orig][1]; 01941 *bt++ = transverts[v_orig][2]; 01942 } 01943 else { 01944 /* static mesh python may have modified */ 01945 xyz= meshobj->GetVertexLocation( v_orig ); 01946 *bt++ = xyz[0]; 01947 *bt++ = xyz[1]; 01948 *bt++ = xyz[2]; 01949 } 01950 01951 vert_tag_array[v_orig]= false; 01952 } 01953 01954 *tri_pt++ = vert_remap_array[v_orig]; 01955 } 01956 } 01957 01958 m_polygonIndexArray[p]= p; /* dumb counting */ 01959 } 01960 } 01961 01962 #if 0 01963 /* needs #include <cstdio> */ 01964 printf("# vert count %d\n", m_vertexArray.size()); 01965 for(int i=0; i<m_vertexArray.size(); i+=3) { 01966 printf("v %.6f %.6f %.6f\n", m_vertexArray[i], m_vertexArray[i+1], m_vertexArray[i+2]); 01967 } 01968 01969 printf("# face count %d\n", m_triFaceArray.size()); 01970 for(int i=0; i<m_triFaceArray.size(); i+=3) { 01971 printf("f %d %d %d\n", m_triFaceArray[i]+1, m_triFaceArray[i+1]+1, m_triFaceArray[i+2]+1); 01972 } 01973 #endif 01974 01975 /* force recreation of the m_unscaledShape. 01976 * If this has multiple users we cant delete */ 01977 if(m_unscaledShape) { 01978 // dont free now so it can re-allocate under the same location and not break pointers. 01979 // DeleteBulletShape(m_unscaledShape); 01980 m_forceReInstance= true; 01981 } 01982 01983 m_meshObject= meshobj; 01984 01985 if (dm) { 01986 dm->needsFree = 1; 01987 dm->release(dm); 01988 } 01989 return true; 01990 } 01991 01992 01993 01994 bool CcdShapeConstructionInfo::SetProxy(CcdShapeConstructionInfo* shapeInfo) 01995 { 01996 if (shapeInfo == NULL) 01997 return false; 01998 // no support for dynamic change 01999 assert(IsUnused()); 02000 m_shapeType = PHY_SHAPE_PROXY; 02001 m_shapeProxy = shapeInfo; 02002 return true; 02003 } 02004 02005 btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape(btScalar margin, bool useGimpact, bool useBvh) 02006 { 02007 btCollisionShape* collisionShape = 0; 02008 btCompoundShape* compoundShape = 0; 02009 02010 if (m_shapeType == PHY_SHAPE_PROXY && m_shapeProxy != NULL) 02011 return m_shapeProxy->CreateBulletShape(margin, useGimpact, useBvh); 02012 02013 switch (m_shapeType) 02014 { 02015 default: 02016 break; 02017 02018 case PHY_SHAPE_BOX: 02019 collisionShape = new btBoxShape(m_halfExtend); 02020 collisionShape->setMargin(margin); 02021 break; 02022 02023 case PHY_SHAPE_SPHERE: 02024 collisionShape = new btSphereShape(m_radius); 02025 collisionShape->setMargin(margin); 02026 break; 02027 02028 case PHY_SHAPE_CYLINDER: 02029 collisionShape = new btCylinderShapeZ(m_halfExtend); 02030 collisionShape->setMargin(margin); 02031 break; 02032 02033 case PHY_SHAPE_CONE: 02034 collisionShape = new btConeShapeZ(m_radius, m_height); 02035 collisionShape->setMargin(margin); 02036 break; 02037 02038 case PHY_SHAPE_POLYTOPE: 02039 collisionShape = new btConvexHullShape(&m_vertexArray[0], m_vertexArray.size()/3, 3*sizeof(btScalar)); 02040 collisionShape->setMargin(margin); 02041 break; 02042 02043 case PHY_SHAPE_CAPSULE: 02044 collisionShape = new btCapsuleShapeZ(m_radius, m_height); 02045 collisionShape->setMargin(margin); 02046 break; 02047 02048 case PHY_SHAPE_MESH: 02049 // Let's use the latest btScaledBvhTriangleMeshShape: it allows true sharing of 02050 // triangle mesh information between duplicates => drastic performance increase when 02051 // duplicating complex mesh objects. 02052 // BUT it causes a small performance decrease when sharing is not required: 02053 // 9 multiplications/additions and one function call for each triangle that passes the mid phase filtering 02054 // One possible optimization is to use directly the btBvhTriangleMeshShape when the scale is 1,1,1 02055 // and btScaledBvhTriangleMeshShape otherwise. 02056 if (useGimpact) 02057 { 02058 btTriangleIndexVertexArray* indexVertexArrays = new btTriangleIndexVertexArray( 02059 m_polygonIndexArray.size(), 02060 &m_triFaceArray[0], 02061 3*sizeof(int), 02062 m_vertexArray.size()/3, 02063 &m_vertexArray[0], 02064 3*sizeof(btScalar) 02065 ); 02066 02067 btGImpactMeshShape* gimpactShape = new btGImpactMeshShape(indexVertexArrays); 02068 gimpactShape->setMargin(margin); 02069 collisionShape = gimpactShape; 02070 gimpactShape->updateBound(); 02071 02072 } else 02073 { 02074 if (!m_unscaledShape || m_forceReInstance) 02075 { 02076 02077 btTriangleIndexVertexArray* indexVertexArrays = 0; 02078 02080 if (0.f != m_weldingThreshold1) 02081 { 02082 btTriangleMesh* collisionMeshData = new btTriangleMesh(true,false); 02083 collisionMeshData->m_weldingThreshold = m_weldingThreshold1; 02084 bool removeDuplicateVertices=true; 02085 // m_vertexArray not in multiple of 3 anymore, use m_triFaceArray 02086 for(unsigned int i=0; i<m_triFaceArray.size(); i+=3) { 02087 btScalar *bt = &m_vertexArray[3*m_triFaceArray[i]]; 02088 btVector3 v1(bt[0], bt[1], bt[2]); 02089 bt = &m_vertexArray[3*m_triFaceArray[i+1]]; 02090 btVector3 v2(bt[0], bt[1], bt[2]); 02091 bt = &m_vertexArray[3*m_triFaceArray[i+2]]; 02092 btVector3 v3(bt[0], bt[1], bt[2]); 02093 collisionMeshData->addTriangle(v1, v2, v3, removeDuplicateVertices); 02094 } 02095 indexVertexArrays = collisionMeshData; 02096 02097 } else 02098 { 02099 indexVertexArrays = new btTriangleIndexVertexArray( 02100 m_polygonIndexArray.size(), 02101 &m_triFaceArray[0], 02102 3*sizeof(int), 02103 m_vertexArray.size()/3, 02104 &m_vertexArray[0], 02105 3*sizeof(btScalar)); 02106 } 02107 02108 // this shape will be shared and not deleted until shapeInfo is deleted 02109 02110 // for UpdateMesh, reuse the last memory location so instancing wont crash. 02111 if(m_unscaledShape) { 02112 DeleteBulletShape(m_unscaledShape, false); 02113 m_unscaledShape->~btBvhTriangleMeshShape(); 02114 m_unscaledShape = new(m_unscaledShape) btBvhTriangleMeshShape( indexVertexArrays, true, useBvh ); 02115 } else { 02116 m_unscaledShape = new btBvhTriangleMeshShape( indexVertexArrays, true, useBvh ); 02117 } 02118 m_forceReInstance= false; 02119 } else if (useBvh && m_unscaledShape->getOptimizedBvh() == NULL) { 02120 // the existing unscaledShape was not build with Bvh, do it now 02121 m_unscaledShape->buildOptimizedBvh(); 02122 } 02123 collisionShape = new btScaledBvhTriangleMeshShape(m_unscaledShape, btVector3(1.0f,1.0f,1.0f)); 02124 collisionShape->setMargin(margin); 02125 } 02126 break; 02127 02128 case PHY_SHAPE_COMPOUND: 02129 if (m_shapeArray.size() > 0) 02130 { 02131 compoundShape = new btCompoundShape(); 02132 for (std::vector<CcdShapeConstructionInfo*>::iterator sit = m_shapeArray.begin(); 02133 sit != m_shapeArray.end(); 02134 sit++) 02135 { 02136 collisionShape = (*sit)->CreateBulletShape(margin, useGimpact, useBvh); 02137 if (collisionShape) 02138 { 02139 collisionShape->setLocalScaling((*sit)->m_childScale); 02140 compoundShape->addChildShape((*sit)->m_childTrans, collisionShape); 02141 } 02142 } 02143 collisionShape = compoundShape; 02144 } 02145 break; 02146 } 02147 return collisionShape; 02148 } 02149 02150 void CcdShapeConstructionInfo::AddShape(CcdShapeConstructionInfo* shapeInfo) 02151 { 02152 m_shapeArray.push_back(shapeInfo); 02153 shapeInfo->AddRef(); 02154 } 02155 02156 CcdShapeConstructionInfo::~CcdShapeConstructionInfo() 02157 { 02158 for (std::vector<CcdShapeConstructionInfo*>::iterator sit = m_shapeArray.begin(); 02159 sit != m_shapeArray.end(); 02160 sit++) 02161 { 02162 (*sit)->Release(); 02163 } 02164 m_shapeArray.clear(); 02165 if (m_unscaledShape) 02166 { 02167 DeleteBulletShape(m_unscaledShape, true); 02168 } 02169 m_vertexArray.clear(); 02170 if (m_shapeType == PHY_SHAPE_MESH && m_meshObject != NULL) 02171 { 02172 std::map<RAS_MeshObject*,CcdShapeConstructionInfo*>::iterator mit = m_meshShapeMap.find(m_meshObject); 02173 if (mit != m_meshShapeMap.end() && mit->second == this) 02174 { 02175 m_meshShapeMap.erase(mit); 02176 } 02177 } 02178 if (m_shapeType == PHY_SHAPE_PROXY && m_shapeProxy != NULL) 02179 { 02180 m_shapeProxy->Release(); 02181 } 02182 } 02183