Binary serialization in the .bullet file format (work-in-progress)
This commit is contained in:
@@ -29,6 +29,7 @@ SET(LinearMath_HDRS
|
||||
btQuickprof.h
|
||||
btRandom.h
|
||||
btScalar.h
|
||||
btSerializer.h
|
||||
btStackAlloc.h
|
||||
btTransform.h
|
||||
btTransformUtil.h
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
288
src/LinearMath/btSerializer.h
Normal file
288
src/LinearMath/btSerializer.h
Normal 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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user