Binary serialization in the .bullet file format (work-in-progress)

This commit is contained in:
erwin.coumans
2009-12-08 18:02:37 +00:00
parent 385c16e309
commit 3edd806b88
14 changed files with 1057 additions and 522 deletions

View File

@@ -29,6 +29,7 @@ SET(LinearMath_HDRS
btQuickprof.h
btRandom.h
btScalar.h
btSerializer.h
btStackAlloc.h
btTransform.h
btTransformUtil.h

View File

@@ -138,6 +138,16 @@ class btAlignedObjectArray
return m_size;
}
SIMD_FORCE_INLINE const T& at(int n) const
{
return m_data[n];
}
SIMD_FORCE_INLINE T& at(int n)
{
return m_data[n];
}
SIMD_FORCE_INLINE const T& operator[](int n) const
{
return m_data[n];

View File

@@ -1,6 +1,8 @@
#ifndef DEFAULT_MOTION_STATE_H
#define DEFAULT_MOTION_STATE_H
#include "btMotionState.h"
///The btDefaultMotionState provides a common implementation to synchronize world transforms with offsets.
struct btDefaultMotionState : public btMotionState
{

View File

@@ -95,14 +95,12 @@ public:
};
template <class Value>
class btHashKeyPtr
class btHashInt
{
int m_uid;
public:
btHashKeyPtr(int uid)
btHashInt(int uid)
:m_uid(uid)
{
}
@@ -112,11 +110,10 @@ public:
return m_uid;
}
bool equals(const btHashKeyPtr<Value>& other) const
bool equals(const btHashInt& other) const
{
return getUid1() == other.getUid1();
}
//to our success
SIMD_FORCE_INLINE unsigned int getHash()const
{
@@ -130,6 +127,46 @@ public:
key ^= (key >> 16);
return key;
}
};
class btHashKeyPtr
{
void* m_pointer;
public:
btHashKeyPtr(void* ptr)
:m_pointer(ptr)
{
}
const void* getPointer() const
{
return m_pointer;
}
bool equals(const btHashKeyPtr& other) const
{
return getPointer() == other.getPointer();
}
//to our success
SIMD_FORCE_INLINE unsigned int getHash()const
{
const bool VOID_IS_8 = ((sizeof(void*)==8));
int* intPtr = (int*)&m_pointer;
int key = VOID_IS_8? intPtr[0]+intPtr[1] : intPtr[0];
// Thomas Wang's hash
key += ~(key << 15);
key ^= (key >> 10);
key += (key << 3);
key ^= (key >> 6);
key += ~(key << 11);
key ^= (key >> 16);
return key;
}
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,288 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2009 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_SERIALIZER_H
#define BT_SERIALIZER_H
#include "btScalar.h" // has definitions like SIMD_FORCE_INLINE
#include "btStackAlloc.h"
class btChunk
{
public:
int m_chunkCode;
int m_length;
void *m_oldPtr;
int m_dna_nr;
int m_number;
};
///Allow to serialize data in a chunk format
class btSerializer
{
public:
virtual ~btSerializer() {}
virtual btChunk* allocate(size_t size,int numElements) = 0;
};
#define BT_HEADER_LENGTH 12
class btDefaultSerializer
{
public:
btAlignedObjectArray<char*> mTypes;
btAlignedObjectArray<short*> mStructs;
btAlignedObjectArray<short> mTlens;
btHashMap<btHashInt, int> mStructReverse;
btHashMap<btHashString,int> mTypeLookup;
btAlignedObjectArray<btChunk*> m_chunkPtrs;
int m_totalSize;
unsigned char* m_buffer;
int m_bufferPointer;
void* m_dna;
int m_dnaLength;
btDefaultSerializer(int totalSize)
:m_totalSize(totalSize),
m_bufferPointer(0)
// m_dna(0),
// m_dnaLength(0)
{
m_buffer = (unsigned char*)btAlignedAlloc(16,totalSize);
m_bufferPointer += BT_HEADER_LENGTH;
memcpy(m_buffer, "BULLET ", 7);
int endian= 1;
endian= ((char*)&endian)[0];
if (endian)
{
m_buffer[7] = '_';
} else
{
m_buffer[7] = '-';
}
if (sizeof(void*)==8)
{
m_buffer[8]='V';
} else
{
m_buffer[8]='v';
}
m_buffer[9] = '2';
m_buffer[10] = '7';
m_buffer[11] = '5';
}
virtual ~btDefaultSerializer()
{
btAlignedFree(m_buffer);
}
int getReverseType(const char *type) const
{
btHashString key(type);
const int* valuePtr = mTypeLookup.find(key);
if (valuePtr)
return *valuePtr;
return -1;
}
void writeDNA()
{
unsigned char* dnaTarget = m_buffer+m_bufferPointer;
memcpy(dnaTarget,m_dna,m_dnaLength);
m_bufferPointer += m_dnaLength;
}
virtual btChunk* allocate(size_t size, int numElements)
{
unsigned char* ptr = m_buffer+m_bufferPointer;
m_bufferPointer += size*numElements+sizeof(btChunk);
unsigned char* data = ptr + sizeof(btChunk);
btChunk* chunk = (btChunk*)ptr;
chunk->m_chunkCode = 0;
chunk->m_oldPtr = data;
chunk->m_length = size;
chunk->m_number = numElements;
m_chunkPtrs.push_back(chunk);
return chunk;
}
void initDNA(const char* bdna,int dnalen)
{
m_dna = btAlignedAlloc(dnalen,16);
memcpy(m_dna,bdna,dnalen);
m_dnaLength = dnalen;
int *intPtr=0;short *shtPtr=0;
char *cp = 0;int dataLen =0;long nr=0;
intPtr = (int*)bdna;
/*
SDNA (4 bytes) (magic number)
NAME (4 bytes)
<nr> (4 bytes) amount of names (int)
<string>
<string>
*/
if (strncmp((const char*)bdna, "SDNA", 4)==0)
{
// skip ++ NAME
intPtr++; intPtr++;
}
// Parse names
dataLen = *intPtr;
intPtr++;
cp = (char*)intPtr;
for (int i=0; i<dataLen; i++)
{
while (*cp)cp++;
cp++;
}
{
nr= (long)cp;
long mask=3;
nr= ((nr+3)&~3)-nr;
while (nr--)
{
cp++;
}
}
/*
TYPE (4 bytes)
<nr> amount of types (int)
<string>
<string>
*/
intPtr = (int*)cp;
assert(strncmp(cp, "TYPE", 4)==0); intPtr++;
dataLen = *intPtr;
intPtr++;
cp = (char*)intPtr;
for (int i=0; i<dataLen; i++)
{
mTypes.push_back(cp);
while (*cp)cp++;
cp++;
}
{
nr= (long)cp;
long mask=3;
nr= ((nr+3)&~3)-nr;
while (nr--)
{
cp++;
}
}
/*
TLEN (4 bytes)
<len> (short) the lengths of types
<len>
*/
// Parse type lens
intPtr = (int*)cp;
assert(strncmp(cp, "TLEN", 4)==0); intPtr++;
dataLen = (int)mTypes.size();
shtPtr = (short*)intPtr;
for (int i=0; i<dataLen; i++, shtPtr++)
{
mTlens.push_back(shtPtr[0]);
}
if (dataLen & 1) shtPtr++;
/*
STRC (4 bytes)
<nr> amount of structs (int)
<typenr>
<nr_of_elems>
<typenr>
<namenr>
<typenr>
<namenr>
*/
intPtr = (int*)shtPtr;
cp = (char*)intPtr;
assert(strncmp(cp, "STRC", 4)==0); intPtr++;
dataLen = *intPtr;
intPtr++;
shtPtr = (short*)intPtr;
for (int i=0; i<dataLen; i++)
{
mStructs.push_back (shtPtr);
shtPtr+= (2*shtPtr[1])+2;
}
// build reverse lookups
for (int i=0; i<(int)mStructs.size(); i++)
{
short *strc = mStructs.at(i);
mStructReverse.insert(strc[0], i);
mTypeLookup.insert(btHashString(mTypes[strc[0]]),i);
}
}
};
#endif //BT_SERIALIZER_H

View File

@@ -17,14 +17,19 @@ subject to the following restrictions:
#ifndef btTransform_H
#define btTransform_H
#include "btVector3.h"
#include "btMatrix3x3.h"
/**@brief The btTransform class supports rigid transforms with only translation and rotation and no scaling/shear.
*It can be used in combination with btVector3, btQuaternion and btMatrix3x3 linear algebra classes. */
class btTransform {
///Storage for the rotation
btMatrix3x3 m_basis;
///Storage for the translation
btVector3 m_origin;
public:
@@ -195,12 +200,11 @@ public:
static const btTransform identityTransform(btMatrix3x3::getIdentity());
return identityTransform;
}
private:
///Storage for the rotation
btMatrix3x3 m_basis;
///Storage for the translation
btVector3 m_origin;
virtual void serialize(struct btTransformData& dataOut) const;
virtual void deSerialize(const struct btTransformData& dataIn);
};
@@ -233,6 +237,24 @@ SIMD_FORCE_INLINE bool operator==(const btTransform& t1, const btTransform& t2)
t1.getOrigin() == t2.getOrigin() );
}
///for serialization
struct btTransformData
{
btMatrix3x3Data m_basis;
btVector3Data m_origin;
};
SIMD_FORCE_INLINE void btTransform::serialize(btTransformData& dataOut) const
{
m_basis.serialize(dataOut.m_basis);
m_origin.serialize(dataOut.m_origin);
}
SIMD_FORCE_INLINE void btTransform::deSerialize(const btTransformData& dataIn)
{
m_basis.deSerialize(dataIn.m_basis);
m_origin.deSerialize(dataIn.m_origin);
}
#endif

View File

@@ -18,14 +18,16 @@ subject to the following restrictions:
#define SIMD__VECTOR3_H
#include "btScalar.h"
#include "btScalar.h"
#include "btMinMax.h"
/**@brief btVector3 can be used to represent 3D points and vectors.
* It has an un-used w component to suit 16-byte alignment when btVector3 is stored in containers. This extra component can be used by derived classes (Quaternion?) or by user
* Ideally, this class should be replaced by a platform optimized SIMD version that keeps the data in registers
*/
ATTRIBUTE_ALIGNED16(class) btVector3
{
public:
@@ -318,6 +320,9 @@ public:
setValue(btScalar(0.),btScalar(0.),btScalar(0.));
}
SIMD_FORCE_INLINE void serialize(struct btVector3Data& dataOut) const;
SIMD_FORCE_INLINE void deSerialize(const struct btVector3Data& dataIn);
};
/**@brief Return the sum of two vectors (Point symantics)*/
@@ -587,8 +592,6 @@ public:
}
};
@@ -657,4 +660,23 @@ SIMD_FORCE_INLINE void btPlaneSpace1 (const btVector3& n, btVector3& p, btVector
}
}
struct btVector3Data
{
btScalar m_floats[4];
};
SIMD_FORCE_INLINE void btVector3::serialize(struct btVector3Data& dataOut) const
{
///could also do a memcpy, check if it is worth it
for (int i=0;i<4;i++)
dataOut.m_floats[i] = m_floats[i];
}
SIMD_FORCE_INLINE void btVector3::deSerialize(const struct btVector3Data& dataIn)
{
for (int i=0;i<4;i++)
m_floats[i] = dataIn.m_floats[i];
}
#endif //SIMD__VECTOR3_H