40 #ifndef _collisionshapemanager_cpp
41 #define _collisionshapemanager_cpp
43 #include "Physics/collisionshapemanager.h"
44 #include "Graphics/mesh.h"
45 #include "Graphics/meshmanager.h"
48 #include "Physics/collisionshape.h"
49 #include "Physics/boxcollisionshape.h"
50 #include "Physics/capsulecollisionshape.h"
51 #include "Physics/conecollisionshape.h"
52 #include "Physics/convexhullcollisionshape.h"
53 #include "Physics/cylindercollisionshape.h"
54 #include "Physics/multispherecollisionshape.h"
55 #include "Physics/spherecollisionshape.h"
56 #include "Physics/dynamicmeshcollisionshape.h"
57 #include "Physics/heightfieldcollisionshape.h"
58 #include "Physics/planecollisionshape.h"
59 #include "Physics/softcollisionshape.h"
60 #include "Physics/staticmeshcollisionshape.h"
61 #include "Physics/compoundcollisionshape.h"
64 #include "stringtool.h"
68 #include "btBulletDynamicsCommon.h"
69 #include "BulletSoftBody/btSoftRigidDynamicsWorld.h"
70 #include "BulletCollision/CollisionShapes/btShapeHull.h"
71 #include "BulletCollision/Gimpact/btGImpactShape.h"
72 #include "ConvexBuilder.h"
73 #include "Internal/decompinterface.h.cpp"
74 #include <btBulletWorldImporter.h>
80 template<> Physics::CollisionShapeManager* Singleton<Physics::CollisionShapeManager>::SingletonPtr = NULL;
104 Ogre::SubMesh* subMesh = NULL;
105 Ogre::IndexData* IndexData = NULL;
106 Ogre::VertexData* VertexData = NULL;
107 bool use32bitindexes =
false;
108 unsigned int triCount = 0;
109 unsigned int vCount = 0;
110 unsigned int iCount = 0;
111 Whole VertPrevSize = 0;
112 Whole IndiPrevSize = 0;
113 Ogre::Vector3* vertices = NULL;
114 unsigned long* indices = NULL;
115 bool SharedVerts = myMesh->getSubMesh(0)->useSharedVertices;
119 for(
Whole X = 0 ; X < myMesh->getNumSubMeshes() ; X++ )
121 vCount += SharedVerts ? myMesh->sharedVertexData->vertexCount : myMesh->getSubMesh(X)->vertexData->vertexCount;
122 iCount += myMesh->getSubMesh(X)->indexData->indexCount;
125 vCount += SharedVerts ? myMesh->sharedVertexData->vertexCount : myMesh->getSubMesh(0)->vertexData->vertexCount;
126 iCount += myMesh->getSubMesh(0)->indexData->indexCount;
129 vertices =
new Ogre::Vector3[vCount];
130 indices =
new unsigned long[iCount];
133 for(
unsigned short int SubMeshIndex = 0 ; SubMeshIndex < myMesh->getNumSubMeshes() ; SubMeshIndex++ )
135 if( !UseAllSubmeshes && ( SubMeshIndex > 0 ) )
137 if( SharedVerts && (SubMeshIndex > 0) )
140 subMesh = myMesh->getSubMesh(SubMeshIndex);
141 IndexData = subMesh->indexData;
142 VertexData = SharedVerts ? myMesh->sharedVertexData : myMesh->getSubMesh(SubMeshIndex)->vertexData;
145 const Ogre::VertexElement* posElem = VertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
147 Ogre::HardwareVertexBufferSharedPtr vBuffer = VertexData->vertexBufferBinding->getBuffer(posElem->getSource());
149 Ogre::HardwareIndexBufferSharedPtr iBuffer = IndexData->indexBuffer;
151 triCount += ( IndexData->indexCount / 3 );
154 unsigned char* vertex =
static_cast<unsigned char*
>(vBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
156 for (
size_t j = 0; j < VertexData->vertexCount; ++j, vertex += vBuffer->getVertexSize() )
158 posElem->baseVertexPointerToElement(vertex, &pReal);
159 Ogre::Vector3 pt(pReal[0], pReal[1], pReal[2]);
160 vertices[j + VertPrevSize] = pt;
163 size_t index_offset = 0;
164 use32bitindexes = (iBuffer->getType() == Ogre::HardwareIndexBuffer::IT_32BIT);
167 unsigned long* pLong =
static_cast<unsigned long*
>(iBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
168 unsigned short* pShort =
reinterpret_cast<unsigned short*
>(pLong);
170 if( use32bitindexes )
172 for (
size_t k = 0; k < triCount*3; ++k)
174 indices[index_offset+IndiPrevSize] = pLong[k];
178 for (
size_t k = 0; k < triCount*3; ++k)
180 indices[index_offset+IndiPrevSize] =
static_cast<unsigned long>(pShort[k]);
186 VertPrevSize+=VertexData->vertexCount;
187 IndiPrevSize+=IndexData->indexCount;
193 btTriangleMesh* trimesh =
new btTriangleMesh(use32bitindexes);
196 btVector3 vert0, vert1, vert2;
200 for (
unsigned int y=0; y<triCount; y++)
203 vert0.setValue(vertices[indices[i]].x, vertices[indices[i]].y, vertices[indices[i]].z);
204 vert1.setValue(vertices[indices[i+1]].x, vertices[indices[i+1]].y, vertices[indices[i+1]].z);
205 vert2.setValue(vertices[indices[i+2]].x, vertices[indices[i+2]].y, vertices[indices[i+2]].z);
208 trimesh->addTriangle(vert0, vert1, vert2);
221 switch(InternalShape->getShapeType())
223 case BOX_SHAPE_PROXYTYPE:
229 case CAPSULE_SHAPE_PROXYTYPE:
235 case CONE_SHAPE_PROXYTYPE:
241 case CONVEX_HULL_SHAPE_PROXYTYPE:
244 return ConvexHullShape;
247 case CYLINDER_SHAPE_PROXYTYPE:
250 return CylinderShape;
253 case MULTI_SPHERE_SHAPE_PROXYTYPE:
256 return MultiSphereShape;
259 case SPHERE_SHAPE_PROXYTYPE:
265 case GIMPACT_SHAPE_PROXYTYPE:
271 case TERRAIN_SHAPE_PROXYTYPE:
274 return HeightFieldShape;
277 case STATIC_PLANE_PROXYTYPE:
283 case SOFTBODY_SHAPE_PROXYTYPE:
286 return SoftBodyShape;
289 case TRIANGLE_MESH_SHAPE_PROXYTYPE:
295 case COMPOUND_SHAPE_PROXYTYPE:
316 if((*CS).second != Shape)
329 else return (*CS).second;
396 btConvexShape *tmpshape =
new btConvexTriangleMeshShape(this->
CreateBulletTrimesh(ObjectMesh,UseAllSubmeshes));
397 btShapeHull *hull =
new btShapeHull(tmpshape);
398 btScalar margin = tmpshape->getMargin();
399 hull->buildHull(margin);
401 btConvexHullShape* convexShape =
new btConvexHullShape();
402 for (
int b=0;b<hull->numVertices();b++)
404 convexShape->addPoint(hull->getVertexPointer()[b]);
419 btGImpactMeshShape* gimpact =
new btGImpactMeshShape(this->
CreateBulletTrimesh(ObjectMesh,UseAllSubmeshes));
431 btBvhTriangleMeshShape* tmpshape =
new btBvhTriangleMeshShape(this->
CreateBulletTrimesh(ObjectMesh,UseAllSubmeshes),
true);
445 Ogre::SubMesh* subMesh = NULL;
446 Ogre::IndexData* indexData = NULL;
447 Ogre::VertexData* vertexData = NULL;
448 bool use32bitindexes =
false;
449 unsigned int currtriCount = 0;
450 unsigned int triCount = 0;
451 unsigned int vCount = 0;
452 unsigned int iCount = 0;
453 Whole VertPrevSize = 0;
454 Whole IndiPrevSize = 0;
455 bool SharedVerts = myMesh->getSubMesh(0)->useSharedVertices;
457 Whole* VertPerSubMesh = NULL;
461 VertPerSubMesh =
new Whole[myMesh->getNumSubMeshes()];
462 for(
Whole X = 0 ; X < myMesh->getNumSubMeshes() ; X++ )
464 vCount += SharedVerts ? myMesh->sharedVertexData->vertexCount : myMesh->getSubMesh(X)->vertexData->vertexCount;
465 iCount += myMesh->getSubMesh(X)->indexData->indexCount;
466 VertPerSubMesh[X] = SharedVerts ? myMesh->sharedVertexData->vertexCount : myMesh->getSubMesh(X)->vertexData->vertexCount;
469 vCount += SharedVerts ? myMesh->sharedVertexData->vertexCount : myMesh->getSubMesh(0)->vertexData->vertexCount;
470 iCount += myMesh->getSubMesh(0)->indexData->indexCount;
473 Ogre::Vector3* vertices =
new Ogre::Vector3[vCount];
474 unsigned int* indices =
new unsigned int[iCount];
476 for(
unsigned short int SubMeshIndex = 0 ; SubMeshIndex < myMesh->getNumSubMeshes() ; SubMeshIndex++ )
478 if( !UseAllSubmeshes && (SubMeshIndex > 0) )
480 if( SharedVerts && (SubMeshIndex > 0) )
483 subMesh = myMesh->getSubMesh(SubMeshIndex);
484 indexData = subMesh->indexData;
485 vertexData = SharedVerts ? myMesh->sharedVertexData : myMesh->getSubMesh(SubMeshIndex)->vertexData;
487 const Ogre::VertexElement* posElem = vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
488 Ogre::HardwareVertexBufferSharedPtr vBuffer = vertexData->vertexBufferBinding->getBuffer(posElem->getSource());
489 Ogre::HardwareIndexBufferSharedPtr iBuffer = indexData->indexBuffer;
490 currtriCount=indexData->indexCount/3;
491 triCount+=(indexData->indexCount/3);
493 unsigned char* vertex =
static_cast<unsigned char*
>(vBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
495 for(
size_t j = 0 ; j < vertexData->vertexCount ; j++, vertex += vBuffer->getVertexSize() )
497 posElem->baseVertexPointerToElement(vertex, &pReal);
498 vertices[j + VertPrevSize].x = *pReal++;
499 vertices[j + VertPrevSize].y = *pReal++;
500 vertices[j + VertPrevSize].z = *pReal++;
503 size_t index_offset = 0;
504 use32bitindexes = (iBuffer->getType() == Ogre::HardwareIndexBuffer::IT_32BIT);
506 unsigned long* pLong =
static_cast<unsigned long*
>(iBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
507 unsigned short* pShort =
reinterpret_cast<unsigned short*
>(pLong);
509 if( use32bitindexes )
511 for (
size_t k = 0; k < currtriCount*3; ++k)
513 if(SubMeshIndex > 0 && VertPerSubMesh) {
514 indices[index_offset+IndiPrevSize] = pLong[k] + VertPerSubMesh[SubMeshIndex];
516 indices[index_offset+IndiPrevSize] = pLong[k];
521 for(
size_t k = 0 ; k < currtriCount * 3 ; ++k )
523 if(SubMeshIndex > 0 && VertPerSubMesh) {
524 indices[index_offset+IndiPrevSize] = (
static_cast<unsigned long>(pShort[k])) + VertPerSubMesh[SubMeshIndex];
526 indices[index_offset+IndiPrevSize] =
static_cast<unsigned long>(pShort[k]);
533 VertPrevSize += vertexData->vertexCount;
534 IndiPrevSize += indexData->indexCount;
537 ConvexDecomposition::DecompDesc desc;
538 desc.mVcount = vertexData->vertexCount;
539 desc.mTcount = triCount;
540 desc.mVertices = &vertices[0].x;
541 desc.mIndices = &indices[0];
542 unsigned int maxv = 16;
543 float skinWidth = 0.0;
545 desc.mCpercent = CPercent;
546 desc.mPpercent = PPercent;
547 desc.mMaxVertices = maxv;
548 desc.mSkinWidth = skinWidth;
550 Internal::MezzConvexDecomposition decomp;
551 desc.mCallback = &decomp;
553 ConvexBuilder cb(desc.mCallback);
559 for (
int i=0;i<decomp.m_convexShapes.size();i++)
561 std::stringstream namestream;
562 namestream << Name <<
"Child" << i;
563 Vector3 centroid(decomp.m_convexCentroids[i]);
569 delete[] VertPerSubMesh;
592 if( ShapesRoot.
Empty() ) {
599 this->
CollisionShapes.insert( std::pair<String,CollisionShape*>(DeSerializedShape->
GetName(),DeSerializedShape) );
613 (*ShapeIt).second->ProtoSerialize( ShapesRoot );
632 for(
ShapeVectorIterator ShapeIt = ShapesToSave.begin() ; ShapeIt != ShapesToSave.end() ; ++ShapeIt )
634 (*ShapeIt)->ProtoSerialize( ShapesRoot );
647 btBulletWorldImporter Importer;
648 Ogre::DataStreamPtr Stream = Ogre::ResourceGroupManager::getSingleton().openResource(FileName,Group);
649 char* buffer =
new char[Stream->size()];
650 Stream->read((
void*)buffer, Stream->size());
651 if(!Importer.loadFileFromMemory(buffer, Stream->size()))
656 for(
Whole X = 0 ; X < Importer.getNumCollisionShapes() ; ++X )
658 btCollisionShape* Shape = Importer.getCollisionShapeByIndex(X);
659 const char* MaybeAName = Importer.getNameForPointer((
void*)Shape);
663 Name =
String(MaybeAName);
668 this->
CollisionShapes.insert( std::pair<String,CollisionShape*>(Name,NewShape) );
671 static Whole NameCount = 0;
681 btDefaultSerializer* BulletSerializer =
new btDefaultSerializer(1024*1024*5);
682 BulletSerializer->startSerialization();
686 BulletSerializer->registerNameForPointer((
void*)Shape->
_GetInternalShape(),(*it).first.c_str());
688 btChunk* chunk = BulletSerializer->allocate(len,1);
689 const char* structType = Shape->
_GetInternalShape()->serialize(chunk->m_oldPtr, BulletSerializer);
690 BulletSerializer->finalizeChunk(chunk,structType,BT_SHAPE_CODE,Shape->
_GetInternalShape());
692 BulletSerializer->finishSerialization();
693 FILE* f2 = fopen(FileName.c_str(),
"wb");
694 fwrite(BulletSerializer->getBufferPointer(),BulletSerializer->getCurrentBufferSize(),1,f2);
700 btDefaultSerializer* BulletSerializer =
new btDefaultSerializer(1024*1024*5);
701 BulletSerializer->startSerialization();
705 BulletSerializer->registerNameForPointer((
void*)Shape->
_GetInternalShape(),(*it)->GetName().c_str());
707 btChunk* chunk = BulletSerializer->allocate(len,1);
708 const char* structType = Shape->
_GetInternalShape()->serialize(chunk->m_oldPtr, BulletSerializer);
709 BulletSerializer->finalizeChunk(chunk,structType,BT_SHAPE_CODE,Shape->
_GetInternalShape());
711 BulletSerializer->finishSerialization();
712 FILE* f2 = fopen(FileName.c_str(),
"wb");
713 fwrite(BulletSerializer->getBufferPointer(),BulletSerializer->getCurrentBufferSize(),1,f2);
729 if( (*ShapeIt) == Shape ) {
741 this->
CollisionShapes.insert( std::pair<String,CollisionShape*>(NewName,Shape) );
757 {
return ManagerBase::MT_CollisionShapeManager; }
760 {
return "DefaultCollisionShapeManager"; }
775 return "DefaultCollisionShapeManager";
798 delete ToBeDestroyed;