Allow btBulletWorldImporter to convert/export a .bullet file to XML
Add first version of btBulletXmlWorldImporter, still incomplete but it can read some files Fix false assert in btSequentialImpulseConstraintSolver
This commit is contained in:
@@ -52,7 +52,7 @@ ${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL
|
||||
)
|
||||
|
||||
LINK_LIBRARIES(
|
||||
LibOpenGLSupport LibBulletDynamics LibBulletCollision LibLinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY}
|
||||
OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY}
|
||||
)
|
||||
|
||||
ADD_EXECUTABLE(BulletDino
|
||||
|
||||
@@ -11,7 +11,7 @@ IF (USE_GLUT)
|
||||
IF(BUILD_CPU_DEMOS)
|
||||
SET(SharedDemoSubdirs
|
||||
OpenGL AllBulletDemos ConvexDecompositionDemo
|
||||
CcdPhysicsDemo ConstraintDemo SliderConstraintDemo GenericJointDemo Raytracer
|
||||
CcdPhysicsDemo BulletXmlImportDemo ConstraintDemo SliderConstraintDemo GenericJointDemo Raytracer
|
||||
RagdollDemo ForkLiftDemo BasicDemo RollingFrictionDemo RaytestDemo VoronoiFractureDemo GyroscopicDemo FractureDemo Box2dDemo BspDemo MovingConcaveDemo VehicleDemo
|
||||
UserCollisionAlgorithm CharacterDemo SoftDemo
|
||||
CollisionInterfaceDemo ConcaveConvexcastDemo SimplexDemo DynamicControlDemo
|
||||
|
||||
@@ -141,7 +141,7 @@ void RollingFrictionDemo::initPhysics()
|
||||
{
|
||||
|
||||
///create a few basic rigid bodies
|
||||
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.)));
|
||||
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(100.),btScalar(50.),btScalar(100.)));
|
||||
|
||||
m_collisionShapes.push_back(groundShape);
|
||||
|
||||
|
||||
@@ -754,8 +754,9 @@ void SerializeDemo::initPhysics()
|
||||
#else
|
||||
m_fileLoader = new btBulletWorldImporter(m_dynamicsWorld);
|
||||
#endif //DESERIALIZE_SOFT_BODIES
|
||||
// fileLoader->setVerboseMode(true);
|
||||
|
||||
|
||||
//m_fileLoader->setVerboseMode(bParse::FD_VERBOSE_EXPORT_XML);
|
||||
|
||||
|
||||
|
||||
if (!m_fileLoader->loadFile("testFile.bullet"))
|
||||
|
||||
@@ -60,9 +60,9 @@ bMain* bBlenderFile::getMain()
|
||||
// ----------------------------------------------------- //
|
||||
void bBlenderFile::parseData()
|
||||
{
|
||||
printf ("Building datablocks\n");
|
||||
printf ("Chunk size = %d\n",CHUNK_HEADER_LEN);
|
||||
printf ("File chunk size = %d\n", ChunkUtils::getOffset(mFlags));
|
||||
// printf ("Building datablocks\n");
|
||||
// printf ("Chunk size = %d\n",CHUNK_HEADER_LEN);
|
||||
// printf ("File chunk size = %d\n", ChunkUtils::getOffset(mFlags));
|
||||
|
||||
const bool swap = (mFlags&FD_ENDIAN_SWAP)!=0;
|
||||
|
||||
@@ -166,15 +166,15 @@ void bBlenderFile::writeDNA(FILE* fp)
|
||||
}
|
||||
}
|
||||
|
||||
void bBlenderFile::parse(bool verboseDumpAllTypes)
|
||||
void bBlenderFile::parse(int verboseMode)
|
||||
{
|
||||
if (VOID_IS_8)
|
||||
{
|
||||
parseInternal(verboseDumpAllTypes,(char*)DNAstr64,DNAlen64);
|
||||
parseInternal(verboseMode,(char*)DNAstr64,DNAlen64);
|
||||
}
|
||||
else
|
||||
{
|
||||
parseInternal(verboseDumpAllTypes,(char*)DNAstr,DNAlen);
|
||||
parseInternal(verboseMode,(char*)DNAstr,DNAlen);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace bParse {
|
||||
// experimental
|
||||
virtual int write(const char* fileName, bool fixupPointers = false);
|
||||
|
||||
virtual void parse(bool verboseDumpAllTypes);
|
||||
virtual void parse(int verboseMode);
|
||||
|
||||
virtual void parseData();
|
||||
|
||||
|
||||
@@ -347,7 +347,6 @@ static int name_is_array(char* name, int* dim1, int* dim2) {
|
||||
// ----------------------------------------------------- //
|
||||
void bDNA::init(char *data, int len, bool swap)
|
||||
{
|
||||
printf("swap = %d\n",swap);
|
||||
int *intPtr=0;short *shtPtr=0;
|
||||
char *cp = 0;int dataLen =0;long nr=0;
|
||||
intPtr = (int*)data;
|
||||
|
||||
@@ -21,11 +21,32 @@ subject to the following restrictions:
|
||||
#include <stdlib.h>
|
||||
#include "bDefines.h"
|
||||
#include "LinearMath/btSerializer.h"
|
||||
#include "LinearMath/btAlignedAllocator.h"
|
||||
#include "LinearMath/btMinMax.h"
|
||||
|
||||
#define SIZEOFBLENDERHEADER 12
|
||||
#define MAX_ARRAY_LENGTH 512
|
||||
using namespace bParse;
|
||||
#define MAX_STRLEN 1024
|
||||
|
||||
const char* getCleanName(const char* memName, char* buffer)
|
||||
{
|
||||
int slen = strlen(memName);
|
||||
assert(slen<MAX_STRLEN);
|
||||
slen=btMin(slen,MAX_STRLEN);
|
||||
for (int i=0;i<slen;i++)
|
||||
{
|
||||
if (memName[i]==']'||memName[i]=='[')
|
||||
{
|
||||
buffer[i] = 0;//'_';
|
||||
} else
|
||||
{
|
||||
buffer[i] = memName[i];
|
||||
}
|
||||
}
|
||||
buffer[slen]=0;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
int numallocs = 0;
|
||||
@@ -119,7 +140,6 @@ void bFile::parseHeader()
|
||||
if (strncmp(header, m_headerString, 6)!=0)
|
||||
{
|
||||
memcpy(header, m_headerString, SIZEOFBLENDERHEADER);
|
||||
printf ("Invalid %s file...",header);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -131,8 +151,9 @@ void bFile::parseHeader()
|
||||
char *ver = header+9;
|
||||
mVersion = atoi(ver);
|
||||
if (mVersion <= 241)
|
||||
printf ("Warning, %d not fully tested : <= 242\n", mVersion);
|
||||
|
||||
{
|
||||
//printf("Warning, %d not fully tested : <= 242\n", mVersion);
|
||||
}
|
||||
|
||||
int littleEndian= 1;
|
||||
littleEndian= ((char*)&littleEndian)[0];
|
||||
@@ -157,16 +178,6 @@ void bFile::parseHeader()
|
||||
mFlags |= FD_ENDIAN_SWAP;
|
||||
|
||||
|
||||
printf ("%s\n",header);
|
||||
printf ("\nsizeof(void*) == %d\n",int(sizeof(void*)));
|
||||
const char* endStr = ((mFlags & FD_ENDIAN_SWAP)!=0) ? "yes" : "no";
|
||||
printf ("Swapping endian? %s\n",endStr);
|
||||
const char* bitStr = (mFlags &FD_FILE_64)!=0 ? "64 bit" : "32bit";
|
||||
printf ("File format is %s\n",bitStr);
|
||||
const char* varStr = (mFlags & FD_BITS_VARIES)!=0 ? "yes" : "no";
|
||||
printf ("Varing pointer sizes? %s\n",varStr);
|
||||
|
||||
|
||||
mFlags |= FD_OK;
|
||||
}
|
||||
|
||||
@@ -177,7 +188,7 @@ bool bFile::ok()
|
||||
}
|
||||
|
||||
// ----------------------------------------------------- //
|
||||
void bFile::parseInternal(bool verboseDumpAllTypes, char* memDna,int memDnaLength)
|
||||
void bFile::parseInternal(int verboseMode, char* memDna,int memDnaLength)
|
||||
{
|
||||
if ( (mFlags &FD_OK) ==0)
|
||||
return;
|
||||
@@ -223,7 +234,7 @@ void bFile::parseInternal(bool verboseDumpAllTypes, char* memDna,int memDnaLengt
|
||||
}
|
||||
if (!dna.oldPtr || !dna.len)
|
||||
{
|
||||
printf("Failed to find DNA1+SDNA pair\n");
|
||||
//printf("Failed to find DNA1+SDNA pair\n");
|
||||
mFlags &= ~FD_OK;
|
||||
return;
|
||||
}
|
||||
@@ -244,16 +255,14 @@ void bFile::parseInternal(bool verboseDumpAllTypes, char* memDna,int memDnaLengt
|
||||
}
|
||||
if ((mFlags&FD_BROKEN_DNA)!=0)
|
||||
{
|
||||
printf("warning: fixing some broken DNA version\n");
|
||||
//printf("warning: fixing some broken DNA version\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (verboseDumpAllTypes)
|
||||
{
|
||||
if (verboseMode & FD_VERBOSE_DUMP_DNA_TYPE_DEFINITIONS)
|
||||
mFileDNA->dumpTypeDefinitions();
|
||||
}
|
||||
|
||||
mMemoryDNA = new bDNA();
|
||||
int littleEndian= 1;
|
||||
@@ -268,24 +277,24 @@ void bFile::parseInternal(bool verboseDumpAllTypes, char* memDna,int memDnaLengt
|
||||
if (mMemoryDNA->getNumNames() != mFileDNA->getNumNames())
|
||||
{
|
||||
mFlags |= FD_VERSION_VARIES;
|
||||
printf ("Warning, file DNA is different than built in, performance is reduced. Best to re-export file with a matching version/platform");
|
||||
//printf ("Warning, file DNA is different than built in, performance is reduced. Best to re-export file with a matching version/platform");
|
||||
}
|
||||
|
||||
// as long as it kept up to date it will be ok!!
|
||||
if (mMemoryDNA->lessThan(mFileDNA))
|
||||
{
|
||||
printf ("Warning, file DNA is newer than built in.");
|
||||
//printf ("Warning, file DNA is newer than built in.");
|
||||
}
|
||||
|
||||
mFileDNA->initCmpFlags(mMemoryDNA);
|
||||
|
||||
parseData();
|
||||
|
||||
resolvePointers(verboseDumpAllTypes);//verboseDumpAllBlocks);
|
||||
resolvePointers(verboseMode);
|
||||
|
||||
updateOldPointers();
|
||||
|
||||
printf("numAllocs = %d\n",numallocs);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -876,7 +885,7 @@ void bFile::resolvePointersMismatch()
|
||||
|
||||
|
||||
///this loop only works fine if the Blender DNA structure of the file matches the headerfiles
|
||||
void bFile::resolvePointersChunk(const bChunkInd& dataChunk, bool verboseDumpAllBlocks)
|
||||
void bFile::resolvePointersChunk(const bChunkInd& dataChunk, int verboseMode)
|
||||
{
|
||||
bParse::bDNA* fileDna = mFileDNA ? mFileDNA : mMemoryDNA;
|
||||
|
||||
@@ -887,13 +896,13 @@ void bFile::resolvePointersChunk(const bChunkInd& dataChunk, bool verboseDumpAll
|
||||
char* cur = (char*)findLibPointer(dataChunk.oldPtr);
|
||||
for (int block=0; block<dataChunk.nr; block++)
|
||||
{
|
||||
resolvePointersStructRecursive(cur,dataChunk.dna_nr, verboseDumpAllBlocks,1);
|
||||
resolvePointersStructRecursive(cur,dataChunk.dna_nr, verboseMode,1);
|
||||
cur += oldLen;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void bFile::resolvePointersStructRecursive(char *strcPtr, int dna_nr, bool verboseDumpAllBlocks,int recursion)
|
||||
int bFile::resolvePointersStructRecursive(char *strcPtr, int dna_nr, int verboseMode,int recursion)
|
||||
{
|
||||
|
||||
bParse::bDNA* fileDna = mFileDNA ? mFileDNA : mMemoryDNA;
|
||||
@@ -910,6 +919,7 @@ void bFile::resolvePointersStructRecursive(char *strcPtr, int dna_nr, bool verbo
|
||||
int elementLength = oldStruct[1];
|
||||
oldStruct+=2;
|
||||
|
||||
int totalSize = 0;
|
||||
|
||||
for (int ele=0; ele<elementLength; ele++, oldStruct+=2)
|
||||
{
|
||||
@@ -926,13 +936,38 @@ void bFile::resolvePointersStructRecursive(char *strcPtr, int dna_nr, bool verbo
|
||||
{
|
||||
void **array= (void**)elemPtr;
|
||||
for (int a=0; a<arrayLen; a++)
|
||||
{
|
||||
if (verboseMode & FD_VERBOSE_EXPORT_XML)
|
||||
{
|
||||
for (int i=0;i<recursion;i++)
|
||||
{
|
||||
printf(" ");
|
||||
}
|
||||
//skip the *
|
||||
printf("<%s type=\"pointer\"> ",&memName[1]);
|
||||
printf("%d ", array[a]);
|
||||
printf("</%s>\n",&memName[1]);
|
||||
}
|
||||
|
||||
array[a] = findLibPointer(array[a]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
void** ptrptr = (void**) elemPtr;
|
||||
void* ptr = *ptrptr;
|
||||
if (verboseMode & FD_VERBOSE_EXPORT_XML)
|
||||
{
|
||||
for (int i=0;i<recursion;i++)
|
||||
{
|
||||
printf(" ");
|
||||
}
|
||||
printf("<%s type=\"pointer\"> ",&memName[1]);
|
||||
printf("%d ", ptr);
|
||||
printf("</%s>\n",&memName[1]);
|
||||
}
|
||||
ptr = findLibPointer(ptr);
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
// printf("Fixup pointer at 0x%x from 0x%x to 0x%x!\n",ptrptr,*ptrptr,ptr);
|
||||
@@ -960,27 +995,44 @@ void bFile::resolvePointersStructRecursive(char *strcPtr, int dna_nr, bool verbo
|
||||
int revType = fileDna->getReverseType(oldStruct[0]);
|
||||
if (oldStruct[0]>=firstStructType) //revType != -1 &&
|
||||
{
|
||||
if (verboseDumpAllBlocks)
|
||||
char cleanName[MAX_STRLEN];
|
||||
getCleanName(memName,cleanName);
|
||||
|
||||
int arrayLen = fileDna->getArraySizeNew(oldStruct[1]);
|
||||
int byteOffset = 0;
|
||||
|
||||
if (verboseMode & FD_VERBOSE_EXPORT_XML)
|
||||
{
|
||||
for (int i=0;i<recursion;i++)
|
||||
{
|
||||
printf(" ");
|
||||
}
|
||||
printf("<%s type=\"%s\">\n",memName,memType);
|
||||
|
||||
if (arrayLen>1)
|
||||
{
|
||||
printf("<%s type=\"%s\" count=%d>\n",cleanName,memType, arrayLen);
|
||||
} else
|
||||
{
|
||||
printf("<%s type=\"%s\">\n",cleanName,memType);
|
||||
}
|
||||
}
|
||||
resolvePointersStructRecursive(elemPtr,revType, verboseDumpAllBlocks,recursion+1);
|
||||
if (verboseDumpAllBlocks)
|
||||
|
||||
for (int i=0;i<arrayLen;i++)
|
||||
{
|
||||
byteOffset += resolvePointersStructRecursive(elemPtr+byteOffset,revType, verboseMode,recursion+1);
|
||||
}
|
||||
if (verboseMode & FD_VERBOSE_EXPORT_XML)
|
||||
{
|
||||
for (int i=0;i<recursion;i++)
|
||||
{
|
||||
printf(" ");
|
||||
}
|
||||
printf("</%s>\n",memName);
|
||||
printf("</%s>\n",cleanName);
|
||||
}
|
||||
} else
|
||||
{
|
||||
//export a simple type
|
||||
if (verboseDumpAllBlocks)
|
||||
if (verboseMode & FD_VERBOSE_EXPORT_XML)
|
||||
{
|
||||
|
||||
if (arrayLen>MAX_ARRAY_LENGTH)
|
||||
@@ -1001,17 +1053,20 @@ void bFile::resolvePointersStructRecursive(char *strcPtr, int dna_nr, bool verbo
|
||||
dbPtr = &dbarray[0];
|
||||
if (dbPtr)
|
||||
{
|
||||
char cleanName[MAX_STRLEN];
|
||||
getCleanName(memName,cleanName);
|
||||
|
||||
int i;
|
||||
getElement(arrayLen, newtype,memType, tmp, (char*)dbPtr);
|
||||
for (i=0;i<recursion;i++)
|
||||
printf(" ");
|
||||
if (arrayLen==1)
|
||||
printf("<%s type=\"%s\">",memName,memType);
|
||||
printf("<%s type=\"%s\">",cleanName,memType);
|
||||
else
|
||||
printf("<%s type=\"%s\" count=%d>",memName,memType,arrayLen);
|
||||
printf("<%s type=\"%s\" count=%d>",cleanName,memType,arrayLen);
|
||||
for (i=0;i<arrayLen;i++)
|
||||
printf(" %d ",dbPtr[i]);
|
||||
printf("</%s>\n",memName);
|
||||
printf("</%s>\n",cleanName);
|
||||
}
|
||||
} else
|
||||
{
|
||||
@@ -1026,13 +1081,20 @@ void bFile::resolvePointersStructRecursive(char *strcPtr, int dna_nr, bool verbo
|
||||
getElement(arrayLen, newtype,memType, tmp, (char*)dbPtr);
|
||||
for (i=0;i<recursion;i++)
|
||||
printf(" ");
|
||||
char cleanName[MAX_STRLEN];
|
||||
getCleanName(memName,cleanName);
|
||||
|
||||
if (arrayLen==1)
|
||||
{
|
||||
printf("<%s type=\"%s\">",memName,memType);
|
||||
}
|
||||
else
|
||||
printf("<%s type=\"%s\" count=%d>",memName,memType,arrayLen);
|
||||
{
|
||||
printf("<%s type=\"%s\" count=%d>",cleanName,memType,arrayLen);
|
||||
}
|
||||
for (i=0;i<arrayLen;i++)
|
||||
printf(" %f ",dbPtr[i]);
|
||||
printf("</%s>\n",memName);
|
||||
printf("</%s>\n",cleanName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1042,18 +1104,20 @@ void bFile::resolvePointersStructRecursive(char *strcPtr, int dna_nr, bool verbo
|
||||
}
|
||||
|
||||
int size = fileDna->getElementSize(oldStruct[0], oldStruct[1]);
|
||||
totalSize += size;
|
||||
elemPtr+=size;
|
||||
|
||||
}
|
||||
|
||||
return totalSize;
|
||||
}
|
||||
|
||||
|
||||
///Resolve pointers replaces the original pointers in structures, and linked lists by the new in-memory structures
|
||||
void bFile::resolvePointers(bool verboseDumpAllBlocks)
|
||||
void bFile::resolvePointers(int verboseMode)
|
||||
{
|
||||
bParse::bDNA* fileDna = mFileDNA ? mFileDNA : mMemoryDNA;
|
||||
|
||||
printf("resolvePointers start\n");
|
||||
//char *dataPtr = mFileBuffer+mDataStart;
|
||||
|
||||
if (1) //mFlags & (FD_BITS_VARIES | FD_VERSION_VARIES))
|
||||
@@ -1062,6 +1126,13 @@ void bFile::resolvePointers(bool verboseDumpAllBlocks)
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
if (verboseMode & FD_VERBOSE_EXPORT_XML)
|
||||
{
|
||||
printf("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
|
||||
int numitems = m_chunks.size();
|
||||
printf("<bullet_physics version=%d itemcount = %d>\n", btGetVersion(), numitems);
|
||||
}
|
||||
for (int i=0;i<m_chunks.size();i++)
|
||||
{
|
||||
const bChunkInd& dataChunk = m_chunks.at(i);
|
||||
@@ -1072,21 +1143,25 @@ void bFile::resolvePointers(bool verboseDumpAllBlocks)
|
||||
short int* oldStruct = fileDna->getStruct(dataChunk.dna_nr);
|
||||
char* oldType = fileDna->getType(oldStruct[0]);
|
||||
|
||||
if (verboseDumpAllBlocks)
|
||||
printf("<%s>\n",oldType);
|
||||
if (verboseMode & FD_VERBOSE_EXPORT_XML)
|
||||
printf(" <%s pointer=%d>\n",oldType,dataChunk.oldPtr);
|
||||
|
||||
resolvePointersChunk(dataChunk, verboseDumpAllBlocks);
|
||||
resolvePointersChunk(dataChunk, verboseMode);
|
||||
|
||||
if (verboseDumpAllBlocks)
|
||||
printf("</%s>\n",oldType);
|
||||
if (verboseMode & FD_VERBOSE_EXPORT_XML)
|
||||
printf(" </%s>\n",oldType);
|
||||
} else
|
||||
{
|
||||
//printf("skipping mStruct\n");
|
||||
}
|
||||
}
|
||||
if (verboseMode & FD_VERBOSE_EXPORT_XML)
|
||||
{
|
||||
printf("</bullet_physics>\n");
|
||||
}
|
||||
}
|
||||
|
||||
printf("resolvePointers end\n");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -36,7 +36,13 @@ namespace bParse {
|
||||
FD_BROKEN_DNA = 128
|
||||
};
|
||||
|
||||
|
||||
enum bFileVerboseMode
|
||||
{
|
||||
FD_VERBOSE_EXPORT_XML = 1,
|
||||
FD_VERBOSE_DUMP_DNA_TYPE_DEFINITIONS = 2,
|
||||
FD_VERBOSE_DUMP_CHUNKS = 4,
|
||||
FD_VERBOSE_DUMP_FILE_INFO=8,
|
||||
};
|
||||
// ----------------------------------------------------- //
|
||||
class bFile
|
||||
{
|
||||
@@ -80,9 +86,9 @@ namespace bParse {
|
||||
virtual void parseData() = 0;
|
||||
|
||||
void resolvePointersMismatch();
|
||||
void resolvePointersChunk(const bChunkInd& dataChunk, bool verboseDumpAllBlocks);
|
||||
void resolvePointersChunk(const bChunkInd& dataChunk, int verboseMode);
|
||||
|
||||
void resolvePointersStructRecursive(char *strcPtr, int old_dna, bool verboseDumpAllBlocks, int recursion);
|
||||
int resolvePointersStructRecursive(char *strcPtr, int old_dna, int verboseMode, int recursion);
|
||||
//void swapPtr(char *dst, char *src);
|
||||
|
||||
void parseStruct(char *strcPtr, char *dtPtr, int old_dna, int new_dna, bool fixupPointers);
|
||||
@@ -101,7 +107,7 @@ namespace bParse {
|
||||
char* readStruct(char *head, class bChunkInd& chunk);
|
||||
char *getAsString(int code);
|
||||
|
||||
void parseInternal(bool verboseDumpAllTypes, char* memDna,int memDnaLength);
|
||||
void parseInternal(int verboseMode, char* memDna,int memDnaLength);
|
||||
|
||||
public:
|
||||
bFile(const char *filename, const char headerString[7]);
|
||||
@@ -132,7 +138,7 @@ namespace bParse {
|
||||
|
||||
bool ok();
|
||||
|
||||
virtual void parse(bool verboseDumpAllTypes) = 0;
|
||||
virtual void parse(int verboseMode) = 0;
|
||||
|
||||
virtual int write(const char* fileName, bool fixupPointers=false) = 0;
|
||||
|
||||
@@ -141,7 +147,7 @@ namespace bParse {
|
||||
virtual void writeDNA(FILE* fp) = 0;
|
||||
|
||||
void updateOldPointers();
|
||||
void resolvePointers(bool verboseDumpAllBlocks);
|
||||
void resolvePointers(int verboseMode);
|
||||
|
||||
void dumpChunks(bDNA* dna);
|
||||
|
||||
|
||||
@@ -114,9 +114,9 @@ btBulletFile::~btBulletFile()
|
||||
// ----------------------------------------------------- //
|
||||
void btBulletFile::parseData()
|
||||
{
|
||||
printf ("Building datablocks");
|
||||
printf ("Chunk size = %d",CHUNK_HEADER_LEN);
|
||||
printf ("File chunk size = %d",ChunkUtils::getOffset(mFlags));
|
||||
// printf ("Building datablocks");
|
||||
// printf ("Chunk size = %d",CHUNK_HEADER_LEN);
|
||||
// printf ("File chunk size = %d",ChunkUtils::getOffset(mFlags));
|
||||
|
||||
const bool brokenDNA = (mFlags&FD_BROKEN_DNA)!=0;
|
||||
|
||||
@@ -282,7 +282,7 @@ void btBulletFile::writeDNA(FILE* fp)
|
||||
}
|
||||
|
||||
|
||||
void btBulletFile::parse(bool verboseDumpAllTypes)
|
||||
void btBulletFile::parse(int verboseMode)
|
||||
{
|
||||
#ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
|
||||
if (VOID_IS_8)
|
||||
@@ -293,7 +293,7 @@ void btBulletFile::parse(bool verboseDumpAllTypes)
|
||||
delete m_DnaCopy;
|
||||
m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64,16);
|
||||
memcpy(m_DnaCopy,sBulletDNAstr64,sBulletDNAlen64);
|
||||
parseInternal(verboseDumpAllTypes,(char*)sBulletDNAstr64,sBulletDNAlen64);
|
||||
parseInternal(verboseMode,(char*)sBulletDNAstr64,sBulletDNAlen64);
|
||||
#else
|
||||
btAssert(0);
|
||||
#endif
|
||||
@@ -306,7 +306,7 @@ void btBulletFile::parse(bool verboseDumpAllTypes)
|
||||
delete m_DnaCopy;
|
||||
m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen,16);
|
||||
memcpy(m_DnaCopy,sBulletDNAstr,sBulletDNAlen);
|
||||
parseInternal(verboseDumpAllTypes,m_DnaCopy,sBulletDNAlen);
|
||||
parseInternal(verboseMode,m_DnaCopy,sBulletDNAlen);
|
||||
#else
|
||||
btAssert(0);
|
||||
#endif
|
||||
@@ -318,7 +318,7 @@ void btBulletFile::parse(bool verboseDumpAllTypes)
|
||||
delete m_DnaCopy;
|
||||
m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64,16);
|
||||
memcpy(m_DnaCopy,sBulletDNAstr64,sBulletDNAlen64);
|
||||
parseInternal(verboseDumpAllTypes,m_DnaCopy,sBulletDNAlen64);
|
||||
parseInternal(verboseMode,m_DnaCopy,sBulletDNAlen64);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -326,7 +326,7 @@ void btBulletFile::parse(bool verboseDumpAllTypes)
|
||||
delete m_DnaCopy;
|
||||
m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen,16);
|
||||
memcpy(m_DnaCopy,sBulletDNAstr,sBulletDNAlen);
|
||||
parseInternal(verboseDumpAllTypes,m_DnaCopy,sBulletDNAlen);
|
||||
parseInternal(verboseMode,m_DnaCopy,sBulletDNAlen);
|
||||
}
|
||||
#endif//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace bParse {
|
||||
// experimental
|
||||
virtual int write(const char* fileName, bool fixupPointers=false);
|
||||
|
||||
virtual void parse(bool verboseDumpAllTypes);
|
||||
virtual void parse(int verboseMode);
|
||||
|
||||
virtual void parseData();
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ ADD_LIBRARY(
|
||||
BulletWorldImporter
|
||||
btBulletWorldImporter.cpp
|
||||
btBulletWorldImporter.h
|
||||
btWorldImporter.cpp
|
||||
btWorldImporter.h
|
||||
)
|
||||
|
||||
SET_TARGET_PROPERTIES(BulletWorldImporter PROPERTIES VERSION ${BULLET_VERSION})
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2010 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
Copyright (c) 2003-2012 Erwin Coumans http://bulletphysics.org
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
@@ -17,34 +17,12 @@ subject to the following restrictions:
|
||||
#ifndef BULLET_WORLD_IMPORTER_H
|
||||
#define BULLET_WORLD_IMPORTER_H
|
||||
|
||||
#include "LinearMath/btTransform.h"
|
||||
#include "LinearMath/btVector3.h"
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
#include "LinearMath/btHashMap.h"
|
||||
|
||||
#include "btWorldImporter.h"
|
||||
|
||||
|
||||
class btBulletFile;
|
||||
class btCollisionShape;
|
||||
class btCollisionObject;
|
||||
class btRigidBody;
|
||||
class btTypedConstraint;
|
||||
class btDynamicsWorld;
|
||||
struct ConstraintInput;
|
||||
class btRigidBodyColladaInfo;
|
||||
struct btCollisionShapeData;
|
||||
class btTriangleIndexVertexArray;
|
||||
class btStridingMeshInterface;
|
||||
struct btStridingMeshInterfaceData;
|
||||
class btGImpactMeshShape;
|
||||
class btOptimizedBvh;
|
||||
struct btTriangleInfoMap;
|
||||
class btBvhTriangleMeshShape;
|
||||
class btPoint2PointConstraint;
|
||||
class btHingeConstraint;
|
||||
class btConeTwistConstraint;
|
||||
class btGeneric6DofConstraint;
|
||||
class btGeneric6DofSpringConstraint;
|
||||
class btSliderConstraint;
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -59,53 +37,9 @@ namespace bParse
|
||||
///The btBulletWorldImporter is a starting point to import .bullet files.
|
||||
///note that not all data is converted yet. You are expected to override or modify this class.
|
||||
///See Bullet/Demos/SerializeDemo for a derived class that extract btSoftBody objects too.
|
||||
class btBulletWorldImporter
|
||||
class btBulletWorldImporter : public btWorldImporter
|
||||
{
|
||||
protected:
|
||||
|
||||
btDynamicsWorld* m_dynamicsWorld;
|
||||
|
||||
bool m_verboseDumpAllTypes;
|
||||
|
||||
btCollisionShape* convertCollisionShape( btCollisionShapeData* shapeData );
|
||||
|
||||
btAlignedObjectArray<btCollisionShape*> m_allocatedCollisionShapes;
|
||||
btAlignedObjectArray<btCollisionObject*> m_allocatedRigidBodies;
|
||||
btAlignedObjectArray<btTypedConstraint*> m_allocatedConstraints;
|
||||
btAlignedObjectArray<btOptimizedBvh*> m_allocatedBvhs;
|
||||
btAlignedObjectArray<btTriangleInfoMap*> m_allocatedTriangleInfoMaps;
|
||||
btAlignedObjectArray<btTriangleIndexVertexArray*> m_allocatedTriangleIndexArrays;
|
||||
btAlignedObjectArray<btStridingMeshInterfaceData*> m_allocatedbtStridingMeshInterfaceDatas;
|
||||
|
||||
btAlignedObjectArray<char*> m_allocatedNames;
|
||||
|
||||
btAlignedObjectArray<int*> m_indexArrays;
|
||||
btAlignedObjectArray<short int*> m_shortIndexArrays;
|
||||
btAlignedObjectArray<unsigned char*> m_charIndexArrays;
|
||||
|
||||
btAlignedObjectArray<btVector3FloatData*> m_floatVertexArrays;
|
||||
btAlignedObjectArray<btVector3DoubleData*> m_doubleVertexArrays;
|
||||
|
||||
|
||||
btHashMap<btHashPtr,btOptimizedBvh*> m_bvhMap;
|
||||
btHashMap<btHashPtr,btTriangleInfoMap*> m_timMap;
|
||||
|
||||
btHashMap<btHashString,btCollisionShape*> m_nameShapeMap;
|
||||
btHashMap<btHashString,btRigidBody*> m_nameBodyMap;
|
||||
btHashMap<btHashString,btTypedConstraint*> m_nameConstraintMap;
|
||||
btHashMap<btHashPtr,const char*> m_objectNameMap;
|
||||
|
||||
btHashMap<btHashPtr,btCollisionShape*> m_shapeMap;
|
||||
btHashMap<btHashPtr,btCollisionObject*> m_bodyMap;
|
||||
|
||||
|
||||
//methods
|
||||
|
||||
|
||||
|
||||
static btRigidBody& getFixedBody();
|
||||
|
||||
char* duplicateName(const char* name);
|
||||
|
||||
public:
|
||||
|
||||
@@ -113,10 +47,6 @@ public:
|
||||
|
||||
virtual ~btBulletWorldImporter();
|
||||
|
||||
///delete all memory collision shapes, rigid bodies, constraints etc. allocated during the load.
|
||||
///make sure you don't use the dynamics world containing objects after you call this method
|
||||
virtual void deleteAllData();
|
||||
|
||||
bool loadFile(const char* fileName);
|
||||
|
||||
///the memoryBuffer might be modified (for example if endian swaps are necessary)
|
||||
@@ -127,82 +57,8 @@ public:
|
||||
//call make sure bulletFile2 has been parsed, either using btBulletFile::parse or btBulletWorldImporter::loadFileFromMemory
|
||||
virtual bool convertAllObjects(bParse::btBulletFile* file);
|
||||
|
||||
void setVerboseMode(bool verboseDumpAllTypes)
|
||||
{
|
||||
m_verboseDumpAllTypes = verboseDumpAllTypes;
|
||||
}
|
||||
|
||||
bool getVerboseMode() const
|
||||
{
|
||||
return m_verboseDumpAllTypes;
|
||||
}
|
||||
|
||||
// query for data
|
||||
int getNumCollisionShapes() const;
|
||||
btCollisionShape* getCollisionShapeByIndex(int index);
|
||||
int getNumRigidBodies() const;
|
||||
btCollisionObject* getRigidBodyByIndex(int index) const;
|
||||
int getNumConstraints() const;
|
||||
btTypedConstraint* getConstraintByIndex(int index) const;
|
||||
int getNumBvhs() const;
|
||||
btOptimizedBvh* getBvhByIndex(int index) const;
|
||||
int getNumTriangleInfoMaps() const;
|
||||
btTriangleInfoMap* getTriangleInfoMapByIndex(int index) const;
|
||||
|
||||
// queris involving named objects
|
||||
btCollisionShape* getCollisionShapeByName(const char* name);
|
||||
btRigidBody* getRigidBodyByName(const char* name);
|
||||
btTypedConstraint* getConstraintByName(const char* name);
|
||||
const char* getNameForPointer(const void* ptr) const;
|
||||
|
||||
///those virtuals are called by load and can be overridden by the user
|
||||
|
||||
//bodies
|
||||
virtual btRigidBody* createRigidBody(bool isDynamic, btScalar mass, const btTransform& startTransform, btCollisionShape* shape,const char* bodyName);
|
||||
virtual btCollisionObject* createCollisionObject( const btTransform& startTransform, btCollisionShape* shape,const char* bodyName);
|
||||
|
||||
///shapes
|
||||
|
||||
virtual btCollisionShape* createPlaneShape(const btVector3& planeNormal,btScalar planeConstant);
|
||||
virtual btCollisionShape* createBoxShape(const btVector3& halfExtents);
|
||||
virtual btCollisionShape* createSphereShape(btScalar radius);
|
||||
virtual btCollisionShape* createCapsuleShapeX(btScalar radius, btScalar height);
|
||||
virtual btCollisionShape* createCapsuleShapeY(btScalar radius, btScalar height);
|
||||
virtual btCollisionShape* createCapsuleShapeZ(btScalar radius, btScalar height);
|
||||
|
||||
virtual btCollisionShape* createCylinderShapeX(btScalar radius,btScalar height);
|
||||
virtual btCollisionShape* createCylinderShapeY(btScalar radius,btScalar height);
|
||||
virtual btCollisionShape* createCylinderShapeZ(btScalar radius,btScalar height);
|
||||
virtual class btTriangleIndexVertexArray* createTriangleMeshContainer();
|
||||
virtual btBvhTriangleMeshShape* createBvhTriangleMeshShape(btStridingMeshInterface* trimesh, btOptimizedBvh* bvh);
|
||||
virtual btCollisionShape* createConvexTriangleMeshShape(btStridingMeshInterface* trimesh);
|
||||
virtual btGImpactMeshShape* createGimpactShape(btStridingMeshInterface* trimesh);
|
||||
virtual btStridingMeshInterfaceData* createStridingMeshInterfaceData(btStridingMeshInterfaceData* interfaceData);
|
||||
|
||||
virtual class btConvexHullShape* createConvexHullShape();
|
||||
virtual class btCompoundShape* createCompoundShape();
|
||||
virtual class btScaledBvhTriangleMeshShape* createScaledTrangleMeshShape(btBvhTriangleMeshShape* meshShape,const btVector3& localScalingbtBvhTriangleMeshShape);
|
||||
|
||||
virtual class btMultiSphereShape* createMultiSphereShape(const btVector3* positions,const btScalar* radi,int numSpheres);
|
||||
|
||||
virtual btTriangleIndexVertexArray* createMeshInterface(btStridingMeshInterfaceData& meshData);
|
||||
|
||||
///acceleration and connectivity structures
|
||||
virtual btOptimizedBvh* createOptimizedBvh();
|
||||
virtual btTriangleInfoMap* createTriangleInfoMap();
|
||||
|
||||
///constraints
|
||||
virtual btPoint2PointConstraint* createPoint2PointConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB);
|
||||
virtual btPoint2PointConstraint* createPoint2PointConstraint(btRigidBody& rbA,const btVector3& pivotInA);
|
||||
virtual btHingeConstraint* createHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA=false);
|
||||
virtual btHingeConstraint* createHingeConstraint(btRigidBody& rbA,const btTransform& rbAFrame, bool useReferenceFrameA=false);
|
||||
virtual btConeTwistConstraint* createConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB,const btTransform& rbAFrame, const btTransform& rbBFrame);
|
||||
virtual btConeTwistConstraint* createConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame);
|
||||
virtual btGeneric6DofConstraint* createGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA);
|
||||
virtual btGeneric6DofConstraint* createGeneric6DofConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB);
|
||||
virtual btGeneric6DofSpringConstraint* createGeneric6DofSpringConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA);
|
||||
virtual btSliderConstraint* createSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA);
|
||||
virtual btSliderConstraint* createSliderConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameA);
|
||||
|
||||
};
|
||||
|
||||
|
||||
1357
Extras/Serialize/BulletWorldImporter/btWorldImporter.cpp
Normal file
1357
Extras/Serialize/BulletWorldImporter/btWorldImporter.cpp
Normal file
File diff suppressed because it is too large
Load Diff
189
Extras/Serialize/BulletWorldImporter/btWorldImporter.h
Normal file
189
Extras/Serialize/BulletWorldImporter/btWorldImporter.h
Normal file
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2012 Erwin Coumans http://bulletphysics.org
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
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.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef BT_WORLD_IMPORTER_H
|
||||
#define BT_WORLD_IMPORTER_H
|
||||
|
||||
#include "LinearMath/btTransform.h"
|
||||
#include "LinearMath/btVector3.h"
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
#include "LinearMath/btHashMap.h"
|
||||
|
||||
class btCollisionShape;
|
||||
class btCollisionObject;
|
||||
class btRigidBody;
|
||||
class btTypedConstraint;
|
||||
class btDynamicsWorld;
|
||||
struct ConstraintInput;
|
||||
class btRigidBodyColladaInfo;
|
||||
struct btCollisionShapeData;
|
||||
class btTriangleIndexVertexArray;
|
||||
class btStridingMeshInterface;
|
||||
struct btStridingMeshInterfaceData;
|
||||
class btGImpactMeshShape;
|
||||
class btOptimizedBvh;
|
||||
struct btTriangleInfoMap;
|
||||
class btBvhTriangleMeshShape;
|
||||
class btPoint2PointConstraint;
|
||||
class btHingeConstraint;
|
||||
class btConeTwistConstraint;
|
||||
class btGeneric6DofConstraint;
|
||||
class btGeneric6DofSpringConstraint;
|
||||
class btSliderConstraint;
|
||||
|
||||
class btTypedConstraintData;
|
||||
struct btRigidBodyFloatData;
|
||||
|
||||
class btWorldImporter
|
||||
{
|
||||
protected:
|
||||
btDynamicsWorld* m_dynamicsWorld;
|
||||
|
||||
int m_verboseMode;
|
||||
|
||||
btAlignedObjectArray<btCollisionShape*> m_allocatedCollisionShapes;
|
||||
btAlignedObjectArray<btCollisionObject*> m_allocatedRigidBodies;
|
||||
btAlignedObjectArray<btTypedConstraint*> m_allocatedConstraints;
|
||||
btAlignedObjectArray<btOptimizedBvh*> m_allocatedBvhs;
|
||||
btAlignedObjectArray<btTriangleInfoMap*> m_allocatedTriangleInfoMaps;
|
||||
btAlignedObjectArray<btTriangleIndexVertexArray*> m_allocatedTriangleIndexArrays;
|
||||
btAlignedObjectArray<btStridingMeshInterfaceData*> m_allocatedbtStridingMeshInterfaceDatas;
|
||||
|
||||
btAlignedObjectArray<char*> m_allocatedNames;
|
||||
|
||||
btAlignedObjectArray<int*> m_indexArrays;
|
||||
btAlignedObjectArray<short int*> m_shortIndexArrays;
|
||||
btAlignedObjectArray<unsigned char*> m_charIndexArrays;
|
||||
|
||||
btAlignedObjectArray<btVector3FloatData*> m_floatVertexArrays;
|
||||
btAlignedObjectArray<btVector3DoubleData*> m_doubleVertexArrays;
|
||||
|
||||
|
||||
btHashMap<btHashPtr,btOptimizedBvh*> m_bvhMap;
|
||||
btHashMap<btHashPtr,btTriangleInfoMap*> m_timMap;
|
||||
|
||||
btHashMap<btHashString,btCollisionShape*> m_nameShapeMap;
|
||||
btHashMap<btHashString,btRigidBody*> m_nameBodyMap;
|
||||
btHashMap<btHashString,btTypedConstraint*> m_nameConstraintMap;
|
||||
btHashMap<btHashPtr,const char*> m_objectNameMap;
|
||||
|
||||
btHashMap<btHashPtr,btCollisionShape*> m_shapeMap;
|
||||
btHashMap<btHashPtr,btCollisionObject*> m_bodyMap;
|
||||
|
||||
|
||||
//methods
|
||||
|
||||
static btRigidBody& getFixedBody();
|
||||
|
||||
char* duplicateName(const char* name);
|
||||
|
||||
btCollisionShape* convertCollisionShape( btCollisionShapeData* shapeData );
|
||||
void convertConstraint(btTypedConstraintData* constraintData, btRigidBody* rbA, btRigidBody* rbB, bool isDoublePrecisionData, int fileVersion);
|
||||
void convertRigidBody(btRigidBodyFloatData* colObjData);
|
||||
|
||||
public:
|
||||
|
||||
btWorldImporter(btDynamicsWorld* world);
|
||||
|
||||
virtual ~btWorldImporter();
|
||||
|
||||
///delete all memory collision shapes, rigid bodies, constraints etc. allocated during the load.
|
||||
///make sure you don't use the dynamics world containing objects after you call this method
|
||||
virtual void deleteAllData();
|
||||
|
||||
void setVerboseMode(int verboseMode)
|
||||
{
|
||||
m_verboseMode = verboseMode;
|
||||
}
|
||||
|
||||
int getVerboseMode() const
|
||||
{
|
||||
return m_verboseMode;
|
||||
}
|
||||
|
||||
// query for data
|
||||
int getNumCollisionShapes() const;
|
||||
btCollisionShape* getCollisionShapeByIndex(int index);
|
||||
int getNumRigidBodies() const;
|
||||
btCollisionObject* getRigidBodyByIndex(int index) const;
|
||||
int getNumConstraints() const;
|
||||
btTypedConstraint* getConstraintByIndex(int index) const;
|
||||
int getNumBvhs() const;
|
||||
btOptimizedBvh* getBvhByIndex(int index) const;
|
||||
int getNumTriangleInfoMaps() const;
|
||||
btTriangleInfoMap* getTriangleInfoMapByIndex(int index) const;
|
||||
|
||||
// queris involving named objects
|
||||
btCollisionShape* getCollisionShapeByName(const char* name);
|
||||
btRigidBody* getRigidBodyByName(const char* name);
|
||||
btTypedConstraint* getConstraintByName(const char* name);
|
||||
const char* getNameForPointer(const void* ptr) const;
|
||||
|
||||
///those virtuals are called by load and can be overridden by the user
|
||||
|
||||
//bodies
|
||||
virtual btRigidBody* createRigidBody(bool isDynamic, btScalar mass, const btTransform& startTransform, btCollisionShape* shape,const char* bodyName);
|
||||
virtual btCollisionObject* createCollisionObject( const btTransform& startTransform, btCollisionShape* shape,const char* bodyName);
|
||||
|
||||
///shapes
|
||||
|
||||
virtual btCollisionShape* createPlaneShape(const btVector3& planeNormal,btScalar planeConstant);
|
||||
virtual btCollisionShape* createBoxShape(const btVector3& halfExtents);
|
||||
virtual btCollisionShape* createSphereShape(btScalar radius);
|
||||
virtual btCollisionShape* createCapsuleShapeX(btScalar radius, btScalar height);
|
||||
virtual btCollisionShape* createCapsuleShapeY(btScalar radius, btScalar height);
|
||||
virtual btCollisionShape* createCapsuleShapeZ(btScalar radius, btScalar height);
|
||||
|
||||
virtual btCollisionShape* createCylinderShapeX(btScalar radius,btScalar height);
|
||||
virtual btCollisionShape* createCylinderShapeY(btScalar radius,btScalar height);
|
||||
virtual btCollisionShape* createCylinderShapeZ(btScalar radius,btScalar height);
|
||||
virtual class btTriangleIndexVertexArray* createTriangleMeshContainer();
|
||||
virtual btBvhTriangleMeshShape* createBvhTriangleMeshShape(btStridingMeshInterface* trimesh, btOptimizedBvh* bvh);
|
||||
virtual btCollisionShape* createConvexTriangleMeshShape(btStridingMeshInterface* trimesh);
|
||||
virtual btGImpactMeshShape* createGimpactShape(btStridingMeshInterface* trimesh);
|
||||
virtual btStridingMeshInterfaceData* createStridingMeshInterfaceData(btStridingMeshInterfaceData* interfaceData);
|
||||
|
||||
virtual class btConvexHullShape* createConvexHullShape();
|
||||
virtual class btCompoundShape* createCompoundShape();
|
||||
virtual class btScaledBvhTriangleMeshShape* createScaledTrangleMeshShape(btBvhTriangleMeshShape* meshShape,const btVector3& localScalingbtBvhTriangleMeshShape);
|
||||
|
||||
virtual class btMultiSphereShape* createMultiSphereShape(const btVector3* positions,const btScalar* radi,int numSpheres);
|
||||
|
||||
virtual btTriangleIndexVertexArray* createMeshInterface(btStridingMeshInterfaceData& meshData);
|
||||
|
||||
///acceleration and connectivity structures
|
||||
virtual btOptimizedBvh* createOptimizedBvh();
|
||||
virtual btTriangleInfoMap* createTriangleInfoMap();
|
||||
|
||||
///constraints
|
||||
virtual btPoint2PointConstraint* createPoint2PointConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB);
|
||||
virtual btPoint2PointConstraint* createPoint2PointConstraint(btRigidBody& rbA,const btVector3& pivotInA);
|
||||
virtual btHingeConstraint* createHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA=false);
|
||||
virtual btHingeConstraint* createHingeConstraint(btRigidBody& rbA,const btTransform& rbAFrame, bool useReferenceFrameA=false);
|
||||
virtual btConeTwistConstraint* createConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB,const btTransform& rbAFrame, const btTransform& rbBFrame);
|
||||
virtual btConeTwistConstraint* createConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame);
|
||||
virtual btGeneric6DofConstraint* createGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA);
|
||||
virtual btGeneric6DofConstraint* createGeneric6DofConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB);
|
||||
virtual btGeneric6DofSpringConstraint* createGeneric6DofSpringConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA);
|
||||
virtual btSliderConstraint* createSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA);
|
||||
virtual btSliderConstraint* createSliderConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameA);
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //BT_WORLD_IMPORTER_H
|
||||
47
Extras/Serialize/BulletXmlWorldImporter/CMakeLists.txt
Normal file
47
Extras/Serialize/BulletXmlWorldImporter/CMakeLists.txt
Normal file
@@ -0,0 +1,47 @@
|
||||
INCLUDE_DIRECTORIES(
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/src
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletFileLoader
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletWorldImporter
|
||||
)
|
||||
|
||||
ADD_LIBRARY(
|
||||
BulletXmlWorldImporter
|
||||
btBulletXmlWorldImporter.cpp
|
||||
btBulletXmlWorldImporter.h
|
||||
string_split.cpp
|
||||
string_split.h
|
||||
tinyxml.cpp
|
||||
tinyxml.h
|
||||
tinystr.cpp
|
||||
tinystr.h
|
||||
tinyxmlerror.cpp
|
||||
tinyxmlparser.cpp
|
||||
)
|
||||
|
||||
SET_TARGET_PROPERTIES(BulletXmlWorldImporter PROPERTIES VERSION ${BULLET_VERSION})
|
||||
SET_TARGET_PROPERTIES(BulletXmlWorldImporter PROPERTIES SOVERSION ${BULLET_VERSION})
|
||||
|
||||
IF (BUILD_SHARED_LIBS)
|
||||
TARGET_LINK_LIBRARIES(BulletXmlWorldImporter BulletWorldImporter BulletDynamics BulletCollision BulletFileLoader LinearMath)
|
||||
ENDIF (BUILD_SHARED_LIBS)
|
||||
|
||||
IF (INSTALL_EXTRA_LIBS)
|
||||
IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
|
||||
#FILES_MATCHING requires CMake 2.6
|
||||
IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
|
||||
IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
INSTALL(TARGETS BulletXmlWorldImporter DESTINATION .)
|
||||
ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
INSTALL(TARGETS BulletXmlWorldImporter DESTINATION lib${LIB_SUFFIX})
|
||||
INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR} FILES_MATCHING PATTERN "*.h" PATTERN
|
||||
".svn" EXCLUDE PATTERN "CMakeFiles" EXCLUDE)
|
||||
ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
|
||||
|
||||
IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
SET_TARGET_PROPERTIES(BulletXmlWorldImporter PROPERTIES FRAMEWORK true)
|
||||
SET_TARGET_PROPERTIES(BulletXmlWorldImporter PROPERTIES PUBLIC_HEADER "btBulletXmlWorldImporter.h")
|
||||
ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
|
||||
ENDIF (INSTALL_EXTRA_LIBS)
|
||||
@@ -0,0 +1,767 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2012 Erwin Coumans http://bulletphysics.org
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
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.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "btBulletXmlWorldImporter.h"
|
||||
#include "tinyxml.h"
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include "string_split.h"
|
||||
|
||||
btBulletXmlWorldImporter::btBulletXmlWorldImporter(btDynamicsWorld* world)
|
||||
:btWorldImporter(world),
|
||||
m_fileVersion(-1)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
btBulletXmlWorldImporter::~btBulletXmlWorldImporter()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int get_double_attribute_by_name(const TiXmlElement* pElement, const char* attribName,double* value)
|
||||
{
|
||||
if ( !pElement )
|
||||
return 0;
|
||||
|
||||
const TiXmlAttribute* pAttrib=pElement->FirstAttribute();
|
||||
while (pAttrib)
|
||||
{
|
||||
if (pAttrib->Name()==attribName)
|
||||
if (pAttrib->QueryDoubleValue(value)==TIXML_SUCCESS)
|
||||
return 1;
|
||||
pAttrib=pAttrib->Next();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int get_int_attribute_by_name(const TiXmlElement* pElement, const char* attribName,int* value)
|
||||
{
|
||||
if ( !pElement )
|
||||
return 0;
|
||||
|
||||
const TiXmlAttribute* pAttrib=pElement->FirstAttribute();
|
||||
while (pAttrib)
|
||||
{
|
||||
if (!stricmp(pAttrib->Name(),attribName))
|
||||
if (pAttrib->QueryIntValue(value)==TIXML_SUCCESS)
|
||||
return 1;
|
||||
// if (pAttrib->QueryDoubleValue(&dval)==TIXML_SUCCESS) printf( " d=%1.1f", dval);
|
||||
pAttrib=pAttrib->Next();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void stringToFloatArray(const std::string& string, btAlignedObjectArray<float>& floats)
|
||||
{
|
||||
btAlignedObjectArray<std::string> pieces;
|
||||
|
||||
bullet_utils::split( pieces, string, " ");
|
||||
for (unsigned int i = 0; i < pieces.size(); ++i)
|
||||
{
|
||||
assert(pieces[i]!="");
|
||||
floats.push_back((float)atof(pieces[i].c_str()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static btVector3FloatData TextToVector3Data(const char* txt)
|
||||
{
|
||||
btAssert(txt);
|
||||
btAlignedObjectArray<float> floats;
|
||||
stringToFloatArray(txt, floats);
|
||||
assert(floats.size()==4);
|
||||
|
||||
btVector3FloatData vec4;
|
||||
vec4.m_floats[0] = floats[0];
|
||||
vec4.m_floats[1] = floats[1];
|
||||
vec4.m_floats[2] = floats[2];
|
||||
vec4.m_floats[3] = floats[3];
|
||||
return vec4;
|
||||
}
|
||||
|
||||
void btBulletXmlWorldImporter::deSerializeVector3FloatData(TiXmlNode* pParent,btAlignedObjectArray<btVector3FloatData>& vectors)
|
||||
{
|
||||
TiXmlNode* flNode = pParent->FirstChild("m_floats");
|
||||
btAssert(flNode);
|
||||
while (flNode && flNode->FirstChild())
|
||||
{
|
||||
TiXmlText* pText = flNode->FirstChild()->ToText();
|
||||
// printf("value = %s\n",pText->Value());
|
||||
btVector3FloatData vec4 = TextToVector3Data(pText->Value());
|
||||
vectors.push_back(vec4);
|
||||
flNode = flNode->NextSibling();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#define SET_INT_VALUE(xmlnode, targetdata, argname) \
|
||||
if ((xmlnode)->FirstChild(#argname) && (xmlnode)->FirstChild(#argname)->ToElement())\
|
||||
(targetdata)->argname= (int)atof(xmlnode->FirstChild(#argname)->ToElement()->GetText());
|
||||
|
||||
|
||||
#define SET_FLOAT_VALUE(xmlnode, targetdata, argname) \
|
||||
if ((xmlnode)->FirstChild(#argname) && (xmlnode)->FirstChild(#argname)->ToElement())\
|
||||
(targetdata)->argname= (float)atof(xmlnode->FirstChild(#argname)->ToElement()->GetText());
|
||||
|
||||
|
||||
#define SET_POINTER_VALUE(xmlnode, targetdata, argname, pointertype) \
|
||||
{\
|
||||
TiXmlNode* node;\
|
||||
if ((node)= xmlnode->FirstChild(#argname))\
|
||||
{\
|
||||
const char* txt = (node)->ToElement()->GetText();\
|
||||
(targetdata).argname= (pointertype) (int) atof(txt);\
|
||||
}\
|
||||
}
|
||||
|
||||
#define SET_VECTOR4_VALUE(xmlnode, targetdata, argname) \
|
||||
{\
|
||||
TiXmlNode* flNode = xmlnode->FirstChild(#argname);\
|
||||
btAssert(flNode);\
|
||||
if (flNode && flNode->FirstChild())\
|
||||
{\
|
||||
const char* txt= flNode->FirstChild()->ToElement()->GetText();\
|
||||
btVector3FloatData vec4 = TextToVector3Data(txt);\
|
||||
(targetdata)->argname.m_floats[0] = vec4.m_floats[0];\
|
||||
(targetdata)->argname.m_floats[1] = vec4.m_floats[1];\
|
||||
(targetdata)->argname.m_floats[2] = vec4.m_floats[2];\
|
||||
(targetdata)->argname.m_floats[3] = vec4.m_floats[3];\
|
||||
}\
|
||||
}
|
||||
|
||||
|
||||
#define SET_MATRIX33_VALUE(n, targetdata, argname) \
|
||||
{\
|
||||
TiXmlNode* xmlnode = n->FirstChild(#argname);\
|
||||
if (xmlnode)\
|
||||
{\
|
||||
TiXmlNode* eleNode = xmlnode->FirstChild("m_el");\
|
||||
btAssert(eleNode);\
|
||||
if (eleNode&& eleNode->FirstChild())\
|
||||
{\
|
||||
const char* txt= eleNode->FirstChild()->ToElement()->GetText();\
|
||||
btVector3FloatData vec4 = TextToVector3Data(txt);\
|
||||
(targetdata)->argname.m_el[0].m_floats[0] = vec4.m_floats[0];\
|
||||
(targetdata)->argname.m_el[0].m_floats[1] = vec4.m_floats[1];\
|
||||
(targetdata)->argname.m_el[0].m_floats[2] = vec4.m_floats[2];\
|
||||
(targetdata)->argname.m_el[0].m_floats[3] = vec4.m_floats[3];\
|
||||
\
|
||||
TiXmlNode* n1 = eleNode->FirstChild()->NextSibling();\
|
||||
if (n1)\
|
||||
{\
|
||||
const char* txt= n1->ToElement()->GetText();\
|
||||
btVector3FloatData vec4 = TextToVector3Data(txt);\
|
||||
(targetdata)->argname.m_el[1].m_floats[0] = vec4.m_floats[0];\
|
||||
(targetdata)->argname.m_el[1].m_floats[1] = vec4.m_floats[1];\
|
||||
(targetdata)->argname.m_el[1].m_floats[2] = vec4.m_floats[2];\
|
||||
(targetdata)->argname.m_el[1].m_floats[3] = vec4.m_floats[3];\
|
||||
\
|
||||
TiXmlNode* n2 = n1->NextSibling();\
|
||||
if (n2)\
|
||||
{\
|
||||
const char* txt= n2->ToElement()->GetText();\
|
||||
btVector3FloatData vec4 = TextToVector3Data(txt);\
|
||||
(targetdata)->argname.m_el[2].m_floats[0] = vec4.m_floats[0];\
|
||||
(targetdata)->argname.m_el[2].m_floats[1] = vec4.m_floats[1];\
|
||||
(targetdata)->argname.m_el[2].m_floats[2] = vec4.m_floats[2];\
|
||||
(targetdata)->argname.m_el[2].m_floats[3] = vec4.m_floats[3];\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
|
||||
#define SET_TRANSFORM_VALUE(n, targetdata, argname) \
|
||||
{\
|
||||
TiXmlNode* trNode = n->FirstChild(#argname);\
|
||||
if (trNode)\
|
||||
{\
|
||||
SET_VECTOR4_VALUE(trNode,&(targetdata)->argname,m_origin)\
|
||||
SET_MATRIX33_VALUE(trNode, &(targetdata)->argname,m_basis)\
|
||||
}\
|
||||
}\
|
||||
|
||||
|
||||
void btBulletXmlWorldImporter::deSerializeCollisionShapeData(TiXmlNode* pParent, btCollisionShapeData* colShapeData)
|
||||
{
|
||||
SET_INT_VALUE(pParent,colShapeData,m_shapeType)
|
||||
colShapeData->m_name = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void btBulletXmlWorldImporter::deSerializeConvexHullShapeData(TiXmlNode* pParent)
|
||||
{
|
||||
int ptr;
|
||||
btAssert(get_int_attribute_by_name(pParent->ToElement(),"pointer",&ptr));
|
||||
btConvexHullShapeData* convexHullData = (btConvexHullShapeData*)btAlignedAlloc(sizeof(btConvexHullShapeData), 16);
|
||||
|
||||
TiXmlNode* xmlConvexInt = pParent->FirstChild("m_convexInternalShapeData");
|
||||
btAssert(xmlConvexInt);
|
||||
|
||||
TiXmlNode* xmlColShape = xmlConvexInt ->FirstChild("m_collisionShapeData");
|
||||
btAssert(xmlColShape);
|
||||
|
||||
deSerializeCollisionShapeData(xmlColShape,&convexHullData->m_convexInternalShapeData.m_collisionShapeData);
|
||||
|
||||
SET_FLOAT_VALUE(xmlConvexInt,&convexHullData->m_convexInternalShapeData,m_collisionMargin)
|
||||
SET_VECTOR4_VALUE(xmlConvexInt,&convexHullData->m_convexInternalShapeData,m_localScaling)
|
||||
SET_VECTOR4_VALUE(xmlConvexInt,&convexHullData->m_convexInternalShapeData,m_implicitShapeDimensions)
|
||||
|
||||
SET_POINTER_VALUE(pParent,*convexHullData,m_unscaledPointsFloatPtr,btVector3FloatData*);
|
||||
SET_POINTER_VALUE(pParent,*convexHullData,m_unscaledPointsDoublePtr,btVector3DoubleData*);
|
||||
SET_INT_VALUE(pParent,convexHullData,m_numUnscaledPoints);
|
||||
|
||||
m_collisionShapeData.push_back((btCollisionShapeData*)convexHullData);
|
||||
m_pointerLookup.insert(ptr,convexHullData);
|
||||
}
|
||||
|
||||
void btBulletXmlWorldImporter::deSerializeCompoundShapeChildData(TiXmlNode* pParent)
|
||||
{
|
||||
int ptr;
|
||||
btAssert(get_int_attribute_by_name(pParent->ToElement(),"pointer",&ptr));
|
||||
|
||||
btCompoundShapeChildData* compoundChildData = (btCompoundShapeChildData*) btAlignedAlloc(sizeof(btCompoundShapeChildData),16);
|
||||
|
||||
SET_TRANSFORM_VALUE(pParent, compoundChildData,m_transform);
|
||||
SET_POINTER_VALUE(pParent, *compoundChildData,m_childShape,btCollisionShapeData*);
|
||||
|
||||
SET_INT_VALUE(pParent, compoundChildData, m_childShapeType);
|
||||
SET_FLOAT_VALUE(pParent, compoundChildData, m_childMargin);
|
||||
|
||||
|
||||
m_compoundShapeChildData.push_back(compoundChildData);
|
||||
m_pointerLookup.insert(ptr,compoundChildData);
|
||||
}
|
||||
|
||||
void btBulletXmlWorldImporter::deSerializeCompoundShapeData(TiXmlNode* pParent)
|
||||
{
|
||||
int ptr;
|
||||
btAssert(get_int_attribute_by_name(pParent->ToElement(),"pointer",&ptr));
|
||||
|
||||
btCompoundShapeData* compoundData = (btCompoundShapeData*) btAlignedAlloc(sizeof(btCompoundShapeData),16);
|
||||
|
||||
TiXmlNode* xmlShapeData = pParent->FirstChild("m_collisionShapeData");
|
||||
btAssert(xmlShapeData );
|
||||
deSerializeCollisionShapeData(xmlShapeData,&compoundData->m_collisionShapeData);
|
||||
|
||||
SET_POINTER_VALUE(pParent, *compoundData,m_childShapePtr,btCompoundShapeChildData*);
|
||||
SET_INT_VALUE(pParent, compoundData,m_numChildShapes);
|
||||
SET_FLOAT_VALUE(pParent, compoundData,m_collisionMargin);
|
||||
|
||||
m_collisionShapeData.push_back((btCollisionShapeData*)compoundData);
|
||||
m_pointerLookup.insert(ptr,compoundData);
|
||||
|
||||
}
|
||||
|
||||
void btBulletXmlWorldImporter::deSerializeStaticPlaneShapeData(TiXmlNode* pParent)
|
||||
{
|
||||
int ptr;
|
||||
btAssert(get_int_attribute_by_name(pParent->ToElement(),"pointer",&ptr));
|
||||
|
||||
btStaticPlaneShapeData* planeData = (btStaticPlaneShapeData*) btAlignedAlloc(sizeof(btStaticPlaneShapeData),16);
|
||||
|
||||
TiXmlNode* xmlShapeData = pParent->FirstChild("m_collisionShapeData");
|
||||
btAssert(xmlShapeData );
|
||||
deSerializeCollisionShapeData(xmlShapeData,&planeData->m_collisionShapeData);
|
||||
|
||||
SET_VECTOR4_VALUE(pParent, planeData,m_localScaling);
|
||||
SET_VECTOR4_VALUE(pParent, planeData,m_planeNormal);
|
||||
SET_FLOAT_VALUE(pParent, planeData,m_planeConstant);
|
||||
|
||||
m_collisionShapeData.push_back((btCollisionShapeData*)planeData);
|
||||
m_pointerLookup.insert(ptr,planeData);
|
||||
|
||||
}
|
||||
|
||||
void btBulletXmlWorldImporter::deSerializeConvexInternalShapeData(TiXmlNode* pParent)
|
||||
{
|
||||
int ptr;
|
||||
btAssert(get_int_attribute_by_name(pParent->ToElement(),"pointer",&ptr));
|
||||
|
||||
btConvexInternalShapeData* convexShape = (btConvexInternalShapeData*) btAlignedAlloc(sizeof(btConvexInternalShapeData),16);
|
||||
memset(convexShape,0,sizeof(btConvexInternalShapeData));
|
||||
|
||||
TiXmlNode* xmlShapeData = pParent->FirstChild("m_collisionShapeData");
|
||||
btAssert(xmlShapeData );
|
||||
|
||||
deSerializeCollisionShapeData(xmlShapeData,&convexShape->m_collisionShapeData);
|
||||
|
||||
SET_FLOAT_VALUE(pParent,convexShape,m_collisionMargin)
|
||||
SET_VECTOR4_VALUE(pParent,convexShape,m_localScaling)
|
||||
SET_VECTOR4_VALUE(pParent,convexShape,m_implicitShapeDimensions)
|
||||
|
||||
m_collisionShapeData.push_back((btCollisionShapeData*)convexShape);
|
||||
m_pointerLookup.insert(ptr,convexShape);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
enum btTypedConstraintType
|
||||
{
|
||||
POINT2POINT_CONSTRAINT_TYPE=3,
|
||||
HINGE_CONSTRAINT_TYPE,
|
||||
CONETWIST_CONSTRAINT_TYPE,
|
||||
// D6_CONSTRAINT_TYPE,
|
||||
SLIDER_CONSTRAINT_TYPE,
|
||||
CONTACT_CONSTRAINT_TYPE,
|
||||
D6_SPRING_CONSTRAINT_TYPE,
|
||||
GEAR_CONSTRAINT_TYPE,
|
||||
MAX_CONSTRAINT_TYPE
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
void btBulletXmlWorldImporter::deSerializeGeneric6DofConstraintData(TiXmlNode* pParent)
|
||||
{
|
||||
int ptr;
|
||||
btAssert(get_int_attribute_by_name(pParent->ToElement(),"pointer",&ptr));
|
||||
btGeneric6DofConstraintData* dof6Data = (btGeneric6DofConstraintData*)btAlignedAlloc(sizeof(btGeneric6DofConstraintData),16);
|
||||
|
||||
|
||||
TiXmlNode* n = pParent->FirstChild("m_typeConstraintData");
|
||||
if (n)
|
||||
{
|
||||
|
||||
SET_POINTER_VALUE(n,dof6Data->m_typeConstraintData,m_rbA,btRigidBodyFloatData*);
|
||||
SET_POINTER_VALUE(n,dof6Data->m_typeConstraintData,m_rbB,btRigidBodyFloatData*);
|
||||
dof6Data->m_typeConstraintData.m_name = 0;//tbd
|
||||
SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_objectType);
|
||||
SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_userConstraintType);
|
||||
SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_userConstraintId);
|
||||
SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_needsFeedback);
|
||||
SET_FLOAT_VALUE(n,&dof6Data->m_typeConstraintData,m_appliedImpulse);
|
||||
SET_FLOAT_VALUE(n,&dof6Data->m_typeConstraintData,m_dbgDrawSize);
|
||||
SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_disableCollisionsBetweenLinkedBodies);
|
||||
SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_overrideNumSolverIterations);
|
||||
SET_FLOAT_VALUE(n,&dof6Data->m_typeConstraintData,m_breakingImpulseThreshold);
|
||||
SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_isEnabled);
|
||||
|
||||
}
|
||||
|
||||
SET_TRANSFORM_VALUE( pParent, dof6Data, m_rbAFrame);
|
||||
SET_TRANSFORM_VALUE( pParent, dof6Data, m_rbBFrame);
|
||||
SET_VECTOR4_VALUE(pParent, dof6Data, m_linearUpperLimit);
|
||||
SET_VECTOR4_VALUE(pParent, dof6Data, m_linearLowerLimit);
|
||||
SET_VECTOR4_VALUE(pParent, dof6Data, m_angularUpperLimit);
|
||||
SET_VECTOR4_VALUE(pParent, dof6Data, m_angularLowerLimit);
|
||||
SET_INT_VALUE(pParent, dof6Data,m_useLinearReferenceFrameA);
|
||||
SET_INT_VALUE(pParent, dof6Data,m_useOffsetForConstraintFrame);
|
||||
|
||||
m_constraintData.push_back((btTypedConstraintData*)dof6Data);
|
||||
m_pointerLookup.insert(ptr,dof6Data);
|
||||
}
|
||||
|
||||
void btBulletXmlWorldImporter::deSerializeRigidBodyFloatData(TiXmlNode* pParent)
|
||||
{
|
||||
int ptr;
|
||||
btAssert(get_int_attribute_by_name(pParent->ToElement(),"pointer",&ptr));
|
||||
|
||||
btRigidBodyFloatData* rbData = (btRigidBodyFloatData*)btAlignedAlloc(sizeof(btRigidBodyFloatData),16);
|
||||
|
||||
TiXmlNode* n = pParent->FirstChild("m_collisionObjectData");
|
||||
|
||||
if (n)
|
||||
{
|
||||
SET_POINTER_VALUE(n,rbData->m_collisionObjectData,m_collisionShape, void*);
|
||||
SET_TRANSFORM_VALUE(n,&rbData->m_collisionObjectData,m_worldTransform);
|
||||
SET_TRANSFORM_VALUE(n,&rbData->m_collisionObjectData,m_interpolationWorldTransform);
|
||||
SET_VECTOR4_VALUE(n,&rbData->m_collisionObjectData,m_interpolationLinearVelocity)
|
||||
SET_VECTOR4_VALUE(n,&rbData->m_collisionObjectData,m_interpolationAngularVelocity)
|
||||
SET_VECTOR4_VALUE(n,&rbData->m_collisionObjectData,m_anisotropicFriction)
|
||||
SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_contactProcessingThreshold);
|
||||
SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_deactivationTime);
|
||||
SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_friction);
|
||||
SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_restitution);
|
||||
SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_hitFraction);
|
||||
SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_ccdSweptSphereRadius);
|
||||
SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_ccdMotionThreshold);
|
||||
SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_hasAnisotropicFriction);
|
||||
SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_collisionFlags);
|
||||
SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_islandTag1);
|
||||
SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_companionId);
|
||||
SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_activationState1);
|
||||
SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_internalType);
|
||||
SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_checkCollideWith);
|
||||
}
|
||||
|
||||
// SET_VECTOR4_VALUE(pParent,rbData,m_linearVelocity);
|
||||
|
||||
SET_MATRIX33_VALUE(pParent,rbData,m_invInertiaTensorWorld);
|
||||
|
||||
|
||||
SET_VECTOR4_VALUE(pParent,rbData,m_linearVelocity)
|
||||
SET_VECTOR4_VALUE(pParent,rbData,m_angularVelocity)
|
||||
SET_VECTOR4_VALUE(pParent,rbData,m_angularFactor)
|
||||
SET_VECTOR4_VALUE(pParent,rbData,m_linearFactor)
|
||||
SET_VECTOR4_VALUE(pParent,rbData,m_gravity)
|
||||
SET_VECTOR4_VALUE(pParent,rbData,m_gravity_acceleration )
|
||||
SET_VECTOR4_VALUE(pParent,rbData,m_invInertiaLocal)
|
||||
SET_VECTOR4_VALUE(pParent,rbData,m_totalTorque)
|
||||
SET_VECTOR4_VALUE(pParent,rbData,m_totalForce)
|
||||
SET_FLOAT_VALUE(pParent,rbData,m_inverseMass);
|
||||
SET_FLOAT_VALUE(pParent,rbData,m_linearDamping);
|
||||
SET_FLOAT_VALUE(pParent,rbData,m_angularDamping);
|
||||
SET_FLOAT_VALUE(pParent,rbData,m_additionalDampingFactor);
|
||||
SET_FLOAT_VALUE(pParent,rbData,m_additionalLinearDampingThresholdSqr);
|
||||
SET_FLOAT_VALUE(pParent,rbData,m_additionalAngularDampingThresholdSqr);
|
||||
SET_FLOAT_VALUE(pParent,rbData,m_additionalAngularDampingFactor);
|
||||
SET_FLOAT_VALUE(pParent,rbData,m_angularSleepingThreshold);
|
||||
SET_FLOAT_VALUE(pParent,rbData,m_linearSleepingThreshold);
|
||||
SET_INT_VALUE(pParent,rbData,m_additionalDamping);
|
||||
|
||||
|
||||
m_rigidBodyData.push_back(rbData);
|
||||
m_pointerLookup.insert(ptr,rbData);
|
||||
|
||||
// rbData->m_collisionObjectData.m_collisionShape = (void*) (int)atof(txt);
|
||||
}
|
||||
|
||||
/*
|
||||
TETRAHEDRAL_SHAPE_PROXYTYPE,
|
||||
CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE,
|
||||
,
|
||||
CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE,
|
||||
CUSTOM_POLYHEDRAL_SHAPE_TYPE,
|
||||
//implicit convex shapes
|
||||
IMPLICIT_CONVEX_SHAPES_START_HERE,
|
||||
SPHERE_SHAPE_PROXYTYPE,
|
||||
MULTI_SPHERE_SHAPE_PROXYTYPE,
|
||||
CAPSULE_SHAPE_PROXYTYPE,
|
||||
CONE_SHAPE_PROXYTYPE,
|
||||
CONVEX_SHAPE_PROXYTYPE,
|
||||
CYLINDER_SHAPE_PROXYTYPE,
|
||||
UNIFORM_SCALING_SHAPE_PROXYTYPE,
|
||||
MINKOWSKI_SUM_SHAPE_PROXYTYPE,
|
||||
MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE,
|
||||
BOX_2D_SHAPE_PROXYTYPE,
|
||||
CONVEX_2D_SHAPE_PROXYTYPE,
|
||||
CUSTOM_CONVEX_SHAPE_TYPE,
|
||||
//concave shapes
|
||||
CONCAVE_SHAPES_START_HERE,
|
||||
//keep all the convex shapetype below here, for the check IsConvexShape in broadphase proxy!
|
||||
TRIANGLE_MESH_SHAPE_PROXYTYPE,
|
||||
SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE,
|
||||
///used for demo integration FAST/Swift collision library and Bullet
|
||||
FAST_CONCAVE_MESH_PROXYTYPE,
|
||||
//terrain
|
||||
TERRAIN_SHAPE_PROXYTYPE,
|
||||
///Used for GIMPACT Trimesh integration
|
||||
GIMPACT_SHAPE_PROXYTYPE,
|
||||
///Multimaterial mesh
|
||||
MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE,
|
||||
|
||||
,
|
||||
,
|
||||
CUSTOM_CONCAVE_SHAPE_TYPE,
|
||||
CONCAVE_SHAPES_END_HERE,
|
||||
|
||||
,
|
||||
|
||||
SOFTBODY_SHAPE_PROXYTYPE,
|
||||
HFFLUID_SHAPE_PROXYTYPE,
|
||||
HFFLUID_BUOYANT_CONVEX_SHAPE_PROXYTYPE,
|
||||
INVALID_SHAPE_PROXYTYPE,
|
||||
|
||||
MAX_BROADPHASE_COLLISION_TYPES
|
||||
*/
|
||||
|
||||
void btBulletXmlWorldImporter::fixupConstraintData(btTypedConstraintData* tcd)
|
||||
{
|
||||
if (tcd->m_rbA)
|
||||
{
|
||||
btRigidBodyFloatData** ptrptr = (btRigidBodyFloatData**)m_pointerLookup.find((int)tcd->m_rbA);
|
||||
btAssert(ptrptr);
|
||||
tcd->m_rbA = ptrptr? *ptrptr : 0;
|
||||
}
|
||||
if (tcd->m_rbB)
|
||||
{
|
||||
btRigidBodyFloatData** ptrptr = (btRigidBodyFloatData**)m_pointerLookup.find((int)tcd->m_rbB);
|
||||
btAssert(ptrptr);
|
||||
tcd->m_rbB = ptrptr? *ptrptr : 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void btBulletXmlWorldImporter::fixupCollisionDataPointers(btCollisionShapeData* shapeData)
|
||||
{
|
||||
|
||||
switch (shapeData->m_shapeType)
|
||||
{
|
||||
|
||||
case COMPOUND_SHAPE_PROXYTYPE:
|
||||
{
|
||||
btCompoundShapeData* compound = (btCompoundShapeData*) shapeData;
|
||||
int ptr = (int) compound->m_childShapePtr;
|
||||
btCompoundShapeChildData** c = (btCompoundShapeChildData**)m_pointerLookup.find(ptr);
|
||||
btAssert(c);
|
||||
if (c)
|
||||
{
|
||||
compound->m_childShapePtr = *c;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CONVEX_HULL_SHAPE_PROXYTYPE:
|
||||
{
|
||||
btConvexHullShapeData* convexData = (btConvexHullShapeData*)shapeData;
|
||||
int ptr = (int)convexData->m_unscaledPointsFloatPtr;
|
||||
btVector3FloatData** ptrptr = (btVector3FloatData**)m_pointerLookup.find(ptr);
|
||||
btAssert(ptrptr);
|
||||
if (ptrptr)
|
||||
{
|
||||
convexData->m_unscaledPointsFloatPtr = *ptrptr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case BOX_SHAPE_PROXYTYPE:
|
||||
case TRIANGLE_SHAPE_PROXYTYPE:
|
||||
case STATIC_PLANE_PROXYTYPE:
|
||||
case EMPTY_SHAPE_PROXYTYPE:
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
btAssert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void btBulletXmlWorldImporter::auto_serialize_root_level_children(TiXmlNode* pParent)
|
||||
{
|
||||
int numChildren = 0;
|
||||
btAssert(pParent);
|
||||
if (pParent)
|
||||
{
|
||||
TiXmlNode*pChild;
|
||||
for ( pChild = pParent->FirstChild(); pChild != 0; pChild = pChild->NextSibling(), numChildren++)
|
||||
{
|
||||
// printf("child Name=%s\n", pChild->Value());
|
||||
if (!stricmp(pChild->Value(),"btVector3FloatData"))
|
||||
{
|
||||
int ptr;
|
||||
btAssert(get_int_attribute_by_name(pChild->ToElement(),"pointer",&ptr));
|
||||
|
||||
btAlignedObjectArray<btVector3FloatData> v;
|
||||
deSerializeVector3FloatData(pChild,v);
|
||||
int numVectors = v.size();
|
||||
btVector3FloatData* vectors= (btVector3FloatData*) btAlignedAlloc(sizeof(btVector3FloatData)*numVectors,16);
|
||||
for (int i=0;i<numVectors;i++)
|
||||
vectors[i] = v[i];
|
||||
m_floatVertexArrays.push_back(vectors);
|
||||
m_pointerLookup.insert(ptr,vectors);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!stricmp(pChild->Value(),"btGeneric6DofConstraintData"))
|
||||
{
|
||||
deSerializeGeneric6DofConstraintData(pChild);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!stricmp(pChild->Value(),"btStaticPlaneShapeData"))
|
||||
{
|
||||
deSerializeStaticPlaneShapeData(pChild);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!stricmp(pChild->Value(),"btCompoundShapeData"))
|
||||
{
|
||||
deSerializeCompoundShapeData(pChild);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!stricmp(pChild->Value(),"btCompoundShapeChildData"))
|
||||
{
|
||||
deSerializeCompoundShapeChildData(pChild);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!stricmp(pChild->Value(),"btConvexHullShapeData"))
|
||||
{
|
||||
deSerializeConvexHullShapeData(pChild);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!stricmp(pChild->Value(),"btConvexInternalShapeData"))
|
||||
{
|
||||
deSerializeConvexInternalShapeData(pChild);
|
||||
continue;
|
||||
}
|
||||
if (!stricmp(pChild->Value(),"btRigidBodyFloatData"))
|
||||
{
|
||||
deSerializeRigidBodyFloatData(pChild);
|
||||
continue;
|
||||
}
|
||||
|
||||
btAssert(0);
|
||||
}
|
||||
}
|
||||
|
||||
///=================================================================
|
||||
///fixup pointers in various places, in the right order
|
||||
|
||||
//fixup compoundshape child data
|
||||
for (int i=0;i<m_compoundShapeChildData.size();i++)
|
||||
{
|
||||
btCompoundShapeChildData* childData = m_compoundShapeChildData[i];
|
||||
int hashKey = (int) childData->m_childShape;
|
||||
btCollisionShapeData** ptrptr = (btCollisionShapeData**)m_pointerLookup[hashKey];
|
||||
btAssert(ptrptr);
|
||||
if (ptrptr)
|
||||
{
|
||||
childData->m_childShape = *ptrptr;
|
||||
}
|
||||
}
|
||||
|
||||
///now fixup pointers
|
||||
for (int i=0;i<m_rigidBodyData.size();i++)
|
||||
{
|
||||
btRigidBodyFloatData* rbData = m_rigidBodyData[i];
|
||||
int hashKey = (int)rbData->m_collisionObjectData.m_collisionShape;
|
||||
void** ptrptr = m_pointerLookup.find(hashKey);
|
||||
btAssert(ptrptr);
|
||||
rbData->m_collisionObjectData.m_broadphaseHandle = 0;
|
||||
rbData->m_collisionObjectData.m_rootCollisionShape = 0;
|
||||
rbData->m_collisionObjectData.m_name = 0;//tbd
|
||||
if (ptrptr)
|
||||
{
|
||||
rbData->m_collisionObjectData.m_collisionShape = *ptrptr;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0;i<this->m_collisionShapeData.size();i++)
|
||||
{
|
||||
btCollisionShapeData* shapeData = m_collisionShapeData[i];
|
||||
fixupCollisionDataPointers(shapeData);
|
||||
|
||||
}
|
||||
|
||||
for (int i=0;i<m_constraintData.size();i++)
|
||||
{
|
||||
btTypedConstraintData* tcd = m_constraintData[i];
|
||||
fixupConstraintData(tcd);
|
||||
|
||||
}
|
||||
///=================================================================
|
||||
///convert data into Bullet data in the right order
|
||||
|
||||
///convert collision shapes
|
||||
for (int i=0;i<this->m_collisionShapeData.size();i++)
|
||||
{
|
||||
btCollisionShapeData* shapeData = m_collisionShapeData[i];
|
||||
btCollisionShape* shape = convertCollisionShape(shapeData);
|
||||
if (shape)
|
||||
{
|
||||
m_shapeMap.insert(shapeData,shape);
|
||||
}
|
||||
if (shape&& shapeData->m_name)
|
||||
{
|
||||
char* newname = duplicateName(shapeData->m_name);
|
||||
m_objectNameMap.insert(shape,newname);
|
||||
m_nameShapeMap.insert(newname,shape);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0;i<m_rigidBodyData.size();i++)
|
||||
{
|
||||
convertRigidBody(m_rigidBodyData[i]);
|
||||
}
|
||||
|
||||
for (int i=0;i<m_constraintData.size();i++)
|
||||
{
|
||||
btTypedConstraintData* tcd = m_constraintData[i];
|
||||
bool isDoublePrecision = false;
|
||||
btRigidBody* rbA = 0;
|
||||
btRigidBody* rbB = 0;
|
||||
{
|
||||
btCollisionObject** ptrptr = m_bodyMap.find(tcd->m_rbA);
|
||||
if (ptrptr)
|
||||
{
|
||||
rbA = btRigidBody::upcast(*ptrptr);
|
||||
}
|
||||
}
|
||||
{
|
||||
btCollisionObject** ptrptr = m_bodyMap.find(tcd->m_rbB);
|
||||
if (ptrptr)
|
||||
{
|
||||
rbB = btRigidBody::upcast(*ptrptr);
|
||||
}
|
||||
}
|
||||
if (rbA || rbB)
|
||||
{
|
||||
convertConstraint(tcd,rbA,rbB,isDoublePrecision, m_fileVersion);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void btBulletXmlWorldImporter::auto_serialize(TiXmlNode* pParent)
|
||||
{
|
||||
// TiXmlElement* root = pParent->FirstChildElement("bullet_physics");
|
||||
if (pParent)
|
||||
{
|
||||
TiXmlNode*pChild;
|
||||
for ( pChild = pParent->FirstChild(); pChild != 0; pChild = pChild->NextSibling())
|
||||
{
|
||||
if (pChild->Type()==TiXmlNode::TINYXML_ELEMENT)
|
||||
{
|
||||
// printf("root Name=%s\n", pChild->Value());
|
||||
auto_serialize_root_level_children(pChild);
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
printf("ERROR: no bullet_physics element\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool btBulletXmlWorldImporter::loadFile(const char* fileName)
|
||||
{
|
||||
TiXmlDocument doc(fileName);
|
||||
|
||||
bool loadOkay = doc.LoadFile();
|
||||
//dump_to_stdout(&doc,0);
|
||||
|
||||
int fileVersion=-1;
|
||||
|
||||
if (get_int_attribute_by_name(doc.FirstChildElement()->ToElement(),"version", &m_fileVersion))
|
||||
{
|
||||
if (m_fileVersion==281)
|
||||
{
|
||||
int itemcount;
|
||||
assert(get_int_attribute_by_name(doc.FirstChildElement()->ToElement(),"itemcount", &itemcount));
|
||||
|
||||
auto_serialize(&doc);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2012 Erwin Coumans http://bulletphysics.org
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
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.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BT_BULLET_XML_WORLD_IMPORTER_H
|
||||
#define BT_BULLET_XML_WORLD_IMPORTER_H
|
||||
|
||||
class btDynamicsWorld;
|
||||
class TiXmlNode;
|
||||
struct btConvexInternalShapeData;
|
||||
struct btCollisionShapeData;
|
||||
struct btRigidBodyFloatData;
|
||||
struct btTypedConstraintData;
|
||||
struct btCompoundShapeChildData;
|
||||
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
#include "btWorldImporter.h"
|
||||
|
||||
class btBulletXmlWorldImporter : public btWorldImporter
|
||||
{
|
||||
|
||||
protected:
|
||||
btAlignedObjectArray<btCollisionShapeData*> m_collisionShapeData;
|
||||
btAlignedObjectArray<btCompoundShapeChildData*> m_compoundShapeChildData;
|
||||
btAlignedObjectArray<btRigidBodyFloatData*> m_rigidBodyData;
|
||||
btAlignedObjectArray<btTypedConstraintData*> m_constraintData;
|
||||
btHashMap<btHashInt,void*> m_pointerLookup;
|
||||
int m_fileVersion;
|
||||
|
||||
void auto_serialize_root_level_children(TiXmlNode* pParent);
|
||||
void auto_serialize(TiXmlNode* pParent);
|
||||
|
||||
void deSerializeVector3FloatData(TiXmlNode* pParent,btAlignedObjectArray<btVector3FloatData>& vectors);
|
||||
|
||||
void fixupCollisionDataPointers(btCollisionShapeData* shapeData);
|
||||
void fixupConstraintData(btTypedConstraintData* tcd);
|
||||
|
||||
//collision shapes data
|
||||
void deSerializeCollisionShapeData(TiXmlNode* pParent,btCollisionShapeData* colShapeData);
|
||||
void deSerializeConvexInternalShapeData(TiXmlNode* pParent);
|
||||
void deSerializeStaticPlaneShapeData(TiXmlNode* pParent);
|
||||
void deSerializeCompoundShapeData(TiXmlNode* pParent);
|
||||
void deSerializeCompoundShapeChildData(TiXmlNode* pParent);
|
||||
void deSerializeConvexHullShapeData(TiXmlNode* pParent);
|
||||
|
||||
|
||||
///bodies
|
||||
void deSerializeRigidBodyFloatData(TiXmlNode* pParent);
|
||||
|
||||
///constraints
|
||||
void deSerializeGeneric6DofConstraintData(TiXmlNode* pParent);
|
||||
|
||||
public:
|
||||
btBulletXmlWorldImporter(btDynamicsWorld* world);
|
||||
|
||||
virtual ~btBulletXmlWorldImporter();
|
||||
|
||||
bool loadFile(const char* fileName);
|
||||
|
||||
};
|
||||
|
||||
#endif //BT_BULLET_XML_WORLD_IMPORTER_H
|
||||
14
Extras/Serialize/BulletXmlWorldImporter/premake4.lua
Normal file
14
Extras/Serialize/BulletXmlWorldImporter/premake4.lua
Normal file
@@ -0,0 +1,14 @@
|
||||
project "BulletXmlWorldImporter"
|
||||
|
||||
kind "StaticLib"
|
||||
targetdir "../../lib"
|
||||
includedirs {
|
||||
"../BulletWorldImporter",
|
||||
"../BulletFileLoader",
|
||||
"../../../src"
|
||||
}
|
||||
|
||||
files {
|
||||
"**.cpp",
|
||||
"**.h"
|
||||
}
|
||||
248
Extras/Serialize/BulletXmlWorldImporter/string_split.cpp
Normal file
248
Extras/Serialize/BulletXmlWorldImporter/string_split.cpp
Normal file
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2012 Erwin Coumans http://bulletphysics.org
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
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.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
//#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "string_split.h"
|
||||
|
||||
namespace bullet_utils
|
||||
{
|
||||
void split( btAlignedObjectArray<std::string>&pieces, const std::string& vector_str, const std::string& separator)
|
||||
{
|
||||
char** strArray = str_split(vector_str.c_str(),separator.c_str());
|
||||
int numSubStr = str_array_len(strArray);
|
||||
for (int i=0;i<numSubStr;i++)
|
||||
pieces.push_back(std::string(strArray[i]));
|
||||
str_array_free(strArray);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Append an item to a dynamically allocated array of strings. On failure,
|
||||
return NULL, in which case the original array is intact. The item
|
||||
string is dynamically copied. If the array is NULL, allocate a new
|
||||
array. Otherwise, extend the array. Make sure the array is always
|
||||
NULL-terminated. Input string might not be '\0'-terminated. */
|
||||
char **str_array_append(char **array, size_t nitems, const char *item,
|
||||
size_t itemlen)
|
||||
{
|
||||
/* Make a dynamic copy of the item. */
|
||||
char *copy;
|
||||
if (item == NULL)
|
||||
copy = NULL;
|
||||
else {
|
||||
copy = (char*)malloc(itemlen + 1);
|
||||
if (copy == NULL)
|
||||
return NULL;
|
||||
memcpy(copy, item, itemlen);
|
||||
copy[itemlen] = '\0';
|
||||
}
|
||||
|
||||
/* Extend array with one element. Except extend it by two elements,
|
||||
in case it did not yet exist. This might mean it is a teeny bit
|
||||
too big, but we don't care. */
|
||||
array = (char**)realloc(array, (nitems + 2) * sizeof(array[0]));
|
||||
if (array == NULL) {
|
||||
free(copy);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Add copy of item to array, and return it. */
|
||||
array[nitems] = copy;
|
||||
array[nitems+1] = NULL;
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
/* Free a dynamic array of dynamic strings. */
|
||||
void str_array_free(char **array)
|
||||
{
|
||||
if (array == NULL)
|
||||
return;
|
||||
for (size_t i = 0; array[i] != NULL; ++i)
|
||||
free(array[i]);
|
||||
free(array);
|
||||
}
|
||||
|
||||
|
||||
/* Split a string into substrings. Return dynamic array of dynamically
|
||||
allocated substrings, or NULL if there was an error. Caller is
|
||||
expected to free the memory, for example with str_array_free. */
|
||||
char **str_split(const char *input, const char *sep)
|
||||
{
|
||||
size_t nitems = 0;
|
||||
char **array = NULL;
|
||||
const char *start = input;
|
||||
const char *next = strstr(start, sep);
|
||||
size_t seplen = strlen(sep);
|
||||
const char *item;
|
||||
size_t itemlen;
|
||||
|
||||
for (;;) {
|
||||
next = strstr(start, sep);
|
||||
if (next == NULL) {
|
||||
/* Add the remaining string (or empty string, if input ends with
|
||||
separator. */
|
||||
char **newstr = str_array_append(array, nitems, start, strlen(start));
|
||||
if (newstr == NULL) {
|
||||
str_array_free(array);
|
||||
return NULL;
|
||||
}
|
||||
array = newstr;
|
||||
++nitems;
|
||||
break;
|
||||
} else if (next == input) {
|
||||
/* Input starts with separator. */
|
||||
item = "";
|
||||
itemlen = 0;
|
||||
} else {
|
||||
item = start;
|
||||
itemlen = next - item;
|
||||
}
|
||||
char **newstr = str_array_append(array, nitems, item, itemlen);
|
||||
if (newstr == NULL) {
|
||||
str_array_free(array);
|
||||
return NULL;
|
||||
}
|
||||
array = newstr;
|
||||
++nitems;
|
||||
start = next + seplen;
|
||||
}
|
||||
|
||||
if (nitems == 0) {
|
||||
/* Input does not contain separator at all. */
|
||||
assert(array == NULL);
|
||||
array = str_array_append(array, nitems, input, strlen(input));
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
/* Return length of a NULL-delimited array of strings. */
|
||||
size_t str_array_len(char **array)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
for (len = 0; array[len] != NULL; ++len)
|
||||
continue;
|
||||
return len;
|
||||
}
|
||||
|
||||
#ifdef UNIT_TEST_STRING
|
||||
|
||||
#define MAX_OUTPUT 20
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct {
|
||||
const char *input;
|
||||
const char *sep;
|
||||
char *output[MAX_OUTPUT];
|
||||
} tab[] = {
|
||||
/* Input is empty string. Output should be a list with an empty
|
||||
string. */
|
||||
{
|
||||
"",
|
||||
"and",
|
||||
{
|
||||
"",
|
||||
NULL,
|
||||
},
|
||||
},
|
||||
/* Input is exactly the separator. Output should be two empty
|
||||
strings. */
|
||||
{
|
||||
"and",
|
||||
"and",
|
||||
{
|
||||
"",
|
||||
"",
|
||||
NULL,
|
||||
},
|
||||
},
|
||||
/* Input is non-empty, but does not have separator. Output should
|
||||
be the same string. */
|
||||
{
|
||||
"foo",
|
||||
"and",
|
||||
{
|
||||
"foo",
|
||||
NULL,
|
||||
},
|
||||
},
|
||||
/* Input is non-empty, and does have separator. */
|
||||
{
|
||||
"foo bar 1 and foo bar 2",
|
||||
" and ",
|
||||
{
|
||||
"foo bar 1",
|
||||
"foo bar 2",
|
||||
NULL,
|
||||
},
|
||||
},
|
||||
};
|
||||
const int tab_len = sizeof(tab) / sizeof(tab[0]);
|
||||
bool errors;
|
||||
|
||||
errors = false;
|
||||
|
||||
for (int i = 0; i < tab_len; ++i) {
|
||||
printf("test %d\n", i);
|
||||
|
||||
char **output = str_split(tab[i].input, tab[i].sep);
|
||||
if (output == NULL) {
|
||||
fprintf(stderr, "output is NULL\n");
|
||||
errors = true;
|
||||
break;
|
||||
}
|
||||
size_t num_output = str_array_len(output);
|
||||
printf("num_output %lu\n", (unsigned long) num_output);
|
||||
|
||||
size_t num_correct = str_array_len(tab[i].output);
|
||||
if (num_output != num_correct) {
|
||||
fprintf(stderr, "wrong number of outputs (%lu, not %lu)\n",
|
||||
(unsigned long) num_output, (unsigned long) num_correct);
|
||||
errors = true;
|
||||
} else {
|
||||
for (size_t j = 0; j < num_output; ++j) {
|
||||
if (strcmp(tab[i].output[j], output[j]) != 0) {
|
||||
fprintf(stderr, "output[%lu] is '%s' not '%s'\n",
|
||||
(unsigned long) j, output[j], tab[i].output[j]);
|
||||
errors = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
str_array_free(output);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (errors)
|
||||
return EXIT_FAILURE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif//
|
||||
|
||||
|
||||
49
Extras/Serialize/BulletXmlWorldImporter/string_split.h
Normal file
49
Extras/Serialize/BulletXmlWorldImporter/string_split.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2012 Erwin Coumans http://bulletphysics.org
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
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.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
///The string split C code is by Lars Wirzenius
|
||||
///See http://stackoverflow.com/questions/2531605/how-to-split-a-string-with-a-delimiter-larger-than-one-single-char
|
||||
|
||||
|
||||
#ifndef STRING_SPLIT_H
|
||||
#define STRING_SPLIT_H
|
||||
|
||||
#include <cstring>
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace bullet_utils
|
||||
{
|
||||
void split( btAlignedObjectArray<std::string>&pieces, const std::string& vector_str, const std::string& separator);
|
||||
};
|
||||
|
||||
///The string split C code is by Lars Wirzenius
|
||||
///See http://stackoverflow.com/questions/2531605/how-to-split-a-string-with-a-delimiter-larger-than-one-single-char
|
||||
|
||||
|
||||
/* Split a string into substrings. Return dynamic array of dynamically
|
||||
allocated substrings, or NULL if there was an error. Caller is
|
||||
expected to free the memory, for example with str_array_free. */
|
||||
char** str_split(const char* input, const char* sep);
|
||||
|
||||
/* Free a dynamic array of dynamic strings. */
|
||||
void str_array_free(char** array);
|
||||
|
||||
/* Return length of a NULL-delimited array of strings. */
|
||||
size_t str_array_len(char** array);
|
||||
|
||||
#endif //STRING_SPLIT_H
|
||||
|
||||
111
Extras/Serialize/BulletXmlWorldImporter/tinystr.cpp
Normal file
111
Extras/Serialize/BulletXmlWorldImporter/tinystr.cpp
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
www.sourceforge.net/projects/tinyxml
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
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.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TIXML_USE_STL
|
||||
|
||||
#include "tinystr.h"
|
||||
|
||||
// Error value for find primitive
|
||||
const TiXmlString::size_type TiXmlString::npos = static_cast< TiXmlString::size_type >(-1);
|
||||
|
||||
|
||||
// Null rep.
|
||||
TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, { '\0' } };
|
||||
|
||||
|
||||
void TiXmlString::reserve (size_type cap)
|
||||
{
|
||||
if (cap > capacity())
|
||||
{
|
||||
TiXmlString tmp;
|
||||
tmp.init(length(), cap);
|
||||
memcpy(tmp.start(), data(), length());
|
||||
swap(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TiXmlString& TiXmlString::assign(const char* str, size_type len)
|
||||
{
|
||||
size_type cap = capacity();
|
||||
if (len > cap || cap > 3*(len + 8))
|
||||
{
|
||||
TiXmlString tmp;
|
||||
tmp.init(len);
|
||||
memcpy(tmp.start(), str, len);
|
||||
swap(tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
memmove(start(), str, len);
|
||||
set_size(len);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
TiXmlString& TiXmlString::append(const char* str, size_type len)
|
||||
{
|
||||
size_type newsize = length() + len;
|
||||
if (newsize > capacity())
|
||||
{
|
||||
reserve (newsize + capacity());
|
||||
}
|
||||
memmove(finish(), str, len);
|
||||
set_size(newsize);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
TiXmlString operator + (const TiXmlString & a, const TiXmlString & b)
|
||||
{
|
||||
TiXmlString tmp;
|
||||
tmp.reserve(a.length() + b.length());
|
||||
tmp += a;
|
||||
tmp += b;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
TiXmlString operator + (const TiXmlString & a, const char* b)
|
||||
{
|
||||
TiXmlString tmp;
|
||||
TiXmlString::size_type b_len = static_cast<TiXmlString::size_type>( strlen(b) );
|
||||
tmp.reserve(a.length() + b_len);
|
||||
tmp += a;
|
||||
tmp.append(b, b_len);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
TiXmlString operator + (const char* a, const TiXmlString & b)
|
||||
{
|
||||
TiXmlString tmp;
|
||||
TiXmlString::size_type a_len = static_cast<TiXmlString::size_type>( strlen(a) );
|
||||
tmp.reserve(a_len + b.length());
|
||||
tmp.append(a, a_len);
|
||||
tmp += b;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
#endif // TIXML_USE_STL
|
||||
305
Extras/Serialize/BulletXmlWorldImporter/tinystr.h
Normal file
305
Extras/Serialize/BulletXmlWorldImporter/tinystr.h
Normal file
@@ -0,0 +1,305 @@
|
||||
/*
|
||||
www.sourceforge.net/projects/tinyxml
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
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.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TIXML_USE_STL
|
||||
|
||||
#ifndef TIXML_STRING_INCLUDED
|
||||
#define TIXML_STRING_INCLUDED
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
/* The support for explicit isn't that universal, and it isn't really
|
||||
required - it is used to check that the TiXmlString class isn't incorrectly
|
||||
used. Be nice to old compilers and macro it here:
|
||||
*/
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200 )
|
||||
// Microsoft visual studio, version 6 and higher.
|
||||
#define TIXML_EXPLICIT explicit
|
||||
#elif defined(__GNUC__) && (__GNUC__ >= 3 )
|
||||
// GCC version 3 and higher.s
|
||||
#define TIXML_EXPLICIT explicit
|
||||
#else
|
||||
#define TIXML_EXPLICIT
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
TiXmlString is an emulation of a subset of the std::string template.
|
||||
Its purpose is to allow compiling TinyXML on compilers with no or poor STL support.
|
||||
Only the member functions relevant to the TinyXML project have been implemented.
|
||||
The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase
|
||||
a string and there's no more room, we allocate a buffer twice as big as we need.
|
||||
*/
|
||||
class TiXmlString
|
||||
{
|
||||
public :
|
||||
// The size type used
|
||||
typedef size_t size_type;
|
||||
|
||||
// Error value for find primitive
|
||||
static const size_type npos; // = -1;
|
||||
|
||||
|
||||
// TiXmlString empty constructor
|
||||
TiXmlString () : rep_(&nullrep_)
|
||||
{
|
||||
}
|
||||
|
||||
// TiXmlString copy constructor
|
||||
TiXmlString ( const TiXmlString & copy) : rep_(0)
|
||||
{
|
||||
init(copy.length());
|
||||
memcpy(start(), copy.data(), length());
|
||||
}
|
||||
|
||||
// TiXmlString constructor, based on a string
|
||||
TIXML_EXPLICIT TiXmlString ( const char * copy) : rep_(0)
|
||||
{
|
||||
init( static_cast<size_type>( strlen(copy) ));
|
||||
memcpy(start(), copy, length());
|
||||
}
|
||||
|
||||
// TiXmlString constructor, based on a string
|
||||
TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) : rep_(0)
|
||||
{
|
||||
init(len);
|
||||
memcpy(start(), str, len);
|
||||
}
|
||||
|
||||
// TiXmlString destructor
|
||||
~TiXmlString ()
|
||||
{
|
||||
quit();
|
||||
}
|
||||
|
||||
TiXmlString& operator = (const char * copy)
|
||||
{
|
||||
return assign( copy, (size_type)strlen(copy));
|
||||
}
|
||||
|
||||
TiXmlString& operator = (const TiXmlString & copy)
|
||||
{
|
||||
return assign(copy.start(), copy.length());
|
||||
}
|
||||
|
||||
|
||||
// += operator. Maps to append
|
||||
TiXmlString& operator += (const char * suffix)
|
||||
{
|
||||
return append(suffix, static_cast<size_type>( strlen(suffix) ));
|
||||
}
|
||||
|
||||
// += operator. Maps to append
|
||||
TiXmlString& operator += (char single)
|
||||
{
|
||||
return append(&single, 1);
|
||||
}
|
||||
|
||||
// += operator. Maps to append
|
||||
TiXmlString& operator += (const TiXmlString & suffix)
|
||||
{
|
||||
return append(suffix.data(), suffix.length());
|
||||
}
|
||||
|
||||
|
||||
// Convert a TiXmlString into a null-terminated char *
|
||||
const char * c_str () const { return rep_->str; }
|
||||
|
||||
// Convert a TiXmlString into a char * (need not be null terminated).
|
||||
const char * data () const { return rep_->str; }
|
||||
|
||||
// Return the length of a TiXmlString
|
||||
size_type length () const { return rep_->size; }
|
||||
|
||||
// Alias for length()
|
||||
size_type size () const { return rep_->size; }
|
||||
|
||||
// Checks if a TiXmlString is empty
|
||||
bool empty () const { return rep_->size == 0; }
|
||||
|
||||
// Return capacity of string
|
||||
size_type capacity () const { return rep_->capacity; }
|
||||
|
||||
|
||||
// single char extraction
|
||||
const char& at (size_type index) const
|
||||
{
|
||||
assert( index < length() );
|
||||
return rep_->str[ index ];
|
||||
}
|
||||
|
||||
// [] operator
|
||||
char& operator [] (size_type index) const
|
||||
{
|
||||
assert( index < length() );
|
||||
return rep_->str[ index ];
|
||||
}
|
||||
|
||||
// find a char in a string. Return TiXmlString::npos if not found
|
||||
size_type find (char lookup) const
|
||||
{
|
||||
return find(lookup, 0);
|
||||
}
|
||||
|
||||
// find a char in a string from an offset. Return TiXmlString::npos if not found
|
||||
size_type find (char tofind, size_type offset) const
|
||||
{
|
||||
if (offset >= length()) return npos;
|
||||
|
||||
for (const char* p = c_str() + offset; *p != '\0'; ++p)
|
||||
{
|
||||
if (*p == tofind) return static_cast< size_type >( p - c_str() );
|
||||
}
|
||||
return npos;
|
||||
}
|
||||
|
||||
void clear ()
|
||||
{
|
||||
//Lee:
|
||||
//The original was just too strange, though correct:
|
||||
// TiXmlString().swap(*this);
|
||||
//Instead use the quit & re-init:
|
||||
quit();
|
||||
init(0,0);
|
||||
}
|
||||
|
||||
/* Function to reserve a big amount of data when we know we'll need it. Be aware that this
|
||||
function DOES NOT clear the content of the TiXmlString if any exists.
|
||||
*/
|
||||
void reserve (size_type cap);
|
||||
|
||||
TiXmlString& assign (const char* str, size_type len);
|
||||
|
||||
TiXmlString& append (const char* str, size_type len);
|
||||
|
||||
void swap (TiXmlString& other)
|
||||
{
|
||||
Rep* r = rep_;
|
||||
rep_ = other.rep_;
|
||||
other.rep_ = r;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void init(size_type sz) { init(sz, sz); }
|
||||
void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; }
|
||||
char* start() const { return rep_->str; }
|
||||
char* finish() const { return rep_->str + rep_->size; }
|
||||
|
||||
struct Rep
|
||||
{
|
||||
size_type size, capacity;
|
||||
char str[1];
|
||||
};
|
||||
|
||||
void init(size_type sz, size_type cap)
|
||||
{
|
||||
if (cap)
|
||||
{
|
||||
// Lee: the original form:
|
||||
// rep_ = static_cast<Rep*>(operator new(sizeof(Rep) + cap));
|
||||
// doesn't work in some cases of new being overloaded. Switching
|
||||
// to the normal allocation, although use an 'int' for systems
|
||||
// that are overly picky about structure alignment.
|
||||
const size_type bytesNeeded = sizeof(Rep) + cap;
|
||||
const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int );
|
||||
rep_ = reinterpret_cast<Rep*>( new int[ intsNeeded ] );
|
||||
|
||||
rep_->str[ rep_->size = sz ] = '\0';
|
||||
rep_->capacity = cap;
|
||||
}
|
||||
else
|
||||
{
|
||||
rep_ = &nullrep_;
|
||||
}
|
||||
}
|
||||
|
||||
void quit()
|
||||
{
|
||||
if (rep_ != &nullrep_)
|
||||
{
|
||||
// The rep_ is really an array of ints. (see the allocator, above).
|
||||
// Cast it back before delete, so the compiler won't incorrectly call destructors.
|
||||
delete [] ( reinterpret_cast<int*>( rep_ ) );
|
||||
}
|
||||
}
|
||||
|
||||
Rep * rep_;
|
||||
static Rep nullrep_;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
inline bool operator == (const TiXmlString & a, const TiXmlString & b)
|
||||
{
|
||||
return ( a.length() == b.length() ) // optimization on some platforms
|
||||
&& ( strcmp(a.c_str(), b.c_str()) == 0 ); // actual compare
|
||||
}
|
||||
inline bool operator < (const TiXmlString & a, const TiXmlString & b)
|
||||
{
|
||||
return strcmp(a.c_str(), b.c_str()) < 0;
|
||||
}
|
||||
|
||||
inline bool operator != (const TiXmlString & a, const TiXmlString & b) { return !(a == b); }
|
||||
inline bool operator > (const TiXmlString & a, const TiXmlString & b) { return b < a; }
|
||||
inline bool operator <= (const TiXmlString & a, const TiXmlString & b) { return !(b < a); }
|
||||
inline bool operator >= (const TiXmlString & a, const TiXmlString & b) { return !(a < b); }
|
||||
|
||||
inline bool operator == (const TiXmlString & a, const char* b) { return strcmp(a.c_str(), b) == 0; }
|
||||
inline bool operator == (const char* a, const TiXmlString & b) { return b == a; }
|
||||
inline bool operator != (const TiXmlString & a, const char* b) { return !(a == b); }
|
||||
inline bool operator != (const char* a, const TiXmlString & b) { return !(b == a); }
|
||||
|
||||
TiXmlString operator + (const TiXmlString & a, const TiXmlString & b);
|
||||
TiXmlString operator + (const TiXmlString & a, const char* b);
|
||||
TiXmlString operator + (const char* a, const TiXmlString & b);
|
||||
|
||||
|
||||
/*
|
||||
TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString.
|
||||
Only the operators that we need for TinyXML have been developped.
|
||||
*/
|
||||
class TiXmlOutStream : public TiXmlString
|
||||
{
|
||||
public :
|
||||
|
||||
// TiXmlOutStream << operator.
|
||||
TiXmlOutStream & operator << (const TiXmlString & in)
|
||||
{
|
||||
*this += in;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// TiXmlOutStream << operator.
|
||||
TiXmlOutStream & operator << (const char * in)
|
||||
{
|
||||
*this += in;
|
||||
return *this;
|
||||
}
|
||||
|
||||
} ;
|
||||
|
||||
#endif // TIXML_STRING_INCLUDED
|
||||
#endif // TIXML_USE_STL
|
||||
1886
Extras/Serialize/BulletXmlWorldImporter/tinyxml.cpp
Normal file
1886
Extras/Serialize/BulletXmlWorldImporter/tinyxml.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1805
Extras/Serialize/BulletXmlWorldImporter/tinyxml.h
Normal file
1805
Extras/Serialize/BulletXmlWorldImporter/tinyxml.h
Normal file
File diff suppressed because it is too large
Load Diff
52
Extras/Serialize/BulletXmlWorldImporter/tinyxmlerror.cpp
Normal file
52
Extras/Serialize/BulletXmlWorldImporter/tinyxmlerror.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
www.sourceforge.net/projects/tinyxml
|
||||
Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
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.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
*/
|
||||
|
||||
#include "tinyxml.h"
|
||||
|
||||
// The goal of the seperate error file is to make the first
|
||||
// step towards localization. tinyxml (currently) only supports
|
||||
// english error messages, but the could now be translated.
|
||||
//
|
||||
// It also cleans up the code a bit.
|
||||
//
|
||||
|
||||
const char* TiXmlBase::errorString[ TiXmlBase::TIXML_ERROR_STRING_COUNT ] =
|
||||
{
|
||||
"No error",
|
||||
"Error",
|
||||
"Failed to open file",
|
||||
"Error parsing Element.",
|
||||
"Failed to read Element name",
|
||||
"Error reading Element value.",
|
||||
"Error reading Attributes.",
|
||||
"Error: empty tag.",
|
||||
"Error reading end tag.",
|
||||
"Error parsing Unknown.",
|
||||
"Error parsing Comment.",
|
||||
"Error parsing Declaration.",
|
||||
"Error document empty.",
|
||||
"Error null (0) or unexpected EOF found in input stream.",
|
||||
"Error parsing CDATA.",
|
||||
"Error when TiXmlDocument added to document, because TiXmlDocument can only be at the root.",
|
||||
};
|
||||
1638
Extras/Serialize/BulletXmlWorldImporter/tinyxmlparser.cpp
Normal file
1638
Extras/Serialize/BulletXmlWorldImporter/tinyxmlparser.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -10,11 +10,11 @@ IF(INTERNAL_UPDATE_SERIALIZATION_STRUCTURES)
|
||||
# makesdna can re-generate the binary DNA representing the Bullet serialization structures
|
||||
# Be very careful modifying any of this, otherwise the .bullet format becomes incompatible
|
||||
|
||||
SUBDIRS ( BulletFileLoader BulletWorldImporter HeaderGenerator makesdna)
|
||||
SUBDIRS ( BulletFileLoader BulletXmlWorldImporter BulletWorldImporter HeaderGenerator makesdna)
|
||||
|
||||
ELSE(INTERNAL_UPDATE_SERIALIZATION_STRUCTURES)
|
||||
|
||||
SUBDIRS ( BulletFileLoader BulletWorldImporter )
|
||||
SUBDIRS ( BulletFileLoader BulletXmlWorldImporter BulletWorldImporter )
|
||||
|
||||
ENDIF (INTERNAL_UPDATE_SERIALIZATION_STRUCTURES)
|
||||
|
||||
|
||||
@@ -900,36 +900,40 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
|
||||
m_maxOverrideNumSolverIterations = 0;
|
||||
|
||||
#ifdef BT_DEBUG
|
||||
//make sure that dynamic bodies exist for all (enabled) constraints
|
||||
for (int i=0;i<numConstraints;i++)
|
||||
{
|
||||
btTypedConstraint* constraint = constraints[i];
|
||||
if (!constraint->getRigidBodyA().isStaticOrKinematicObject())
|
||||
{
|
||||
bool found=false;
|
||||
for (int b=0;b<numBodies;b++)
|
||||
{
|
||||
if (constraint->isEnabled())
|
||||
{
|
||||
if (!constraint->getRigidBodyA().isStaticOrKinematicObject())
|
||||
{
|
||||
bool found=false;
|
||||
for (int b=0;b<numBodies;b++)
|
||||
{
|
||||
|
||||
if (&constraint->getRigidBodyA()==bodies[b])
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
btAssert(found);
|
||||
}
|
||||
if (!constraint->getRigidBodyB().isStaticOrKinematicObject())
|
||||
{
|
||||
bool found=false;
|
||||
for (int b=0;b<numBodies;b++)
|
||||
{
|
||||
if (&constraint->getRigidBodyB()==bodies[b])
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
btAssert(found);
|
||||
}
|
||||
if (&constraint->getRigidBodyA()==bodies[b])
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
btAssert(found);
|
||||
}
|
||||
if (!constraint->getRigidBodyB().isStaticOrKinematicObject())
|
||||
{
|
||||
bool found=false;
|
||||
for (int b=0;b<numBodies;b++)
|
||||
{
|
||||
if (&constraint->getRigidBodyB()==bodies[b])
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
btAssert(found);
|
||||
}
|
||||
}
|
||||
}
|
||||
//make sure that dynamic bodies exist for all contact manifolds
|
||||
for (int i=0;i<numManifolds;i++)
|
||||
|
||||
Reference in New Issue
Block a user