Binary serialization in the .bullet file format (work-in-progress)
This commit is contained in:
@@ -830,7 +830,7 @@ unsigned int btQuantizedBvh::getAlignmentSerializationPadding()
|
||||
return 0;//BVH_ALIGNMENT_BLOCKS * BVH_ALIGNMENT;
|
||||
}
|
||||
|
||||
unsigned btQuantizedBvh::calculateSerializeBufferSize()
|
||||
unsigned btQuantizedBvh::calculateSerializeBufferSize() const
|
||||
{
|
||||
unsigned baseSize = sizeof(btQuantizedBvh) + getAlignmentSerializationPadding();
|
||||
baseSize += sizeof(btBvhSubtreeInfo) * m_subtreeHeaderCount;
|
||||
@@ -841,7 +841,7 @@ unsigned btQuantizedBvh::calculateSerializeBufferSize()
|
||||
return baseSize + m_curNodeIndex * sizeof(btOptimizedBvhNode);
|
||||
}
|
||||
|
||||
bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBufferSize */, bool i_swapEndian)
|
||||
bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBufferSize */, bool i_swapEndian) const
|
||||
{
|
||||
btAssert(m_subtreeHeaderCount == m_SubtreeHeaders.size());
|
||||
m_subtreeHeaderCount = m_SubtreeHeaders.size();
|
||||
|
||||
@@ -190,7 +190,7 @@ protected:
|
||||
BvhSubtreeInfoArray m_SubtreeHeaders;
|
||||
|
||||
//This is only used for serialization so we don't have to add serialization directly to btAlignedObjectArray
|
||||
int m_subtreeHeaderCount;
|
||||
mutable int m_subtreeHeaderCount;
|
||||
|
||||
|
||||
|
||||
@@ -445,10 +445,10 @@ public:
|
||||
|
||||
|
||||
/////Calculate space needed to store BVH for serialization
|
||||
unsigned calculateSerializeBufferSize();
|
||||
unsigned calculateSerializeBufferSize() const;
|
||||
|
||||
/// Data buffer MUST be 16 byte aligned
|
||||
virtual bool serialize(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian);
|
||||
virtual bool serialize(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian) const;
|
||||
|
||||
///deSerializeInPlace loads and initializes a BVH from a buffer in memory 'in place'
|
||||
static btQuantizedBvh *deSerializeInPlace(void *i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian);
|
||||
|
||||
@@ -27,11 +27,11 @@ subject to the following restrictions:
|
||||
|
||||
struct btBroadphaseProxy;
|
||||
class btCollisionShape;
|
||||
struct btCollisionShapeData;
|
||||
#include "LinearMath/btMotionState.h"
|
||||
#include "LinearMath/btAlignedAllocator.h"
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
|
||||
|
||||
typedef btAlignedObjectArray<class btCollisionObject*> btCollisionObjectArray;
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ protected:
|
||||
btVector3 m_interpolationAngularVelocity;
|
||||
|
||||
btVector3 m_anisotropicFriction;
|
||||
bool m_hasAnisotropicFriction;
|
||||
int m_hasAnisotropicFriction;
|
||||
btScalar m_contactProcessingThreshold;
|
||||
|
||||
btBroadphaseProxy* m_broadphaseHandle;
|
||||
@@ -76,13 +76,13 @@ protected:
|
||||
btScalar m_friction;
|
||||
btScalar m_restitution;
|
||||
|
||||
///users can point to their objects, m_userPointer is not used by Bullet, see setUserPointer/getUserPointer
|
||||
void* m_userObjectPointer;
|
||||
|
||||
///m_internalType is reserved to distinguish Bullet's btCollisionObject, btRigidBody, btSoftBody, btGhostObject etc.
|
||||
///do not assign your own m_internalType unless you write a new dynamics object class.
|
||||
int m_internalType;
|
||||
|
||||
///users can point to their objects, m_userPointer is not used by Bullet, see setUserPointer/getUserPointer
|
||||
void* m_userObjectPointer;
|
||||
|
||||
///time of impact calculation
|
||||
btScalar m_hitFraction;
|
||||
|
||||
@@ -93,9 +93,7 @@ protected:
|
||||
btScalar m_ccdMotionThreshold;
|
||||
|
||||
/// If some object should have elaborate collision filtering by sub-classes
|
||||
bool m_checkCollideWith;
|
||||
|
||||
char m_pad[7];
|
||||
int m_checkCollideWith;
|
||||
|
||||
virtual bool checkCollideWithOverride(btCollisionObject* /* co */)
|
||||
{
|
||||
@@ -143,7 +141,7 @@ public:
|
||||
}
|
||||
bool hasAnisotropicFriction() const
|
||||
{
|
||||
return m_hasAnisotropicFriction;
|
||||
return m_hasAnisotropicFriction!=0;
|
||||
}
|
||||
|
||||
///the constraint solver can discard solving contacts, if the distance is above this threshold. 0 by default.
|
||||
@@ -416,6 +414,85 @@ public:
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual int calculateSerializeBufferSize() const;
|
||||
|
||||
///fills the dataBuffer and returns the struct name (and 0 on failure)
|
||||
virtual const char* serialize(void* dataBuffer) const;
|
||||
|
||||
|
||||
};
|
||||
|
||||
///using offsetof for m_vtablePadding might break some compilers, in that case define m_vtablePadding manually
|
||||
|
||||
///for serialization
|
||||
struct btCollisionObjectData
|
||||
{
|
||||
btTransformData m_worldTransform;
|
||||
btTransformData m_interpolationWorldTransform;
|
||||
btVector3Data m_interpolationLinearVelocity;
|
||||
btVector3Data m_interpolationAngularVelocity;
|
||||
btVector3Data m_anisotropicFriction;
|
||||
int m_hasAnisotropicFriction;
|
||||
btScalar m_contactProcessingThreshold;
|
||||
void *m_broadphaseHandle;
|
||||
void *m_collisionShape;
|
||||
btCollisionShapeData *m_rootCollisionShape;
|
||||
int m_collisionFlags;
|
||||
int m_islandTag1;
|
||||
int m_companionId;
|
||||
int m_activationState1;
|
||||
btScalar m_deactivationTime;
|
||||
btScalar m_friction;
|
||||
btScalar m_restitution;
|
||||
int m_internalType;
|
||||
void *m_userObjectPointer;
|
||||
btScalar m_hitFraction;
|
||||
btScalar m_ccdSweptSphereRadius;
|
||||
btScalar m_ccdMotionThreshold;
|
||||
int m_checkCollideWith;
|
||||
};
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE int btCollisionObject::calculateSerializeBufferSize() const
|
||||
{
|
||||
return sizeof(btCollisionObjectData);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE const char* btCollisionObject::serialize(void* dataBuffer) const
|
||||
{
|
||||
|
||||
btCollisionObjectData* dataOut = (btCollisionObjectData*)dataBuffer;
|
||||
|
||||
m_worldTransform.serialize(dataOut->m_worldTransform);
|
||||
m_interpolationWorldTransform.serialize(dataOut->m_interpolationWorldTransform);
|
||||
m_interpolationLinearVelocity.serialize(dataOut->m_interpolationLinearVelocity);
|
||||
m_interpolationAngularVelocity.serialize(dataOut->m_interpolationAngularVelocity);
|
||||
m_anisotropicFriction.serialize(dataOut->m_anisotropicFriction);
|
||||
dataOut->m_hasAnisotropicFriction = m_hasAnisotropicFriction;
|
||||
dataOut->m_contactProcessingThreshold = m_contactProcessingThreshold;
|
||||
dataOut->m_broadphaseHandle = 0;
|
||||
dataOut->m_collisionShape = m_collisionShape; //@todo
|
||||
dataOut->m_rootCollisionShape = 0;//@todo
|
||||
dataOut->m_collisionFlags = m_collisionFlags;
|
||||
dataOut->m_islandTag1 = m_islandTag1;
|
||||
dataOut->m_companionId = m_companionId;
|
||||
dataOut->m_activationState1 = m_activationState1;
|
||||
dataOut->m_activationState1 = m_activationState1;
|
||||
dataOut->m_deactivationTime = m_deactivationTime;
|
||||
dataOut->m_friction = m_friction;
|
||||
dataOut->m_restitution = m_restitution;
|
||||
dataOut->m_internalType = m_internalType;
|
||||
dataOut->m_userObjectPointer = m_userObjectPointer;
|
||||
dataOut->m_hitFraction = m_hitFraction;
|
||||
dataOut->m_ccdSweptSphereRadius = m_ccdSweptSphereRadius;
|
||||
dataOut->m_ccdMotionThreshold = m_ccdMotionThreshold;
|
||||
dataOut->m_ccdMotionThreshold = m_ccdMotionThreshold;
|
||||
dataOut->m_checkCollideWith = m_checkCollideWith;
|
||||
|
||||
return "btCollisionObjectData";
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif //COLLISION_OBJECT_H
|
||||
|
||||
@@ -310,8 +310,41 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual int calculateSerializeBufferSize();
|
||||
|
||||
///fills the dataBuffer and returns the struct name (and 0 on failure)
|
||||
virtual const char* serialize(void* dataBuffer) const;
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct btBoxShapeData
|
||||
{
|
||||
btVector3Data m_halfExtents;
|
||||
btVector3Data m_localScaling;
|
||||
};
|
||||
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE int btBoxShape::calculateSerializeBufferSize()
|
||||
{
|
||||
return sizeof(btBoxShapeData);
|
||||
}
|
||||
|
||||
///fills the dataBuffer and returns the struct name (and 0 on failure)
|
||||
SIMD_FORCE_INLINE const char* btBoxShape::serialize(void* dataBuffer) const
|
||||
{
|
||||
btBoxShapeData* boxData = (btBoxShapeData*) dataBuffer;
|
||||
|
||||
m_implicitShapeDimensions.serialize(boxData->m_halfExtents);
|
||||
m_localScaling.serialize(boxData->m_localScaling);
|
||||
return "btBoxShapeData";
|
||||
}
|
||||
|
||||
|
||||
#endif //OBB_BOX_MINKOWSKI_H
|
||||
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@ subject to the following restrictions:
|
||||
#include "LinearMath/btMatrix3x3.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" //for the shape types
|
||||
|
||||
|
||||
|
||||
///The btCollisionShape class provides an interface for collision shapes that can be shared among btCollisionObjects.
|
||||
class btCollisionShape
|
||||
{
|
||||
@@ -113,5 +115,14 @@ public:
|
||||
|
||||
};
|
||||
|
||||
///for serialization
|
||||
struct btCollisionShapeData
|
||||
{
|
||||
void *m_userPointer;
|
||||
int m_shapeType;
|
||||
char m_padding[4];
|
||||
};
|
||||
|
||||
|
||||
#endif //COLLISION_SHAPE_H
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
void updateBvhNodes(btStridingMeshInterface* meshInterface,int firstNode,int endNode,int index);
|
||||
|
||||
/// Data buffer MUST be 16 byte aligned
|
||||
virtual bool serialize(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian)
|
||||
virtual bool serialize(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian) const
|
||||
{
|
||||
return btQuantizedBvh::serialize(o_alignedDataBuffer,i_dataBufferSize,i_swapEndian);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
@@ -13,10 +13,8 @@ subject to the following restrictions:
|
||||
*/
|
||||
|
||||
|
||||
#ifndef btMatrix3x3_H
|
||||
#define btMatrix3x3_H
|
||||
|
||||
#include "btScalar.h"
|
||||
#ifndef BT_MATRIX3x3_H
|
||||
#define BT_MATRIX3x3_H
|
||||
|
||||
#include "btVector3.h"
|
||||
#include "btQuaternion.h"
|
||||
@@ -26,6 +24,10 @@ subject to the following restrictions:
|
||||
/**@brief The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with btQuaternion, btTransform and btVector3.
|
||||
* Make sure to only include a pure orthogonal matrix without scaling. */
|
||||
class btMatrix3x3 {
|
||||
|
||||
///Data storage for the matrix, each vector is a row of the matrix
|
||||
btVector3 m_el[3];
|
||||
|
||||
public:
|
||||
/** @brief No initializaion constructor */
|
||||
btMatrix3x3 () {}
|
||||
@@ -290,7 +292,13 @@ class btMatrix3x3 {
|
||||
* @param solution_number Which solution of two possible solutions ( 1 or 2) are possible values*/
|
||||
void getEulerZYX(btScalar& yaw, btScalar& pitch, btScalar& roll, unsigned int solution_number = 1) const
|
||||
{
|
||||
struct Euler{btScalar yaw, pitch, roll;};
|
||||
struct Euler
|
||||
{
|
||||
btScalar yaw;
|
||||
btScalar pitch;
|
||||
btScalar roll;
|
||||
};
|
||||
|
||||
Euler euler_out;
|
||||
Euler euler_out2; //second solution
|
||||
//get the pointer to the raw data
|
||||
@@ -475,7 +483,7 @@ class btMatrix3x3 {
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
/**@brief Calculate the matrix cofactor
|
||||
* @param r1 The first row to use for calculating the cofactor
|
||||
* @param c1 The first column to use for calculating the cofactor
|
||||
@@ -487,10 +495,14 @@ class btMatrix3x3 {
|
||||
{
|
||||
return m_el[r1][c1] * m_el[r2][c2] - m_el[r1][c2] * m_el[r2][c1];
|
||||
}
|
||||
///Data storage for the matrix, each vector is a row of the matrix
|
||||
btVector3 m_el[3];
|
||||
|
||||
virtual void serialize(struct btMatrix3x3Data& dataOut) const;
|
||||
|
||||
virtual void deSerialize(const struct btMatrix3x3Data& dataIn);
|
||||
|
||||
};
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE btMatrix3x3&
|
||||
btMatrix3x3::operator*=(const btMatrix3x3& m)
|
||||
{
|
||||
@@ -615,4 +627,24 @@ SIMD_FORCE_INLINE bool operator==(const btMatrix3x3& m1, const btMatrix3x3& m2)
|
||||
m1[0][2] == m2[0][2] && m1[1][2] == m2[1][2] && m1[2][2] == m2[2][2] );
|
||||
}
|
||||
|
||||
#endif
|
||||
///for serialization
|
||||
struct btMatrix3x3Data
|
||||
{
|
||||
btVector3Data m_el[3];
|
||||
};
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE void btMatrix3x3::serialize(struct btMatrix3x3Data& dataOut) const
|
||||
{
|
||||
for (int i=0;i<3;i++)
|
||||
m_el[i].serialize(dataOut.m_el[i]);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void btMatrix3x3::deSerialize(const struct btMatrix3x3Data& dataIn)
|
||||
{
|
||||
for (int i=0;i<3;i++)
|
||||
m_el[i].deSerialize(dataIn.m_el[i]);
|
||||
}
|
||||
|
||||
#endif //BT_MATRIX3x3_H
|
||||
|
||||
|
||||
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:
|
||||
|
||||
@@ -196,11 +201,10 @@ public:
|
||||
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