Blender V2.61 - r43446

CcdPhysicsController.cpp

Go to the documentation of this file.
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