Blender  V2.59
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 environement. Note that we don't handle sensor explicitely: 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