add bullet
This commit is contained in:
236
libs/bullet/LinearMath/btAabbUtil2.h
Normal file
236
libs/bullet/LinearMath/btAabbUtil2.h
Normal file
@ -0,0 +1,236 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
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 AABB_UTIL2
|
||||
#define AABB_UTIL2
|
||||
|
||||
#include "btTransform.h"
|
||||
#include "btVector3.h"
|
||||
#include "btMinMax.h"
|
||||
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE void AabbExpand (btVector3& aabbMin,
|
||||
btVector3& aabbMax,
|
||||
const btVector3& expansionMin,
|
||||
const btVector3& expansionMax)
|
||||
{
|
||||
aabbMin = aabbMin + expansionMin;
|
||||
aabbMax = aabbMax + expansionMax;
|
||||
}
|
||||
|
||||
/// conservative test for overlap between two aabbs
|
||||
SIMD_FORCE_INLINE bool TestPointAgainstAabb2(const btVector3 &aabbMin1, const btVector3 &aabbMax1,
|
||||
const btVector3 &point)
|
||||
{
|
||||
bool overlap = true;
|
||||
overlap = (aabbMin1.getX() > point.getX() || aabbMax1.getX() < point.getX()) ? false : overlap;
|
||||
overlap = (aabbMin1.getZ() > point.getZ() || aabbMax1.getZ() < point.getZ()) ? false : overlap;
|
||||
overlap = (aabbMin1.getY() > point.getY() || aabbMax1.getY() < point.getY()) ? false : overlap;
|
||||
return overlap;
|
||||
}
|
||||
|
||||
|
||||
/// conservative test for overlap between two aabbs
|
||||
SIMD_FORCE_INLINE bool TestAabbAgainstAabb2(const btVector3 &aabbMin1, const btVector3 &aabbMax1,
|
||||
const btVector3 &aabbMin2, const btVector3 &aabbMax2)
|
||||
{
|
||||
bool overlap = true;
|
||||
overlap = (aabbMin1.getX() > aabbMax2.getX() || aabbMax1.getX() < aabbMin2.getX()) ? false : overlap;
|
||||
overlap = (aabbMin1.getZ() > aabbMax2.getZ() || aabbMax1.getZ() < aabbMin2.getZ()) ? false : overlap;
|
||||
overlap = (aabbMin1.getY() > aabbMax2.getY() || aabbMax1.getY() < aabbMin2.getY()) ? false : overlap;
|
||||
return overlap;
|
||||
}
|
||||
|
||||
/// conservative test for overlap between triangle and aabb
|
||||
SIMD_FORCE_INLINE bool TestTriangleAgainstAabb2(const btVector3 *vertices,
|
||||
const btVector3 &aabbMin, const btVector3 &aabbMax)
|
||||
{
|
||||
const btVector3 &p1 = vertices[0];
|
||||
const btVector3 &p2 = vertices[1];
|
||||
const btVector3 &p3 = vertices[2];
|
||||
|
||||
if (btMin(btMin(p1[0], p2[0]), p3[0]) > aabbMax[0]) return false;
|
||||
if (btMax(btMax(p1[0], p2[0]), p3[0]) < aabbMin[0]) return false;
|
||||
|
||||
if (btMin(btMin(p1[2], p2[2]), p3[2]) > aabbMax[2]) return false;
|
||||
if (btMax(btMax(p1[2], p2[2]), p3[2]) < aabbMin[2]) return false;
|
||||
|
||||
if (btMin(btMin(p1[1], p2[1]), p3[1]) > aabbMax[1]) return false;
|
||||
if (btMax(btMax(p1[1], p2[1]), p3[1]) < aabbMin[1]) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE int btOutcode(const btVector3& p,const btVector3& halfExtent)
|
||||
{
|
||||
return (p.getX() < -halfExtent.getX() ? 0x01 : 0x0) |
|
||||
(p.getX() > halfExtent.getX() ? 0x08 : 0x0) |
|
||||
(p.getY() < -halfExtent.getY() ? 0x02 : 0x0) |
|
||||
(p.getY() > halfExtent.getY() ? 0x10 : 0x0) |
|
||||
(p.getZ() < -halfExtent.getZ() ? 0x4 : 0x0) |
|
||||
(p.getZ() > halfExtent.getZ() ? 0x20 : 0x0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE bool btRayAabb2(const btVector3& rayFrom,
|
||||
const btVector3& rayInvDirection,
|
||||
const unsigned int raySign[3],
|
||||
const btVector3 bounds[2],
|
||||
btScalar& tmin,
|
||||
btScalar lambda_min,
|
||||
btScalar lambda_max)
|
||||
{
|
||||
btScalar tmax, tymin, tymax, tzmin, tzmax;
|
||||
tmin = (bounds[raySign[0]].getX() - rayFrom.getX()) * rayInvDirection.getX();
|
||||
tmax = (bounds[1-raySign[0]].getX() - rayFrom.getX()) * rayInvDirection.getX();
|
||||
tymin = (bounds[raySign[1]].getY() - rayFrom.getY()) * rayInvDirection.getY();
|
||||
tymax = (bounds[1-raySign[1]].getY() - rayFrom.getY()) * rayInvDirection.getY();
|
||||
|
||||
if ( (tmin > tymax) || (tymin > tmax) )
|
||||
return false;
|
||||
|
||||
if (tymin > tmin)
|
||||
tmin = tymin;
|
||||
|
||||
if (tymax < tmax)
|
||||
tmax = tymax;
|
||||
|
||||
tzmin = (bounds[raySign[2]].getZ() - rayFrom.getZ()) * rayInvDirection.getZ();
|
||||
tzmax = (bounds[1-raySign[2]].getZ() - rayFrom.getZ()) * rayInvDirection.getZ();
|
||||
|
||||
if ( (tmin > tzmax) || (tzmin > tmax) )
|
||||
return false;
|
||||
if (tzmin > tmin)
|
||||
tmin = tzmin;
|
||||
if (tzmax < tmax)
|
||||
tmax = tzmax;
|
||||
return ( (tmin < lambda_max) && (tmax > lambda_min) );
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE bool btRayAabb(const btVector3& rayFrom,
|
||||
const btVector3& rayTo,
|
||||
const btVector3& aabbMin,
|
||||
const btVector3& aabbMax,
|
||||
btScalar& param, btVector3& normal)
|
||||
{
|
||||
btVector3 aabbHalfExtent = (aabbMax-aabbMin)* btScalar(0.5);
|
||||
btVector3 aabbCenter = (aabbMax+aabbMin)* btScalar(0.5);
|
||||
btVector3 source = rayFrom - aabbCenter;
|
||||
btVector3 target = rayTo - aabbCenter;
|
||||
int sourceOutcode = btOutcode(source,aabbHalfExtent);
|
||||
int targetOutcode = btOutcode(target,aabbHalfExtent);
|
||||
if ((sourceOutcode & targetOutcode) == 0x0)
|
||||
{
|
||||
btScalar lambda_enter = btScalar(0.0);
|
||||
btScalar lambda_exit = param;
|
||||
btVector3 r = target - source;
|
||||
int i;
|
||||
btScalar normSign = 1;
|
||||
btVector3 hitNormal(0,0,0);
|
||||
int bit=1;
|
||||
|
||||
for (int j=0;j<2;j++)
|
||||
{
|
||||
for (i = 0; i != 3; ++i)
|
||||
{
|
||||
if (sourceOutcode & bit)
|
||||
{
|
||||
btScalar lambda = (-source[i] - aabbHalfExtent[i]*normSign) / r[i];
|
||||
if (lambda_enter <= lambda)
|
||||
{
|
||||
lambda_enter = lambda;
|
||||
hitNormal.setValue(0,0,0);
|
||||
hitNormal[i] = normSign;
|
||||
}
|
||||
}
|
||||
else if (targetOutcode & bit)
|
||||
{
|
||||
btScalar lambda = (-source[i] - aabbHalfExtent[i]*normSign) / r[i];
|
||||
btSetMin(lambda_exit, lambda);
|
||||
}
|
||||
bit<<=1;
|
||||
}
|
||||
normSign = btScalar(-1.);
|
||||
}
|
||||
if (lambda_enter <= lambda_exit)
|
||||
{
|
||||
param = lambda_enter;
|
||||
normal = hitNormal;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE void btTransformAabb(const btVector3& halfExtents, btScalar margin,const btTransform& t,btVector3& aabbMinOut,btVector3& aabbMaxOut)
|
||||
{
|
||||
btVector3 halfExtentsWithMargin = halfExtents+btVector3(margin,margin,margin);
|
||||
btMatrix3x3 abs_b = t.getBasis().absolute();
|
||||
btVector3 center = t.getOrigin();
|
||||
btVector3 extent = btVector3(abs_b[0].dot(halfExtentsWithMargin),
|
||||
abs_b[1].dot(halfExtentsWithMargin),
|
||||
abs_b[2].dot(halfExtentsWithMargin));
|
||||
aabbMinOut = center - extent;
|
||||
aabbMaxOut = center + extent;
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE void btTransformAabb(const btVector3& localAabbMin,const btVector3& localAabbMax, btScalar margin,const btTransform& trans,btVector3& aabbMinOut,btVector3& aabbMaxOut)
|
||||
{
|
||||
btAssert(localAabbMin.getX() <= localAabbMax.getX());
|
||||
btAssert(localAabbMin.getY() <= localAabbMax.getY());
|
||||
btAssert(localAabbMin.getZ() <= localAabbMax.getZ());
|
||||
btVector3 localHalfExtents = btScalar(0.5)*(localAabbMax-localAabbMin);
|
||||
localHalfExtents+=btVector3(margin,margin,margin);
|
||||
|
||||
btVector3 localCenter = btScalar(0.5)*(localAabbMax+localAabbMin);
|
||||
btMatrix3x3 abs_b = trans.getBasis().absolute();
|
||||
btVector3 center = trans(localCenter);
|
||||
btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents),
|
||||
abs_b[1].dot(localHalfExtents),
|
||||
abs_b[2].dot(localHalfExtents));
|
||||
aabbMinOut = center-extent;
|
||||
aabbMaxOut = center+extent;
|
||||
}
|
||||
|
||||
#define USE_BANCHLESS 1
|
||||
#ifdef USE_BANCHLESS
|
||||
//This block replaces the block below and uses no branches, and replaces the 8 bit return with a 32 bit return for improved performance (~3x on XBox 360)
|
||||
SIMD_FORCE_INLINE unsigned testQuantizedAabbAgainstQuantizedAabb(const unsigned short int* aabbMin1,const unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2)
|
||||
{
|
||||
return static_cast<unsigned int>(btSelect((unsigned)((aabbMin1[0] <= aabbMax2[0]) & (aabbMax1[0] >= aabbMin2[0])
|
||||
& (aabbMin1[2] <= aabbMax2[2]) & (aabbMax1[2] >= aabbMin2[2])
|
||||
& (aabbMin1[1] <= aabbMax2[1]) & (aabbMax1[1] >= aabbMin2[1])),
|
||||
1, 0));
|
||||
}
|
||||
#else
|
||||
SIMD_FORCE_INLINE bool testQuantizedAabbAgainstQuantizedAabb(const unsigned short int* aabbMin1,const unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2)
|
||||
{
|
||||
bool overlap = true;
|
||||
overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap;
|
||||
overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap;
|
||||
overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap;
|
||||
return overlap;
|
||||
}
|
||||
#endif //USE_BANCHLESS
|
||||
|
||||
#endif
|
||||
|
||||
|
182
libs/bullet/LinearMath/btAlignedAllocator.cpp
Normal file
182
libs/bullet/LinearMath/btAlignedAllocator.cpp
Normal file
@ -0,0 +1,182 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
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 "btAlignedAllocator.h"
|
||||
|
||||
int gNumAlignedAllocs = 0;
|
||||
int gNumAlignedFree = 0;
|
||||
int gTotalBytesAlignedAllocs = 0;//detect memory leaks
|
||||
|
||||
static void *btAllocDefault(size_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
static void btFreeDefault(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
static btAllocFunc *sAllocFunc = btAllocDefault;
|
||||
static btFreeFunc *sFreeFunc = btFreeDefault;
|
||||
|
||||
|
||||
|
||||
#if defined (BT_HAS_ALIGNED_ALLOCATOR)
|
||||
#include <malloc.h>
|
||||
static void *btAlignedAllocDefault(size_t size, int alignment)
|
||||
{
|
||||
return _aligned_malloc(size, (size_t)alignment);
|
||||
}
|
||||
|
||||
static void btAlignedFreeDefault(void *ptr)
|
||||
{
|
||||
_aligned_free(ptr);
|
||||
}
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
#include <stdlib.h>
|
||||
|
||||
static inline void *btAlignedAllocDefault(size_t size, int alignment)
|
||||
{
|
||||
return memalign(alignment, size);
|
||||
}
|
||||
|
||||
static inline void btAlignedFreeDefault(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
#else
|
||||
static inline void *btAlignedAllocDefault(size_t size, int alignment)
|
||||
{
|
||||
void *ret;
|
||||
char *real;
|
||||
unsigned long offset;
|
||||
|
||||
real = (char *)sAllocFunc(size + sizeof(void *) + (alignment-1));
|
||||
if (real) {
|
||||
offset = (alignment - (unsigned long)(real + sizeof(void *))) & (alignment-1);
|
||||
ret = (void *)((real + sizeof(void *)) + offset);
|
||||
*((void **)(ret)-1) = (void *)(real);
|
||||
} else {
|
||||
ret = (void *)(real);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static inline void btAlignedFreeDefault(void *ptr)
|
||||
{
|
||||
void* real;
|
||||
|
||||
if (ptr) {
|
||||
real = *((void **)(ptr)-1);
|
||||
sFreeFunc(real);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static btAlignedAllocFunc *sAlignedAllocFunc = btAlignedAllocDefault;
|
||||
static btAlignedFreeFunc *sAlignedFreeFunc = btAlignedFreeDefault;
|
||||
|
||||
void btAlignedAllocSetCustomAligned(btAlignedAllocFunc *allocFunc, btAlignedFreeFunc *freeFunc)
|
||||
{
|
||||
sAlignedAllocFunc = allocFunc ? allocFunc : btAlignedAllocDefault;
|
||||
sAlignedFreeFunc = freeFunc ? freeFunc : btAlignedFreeDefault;
|
||||
}
|
||||
|
||||
void btAlignedAllocSetCustom(btAllocFunc *allocFunc, btFreeFunc *freeFunc)
|
||||
{
|
||||
sAllocFunc = allocFunc ? allocFunc : btAllocDefault;
|
||||
sFreeFunc = freeFunc ? freeFunc : btFreeDefault;
|
||||
}
|
||||
|
||||
#ifdef BT_DEBUG_MEMORY_ALLOCATIONS
|
||||
//this generic allocator provides the total allocated number of bytes
|
||||
#include <stdio.h>
|
||||
|
||||
void* btAlignedAllocInternal (size_t size, int alignment,int line,char* filename)
|
||||
{
|
||||
void *ret;
|
||||
char *real;
|
||||
unsigned long offset;
|
||||
|
||||
gTotalBytesAlignedAllocs += size;
|
||||
gNumAlignedAllocs++;
|
||||
|
||||
|
||||
real = (char *)sAllocFunc(size + 2*sizeof(void *) + (alignment-1));
|
||||
if (real) {
|
||||
offset = (alignment - (unsigned long)(real + 2*sizeof(void *))) &
|
||||
(alignment-1);
|
||||
ret = (void *)((real + 2*sizeof(void *)) + offset);
|
||||
*((void **)(ret)-1) = (void *)(real);
|
||||
*((int*)(ret)-2) = size;
|
||||
|
||||
} else {
|
||||
ret = (void *)(real);//??
|
||||
}
|
||||
|
||||
printf("allocation#%d at address %x, from %s,line %d, size %d\n",gNumAlignedAllocs,real, filename,line,size);
|
||||
|
||||
int* ptr = (int*)ret;
|
||||
*ptr = 12;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void btAlignedFreeInternal (void* ptr,int line,char* filename)
|
||||
{
|
||||
|
||||
void* real;
|
||||
gNumAlignedFree++;
|
||||
|
||||
if (ptr) {
|
||||
real = *((void **)(ptr)-1);
|
||||
int size = *((int*)(ptr)-2);
|
||||
gTotalBytesAlignedAllocs -= size;
|
||||
|
||||
printf("free #%d at address %x, from %s,line %d, size %d\n",gNumAlignedFree,real, filename,line,size);
|
||||
|
||||
sFreeFunc(real);
|
||||
} else
|
||||
{
|
||||
printf("NULL ptr\n");
|
||||
}
|
||||
}
|
||||
|
||||
#else //BT_DEBUG_MEMORY_ALLOCATIONS
|
||||
|
||||
void* btAlignedAllocInternal (size_t size, int alignment)
|
||||
{
|
||||
gNumAlignedAllocs++;
|
||||
void* ptr;
|
||||
ptr = sAlignedAllocFunc(size, alignment);
|
||||
// printf("btAlignedAllocInternal %d, %x\n",size,ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void btAlignedFreeInternal (void* ptr)
|
||||
{
|
||||
if (!ptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gNumAlignedFree++;
|
||||
// printf("btAlignedFreeInternal %x\n",ptr);
|
||||
sAlignedFreeFunc(ptr);
|
||||
}
|
||||
|
||||
#endif //BT_DEBUG_MEMORY_ALLOCATIONS
|
||||
|
107
libs/bullet/LinearMath/btAlignedAllocator.h
Normal file
107
libs/bullet/LinearMath/btAlignedAllocator.h
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
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_ALIGNED_ALLOCATOR
|
||||
#define BT_ALIGNED_ALLOCATOR
|
||||
|
||||
///we probably replace this with our own aligned memory allocator
|
||||
///so we replace _aligned_malloc and _aligned_free with our own
|
||||
///that is better portable and more predictable
|
||||
|
||||
#include "btScalar.h"
|
||||
//#define BT_DEBUG_MEMORY_ALLOCATIONS 1
|
||||
#ifdef BT_DEBUG_MEMORY_ALLOCATIONS
|
||||
|
||||
#define btAlignedAlloc(a,b) \
|
||||
btAlignedAllocInternal(a,b,__LINE__,__FILE__)
|
||||
|
||||
#define btAlignedFree(ptr) \
|
||||
btAlignedFreeInternal(ptr,__LINE__,__FILE__)
|
||||
|
||||
void* btAlignedAllocInternal (size_t size, int alignment,int line,char* filename);
|
||||
|
||||
void btAlignedFreeInternal (void* ptr,int line,char* filename);
|
||||
|
||||
#else
|
||||
void* btAlignedAllocInternal (size_t size, int alignment);
|
||||
void btAlignedFreeInternal (void* ptr);
|
||||
|
||||
#define btAlignedAlloc(size,alignment) btAlignedAllocInternal(size,alignment)
|
||||
#define btAlignedFree(ptr) btAlignedFreeInternal(ptr)
|
||||
|
||||
#endif
|
||||
typedef int size_type;
|
||||
|
||||
typedef void *(btAlignedAllocFunc)(size_t size, int alignment);
|
||||
typedef void (btAlignedFreeFunc)(void *memblock);
|
||||
typedef void *(btAllocFunc)(size_t size);
|
||||
typedef void (btFreeFunc)(void *memblock);
|
||||
|
||||
///The developer can let all Bullet memory allocations go through a custom memory allocator, using btAlignedAllocSetCustom
|
||||
void btAlignedAllocSetCustom(btAllocFunc *allocFunc, btFreeFunc *freeFunc);
|
||||
///If the developer has already an custom aligned allocator, then btAlignedAllocSetCustomAligned can be used. The default aligned allocator pre-allocates extra memory using the non-aligned allocator, and instruments it.
|
||||
void btAlignedAllocSetCustomAligned(btAlignedAllocFunc *allocFunc, btAlignedFreeFunc *freeFunc);
|
||||
|
||||
|
||||
///The btAlignedAllocator is a portable class for aligned memory allocations.
|
||||
///Default implementations for unaligned and aligned allocations can be overridden by a custom allocator using btAlignedAllocSetCustom and btAlignedAllocSetCustomAligned.
|
||||
template < typename T , unsigned Alignment >
|
||||
class btAlignedAllocator {
|
||||
|
||||
typedef btAlignedAllocator< T , Alignment > self_type;
|
||||
|
||||
public:
|
||||
|
||||
//just going down a list:
|
||||
btAlignedAllocator() {}
|
||||
/*
|
||||
btAlignedAllocator( const self_type & ) {}
|
||||
*/
|
||||
|
||||
template < typename Other >
|
||||
btAlignedAllocator( const btAlignedAllocator< Other , Alignment > & ) {}
|
||||
|
||||
typedef const T* const_pointer;
|
||||
typedef const T& const_reference;
|
||||
typedef T* pointer;
|
||||
typedef T& reference;
|
||||
typedef T value_type;
|
||||
|
||||
pointer address ( reference ref ) const { return &ref; }
|
||||
const_pointer address ( const_reference ref ) const { return &ref; }
|
||||
pointer allocate ( size_type n , const_pointer * hint = 0 ) {
|
||||
(void)hint;
|
||||
return reinterpret_cast< pointer >(btAlignedAlloc( sizeof(value_type) * n , Alignment ));
|
||||
}
|
||||
void construct ( pointer ptr , const value_type & value ) { new (ptr) value_type( value ); }
|
||||
void deallocate( pointer ptr ) {
|
||||
btAlignedFree( reinterpret_cast< void * >( ptr ) );
|
||||
}
|
||||
void destroy ( pointer ptr ) { ptr->~value_type(); }
|
||||
|
||||
|
||||
template < typename O > struct rebind {
|
||||
typedef btAlignedAllocator< O , Alignment > other;
|
||||
};
|
||||
template < typename O >
|
||||
self_type & operator=( const btAlignedAllocator< O , Alignment > & ) { return *this; }
|
||||
|
||||
friend bool operator==( const self_type & , const self_type & ) { return true; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //BT_ALIGNED_ALLOCATOR
|
||||
|
471
libs/bullet/LinearMath/btAlignedObjectArray.h
Normal file
471
libs/bullet/LinearMath/btAlignedObjectArray.h
Normal file
@ -0,0 +1,471 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
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_OBJECT_ARRAY__
|
||||
#define BT_OBJECT_ARRAY__
|
||||
|
||||
#include "btScalar.h" // has definitions like SIMD_FORCE_INLINE
|
||||
#include "btAlignedAllocator.h"
|
||||
|
||||
///If the platform doesn't support placement new, you can disable BT_USE_PLACEMENT_NEW
|
||||
///then the btAlignedObjectArray doesn't support objects with virtual methods, and non-trivial constructors/destructors
|
||||
///You can enable BT_USE_MEMCPY, then swapping elements in the array will use memcpy instead of operator=
|
||||
///see discussion here: http://continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1231 and
|
||||
///http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1240
|
||||
|
||||
#define BT_USE_PLACEMENT_NEW 1
|
||||
//#define BT_USE_MEMCPY 1 //disable, because it is cumbersome to find out for each platform where memcpy is defined. It can be in <memory.h> or <string.h> or otherwise...
|
||||
|
||||
#ifdef BT_USE_MEMCPY
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#endif //BT_USE_MEMCPY
|
||||
|
||||
#ifdef BT_USE_PLACEMENT_NEW
|
||||
#include <new> //for placement new
|
||||
#endif //BT_USE_PLACEMENT_NEW
|
||||
|
||||
|
||||
///The btAlignedObjectArray template class uses a subset of the stl::vector interface for its methods
|
||||
///It is developed to replace stl::vector to avoid portability issues, including STL alignment issues to add SIMD/SSE data
|
||||
template <typename T>
|
||||
//template <class T>
|
||||
class btAlignedObjectArray
|
||||
{
|
||||
btAlignedAllocator<T , 16> m_allocator;
|
||||
|
||||
int m_size;
|
||||
int m_capacity;
|
||||
T* m_data;
|
||||
//PCK: added this line
|
||||
bool m_ownsMemory;
|
||||
|
||||
protected:
|
||||
SIMD_FORCE_INLINE int allocSize(int size)
|
||||
{
|
||||
return (size ? size*2 : 1);
|
||||
}
|
||||
SIMD_FORCE_INLINE void copy(int start,int end, T* dest) const
|
||||
{
|
||||
int i;
|
||||
for (i=start;i<end;++i)
|
||||
#ifdef BT_USE_PLACEMENT_NEW
|
||||
new (&dest[i]) T(m_data[i]);
|
||||
#else
|
||||
dest[i] = m_data[i];
|
||||
#endif //BT_USE_PLACEMENT_NEW
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void init()
|
||||
{
|
||||
//PCK: added this line
|
||||
m_ownsMemory = true;
|
||||
m_data = 0;
|
||||
m_size = 0;
|
||||
m_capacity = 0;
|
||||
}
|
||||
SIMD_FORCE_INLINE void destroy(int first,int last)
|
||||
{
|
||||
int i;
|
||||
for (i=first; i<last;i++)
|
||||
{
|
||||
m_data[i].~T();
|
||||
}
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void* allocate(int size)
|
||||
{
|
||||
if (size)
|
||||
return m_allocator.allocate(size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void deallocate()
|
||||
{
|
||||
if(m_data) {
|
||||
//PCK: enclosed the deallocation in this block
|
||||
if (m_ownsMemory)
|
||||
{
|
||||
m_allocator.deallocate(m_data);
|
||||
}
|
||||
m_data = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public:
|
||||
|
||||
btAlignedObjectArray()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
~btAlignedObjectArray()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
///Generally it is best to avoid using the copy constructor of an btAlignedObjectArray, and use a (const) reference to the array instead.
|
||||
btAlignedObjectArray(const btAlignedObjectArray& otherArray)
|
||||
{
|
||||
init();
|
||||
|
||||
int otherSize = otherArray.size();
|
||||
resize (otherSize);
|
||||
otherArray.copy(0, otherSize, m_data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// return the number of elements in the array
|
||||
SIMD_FORCE_INLINE int size() const
|
||||
{
|
||||
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];
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE T& operator[](int n)
|
||||
{
|
||||
return m_data[n];
|
||||
}
|
||||
|
||||
|
||||
///clear the array, deallocated memory. Generally it is better to use array.resize(0), to reduce performance overhead of run-time memory (de)allocations.
|
||||
SIMD_FORCE_INLINE void clear()
|
||||
{
|
||||
destroy(0,size());
|
||||
|
||||
deallocate();
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void pop_back()
|
||||
{
|
||||
m_size--;
|
||||
m_data[m_size].~T();
|
||||
}
|
||||
|
||||
///resize changes the number of elements in the array. If the new size is larger, the new elements will be constructed using the optional second argument.
|
||||
///when the new number of elements is smaller, the destructor will be called, but memory will not be freed, to reduce performance overhead of run-time memory (de)allocations.
|
||||
SIMD_FORCE_INLINE void resize(int newsize, const T& fillData=T())
|
||||
{
|
||||
int curSize = size();
|
||||
|
||||
if (newsize < curSize)
|
||||
{
|
||||
for(int i = newsize; i < curSize; i++)
|
||||
{
|
||||
m_data[i].~T();
|
||||
}
|
||||
} else
|
||||
{
|
||||
if (newsize > size())
|
||||
{
|
||||
reserve(newsize);
|
||||
}
|
||||
#ifdef BT_USE_PLACEMENT_NEW
|
||||
for (int i=curSize;i<newsize;i++)
|
||||
{
|
||||
new ( &m_data[i]) T(fillData);
|
||||
}
|
||||
#endif //BT_USE_PLACEMENT_NEW
|
||||
|
||||
}
|
||||
|
||||
m_size = newsize;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE T& expandNonInitializing( )
|
||||
{
|
||||
int sz = size();
|
||||
if( sz == capacity() )
|
||||
{
|
||||
reserve( allocSize(size()) );
|
||||
}
|
||||
m_size++;
|
||||
|
||||
return m_data[sz];
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE T& expand( const T& fillValue=T())
|
||||
{
|
||||
int sz = size();
|
||||
if( sz == capacity() )
|
||||
{
|
||||
reserve( allocSize(size()) );
|
||||
}
|
||||
m_size++;
|
||||
#ifdef BT_USE_PLACEMENT_NEW
|
||||
new (&m_data[sz]) T(fillValue); //use the in-place new (not really allocating heap memory)
|
||||
#endif
|
||||
|
||||
return m_data[sz];
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE void push_back(const T& _Val)
|
||||
{
|
||||
int sz = size();
|
||||
if( sz == capacity() )
|
||||
{
|
||||
reserve( allocSize(size()) );
|
||||
}
|
||||
|
||||
#ifdef BT_USE_PLACEMENT_NEW
|
||||
new ( &m_data[m_size] ) T(_Val);
|
||||
#else
|
||||
m_data[size()] = _Val;
|
||||
#endif //BT_USE_PLACEMENT_NEW
|
||||
|
||||
m_size++;
|
||||
}
|
||||
|
||||
|
||||
/// return the pre-allocated (reserved) elements, this is at least as large as the total number of elements,see size() and reserve()
|
||||
SIMD_FORCE_INLINE int capacity() const
|
||||
{
|
||||
return m_capacity;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void reserve(int _Count)
|
||||
{ // determine new minimum length of allocated storage
|
||||
if (capacity() < _Count)
|
||||
{ // not enough room, reallocate
|
||||
T* s = (T*)allocate(_Count);
|
||||
|
||||
copy(0, size(), s);
|
||||
|
||||
destroy(0,size());
|
||||
|
||||
deallocate();
|
||||
|
||||
//PCK: added this line
|
||||
m_ownsMemory = true;
|
||||
|
||||
m_data = s;
|
||||
|
||||
m_capacity = _Count;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class less
|
||||
{
|
||||
public:
|
||||
|
||||
bool operator() ( const T& a, const T& b )
|
||||
{
|
||||
return ( a < b );
|
||||
}
|
||||
};
|
||||
|
||||
template <typename L>
|
||||
void quickSortInternal(L CompareFunc,int lo, int hi)
|
||||
{
|
||||
// lo is the lower index, hi is the upper index
|
||||
// of the region of array a that is to be sorted
|
||||
int i=lo, j=hi;
|
||||
T x=m_data[(lo+hi)/2];
|
||||
|
||||
// partition
|
||||
do
|
||||
{
|
||||
while (CompareFunc(m_data[i],x))
|
||||
i++;
|
||||
while (CompareFunc(x,m_data[j]))
|
||||
j--;
|
||||
if (i<=j)
|
||||
{
|
||||
swap(i,j);
|
||||
i++; j--;
|
||||
}
|
||||
} while (i<=j);
|
||||
|
||||
// recursion
|
||||
if (lo<j)
|
||||
quickSortInternal( CompareFunc, lo, j);
|
||||
if (i<hi)
|
||||
quickSortInternal( CompareFunc, i, hi);
|
||||
}
|
||||
|
||||
|
||||
template <typename L>
|
||||
void quickSort(L CompareFunc)
|
||||
{
|
||||
//don't sort 0 or 1 elements
|
||||
if (size()>1)
|
||||
{
|
||||
quickSortInternal(CompareFunc,0,size()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///heap sort from http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Sort/Heap/
|
||||
template <typename L>
|
||||
void downHeap(T *pArr, int k, int n,L CompareFunc)
|
||||
{
|
||||
/* PRE: a[k+1..N] is a heap */
|
||||
/* POST: a[k..N] is a heap */
|
||||
|
||||
T temp = pArr[k - 1];
|
||||
/* k has child(s) */
|
||||
while (k <= n/2)
|
||||
{
|
||||
int child = 2*k;
|
||||
|
||||
if ((child < n) && CompareFunc(pArr[child - 1] , pArr[child]))
|
||||
{
|
||||
child++;
|
||||
}
|
||||
/* pick larger child */
|
||||
if (CompareFunc(temp , pArr[child - 1]))
|
||||
{
|
||||
/* move child up */
|
||||
pArr[k - 1] = pArr[child - 1];
|
||||
k = child;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
pArr[k - 1] = temp;
|
||||
} /*downHeap*/
|
||||
|
||||
void swap(int index0,int index1)
|
||||
{
|
||||
#ifdef BT_USE_MEMCPY
|
||||
char temp[sizeof(T)];
|
||||
memcpy(temp,&m_data[index0],sizeof(T));
|
||||
memcpy(&m_data[index0],&m_data[index1],sizeof(T));
|
||||
memcpy(&m_data[index1],temp,sizeof(T));
|
||||
#else
|
||||
T temp = m_data[index0];
|
||||
m_data[index0] = m_data[index1];
|
||||
m_data[index1] = temp;
|
||||
#endif //BT_USE_PLACEMENT_NEW
|
||||
|
||||
}
|
||||
|
||||
template <typename L>
|
||||
void heapSort(L CompareFunc)
|
||||
{
|
||||
/* sort a[0..N-1], N.B. 0 to N-1 */
|
||||
int k;
|
||||
int n = m_size;
|
||||
for (k = n/2; k > 0; k--)
|
||||
{
|
||||
downHeap(m_data, k, n, CompareFunc);
|
||||
}
|
||||
|
||||
/* a[1..N] is now a heap */
|
||||
while ( n>=1 )
|
||||
{
|
||||
swap(0,n-1); /* largest of a[0..n-1] */
|
||||
|
||||
|
||||
n = n - 1;
|
||||
/* restore a[1..i-1] heap */
|
||||
downHeap(m_data, 1, n, CompareFunc);
|
||||
}
|
||||
}
|
||||
|
||||
///non-recursive binary search, assumes sorted array
|
||||
int findBinarySearch(const T& key) const
|
||||
{
|
||||
int first = 0;
|
||||
int last = size();
|
||||
|
||||
//assume sorted array
|
||||
while (first <= last) {
|
||||
int mid = (first + last) / 2; // compute mid point.
|
||||
if (key > m_data[mid])
|
||||
first = mid + 1; // repeat search in top half.
|
||||
else if (key < m_data[mid])
|
||||
last = mid - 1; // repeat search in bottom half.
|
||||
else
|
||||
return mid; // found it. return position /////
|
||||
}
|
||||
return size(); // failed to find key
|
||||
}
|
||||
|
||||
|
||||
int findLinearSearch(const T& key) const
|
||||
{
|
||||
int index=size();
|
||||
int i;
|
||||
|
||||
for (i=0;i<size();i++)
|
||||
{
|
||||
if (m_data[i] == key)
|
||||
{
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
void remove(const T& key)
|
||||
{
|
||||
|
||||
int findIndex = findLinearSearch(key);
|
||||
if (findIndex<size())
|
||||
{
|
||||
swap( findIndex,size()-1);
|
||||
pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
//PCK: whole function
|
||||
void initializeFromBuffer(void *buffer, int size, int capacity)
|
||||
{
|
||||
clear();
|
||||
m_ownsMemory = false;
|
||||
m_data = (T*)buffer;
|
||||
m_size = size;
|
||||
m_capacity = capacity;
|
||||
}
|
||||
|
||||
void copyFromArray(const btAlignedObjectArray& otherArray)
|
||||
{
|
||||
int otherSize = otherArray.size();
|
||||
resize (otherSize);
|
||||
otherArray.copy(0, otherSize, m_data);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif //BT_OBJECT_ARRAY__
|
1174
libs/bullet/LinearMath/btConvexHull.cpp
Normal file
1174
libs/bullet/LinearMath/btConvexHull.cpp
Normal file
File diff suppressed because it is too large
Load Diff
241
libs/bullet/LinearMath/btConvexHull.h
Normal file
241
libs/bullet/LinearMath/btConvexHull.h
Normal file
@ -0,0 +1,241 @@
|
||||
|
||||
/*
|
||||
Stan Melax Convex Hull Computation
|
||||
Copyright (c) 2008 Stan Melax http://www.melax.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.
|
||||
*/
|
||||
|
||||
///includes modifications/improvements by John Ratcliff, see BringOutYourDead below.
|
||||
|
||||
#ifndef CD_HULL_H
|
||||
#define CD_HULL_H
|
||||
|
||||
#include "btVector3.h"
|
||||
#include "btAlignedObjectArray.h"
|
||||
|
||||
typedef btAlignedObjectArray<unsigned int> TUIntArray;
|
||||
|
||||
class HullResult
|
||||
{
|
||||
public:
|
||||
HullResult(void)
|
||||
{
|
||||
mPolygons = true;
|
||||
mNumOutputVertices = 0;
|
||||
mNumFaces = 0;
|
||||
mNumIndices = 0;
|
||||
}
|
||||
bool mPolygons; // true if indices represents polygons, false indices are triangles
|
||||
unsigned int mNumOutputVertices; // number of vertices in the output hull
|
||||
btAlignedObjectArray<btVector3> m_OutputVertices; // array of vertices
|
||||
unsigned int mNumFaces; // the number of faces produced
|
||||
unsigned int mNumIndices; // the total number of indices
|
||||
btAlignedObjectArray<unsigned int> m_Indices; // pointer to indices.
|
||||
|
||||
// If triangles, then indices are array indexes into the vertex list.
|
||||
// If polygons, indices are in the form (number of points in face) (p1, p2, p3, ..) etc..
|
||||
};
|
||||
|
||||
enum HullFlag
|
||||
{
|
||||
QF_TRIANGLES = (1<<0), // report results as triangles, not polygons.
|
||||
QF_REVERSE_ORDER = (1<<1), // reverse order of the triangle indices.
|
||||
QF_DEFAULT = QF_TRIANGLES
|
||||
};
|
||||
|
||||
|
||||
class HullDesc
|
||||
{
|
||||
public:
|
||||
HullDesc(void)
|
||||
{
|
||||
mFlags = QF_DEFAULT;
|
||||
mVcount = 0;
|
||||
mVertices = 0;
|
||||
mVertexStride = sizeof(btVector3);
|
||||
mNormalEpsilon = 0.001f;
|
||||
mMaxVertices = 4096; // maximum number of points to be considered for a convex hull.
|
||||
mMaxFaces = 4096;
|
||||
};
|
||||
|
||||
HullDesc(HullFlag flag,
|
||||
unsigned int vcount,
|
||||
const btVector3 *vertices,
|
||||
unsigned int stride = sizeof(btVector3))
|
||||
{
|
||||
mFlags = flag;
|
||||
mVcount = vcount;
|
||||
mVertices = vertices;
|
||||
mVertexStride = stride;
|
||||
mNormalEpsilon = btScalar(0.001);
|
||||
mMaxVertices = 4096;
|
||||
}
|
||||
|
||||
bool HasHullFlag(HullFlag flag) const
|
||||
{
|
||||
if ( mFlags & flag ) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void SetHullFlag(HullFlag flag)
|
||||
{
|
||||
mFlags|=flag;
|
||||
}
|
||||
|
||||
void ClearHullFlag(HullFlag flag)
|
||||
{
|
||||
mFlags&=~flag;
|
||||
}
|
||||
|
||||
unsigned int mFlags; // flags to use when generating the convex hull.
|
||||
unsigned int mVcount; // number of vertices in the input point cloud
|
||||
const btVector3 *mVertices; // the array of vertices.
|
||||
unsigned int mVertexStride; // the stride of each vertex, in bytes.
|
||||
btScalar mNormalEpsilon; // the epsilon for removing duplicates. This is a normalized value, if normalized bit is on.
|
||||
unsigned int mMaxVertices; // maximum number of vertices to be considered for the hull!
|
||||
unsigned int mMaxFaces;
|
||||
};
|
||||
|
||||
enum HullError
|
||||
{
|
||||
QE_OK, // success!
|
||||
QE_FAIL // failed.
|
||||
};
|
||||
|
||||
class btPlane
|
||||
{
|
||||
public:
|
||||
btVector3 normal;
|
||||
btScalar dist; // distance below origin - the D from plane equasion Ax+By+Cz+D=0
|
||||
btPlane(const btVector3 &n,btScalar d):normal(n),dist(d){}
|
||||
btPlane():normal(),dist(0){}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
class ConvexH
|
||||
{
|
||||
public:
|
||||
class HalfEdge
|
||||
{
|
||||
public:
|
||||
short ea; // the other half of the edge (index into edges list)
|
||||
unsigned char v; // the vertex at the start of this edge (index into vertices list)
|
||||
unsigned char p; // the facet on which this edge lies (index into facets list)
|
||||
HalfEdge(){}
|
||||
HalfEdge(short _ea,unsigned char _v, unsigned char _p):ea(_ea),v(_v),p(_p){}
|
||||
};
|
||||
ConvexH()
|
||||
{
|
||||
}
|
||||
~ConvexH()
|
||||
{
|
||||
}
|
||||
btAlignedObjectArray<btVector3> vertices;
|
||||
btAlignedObjectArray<HalfEdge> edges;
|
||||
btAlignedObjectArray<btPlane> facets;
|
||||
ConvexH(int vertices_size,int edges_size,int facets_size);
|
||||
};
|
||||
|
||||
|
||||
class int4
|
||||
{
|
||||
public:
|
||||
int x,y,z,w;
|
||||
int4(){};
|
||||
int4(int _x,int _y, int _z,int _w){x=_x;y=_y;z=_z;w=_w;}
|
||||
const int& operator[](int i) const {return (&x)[i];}
|
||||
int& operator[](int i) {return (&x)[i];}
|
||||
};
|
||||
|
||||
class PHullResult
|
||||
{
|
||||
public:
|
||||
|
||||
PHullResult(void)
|
||||
{
|
||||
mVcount = 0;
|
||||
mIndexCount = 0;
|
||||
mFaceCount = 0;
|
||||
mVertices = 0;
|
||||
}
|
||||
|
||||
unsigned int mVcount;
|
||||
unsigned int mIndexCount;
|
||||
unsigned int mFaceCount;
|
||||
btVector3* mVertices;
|
||||
TUIntArray m_Indices;
|
||||
};
|
||||
|
||||
|
||||
|
||||
///The HullLibrary class can create a convex hull from a collection of vertices, using the ComputeHull method.
|
||||
///The btShapeHull class uses this HullLibrary to create a approximate convex mesh given a general (non-polyhedral) convex shape.
|
||||
class HullLibrary
|
||||
{
|
||||
|
||||
btAlignedObjectArray<class btHullTriangle*> m_tris;
|
||||
|
||||
public:
|
||||
|
||||
btAlignedObjectArray<int> m_vertexIndexMapping;
|
||||
|
||||
|
||||
HullError CreateConvexHull(const HullDesc& desc, // describes the input request
|
||||
HullResult& result); // contains the resulst
|
||||
HullError ReleaseResult(HullResult &result); // release memory allocated for this result, we are done with it.
|
||||
|
||||
private:
|
||||
|
||||
bool ComputeHull(unsigned int vcount,const btVector3 *vertices,PHullResult &result,unsigned int vlimit);
|
||||
|
||||
class btHullTriangle* allocateTriangle(int a,int b,int c);
|
||||
void deAllocateTriangle(btHullTriangle*);
|
||||
void b2bfix(btHullTriangle* s,btHullTriangle*t);
|
||||
|
||||
void removeb2b(btHullTriangle* s,btHullTriangle*t);
|
||||
|
||||
void checkit(btHullTriangle *t);
|
||||
|
||||
btHullTriangle* extrudable(btScalar epsilon);
|
||||
|
||||
int calchull(btVector3 *verts,int verts_count, TUIntArray& tris_out, int &tris_count,int vlimit);
|
||||
|
||||
int calchullgen(btVector3 *verts,int verts_count, int vlimit);
|
||||
|
||||
int4 FindSimplex(btVector3 *verts,int verts_count,btAlignedObjectArray<int> &allow);
|
||||
|
||||
class ConvexH* ConvexHCrop(ConvexH& convex,const btPlane& slice);
|
||||
|
||||
void extrude(class btHullTriangle* t0,int v);
|
||||
|
||||
ConvexH* test_cube();
|
||||
|
||||
//BringOutYourDead (John Ratcliff): When you create a convex hull you hand it a large input set of vertices forming a 'point cloud'.
|
||||
//After the hull is generated it give you back a set of polygon faces which index the *original* point cloud.
|
||||
//The thing is, often times, there are many 'dead vertices' in the point cloud that are on longer referenced by the hull.
|
||||
//The routine 'BringOutYourDead' find only the referenced vertices, copies them to an new buffer, and re-indexes the hull so that it is a minimal representation.
|
||||
void BringOutYourDead(const btVector3* verts,unsigned int vcount, btVector3* overts,unsigned int &ocount,unsigned int* indices,unsigned indexcount);
|
||||
|
||||
bool CleanupVertices(unsigned int svcount,
|
||||
const btVector3* svertices,
|
||||
unsigned int stride,
|
||||
unsigned int &vcount, // output number of vertices
|
||||
btVector3* vertices, // location to store the results.
|
||||
btScalar normalepsilon,
|
||||
btVector3& scale);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
40
libs/bullet/LinearMath/btDefaultMotionState.h
Normal file
40
libs/bullet/LinearMath/btDefaultMotionState.h
Normal file
@ -0,0 +1,40 @@
|
||||
#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
|
||||
{
|
||||
btTransform m_graphicsWorldTrans;
|
||||
btTransform m_centerOfMassOffset;
|
||||
btTransform m_startWorldTrans;
|
||||
void* m_userPointer;
|
||||
|
||||
btDefaultMotionState(const btTransform& startTrans = btTransform::getIdentity(),const btTransform& centerOfMassOffset = btTransform::getIdentity())
|
||||
: m_graphicsWorldTrans(startTrans),
|
||||
m_centerOfMassOffset(centerOfMassOffset),
|
||||
m_startWorldTrans(startTrans),
|
||||
m_userPointer(0)
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
///synchronizes world transform from user to physics
|
||||
virtual void getWorldTransform(btTransform& centerOfMassWorldTrans ) const
|
||||
{
|
||||
centerOfMassWorldTrans = m_centerOfMassOffset.inverse() * m_graphicsWorldTrans ;
|
||||
}
|
||||
|
||||
///synchronizes world transform from physics to user
|
||||
///Bullet only calls the update of worldtransform for active objects
|
||||
virtual void setWorldTransform(const btTransform& centerOfMassWorldTrans)
|
||||
{
|
||||
m_graphicsWorldTrans = centerOfMassWorldTrans * m_centerOfMassOffset ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif //DEFAULT_MOTION_STATE_H
|
185
libs/bullet/LinearMath/btGeometryUtil.cpp
Normal file
185
libs/bullet/LinearMath/btGeometryUtil.cpp
Normal file
@ -0,0 +1,185 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
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 "btGeometryUtil.h"
|
||||
|
||||
|
||||
/*
|
||||
Make sure this dummy function never changes so that it
|
||||
can be used by probes that are checking whether the
|
||||
library is actually installed.
|
||||
*/
|
||||
extern "C"
|
||||
{
|
||||
void btBulletMathProbe ();
|
||||
|
||||
void btBulletMathProbe () {}
|
||||
}
|
||||
|
||||
|
||||
bool btGeometryUtil::isPointInsidePlanes(const btAlignedObjectArray<btVector3>& planeEquations, const btVector3& point, btScalar margin)
|
||||
{
|
||||
int numbrushes = planeEquations.size();
|
||||
for (int i=0;i<numbrushes;i++)
|
||||
{
|
||||
const btVector3& N1 = planeEquations[i];
|
||||
btScalar dist = btScalar(N1.dot(point))+btScalar(N1[3])-margin;
|
||||
if (dist>btScalar(0.))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool btGeometryUtil::areVerticesBehindPlane(const btVector3& planeNormal, const btAlignedObjectArray<btVector3>& vertices, btScalar margin)
|
||||
{
|
||||
int numvertices = vertices.size();
|
||||
for (int i=0;i<numvertices;i++)
|
||||
{
|
||||
const btVector3& N1 = vertices[i];
|
||||
btScalar dist = btScalar(planeNormal.dot(N1))+btScalar(planeNormal[3])-margin;
|
||||
if (dist>btScalar(0.))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool notExist(const btVector3& planeEquation,const btAlignedObjectArray<btVector3>& planeEquations);
|
||||
|
||||
bool notExist(const btVector3& planeEquation,const btAlignedObjectArray<btVector3>& planeEquations)
|
||||
{
|
||||
int numbrushes = planeEquations.size();
|
||||
for (int i=0;i<numbrushes;i++)
|
||||
{
|
||||
const btVector3& N1 = planeEquations[i];
|
||||
if (planeEquation.dot(N1) > btScalar(0.999))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void btGeometryUtil::getPlaneEquationsFromVertices(btAlignedObjectArray<btVector3>& vertices, btAlignedObjectArray<btVector3>& planeEquationsOut )
|
||||
{
|
||||
const int numvertices = vertices.size();
|
||||
// brute force:
|
||||
for (int i=0;i<numvertices;i++)
|
||||
{
|
||||
const btVector3& N1 = vertices[i];
|
||||
|
||||
|
||||
for (int j=i+1;j<numvertices;j++)
|
||||
{
|
||||
const btVector3& N2 = vertices[j];
|
||||
|
||||
for (int k=j+1;k<numvertices;k++)
|
||||
{
|
||||
|
||||
const btVector3& N3 = vertices[k];
|
||||
|
||||
btVector3 planeEquation,edge0,edge1;
|
||||
edge0 = N2-N1;
|
||||
edge1 = N3-N1;
|
||||
btScalar normalSign = btScalar(1.);
|
||||
for (int ww=0;ww<2;ww++)
|
||||
{
|
||||
planeEquation = normalSign * edge0.cross(edge1);
|
||||
if (planeEquation.length2() > btScalar(0.0001))
|
||||
{
|
||||
planeEquation.normalize();
|
||||
if (notExist(planeEquation,planeEquationsOut))
|
||||
{
|
||||
planeEquation[3] = -planeEquation.dot(N1);
|
||||
|
||||
//check if inside, and replace supportingVertexOut if needed
|
||||
if (areVerticesBehindPlane(planeEquation,vertices,btScalar(0.01)))
|
||||
{
|
||||
planeEquationsOut.push_back(planeEquation);
|
||||
}
|
||||
}
|
||||
}
|
||||
normalSign = btScalar(-1.);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void btGeometryUtil::getVerticesFromPlaneEquations(const btAlignedObjectArray<btVector3>& planeEquations , btAlignedObjectArray<btVector3>& verticesOut )
|
||||
{
|
||||
const int numbrushes = planeEquations.size();
|
||||
// brute force:
|
||||
for (int i=0;i<numbrushes;i++)
|
||||
{
|
||||
const btVector3& N1 = planeEquations[i];
|
||||
|
||||
|
||||
for (int j=i+1;j<numbrushes;j++)
|
||||
{
|
||||
const btVector3& N2 = planeEquations[j];
|
||||
|
||||
for (int k=j+1;k<numbrushes;k++)
|
||||
{
|
||||
|
||||
const btVector3& N3 = planeEquations[k];
|
||||
|
||||
btVector3 n2n3; n2n3 = N2.cross(N3);
|
||||
btVector3 n3n1; n3n1 = N3.cross(N1);
|
||||
btVector3 n1n2; n1n2 = N1.cross(N2);
|
||||
|
||||
if ( ( n2n3.length2() > btScalar(0.0001) ) &&
|
||||
( n3n1.length2() > btScalar(0.0001) ) &&
|
||||
( n1n2.length2() > btScalar(0.0001) ) )
|
||||
{
|
||||
//point P out of 3 plane equations:
|
||||
|
||||
// d1 ( N2 * N3 ) + d2 ( N3 * N1 ) + d3 ( N1 * N2 )
|
||||
//P = -------------------------------------------------------------------------
|
||||
// N1 . ( N2 * N3 )
|
||||
|
||||
|
||||
btScalar quotient = (N1.dot(n2n3));
|
||||
if (btFabs(quotient) > btScalar(0.000001))
|
||||
{
|
||||
quotient = btScalar(-1.) / quotient;
|
||||
n2n3 *= N1[3];
|
||||
n3n1 *= N2[3];
|
||||
n1n2 *= N3[3];
|
||||
btVector3 potentialVertex = n2n3;
|
||||
potentialVertex += n3n1;
|
||||
potentialVertex += n1n2;
|
||||
potentialVertex *= quotient;
|
||||
|
||||
//check if inside, and replace supportingVertexOut if needed
|
||||
if (isPointInsidePlanes(planeEquations,potentialVertex,btScalar(0.01)))
|
||||
{
|
||||
verticesOut.push_back(potentialVertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
42
libs/bullet/LinearMath/btGeometryUtil.h
Normal file
42
libs/bullet/LinearMath/btGeometryUtil.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
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_GEOMETRY_UTIL_H
|
||||
#define BT_GEOMETRY_UTIL_H
|
||||
|
||||
#include "btVector3.h"
|
||||
#include "btAlignedObjectArray.h"
|
||||
|
||||
///The btGeometryUtil helper class provides a few methods to convert between plane equations and vertices.
|
||||
class btGeometryUtil
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
static void getPlaneEquationsFromVertices(btAlignedObjectArray<btVector3>& vertices, btAlignedObjectArray<btVector3>& planeEquationsOut );
|
||||
|
||||
static void getVerticesFromPlaneEquations(const btAlignedObjectArray<btVector3>& planeEquations , btAlignedObjectArray<btVector3>& verticesOut );
|
||||
|
||||
static bool isInside(const btAlignedObjectArray<btVector3>& vertices, const btVector3& planeNormal, btScalar margin);
|
||||
|
||||
static bool isPointInsidePlanes(const btAlignedObjectArray<btVector3>& planeEquations, const btVector3& point, btScalar margin);
|
||||
|
||||
static bool areVerticesBehindPlane(const btVector3& planeNormal, const btAlignedObjectArray<btVector3>& vertices, btScalar margin);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //BT_GEOMETRY_UTIL_H
|
||||
|
434
libs/bullet/LinearMath/btHashMap.h
Normal file
434
libs/bullet/LinearMath/btHashMap.h
Normal file
@ -0,0 +1,434 @@
|
||||
#ifndef BT_HASH_MAP_H
|
||||
#define BT_HASH_MAP_H
|
||||
|
||||
#include "btAlignedObjectArray.h"
|
||||
|
||||
///very basic hashable string implementation, compatible with btHashMap
|
||||
struct btHashString
|
||||
{
|
||||
const char* m_string;
|
||||
unsigned int m_hash;
|
||||
|
||||
SIMD_FORCE_INLINE unsigned int getHash()const
|
||||
{
|
||||
return m_hash;
|
||||
}
|
||||
|
||||
btHashString(const char* name)
|
||||
:m_string(name)
|
||||
{
|
||||
/* magic numbers from http://www.isthe.com/chongo/tech/comp/fnv/ */
|
||||
static const unsigned int InitialFNV = 2166136261u;
|
||||
static const unsigned int FNVMultiple = 16777619u;
|
||||
|
||||
/* Fowler / Noll / Vo (FNV) Hash */
|
||||
unsigned int hash = InitialFNV;
|
||||
|
||||
for(int i = 0; m_string[i]; i++)
|
||||
{
|
||||
hash = hash ^ (m_string[i]); /* xor the low 8 bits */
|
||||
hash = hash * FNVMultiple; /* multiply by the magic number */
|
||||
}
|
||||
m_hash = hash;
|
||||
}
|
||||
|
||||
int portableStringCompare(const char* src, const char* dst) const
|
||||
{
|
||||
int ret = 0 ;
|
||||
|
||||
while( ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
|
||||
++src, ++dst;
|
||||
|
||||
if ( ret < 0 )
|
||||
ret = -1 ;
|
||||
else if ( ret > 0 )
|
||||
ret = 1 ;
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
bool equals(const btHashString& other) const
|
||||
{
|
||||
return (m_string == other.m_string) ||
|
||||
(0==portableStringCompare(m_string,other.m_string));
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const int BT_HASH_NULL=0xffffffff;
|
||||
|
||||
|
||||
class btHashInt
|
||||
{
|
||||
int m_uid;
|
||||
public:
|
||||
btHashInt(int uid) :m_uid(uid)
|
||||
{
|
||||
}
|
||||
|
||||
int getUid1() const
|
||||
{
|
||||
return m_uid;
|
||||
}
|
||||
|
||||
void setUid1(int uid)
|
||||
{
|
||||
m_uid = uid;
|
||||
}
|
||||
|
||||
bool equals(const btHashInt& other) const
|
||||
{
|
||||
return getUid1() == other.getUid1();
|
||||
}
|
||||
//to our success
|
||||
SIMD_FORCE_INLINE unsigned int getHash()const
|
||||
{
|
||||
int key = m_uid;
|
||||
// Thomas Wang's hash
|
||||
key += ~(key << 15); key ^= (key >> 10); key += (key << 3); key ^= (key >> 6); key += ~(key << 11); key ^= (key >> 16);
|
||||
return key;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
class btHashPtr
|
||||
{
|
||||
|
||||
union
|
||||
{
|
||||
const void* m_pointer;
|
||||
int m_hashValues[2];
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
btHashPtr(const void* ptr)
|
||||
:m_pointer(ptr)
|
||||
{
|
||||
}
|
||||
|
||||
const void* getPointer() const
|
||||
{
|
||||
return m_pointer;
|
||||
}
|
||||
|
||||
bool equals(const btHashPtr& 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 key = VOID_IS_8? m_hashValues[0]+m_hashValues[1] : m_hashValues[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;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
template <class Value>
|
||||
class btHashKeyPtr
|
||||
{
|
||||
int m_uid;
|
||||
public:
|
||||
|
||||
btHashKeyPtr(int uid) :m_uid(uid)
|
||||
{
|
||||
}
|
||||
|
||||
int getUid1() const
|
||||
{
|
||||
return m_uid;
|
||||
}
|
||||
|
||||
bool equals(const btHashKeyPtr<Value>& other) const
|
||||
{
|
||||
return getUid1() == other.getUid1();
|
||||
}
|
||||
|
||||
//to our success
|
||||
SIMD_FORCE_INLINE unsigned int getHash()const
|
||||
{
|
||||
int key = m_uid;
|
||||
// Thomas Wang's hash
|
||||
key += ~(key << 15); key ^= (key >> 10); key += (key << 3); key ^= (key >> 6); key += ~(key << 11); key ^= (key >> 16);
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
template <class Value>
|
||||
class btHashKey
|
||||
{
|
||||
int m_uid;
|
||||
public:
|
||||
|
||||
btHashKey(int uid) :m_uid(uid)
|
||||
{
|
||||
}
|
||||
|
||||
int getUid1() const
|
||||
{
|
||||
return m_uid;
|
||||
}
|
||||
|
||||
bool equals(const btHashKey<Value>& other) const
|
||||
{
|
||||
return getUid1() == other.getUid1();
|
||||
}
|
||||
//to our success
|
||||
SIMD_FORCE_INLINE unsigned int getHash()const
|
||||
{
|
||||
int key = m_uid;
|
||||
// Thomas Wang's hash
|
||||
key += ~(key << 15); key ^= (key >> 10); key += (key << 3); key ^= (key >> 6); key += ~(key << 11); key ^= (key >> 16);
|
||||
return key;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
///The btHashMap template class implements a generic and lightweight hashmap.
|
||||
///A basic sample of how to use btHashMap is located in Demos\BasicDemo\main.cpp
|
||||
template <class Key, class Value>
|
||||
class btHashMap
|
||||
{
|
||||
|
||||
protected:
|
||||
btAlignedObjectArray<int> m_hashTable;
|
||||
btAlignedObjectArray<int> m_next;
|
||||
|
||||
btAlignedObjectArray<Value> m_valueArray;
|
||||
btAlignedObjectArray<Key> m_keyArray;
|
||||
|
||||
void growTables(const Key& /*key*/)
|
||||
{
|
||||
int newCapacity = m_valueArray.capacity();
|
||||
|
||||
if (m_hashTable.size() < newCapacity)
|
||||
{
|
||||
//grow hashtable and next table
|
||||
int curHashtableSize = m_hashTable.size();
|
||||
|
||||
m_hashTable.resize(newCapacity);
|
||||
m_next.resize(newCapacity);
|
||||
|
||||
int i;
|
||||
|
||||
for (i= 0; i < newCapacity; ++i)
|
||||
{
|
||||
m_hashTable[i] = BT_HASH_NULL;
|
||||
}
|
||||
for (i = 0; i < newCapacity; ++i)
|
||||
{
|
||||
m_next[i] = BT_HASH_NULL;
|
||||
}
|
||||
|
||||
for(i=0;i<curHashtableSize;i++)
|
||||
{
|
||||
//const Value& value = m_valueArray[i];
|
||||
//const Key& key = m_keyArray[i];
|
||||
|
||||
int hashValue = m_keyArray[i].getHash() & (m_valueArray.capacity()-1); // New hash value with new mask
|
||||
m_next[i] = m_hashTable[hashValue];
|
||||
m_hashTable[hashValue] = i;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
void insert(const Key& key, const Value& value) {
|
||||
int hash = key.getHash() & (m_valueArray.capacity()-1);
|
||||
|
||||
//replace value if the key is already there
|
||||
int index = findIndex(key);
|
||||
if (index != BT_HASH_NULL)
|
||||
{
|
||||
m_valueArray[index]=value;
|
||||
return;
|
||||
}
|
||||
|
||||
int count = m_valueArray.size();
|
||||
int oldCapacity = m_valueArray.capacity();
|
||||
m_valueArray.push_back(value);
|
||||
m_keyArray.push_back(key);
|
||||
|
||||
int newCapacity = m_valueArray.capacity();
|
||||
if (oldCapacity < newCapacity)
|
||||
{
|
||||
growTables(key);
|
||||
//hash with new capacity
|
||||
hash = key.getHash() & (m_valueArray.capacity()-1);
|
||||
}
|
||||
m_next[count] = m_hashTable[hash];
|
||||
m_hashTable[hash] = count;
|
||||
}
|
||||
|
||||
void remove(const Key& key) {
|
||||
|
||||
int hash = key.getHash() & (m_valueArray.capacity()-1);
|
||||
|
||||
int pairIndex = findIndex(key);
|
||||
|
||||
if (pairIndex ==BT_HASH_NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the pair from the hash table.
|
||||
int index = m_hashTable[hash];
|
||||
btAssert(index != BT_HASH_NULL);
|
||||
|
||||
int previous = BT_HASH_NULL;
|
||||
while (index != pairIndex)
|
||||
{
|
||||
previous = index;
|
||||
index = m_next[index];
|
||||
}
|
||||
|
||||
if (previous != BT_HASH_NULL)
|
||||
{
|
||||
btAssert(m_next[previous] == pairIndex);
|
||||
m_next[previous] = m_next[pairIndex];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_hashTable[hash] = m_next[pairIndex];
|
||||
}
|
||||
|
||||
// We now move the last pair into spot of the
|
||||
// pair being removed. We need to fix the hash
|
||||
// table indices to support the move.
|
||||
|
||||
int lastPairIndex = m_valueArray.size() - 1;
|
||||
|
||||
// If the removed pair is the last pair, we are done.
|
||||
if (lastPairIndex == pairIndex)
|
||||
{
|
||||
m_valueArray.pop_back();
|
||||
m_keyArray.pop_back();
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the last pair from the hash table.
|
||||
int lastHash = m_keyArray[lastPairIndex].getHash() & (m_valueArray.capacity()-1);
|
||||
|
||||
index = m_hashTable[lastHash];
|
||||
btAssert(index != BT_HASH_NULL);
|
||||
|
||||
previous = BT_HASH_NULL;
|
||||
while (index != lastPairIndex)
|
||||
{
|
||||
previous = index;
|
||||
index = m_next[index];
|
||||
}
|
||||
|
||||
if (previous != BT_HASH_NULL)
|
||||
{
|
||||
btAssert(m_next[previous] == lastPairIndex);
|
||||
m_next[previous] = m_next[lastPairIndex];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_hashTable[lastHash] = m_next[lastPairIndex];
|
||||
}
|
||||
|
||||
// Copy the last pair into the remove pair's spot.
|
||||
m_valueArray[pairIndex] = m_valueArray[lastPairIndex];
|
||||
m_keyArray[pairIndex] = m_keyArray[lastPairIndex];
|
||||
|
||||
// Insert the last pair into the hash table
|
||||
m_next[pairIndex] = m_hashTable[lastHash];
|
||||
m_hashTable[lastHash] = pairIndex;
|
||||
|
||||
m_valueArray.pop_back();
|
||||
m_keyArray.pop_back();
|
||||
|
||||
}
|
||||
|
||||
|
||||
int size() const
|
||||
{
|
||||
return m_valueArray.size();
|
||||
}
|
||||
|
||||
const Value* getAtIndex(int index) const
|
||||
{
|
||||
btAssert(index < m_valueArray.size());
|
||||
|
||||
return &m_valueArray[index];
|
||||
}
|
||||
|
||||
Value* getAtIndex(int index)
|
||||
{
|
||||
btAssert(index < m_valueArray.size());
|
||||
|
||||
return &m_valueArray[index];
|
||||
}
|
||||
|
||||
Value* operator[](const Key& key) {
|
||||
return find(key);
|
||||
}
|
||||
|
||||
const Value* find(const Key& key) const
|
||||
{
|
||||
int index = findIndex(key);
|
||||
if (index == BT_HASH_NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return &m_valueArray[index];
|
||||
}
|
||||
|
||||
Value* find(const Key& key)
|
||||
{
|
||||
int index = findIndex(key);
|
||||
if (index == BT_HASH_NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return &m_valueArray[index];
|
||||
}
|
||||
|
||||
|
||||
int findIndex(const Key& key) const
|
||||
{
|
||||
unsigned int hash = key.getHash() & (m_valueArray.capacity()-1);
|
||||
|
||||
if (hash >= (unsigned int)m_hashTable.size())
|
||||
{
|
||||
return BT_HASH_NULL;
|
||||
}
|
||||
|
||||
int index = m_hashTable[hash];
|
||||
while ((index != BT_HASH_NULL) && key.equals(m_keyArray[index]) == false)
|
||||
{
|
||||
index = m_next[index];
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
m_hashTable.clear();
|
||||
m_next.clear();
|
||||
m_valueArray.clear();
|
||||
m_keyArray.clear();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif //BT_HASH_MAP_H
|
316
libs/bullet/LinearMath/btIDebugDraw.h
Normal file
316
libs/bullet/LinearMath/btIDebugDraw.h
Normal file
@ -0,0 +1,316 @@
|
||||
/*
|
||||
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 IDEBUG_DRAW__H
|
||||
#define IDEBUG_DRAW__H
|
||||
|
||||
#include "btVector3.h"
|
||||
#include "btTransform.h"
|
||||
|
||||
|
||||
///The btIDebugDraw interface class allows hooking up a debug renderer to visually debug simulations.
|
||||
///Typical use case: create a debug drawer object, and assign it to a btCollisionWorld or btDynamicsWorld using setDebugDrawer and call debugDrawWorld.
|
||||
///A class that implements the btIDebugDraw interface has to implement the drawLine method at a minimum.
|
||||
///For color arguments the X,Y,Z components refer to Red, Green and Blue each in the range [0..1]
|
||||
class btIDebugDraw
|
||||
{
|
||||
public:
|
||||
|
||||
enum DebugDrawModes
|
||||
{
|
||||
DBG_NoDebug=0,
|
||||
DBG_DrawWireframe = 1,
|
||||
DBG_DrawAabb=2,
|
||||
DBG_DrawFeaturesText=4,
|
||||
DBG_DrawContactPoints=8,
|
||||
DBG_NoDeactivation=16,
|
||||
DBG_NoHelpText = 32,
|
||||
DBG_DrawText=64,
|
||||
DBG_ProfileTimings = 128,
|
||||
DBG_EnableSatComparison = 256,
|
||||
DBG_DisableBulletLCP = 512,
|
||||
DBG_EnableCCD = 1024,
|
||||
DBG_DrawConstraints = (1 << 11),
|
||||
DBG_DrawConstraintLimits = (1 << 12),
|
||||
DBG_FastWireframe = (1<<13),
|
||||
DBG_MAX_DEBUG_DRAW_MODE
|
||||
};
|
||||
|
||||
virtual ~btIDebugDraw() {};
|
||||
|
||||
virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& color)=0;
|
||||
|
||||
virtual void drawLine(const btVector3& from,const btVector3& to, const btVector3& fromColor, const btVector3& toColor)
|
||||
{
|
||||
(void) toColor;
|
||||
drawLine (from, to, fromColor);
|
||||
}
|
||||
|
||||
virtual void drawSphere(btScalar radius, const btTransform& transform, const btVector3& color)
|
||||
{
|
||||
btVector3 start = transform.getOrigin();
|
||||
|
||||
const btVector3 xoffs = transform.getBasis() * btVector3(radius,0,0);
|
||||
const btVector3 yoffs = transform.getBasis() * btVector3(0,radius,0);
|
||||
const btVector3 zoffs = transform.getBasis() * btVector3(0,0,radius);
|
||||
|
||||
// XY
|
||||
drawLine(start-xoffs, start+yoffs, color);
|
||||
drawLine(start+yoffs, start+xoffs, color);
|
||||
drawLine(start+xoffs, start-yoffs, color);
|
||||
drawLine(start-yoffs, start-xoffs, color);
|
||||
|
||||
// XZ
|
||||
drawLine(start-xoffs, start+zoffs, color);
|
||||
drawLine(start+zoffs, start+xoffs, color);
|
||||
drawLine(start+xoffs, start-zoffs, color);
|
||||
drawLine(start-zoffs, start-xoffs, color);
|
||||
|
||||
// YZ
|
||||
drawLine(start-yoffs, start+zoffs, color);
|
||||
drawLine(start+zoffs, start+yoffs, color);
|
||||
drawLine(start+yoffs, start-zoffs, color);
|
||||
drawLine(start-zoffs, start-yoffs, color);
|
||||
}
|
||||
|
||||
virtual void drawSphere (const btVector3& p, btScalar radius, const btVector3& color)
|
||||
{
|
||||
btTransform tr;
|
||||
tr.setIdentity();
|
||||
tr.setOrigin(p);
|
||||
drawSphere(radius,tr,color);
|
||||
}
|
||||
|
||||
virtual void drawTriangle(const btVector3& v0,const btVector3& v1,const btVector3& v2,const btVector3& /*n0*/,const btVector3& /*n1*/,const btVector3& /*n2*/,const btVector3& color, btScalar alpha)
|
||||
{
|
||||
drawTriangle(v0,v1,v2,color,alpha);
|
||||
}
|
||||
virtual void drawTriangle(const btVector3& v0,const btVector3& v1,const btVector3& v2,const btVector3& color, btScalar /*alpha*/)
|
||||
{
|
||||
drawLine(v0,v1,color);
|
||||
drawLine(v1,v2,color);
|
||||
drawLine(v2,v0,color);
|
||||
}
|
||||
|
||||
virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color)=0;
|
||||
|
||||
virtual void reportErrorWarning(const char* warningString) = 0;
|
||||
|
||||
virtual void draw3dText(const btVector3& location,const char* textString) = 0;
|
||||
|
||||
virtual void setDebugMode(int debugMode) =0;
|
||||
|
||||
virtual int getDebugMode() const = 0;
|
||||
|
||||
virtual void drawAabb(const btVector3& from,const btVector3& to,const btVector3& color)
|
||||
{
|
||||
|
||||
btVector3 halfExtents = (to-from)* 0.5f;
|
||||
btVector3 center = (to+from) *0.5f;
|
||||
int i,j;
|
||||
|
||||
btVector3 edgecoord(1.f,1.f,1.f),pa,pb;
|
||||
for (i=0;i<4;i++)
|
||||
{
|
||||
for (j=0;j<3;j++)
|
||||
{
|
||||
pa = btVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1],
|
||||
edgecoord[2]*halfExtents[2]);
|
||||
pa+=center;
|
||||
|
||||
int othercoord = j%3;
|
||||
edgecoord[othercoord]*=-1.f;
|
||||
pb = btVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1],
|
||||
edgecoord[2]*halfExtents[2]);
|
||||
pb+=center;
|
||||
|
||||
drawLine(pa,pb,color);
|
||||
}
|
||||
edgecoord = btVector3(-1.f,-1.f,-1.f);
|
||||
if (i<3)
|
||||
edgecoord[i]*=-1.f;
|
||||
}
|
||||
}
|
||||
virtual void drawTransform(const btTransform& transform, btScalar orthoLen)
|
||||
{
|
||||
btVector3 start = transform.getOrigin();
|
||||
drawLine(start, start+transform.getBasis() * btVector3(orthoLen, 0, 0), btVector3(0.7f,0,0));
|
||||
drawLine(start, start+transform.getBasis() * btVector3(0, orthoLen, 0), btVector3(0,0.7f,0));
|
||||
drawLine(start, start+transform.getBasis() * btVector3(0, 0, orthoLen), btVector3(0,0,0.7f));
|
||||
}
|
||||
|
||||
virtual void drawArc(const btVector3& center, const btVector3& normal, const btVector3& axis, btScalar radiusA, btScalar radiusB, btScalar minAngle, btScalar maxAngle,
|
||||
const btVector3& color, bool drawSect, btScalar stepDegrees = btScalar(10.f))
|
||||
{
|
||||
const btVector3& vx = axis;
|
||||
btVector3 vy = normal.cross(axis);
|
||||
btScalar step = stepDegrees * SIMD_RADS_PER_DEG;
|
||||
int nSteps = (int)((maxAngle - minAngle) / step);
|
||||
if(!nSteps) nSteps = 1;
|
||||
btVector3 prev = center + radiusA * vx * btCos(minAngle) + radiusB * vy * btSin(minAngle);
|
||||
if(drawSect)
|
||||
{
|
||||
drawLine(center, prev, color);
|
||||
}
|
||||
for(int i = 1; i <= nSteps; i++)
|
||||
{
|
||||
btScalar angle = minAngle + (maxAngle - minAngle) * btScalar(i) / btScalar(nSteps);
|
||||
btVector3 next = center + radiusA * vx * btCos(angle) + radiusB * vy * btSin(angle);
|
||||
drawLine(prev, next, color);
|
||||
prev = next;
|
||||
}
|
||||
if(drawSect)
|
||||
{
|
||||
drawLine(center, prev, color);
|
||||
}
|
||||
}
|
||||
virtual void drawSpherePatch(const btVector3& center, const btVector3& up, const btVector3& axis, btScalar radius,
|
||||
btScalar minTh, btScalar maxTh, btScalar minPs, btScalar maxPs, const btVector3& color, btScalar stepDegrees = btScalar(10.f))
|
||||
{
|
||||
btVector3 vA[74];
|
||||
btVector3 vB[74];
|
||||
btVector3 *pvA = vA, *pvB = vB, *pT;
|
||||
btVector3 npole = center + up * radius;
|
||||
btVector3 spole = center - up * radius;
|
||||
btVector3 arcStart;
|
||||
btScalar step = stepDegrees * SIMD_RADS_PER_DEG;
|
||||
const btVector3& kv = up;
|
||||
const btVector3& iv = axis;
|
||||
btVector3 jv = kv.cross(iv);
|
||||
bool drawN = false;
|
||||
bool drawS = false;
|
||||
if(minTh <= -SIMD_HALF_PI)
|
||||
{
|
||||
minTh = -SIMD_HALF_PI + step;
|
||||
drawN = true;
|
||||
}
|
||||
if(maxTh >= SIMD_HALF_PI)
|
||||
{
|
||||
maxTh = SIMD_HALF_PI - step;
|
||||
drawS = true;
|
||||
}
|
||||
if(minTh > maxTh)
|
||||
{
|
||||
minTh = -SIMD_HALF_PI + step;
|
||||
maxTh = SIMD_HALF_PI - step;
|
||||
drawN = drawS = true;
|
||||
}
|
||||
int n_hor = (int)((maxTh - minTh) / step) + 1;
|
||||
if(n_hor < 2) n_hor = 2;
|
||||
btScalar step_h = (maxTh - minTh) / btScalar(n_hor - 1);
|
||||
bool isClosed = false;
|
||||
if(minPs > maxPs)
|
||||
{
|
||||
minPs = -SIMD_PI + step;
|
||||
maxPs = SIMD_PI;
|
||||
isClosed = true;
|
||||
}
|
||||
else if((maxPs - minPs) >= SIMD_PI * btScalar(2.f))
|
||||
{
|
||||
isClosed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
isClosed = false;
|
||||
}
|
||||
int n_vert = (int)((maxPs - minPs) / step) + 1;
|
||||
if(n_vert < 2) n_vert = 2;
|
||||
btScalar step_v = (maxPs - minPs) / btScalar(n_vert - 1);
|
||||
for(int i = 0; i < n_hor; i++)
|
||||
{
|
||||
btScalar th = minTh + btScalar(i) * step_h;
|
||||
btScalar sth = radius * btSin(th);
|
||||
btScalar cth = radius * btCos(th);
|
||||
for(int j = 0; j < n_vert; j++)
|
||||
{
|
||||
btScalar psi = minPs + btScalar(j) * step_v;
|
||||
btScalar sps = btSin(psi);
|
||||
btScalar cps = btCos(psi);
|
||||
pvB[j] = center + cth * cps * iv + cth * sps * jv + sth * kv;
|
||||
if(i)
|
||||
{
|
||||
drawLine(pvA[j], pvB[j], color);
|
||||
}
|
||||
else if(drawS)
|
||||
{
|
||||
drawLine(spole, pvB[j], color);
|
||||
}
|
||||
if(j)
|
||||
{
|
||||
drawLine(pvB[j-1], pvB[j], color);
|
||||
}
|
||||
else
|
||||
{
|
||||
arcStart = pvB[j];
|
||||
}
|
||||
if((i == (n_hor - 1)) && drawN)
|
||||
{
|
||||
drawLine(npole, pvB[j], color);
|
||||
}
|
||||
if(isClosed)
|
||||
{
|
||||
if(j == (n_vert-1))
|
||||
{
|
||||
drawLine(arcStart, pvB[j], color);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(((!i) || (i == (n_hor-1))) && ((!j) || (j == (n_vert-1))))
|
||||
{
|
||||
drawLine(center, pvB[j], color);
|
||||
}
|
||||
}
|
||||
}
|
||||
pT = pvA; pvA = pvB; pvB = pT;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void drawBox(const btVector3& bbMin, const btVector3& bbMax, const btVector3& color)
|
||||
{
|
||||
drawLine(btVector3(bbMin[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMin[1], bbMin[2]), color);
|
||||
drawLine(btVector3(bbMax[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMax[1], bbMin[2]), color);
|
||||
drawLine(btVector3(bbMax[0], bbMax[1], bbMin[2]), btVector3(bbMin[0], bbMax[1], bbMin[2]), color);
|
||||
drawLine(btVector3(bbMin[0], bbMax[1], bbMin[2]), btVector3(bbMin[0], bbMin[1], bbMin[2]), color);
|
||||
drawLine(btVector3(bbMin[0], bbMin[1], bbMin[2]), btVector3(bbMin[0], bbMin[1], bbMax[2]), color);
|
||||
drawLine(btVector3(bbMax[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMin[1], bbMax[2]), color);
|
||||
drawLine(btVector3(bbMax[0], bbMax[1], bbMin[2]), btVector3(bbMax[0], bbMax[1], bbMax[2]), color);
|
||||
drawLine(btVector3(bbMin[0], bbMax[1], bbMin[2]), btVector3(bbMin[0], bbMax[1], bbMax[2]), color);
|
||||
drawLine(btVector3(bbMin[0], bbMin[1], bbMax[2]), btVector3(bbMax[0], bbMin[1], bbMax[2]), color);
|
||||
drawLine(btVector3(bbMax[0], bbMin[1], bbMax[2]), btVector3(bbMax[0], bbMax[1], bbMax[2]), color);
|
||||
drawLine(btVector3(bbMax[0], bbMax[1], bbMax[2]), btVector3(bbMin[0], bbMax[1], bbMax[2]), color);
|
||||
drawLine(btVector3(bbMin[0], bbMax[1], bbMax[2]), btVector3(bbMin[0], bbMin[1], bbMax[2]), color);
|
||||
}
|
||||
virtual void drawBox(const btVector3& bbMin, const btVector3& bbMax, const btTransform& trans, const btVector3& color)
|
||||
{
|
||||
drawLine(trans * btVector3(bbMin[0], bbMin[1], bbMin[2]), trans * btVector3(bbMax[0], bbMin[1], bbMin[2]), color);
|
||||
drawLine(trans * btVector3(bbMax[0], bbMin[1], bbMin[2]), trans * btVector3(bbMax[0], bbMax[1], bbMin[2]), color);
|
||||
drawLine(trans * btVector3(bbMax[0], bbMax[1], bbMin[2]), trans * btVector3(bbMin[0], bbMax[1], bbMin[2]), color);
|
||||
drawLine(trans * btVector3(bbMin[0], bbMax[1], bbMin[2]), trans * btVector3(bbMin[0], bbMin[1], bbMin[2]), color);
|
||||
drawLine(trans * btVector3(bbMin[0], bbMin[1], bbMin[2]), trans * btVector3(bbMin[0], bbMin[1], bbMax[2]), color);
|
||||
drawLine(trans * btVector3(bbMax[0], bbMin[1], bbMin[2]), trans * btVector3(bbMax[0], bbMin[1], bbMax[2]), color);
|
||||
drawLine(trans * btVector3(bbMax[0], bbMax[1], bbMin[2]), trans * btVector3(bbMax[0], bbMax[1], bbMax[2]), color);
|
||||
drawLine(trans * btVector3(bbMin[0], bbMax[1], bbMin[2]), trans * btVector3(bbMin[0], bbMax[1], bbMax[2]), color);
|
||||
drawLine(trans * btVector3(bbMin[0], bbMin[1], bbMax[2]), trans * btVector3(bbMax[0], bbMin[1], bbMax[2]), color);
|
||||
drawLine(trans * btVector3(bbMax[0], bbMin[1], bbMax[2]), trans * btVector3(bbMax[0], bbMax[1], bbMax[2]), color);
|
||||
drawLine(trans * btVector3(bbMax[0], bbMax[1], bbMax[2]), trans * btVector3(bbMin[0], bbMax[1], bbMax[2]), color);
|
||||
drawLine(trans * btVector3(bbMin[0], bbMax[1], bbMax[2]), trans * btVector3(bbMin[0], bbMin[1], bbMax[2]), color);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif //IDEBUG_DRAW__H
|
||||
|
73
libs/bullet/LinearMath/btList.h
Normal file
73
libs/bullet/LinearMath/btList.h
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
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 GEN_LIST_H
|
||||
#define GEN_LIST_H
|
||||
|
||||
class btGEN_Link {
|
||||
public:
|
||||
btGEN_Link() : m_next(0), m_prev(0) {}
|
||||
btGEN_Link(btGEN_Link *next, btGEN_Link *prev) : m_next(next), m_prev(prev) {}
|
||||
|
||||
btGEN_Link *getNext() const { return m_next; }
|
||||
btGEN_Link *getPrev() const { return m_prev; }
|
||||
|
||||
bool isHead() const { return m_prev == 0; }
|
||||
bool isTail() const { return m_next == 0; }
|
||||
|
||||
void insertBefore(btGEN_Link *link) {
|
||||
m_next = link;
|
||||
m_prev = link->m_prev;
|
||||
m_next->m_prev = this;
|
||||
m_prev->m_next = this;
|
||||
}
|
||||
|
||||
void insertAfter(btGEN_Link *link) {
|
||||
m_next = link->m_next;
|
||||
m_prev = link;
|
||||
m_next->m_prev = this;
|
||||
m_prev->m_next = this;
|
||||
}
|
||||
|
||||
void remove() {
|
||||
m_next->m_prev = m_prev;
|
||||
m_prev->m_next = m_next;
|
||||
}
|
||||
|
||||
private:
|
||||
btGEN_Link *m_next;
|
||||
btGEN_Link *m_prev;
|
||||
};
|
||||
|
||||
class btGEN_List {
|
||||
public:
|
||||
btGEN_List() : m_head(&m_tail, 0), m_tail(0, &m_head) {}
|
||||
|
||||
btGEN_Link *getHead() const { return m_head.getNext(); }
|
||||
btGEN_Link *getTail() const { return m_tail.getPrev(); }
|
||||
|
||||
void addHead(btGEN_Link *link) { link->insertAfter(&m_head); }
|
||||
void addTail(btGEN_Link *link) { link->insertBefore(&m_tail); }
|
||||
|
||||
private:
|
||||
btGEN_Link m_head;
|
||||
btGEN_Link m_tail;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
688
libs/bullet/LinearMath/btMatrix3x3.h
Normal file
688
libs/bullet/LinearMath/btMatrix3x3.h
Normal file
@ -0,0 +1,688 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
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_MATRIX3x3_H
|
||||
#define BT_MATRIX3x3_H
|
||||
|
||||
#include "btVector3.h"
|
||||
#include "btQuaternion.h"
|
||||
|
||||
#ifdef BT_USE_DOUBLE_PRECISION
|
||||
#define btMatrix3x3Data btMatrix3x3DoubleData
|
||||
#else
|
||||
#define btMatrix3x3Data btMatrix3x3FloatData
|
||||
#endif //BT_USE_DOUBLE_PRECISION
|
||||
|
||||
|
||||
/**@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 () {}
|
||||
|
||||
// explicit btMatrix3x3(const btScalar *m) { setFromOpenGLSubMatrix(m); }
|
||||
|
||||
/**@brief Constructor from Quaternion */
|
||||
explicit btMatrix3x3(const btQuaternion& q) { setRotation(q); }
|
||||
/*
|
||||
template <typename btScalar>
|
||||
Matrix3x3(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
|
||||
{
|
||||
setEulerYPR(yaw, pitch, roll);
|
||||
}
|
||||
*/
|
||||
/** @brief Constructor with row major formatting */
|
||||
btMatrix3x3(const btScalar& xx, const btScalar& xy, const btScalar& xz,
|
||||
const btScalar& yx, const btScalar& yy, const btScalar& yz,
|
||||
const btScalar& zx, const btScalar& zy, const btScalar& zz)
|
||||
{
|
||||
setValue(xx, xy, xz,
|
||||
yx, yy, yz,
|
||||
zx, zy, zz);
|
||||
}
|
||||
/** @brief Copy constructor */
|
||||
SIMD_FORCE_INLINE btMatrix3x3 (const btMatrix3x3& other)
|
||||
{
|
||||
m_el[0] = other.m_el[0];
|
||||
m_el[1] = other.m_el[1];
|
||||
m_el[2] = other.m_el[2];
|
||||
}
|
||||
/** @brief Assignment Operator */
|
||||
SIMD_FORCE_INLINE btMatrix3x3& operator=(const btMatrix3x3& other)
|
||||
{
|
||||
m_el[0] = other.m_el[0];
|
||||
m_el[1] = other.m_el[1];
|
||||
m_el[2] = other.m_el[2];
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** @brief Get a column of the matrix as a vector
|
||||
* @param i Column number 0 indexed */
|
||||
SIMD_FORCE_INLINE btVector3 getColumn(int i) const
|
||||
{
|
||||
return btVector3(m_el[0][i],m_el[1][i],m_el[2][i]);
|
||||
}
|
||||
|
||||
|
||||
/** @brief Get a row of the matrix as a vector
|
||||
* @param i Row number 0 indexed */
|
||||
SIMD_FORCE_INLINE const btVector3& getRow(int i) const
|
||||
{
|
||||
btFullAssert(0 <= i && i < 3);
|
||||
return m_el[i];
|
||||
}
|
||||
|
||||
/** @brief Get a mutable reference to a row of the matrix as a vector
|
||||
* @param i Row number 0 indexed */
|
||||
SIMD_FORCE_INLINE btVector3& operator[](int i)
|
||||
{
|
||||
btFullAssert(0 <= i && i < 3);
|
||||
return m_el[i];
|
||||
}
|
||||
|
||||
/** @brief Get a const reference to a row of the matrix as a vector
|
||||
* @param i Row number 0 indexed */
|
||||
SIMD_FORCE_INLINE const btVector3& operator[](int i) const
|
||||
{
|
||||
btFullAssert(0 <= i && i < 3);
|
||||
return m_el[i];
|
||||
}
|
||||
|
||||
/** @brief Multiply by the target matrix on the right
|
||||
* @param m Rotation matrix to be applied
|
||||
* Equivilant to this = this * m */
|
||||
btMatrix3x3& operator*=(const btMatrix3x3& m);
|
||||
|
||||
/** @brief Set from a carray of btScalars
|
||||
* @param m A pointer to the beginning of an array of 9 btScalars */
|
||||
void setFromOpenGLSubMatrix(const btScalar *m)
|
||||
{
|
||||
m_el[0].setValue(m[0],m[4],m[8]);
|
||||
m_el[1].setValue(m[1],m[5],m[9]);
|
||||
m_el[2].setValue(m[2],m[6],m[10]);
|
||||
|
||||
}
|
||||
/** @brief Set the values of the matrix explicitly (row major)
|
||||
* @param xx Top left
|
||||
* @param xy Top Middle
|
||||
* @param xz Top Right
|
||||
* @param yx Middle Left
|
||||
* @param yy Middle Middle
|
||||
* @param yz Middle Right
|
||||
* @param zx Bottom Left
|
||||
* @param zy Bottom Middle
|
||||
* @param zz Bottom Right*/
|
||||
void setValue(const btScalar& xx, const btScalar& xy, const btScalar& xz,
|
||||
const btScalar& yx, const btScalar& yy, const btScalar& yz,
|
||||
const btScalar& zx, const btScalar& zy, const btScalar& zz)
|
||||
{
|
||||
m_el[0].setValue(xx,xy,xz);
|
||||
m_el[1].setValue(yx,yy,yz);
|
||||
m_el[2].setValue(zx,zy,zz);
|
||||
}
|
||||
|
||||
/** @brief Set the matrix from a quaternion
|
||||
* @param q The Quaternion to match */
|
||||
void setRotation(const btQuaternion& q)
|
||||
{
|
||||
btScalar d = q.length2();
|
||||
btFullAssert(d != btScalar(0.0));
|
||||
btScalar s = btScalar(2.0) / d;
|
||||
btScalar xs = q.x() * s, ys = q.y() * s, zs = q.z() * s;
|
||||
btScalar wx = q.w() * xs, wy = q.w() * ys, wz = q.w() * zs;
|
||||
btScalar xx = q.x() * xs, xy = q.x() * ys, xz = q.x() * zs;
|
||||
btScalar yy = q.y() * ys, yz = q.y() * zs, zz = q.z() * zs;
|
||||
setValue(btScalar(1.0) - (yy + zz), xy - wz, xz + wy,
|
||||
xy + wz, btScalar(1.0) - (xx + zz), yz - wx,
|
||||
xz - wy, yz + wx, btScalar(1.0) - (xx + yy));
|
||||
}
|
||||
|
||||
|
||||
/** @brief Set the matrix from euler angles using YPR around YXZ respectively
|
||||
* @param yaw Yaw about Y axis
|
||||
* @param pitch Pitch about X axis
|
||||
* @param roll Roll about Z axis
|
||||
*/
|
||||
void setEulerYPR(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
|
||||
{
|
||||
setEulerZYX(roll, pitch, yaw);
|
||||
}
|
||||
|
||||
/** @brief Set the matrix from euler angles YPR around ZYX axes
|
||||
* @param eulerX Roll about X axis
|
||||
* @param eulerY Pitch around Y axis
|
||||
* @param eulerZ Yaw aboud Z axis
|
||||
*
|
||||
* These angles are used to produce a rotation matrix. The euler
|
||||
* angles are applied in ZYX order. I.e a vector is first rotated
|
||||
* about X then Y and then Z
|
||||
**/
|
||||
void setEulerZYX(btScalar eulerX,btScalar eulerY,btScalar eulerZ) {
|
||||
///@todo proposed to reverse this since it's labeled zyx but takes arguments xyz and it will match all other parts of the code
|
||||
btScalar ci ( btCos(eulerX));
|
||||
btScalar cj ( btCos(eulerY));
|
||||
btScalar ch ( btCos(eulerZ));
|
||||
btScalar si ( btSin(eulerX));
|
||||
btScalar sj ( btSin(eulerY));
|
||||
btScalar sh ( btSin(eulerZ));
|
||||
btScalar cc = ci * ch;
|
||||
btScalar cs = ci * sh;
|
||||
btScalar sc = si * ch;
|
||||
btScalar ss = si * sh;
|
||||
|
||||
setValue(cj * ch, sj * sc - cs, sj * cc + ss,
|
||||
cj * sh, sj * ss + cc, sj * cs - sc,
|
||||
-sj, cj * si, cj * ci);
|
||||
}
|
||||
|
||||
/**@brief Set the matrix to the identity */
|
||||
void setIdentity()
|
||||
{
|
||||
setValue(btScalar(1.0), btScalar(0.0), btScalar(0.0),
|
||||
btScalar(0.0), btScalar(1.0), btScalar(0.0),
|
||||
btScalar(0.0), btScalar(0.0), btScalar(1.0));
|
||||
}
|
||||
|
||||
static const btMatrix3x3& getIdentity()
|
||||
{
|
||||
static const btMatrix3x3 identityMatrix(btScalar(1.0), btScalar(0.0), btScalar(0.0),
|
||||
btScalar(0.0), btScalar(1.0), btScalar(0.0),
|
||||
btScalar(0.0), btScalar(0.0), btScalar(1.0));
|
||||
return identityMatrix;
|
||||
}
|
||||
|
||||
/**@brief Fill the values of the matrix into a 9 element array
|
||||
* @param m The array to be filled */
|
||||
void getOpenGLSubMatrix(btScalar *m) const
|
||||
{
|
||||
m[0] = btScalar(m_el[0].x());
|
||||
m[1] = btScalar(m_el[1].x());
|
||||
m[2] = btScalar(m_el[2].x());
|
||||
m[3] = btScalar(0.0);
|
||||
m[4] = btScalar(m_el[0].y());
|
||||
m[5] = btScalar(m_el[1].y());
|
||||
m[6] = btScalar(m_el[2].y());
|
||||
m[7] = btScalar(0.0);
|
||||
m[8] = btScalar(m_el[0].z());
|
||||
m[9] = btScalar(m_el[1].z());
|
||||
m[10] = btScalar(m_el[2].z());
|
||||
m[11] = btScalar(0.0);
|
||||
}
|
||||
|
||||
/**@brief Get the matrix represented as a quaternion
|
||||
* @param q The quaternion which will be set */
|
||||
void getRotation(btQuaternion& q) const
|
||||
{
|
||||
btScalar trace = m_el[0].x() + m_el[1].y() + m_el[2].z();
|
||||
btScalar temp[4];
|
||||
|
||||
if (trace > btScalar(0.0))
|
||||
{
|
||||
btScalar s = btSqrt(trace + btScalar(1.0));
|
||||
temp[3]=(s * btScalar(0.5));
|
||||
s = btScalar(0.5) / s;
|
||||
|
||||
temp[0]=((m_el[2].y() - m_el[1].z()) * s);
|
||||
temp[1]=((m_el[0].z() - m_el[2].x()) * s);
|
||||
temp[2]=((m_el[1].x() - m_el[0].y()) * s);
|
||||
}
|
||||
else
|
||||
{
|
||||
int i = m_el[0].x() < m_el[1].y() ?
|
||||
(m_el[1].y() < m_el[2].z() ? 2 : 1) :
|
||||
(m_el[0].x() < m_el[2].z() ? 2 : 0);
|
||||
int j = (i + 1) % 3;
|
||||
int k = (i + 2) % 3;
|
||||
|
||||
btScalar s = btSqrt(m_el[i][i] - m_el[j][j] - m_el[k][k] + btScalar(1.0));
|
||||
temp[i] = s * btScalar(0.5);
|
||||
s = btScalar(0.5) / s;
|
||||
|
||||
temp[3] = (m_el[k][j] - m_el[j][k]) * s;
|
||||
temp[j] = (m_el[j][i] + m_el[i][j]) * s;
|
||||
temp[k] = (m_el[k][i] + m_el[i][k]) * s;
|
||||
}
|
||||
q.setValue(temp[0],temp[1],temp[2],temp[3]);
|
||||
}
|
||||
|
||||
/**@brief Get the matrix represented as euler angles around YXZ, roundtrip with setEulerYPR
|
||||
* @param yaw Yaw around Y axis
|
||||
* @param pitch Pitch around X axis
|
||||
* @param roll around Z axis */
|
||||
void getEulerYPR(btScalar& yaw, btScalar& pitch, btScalar& roll) const
|
||||
{
|
||||
|
||||
// first use the normal calculus
|
||||
yaw = btScalar(btAtan2(m_el[1].x(), m_el[0].x()));
|
||||
pitch = btScalar(btAsin(-m_el[2].x()));
|
||||
roll = btScalar(btAtan2(m_el[2].y(), m_el[2].z()));
|
||||
|
||||
// on pitch = +/-HalfPI
|
||||
if (btFabs(pitch)==SIMD_HALF_PI)
|
||||
{
|
||||
if (yaw>0)
|
||||
yaw-=SIMD_PI;
|
||||
else
|
||||
yaw+=SIMD_PI;
|
||||
|
||||
if (roll>0)
|
||||
roll-=SIMD_PI;
|
||||
else
|
||||
roll+=SIMD_PI;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**@brief Get the matrix represented as euler angles around ZYX
|
||||
* @param yaw Yaw around X axis
|
||||
* @param pitch Pitch around Y axis
|
||||
* @param roll around X axis
|
||||
* @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;
|
||||
btScalar pitch;
|
||||
btScalar roll;
|
||||
};
|
||||
|
||||
Euler euler_out;
|
||||
Euler euler_out2; //second solution
|
||||
//get the pointer to the raw data
|
||||
|
||||
// Check that pitch is not at a singularity
|
||||
if (btFabs(m_el[2].x()) >= 1)
|
||||
{
|
||||
euler_out.yaw = 0;
|
||||
euler_out2.yaw = 0;
|
||||
|
||||
// From difference of angles formula
|
||||
btScalar delta = btAtan2(m_el[0].x(),m_el[0].z());
|
||||
if (m_el[2].x() > 0) //gimbal locked up
|
||||
{
|
||||
euler_out.pitch = SIMD_PI / btScalar(2.0);
|
||||
euler_out2.pitch = SIMD_PI / btScalar(2.0);
|
||||
euler_out.roll = euler_out.pitch + delta;
|
||||
euler_out2.roll = euler_out.pitch + delta;
|
||||
}
|
||||
else // gimbal locked down
|
||||
{
|
||||
euler_out.pitch = -SIMD_PI / btScalar(2.0);
|
||||
euler_out2.pitch = -SIMD_PI / btScalar(2.0);
|
||||
euler_out.roll = -euler_out.pitch + delta;
|
||||
euler_out2.roll = -euler_out.pitch + delta;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
euler_out.pitch = - btAsin(m_el[2].x());
|
||||
euler_out2.pitch = SIMD_PI - euler_out.pitch;
|
||||
|
||||
euler_out.roll = btAtan2(m_el[2].y()/btCos(euler_out.pitch),
|
||||
m_el[2].z()/btCos(euler_out.pitch));
|
||||
euler_out2.roll = btAtan2(m_el[2].y()/btCos(euler_out2.pitch),
|
||||
m_el[2].z()/btCos(euler_out2.pitch));
|
||||
|
||||
euler_out.yaw = btAtan2(m_el[1].x()/btCos(euler_out.pitch),
|
||||
m_el[0].x()/btCos(euler_out.pitch));
|
||||
euler_out2.yaw = btAtan2(m_el[1].x()/btCos(euler_out2.pitch),
|
||||
m_el[0].x()/btCos(euler_out2.pitch));
|
||||
}
|
||||
|
||||
if (solution_number == 1)
|
||||
{
|
||||
yaw = euler_out.yaw;
|
||||
pitch = euler_out.pitch;
|
||||
roll = euler_out.roll;
|
||||
}
|
||||
else
|
||||
{
|
||||
yaw = euler_out2.yaw;
|
||||
pitch = euler_out2.pitch;
|
||||
roll = euler_out2.roll;
|
||||
}
|
||||
}
|
||||
|
||||
/**@brief Create a scaled copy of the matrix
|
||||
* @param s Scaling vector The elements of the vector will scale each column */
|
||||
|
||||
btMatrix3x3 scaled(const btVector3& s) const
|
||||
{
|
||||
return btMatrix3x3(m_el[0].x() * s.x(), m_el[0].y() * s.y(), m_el[0].z() * s.z(),
|
||||
m_el[1].x() * s.x(), m_el[1].y() * s.y(), m_el[1].z() * s.z(),
|
||||
m_el[2].x() * s.x(), m_el[2].y() * s.y(), m_el[2].z() * s.z());
|
||||
}
|
||||
|
||||
/**@brief Return the determinant of the matrix */
|
||||
btScalar determinant() const;
|
||||
/**@brief Return the adjoint of the matrix */
|
||||
btMatrix3x3 adjoint() const;
|
||||
/**@brief Return the matrix with all values non negative */
|
||||
btMatrix3x3 absolute() const;
|
||||
/**@brief Return the transpose of the matrix */
|
||||
btMatrix3x3 transpose() const;
|
||||
/**@brief Return the inverse of the matrix */
|
||||
btMatrix3x3 inverse() const;
|
||||
|
||||
btMatrix3x3 transposeTimes(const btMatrix3x3& m) const;
|
||||
btMatrix3x3 timesTranspose(const btMatrix3x3& m) const;
|
||||
|
||||
SIMD_FORCE_INLINE btScalar tdotx(const btVector3& v) const
|
||||
{
|
||||
return m_el[0].x() * v.x() + m_el[1].x() * v.y() + m_el[2].x() * v.z();
|
||||
}
|
||||
SIMD_FORCE_INLINE btScalar tdoty(const btVector3& v) const
|
||||
{
|
||||
return m_el[0].y() * v.x() + m_el[1].y() * v.y() + m_el[2].y() * v.z();
|
||||
}
|
||||
SIMD_FORCE_INLINE btScalar tdotz(const btVector3& v) const
|
||||
{
|
||||
return m_el[0].z() * v.x() + m_el[1].z() * v.y() + m_el[2].z() * v.z();
|
||||
}
|
||||
|
||||
|
||||
/**@brief diagonalizes this matrix by the Jacobi method.
|
||||
* @param rot stores the rotation from the coordinate system in which the matrix is diagonal to the original
|
||||
* coordinate system, i.e., old_this = rot * new_this * rot^T.
|
||||
* @param threshold See iteration
|
||||
* @param iteration The iteration stops when all off-diagonal elements are less than the threshold multiplied
|
||||
* by the sum of the absolute values of the diagonal, or when maxSteps have been executed.
|
||||
*
|
||||
* Note that this matrix is assumed to be symmetric.
|
||||
*/
|
||||
void diagonalize(btMatrix3x3& rot, btScalar threshold, int maxSteps)
|
||||
{
|
||||
rot.setIdentity();
|
||||
for (int step = maxSteps; step > 0; step--)
|
||||
{
|
||||
// find off-diagonal element [p][q] with largest magnitude
|
||||
int p = 0;
|
||||
int q = 1;
|
||||
int r = 2;
|
||||
btScalar max = btFabs(m_el[0][1]);
|
||||
btScalar v = btFabs(m_el[0][2]);
|
||||
if (v > max)
|
||||
{
|
||||
q = 2;
|
||||
r = 1;
|
||||
max = v;
|
||||
}
|
||||
v = btFabs(m_el[1][2]);
|
||||
if (v > max)
|
||||
{
|
||||
p = 1;
|
||||
q = 2;
|
||||
r = 0;
|
||||
max = v;
|
||||
}
|
||||
|
||||
btScalar t = threshold * (btFabs(m_el[0][0]) + btFabs(m_el[1][1]) + btFabs(m_el[2][2]));
|
||||
if (max <= t)
|
||||
{
|
||||
if (max <= SIMD_EPSILON * t)
|
||||
{
|
||||
return;
|
||||
}
|
||||
step = 1;
|
||||
}
|
||||
|
||||
// compute Jacobi rotation J which leads to a zero for element [p][q]
|
||||
btScalar mpq = m_el[p][q];
|
||||
btScalar theta = (m_el[q][q] - m_el[p][p]) / (2 * mpq);
|
||||
btScalar theta2 = theta * theta;
|
||||
btScalar cos;
|
||||
btScalar sin;
|
||||
if (theta2 * theta2 < btScalar(10 / SIMD_EPSILON))
|
||||
{
|
||||
t = (theta >= 0) ? 1 / (theta + btSqrt(1 + theta2))
|
||||
: 1 / (theta - btSqrt(1 + theta2));
|
||||
cos = 1 / btSqrt(1 + t * t);
|
||||
sin = cos * t;
|
||||
}
|
||||
else
|
||||
{
|
||||
// approximation for large theta-value, i.e., a nearly diagonal matrix
|
||||
t = 1 / (theta * (2 + btScalar(0.5) / theta2));
|
||||
cos = 1 - btScalar(0.5) * t * t;
|
||||
sin = cos * t;
|
||||
}
|
||||
|
||||
// apply rotation to matrix (this = J^T * this * J)
|
||||
m_el[p][q] = m_el[q][p] = 0;
|
||||
m_el[p][p] -= t * mpq;
|
||||
m_el[q][q] += t * mpq;
|
||||
btScalar mrp = m_el[r][p];
|
||||
btScalar mrq = m_el[r][q];
|
||||
m_el[r][p] = m_el[p][r] = cos * mrp - sin * mrq;
|
||||
m_el[r][q] = m_el[q][r] = cos * mrq + sin * mrp;
|
||||
|
||||
// apply rotation to rot (rot = rot * J)
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
btVector3& row = rot[i];
|
||||
mrp = row[p];
|
||||
mrq = row[q];
|
||||
row[p] = cos * mrp - sin * mrq;
|
||||
row[q] = cos * mrq + sin * mrp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**@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
|
||||
* @param r1 The second row to use for calculating the cofactor
|
||||
* @param c1 The second column to use for calculating the cofactor
|
||||
* See http://en.wikipedia.org/wiki/Cofactor_(linear_algebra) for more details
|
||||
*/
|
||||
btScalar cofac(int r1, int c1, int r2, int c2) const
|
||||
{
|
||||
return m_el[r1][c1] * m_el[r2][c2] - m_el[r1][c2] * m_el[r2][c1];
|
||||
}
|
||||
|
||||
void serialize(struct btMatrix3x3Data& dataOut) const;
|
||||
|
||||
void serializeFloat(struct btMatrix3x3FloatData& dataOut) const;
|
||||
|
||||
void deSerialize(const struct btMatrix3x3Data& dataIn);
|
||||
|
||||
void deSerializeFloat(const struct btMatrix3x3FloatData& dataIn);
|
||||
|
||||
void deSerializeDouble(const struct btMatrix3x3DoubleData& dataIn);
|
||||
|
||||
};
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE btMatrix3x3&
|
||||
btMatrix3x3::operator*=(const btMatrix3x3& m)
|
||||
{
|
||||
setValue(m.tdotx(m_el[0]), m.tdoty(m_el[0]), m.tdotz(m_el[0]),
|
||||
m.tdotx(m_el[1]), m.tdoty(m_el[1]), m.tdotz(m_el[1]),
|
||||
m.tdotx(m_el[2]), m.tdoty(m_el[2]), m.tdotz(m_el[2]));
|
||||
return *this;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btScalar
|
||||
btMatrix3x3::determinant() const
|
||||
{
|
||||
return btTriple((*this)[0], (*this)[1], (*this)[2]);
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE btMatrix3x3
|
||||
btMatrix3x3::absolute() const
|
||||
{
|
||||
return btMatrix3x3(
|
||||
btFabs(m_el[0].x()), btFabs(m_el[0].y()), btFabs(m_el[0].z()),
|
||||
btFabs(m_el[1].x()), btFabs(m_el[1].y()), btFabs(m_el[1].z()),
|
||||
btFabs(m_el[2].x()), btFabs(m_el[2].y()), btFabs(m_el[2].z()));
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btMatrix3x3
|
||||
btMatrix3x3::transpose() const
|
||||
{
|
||||
return btMatrix3x3(m_el[0].x(), m_el[1].x(), m_el[2].x(),
|
||||
m_el[0].y(), m_el[1].y(), m_el[2].y(),
|
||||
m_el[0].z(), m_el[1].z(), m_el[2].z());
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btMatrix3x3
|
||||
btMatrix3x3::adjoint() const
|
||||
{
|
||||
return btMatrix3x3(cofac(1, 1, 2, 2), cofac(0, 2, 2, 1), cofac(0, 1, 1, 2),
|
||||
cofac(1, 2, 2, 0), cofac(0, 0, 2, 2), cofac(0, 2, 1, 0),
|
||||
cofac(1, 0, 2, 1), cofac(0, 1, 2, 0), cofac(0, 0, 1, 1));
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btMatrix3x3
|
||||
btMatrix3x3::inverse() const
|
||||
{
|
||||
btVector3 co(cofac(1, 1, 2, 2), cofac(1, 2, 2, 0), cofac(1, 0, 2, 1));
|
||||
btScalar det = (*this)[0].dot(co);
|
||||
btFullAssert(det != btScalar(0.0));
|
||||
btScalar s = btScalar(1.0) / det;
|
||||
return btMatrix3x3(co.x() * s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s,
|
||||
co.y() * s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s,
|
||||
co.z() * s, cofac(0, 1, 2, 0) * s, cofac(0, 0, 1, 1) * s);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btMatrix3x3
|
||||
btMatrix3x3::transposeTimes(const btMatrix3x3& m) const
|
||||
{
|
||||
return btMatrix3x3(
|
||||
m_el[0].x() * m[0].x() + m_el[1].x() * m[1].x() + m_el[2].x() * m[2].x(),
|
||||
m_el[0].x() * m[0].y() + m_el[1].x() * m[1].y() + m_el[2].x() * m[2].y(),
|
||||
m_el[0].x() * m[0].z() + m_el[1].x() * m[1].z() + m_el[2].x() * m[2].z(),
|
||||
m_el[0].y() * m[0].x() + m_el[1].y() * m[1].x() + m_el[2].y() * m[2].x(),
|
||||
m_el[0].y() * m[0].y() + m_el[1].y() * m[1].y() + m_el[2].y() * m[2].y(),
|
||||
m_el[0].y() * m[0].z() + m_el[1].y() * m[1].z() + m_el[2].y() * m[2].z(),
|
||||
m_el[0].z() * m[0].x() + m_el[1].z() * m[1].x() + m_el[2].z() * m[2].x(),
|
||||
m_el[0].z() * m[0].y() + m_el[1].z() * m[1].y() + m_el[2].z() * m[2].y(),
|
||||
m_el[0].z() * m[0].z() + m_el[1].z() * m[1].z() + m_el[2].z() * m[2].z());
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btMatrix3x3
|
||||
btMatrix3x3::timesTranspose(const btMatrix3x3& m) const
|
||||
{
|
||||
return btMatrix3x3(
|
||||
m_el[0].dot(m[0]), m_el[0].dot(m[1]), m_el[0].dot(m[2]),
|
||||
m_el[1].dot(m[0]), m_el[1].dot(m[1]), m_el[1].dot(m[2]),
|
||||
m_el[2].dot(m[0]), m_el[2].dot(m[1]), m_el[2].dot(m[2]));
|
||||
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btVector3
|
||||
operator*(const btMatrix3x3& m, const btVector3& v)
|
||||
{
|
||||
return btVector3(m[0].dot(v), m[1].dot(v), m[2].dot(v));
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE btVector3
|
||||
operator*(const btVector3& v, const btMatrix3x3& m)
|
||||
{
|
||||
return btVector3(m.tdotx(v), m.tdoty(v), m.tdotz(v));
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btMatrix3x3
|
||||
operator*(const btMatrix3x3& m1, const btMatrix3x3& m2)
|
||||
{
|
||||
return btMatrix3x3(
|
||||
m2.tdotx( m1[0]), m2.tdoty( m1[0]), m2.tdotz( m1[0]),
|
||||
m2.tdotx( m1[1]), m2.tdoty( m1[1]), m2.tdotz( m1[1]),
|
||||
m2.tdotx( m1[2]), m2.tdoty( m1[2]), m2.tdotz( m1[2]));
|
||||
}
|
||||
|
||||
/*
|
||||
SIMD_FORCE_INLINE btMatrix3x3 btMultTransposeLeft(const btMatrix3x3& m1, const btMatrix3x3& m2) {
|
||||
return btMatrix3x3(
|
||||
m1[0][0] * m2[0][0] + m1[1][0] * m2[1][0] + m1[2][0] * m2[2][0],
|
||||
m1[0][0] * m2[0][1] + m1[1][0] * m2[1][1] + m1[2][0] * m2[2][1],
|
||||
m1[0][0] * m2[0][2] + m1[1][0] * m2[1][2] + m1[2][0] * m2[2][2],
|
||||
m1[0][1] * m2[0][0] + m1[1][1] * m2[1][0] + m1[2][1] * m2[2][0],
|
||||
m1[0][1] * m2[0][1] + m1[1][1] * m2[1][1] + m1[2][1] * m2[2][1],
|
||||
m1[0][1] * m2[0][2] + m1[1][1] * m2[1][2] + m1[2][1] * m2[2][2],
|
||||
m1[0][2] * m2[0][0] + m1[1][2] * m2[1][0] + m1[2][2] * m2[2][0],
|
||||
m1[0][2] * m2[0][1] + m1[1][2] * m2[1][1] + m1[2][2] * m2[2][1],
|
||||
m1[0][2] * m2[0][2] + m1[1][2] * m2[1][2] + m1[2][2] * m2[2][2]);
|
||||
}
|
||||
*/
|
||||
|
||||
/**@brief Equality operator between two matrices
|
||||
* It will test all elements are equal. */
|
||||
SIMD_FORCE_INLINE bool operator==(const btMatrix3x3& m1, const btMatrix3x3& m2)
|
||||
{
|
||||
return ( m1[0][0] == m2[0][0] && m1[1][0] == m2[1][0] && m1[2][0] == m2[2][0] &&
|
||||
m1[0][1] == m2[0][1] && m1[1][1] == m2[1][1] && m1[2][1] == m2[2][1] &&
|
||||
m1[0][2] == m2[0][2] && m1[1][2] == m2[1][2] && m1[2][2] == m2[2][2] );
|
||||
}
|
||||
|
||||
///for serialization
|
||||
struct btMatrix3x3FloatData
|
||||
{
|
||||
btVector3FloatData m_el[3];
|
||||
};
|
||||
|
||||
///for serialization
|
||||
struct btMatrix3x3DoubleData
|
||||
{
|
||||
btVector3DoubleData 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::serializeFloat(struct btMatrix3x3FloatData& dataOut) const
|
||||
{
|
||||
for (int i=0;i<3;i++)
|
||||
m_el[i].serializeFloat(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]);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void btMatrix3x3::deSerializeFloat(const struct btMatrix3x3FloatData& dataIn)
|
||||
{
|
||||
for (int i=0;i<3;i++)
|
||||
m_el[i].deSerializeFloat(dataIn.m_el[i]);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void btMatrix3x3::deSerializeDouble(const struct btMatrix3x3DoubleData& dataIn)
|
||||
{
|
||||
for (int i=0;i<3;i++)
|
||||
m_el[i].deSerializeDouble(dataIn.m_el[i]);
|
||||
}
|
||||
|
||||
#endif //BT_MATRIX3x3_H
|
||||
|
71
libs/bullet/LinearMath/btMinMax.h
Normal file
71
libs/bullet/LinearMath/btMinMax.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
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 GEN_MINMAX_H
|
||||
#define GEN_MINMAX_H
|
||||
|
||||
#include "LinearMath/btScalar.h"
|
||||
|
||||
template <class T>
|
||||
SIMD_FORCE_INLINE const T& btMin(const T& a, const T& b)
|
||||
{
|
||||
return a < b ? a : b ;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
SIMD_FORCE_INLINE const T& btMax(const T& a, const T& b)
|
||||
{
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
SIMD_FORCE_INLINE const T& btClamped(const T& a, const T& lb, const T& ub)
|
||||
{
|
||||
return a < lb ? lb : (ub < a ? ub : a);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
SIMD_FORCE_INLINE void btSetMin(T& a, const T& b)
|
||||
{
|
||||
if (b < a)
|
||||
{
|
||||
a = b;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
SIMD_FORCE_INLINE void btSetMax(T& a, const T& b)
|
||||
{
|
||||
if (a < b)
|
||||
{
|
||||
a = b;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
SIMD_FORCE_INLINE void btClamp(T& a, const T& lb, const T& ub)
|
||||
{
|
||||
if (a < lb)
|
||||
{
|
||||
a = lb;
|
||||
}
|
||||
else if (ub < a)
|
||||
{
|
||||
a = ub;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
40
libs/bullet/LinearMath/btMotionState.h
Normal file
40
libs/bullet/LinearMath/btMotionState.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
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_MOTIONSTATE_H
|
||||
#define BT_MOTIONSTATE_H
|
||||
|
||||
#include "btTransform.h"
|
||||
|
||||
///The btMotionState interface class allows the dynamics world to synchronize and interpolate the updated world transforms with graphics
|
||||
///For optimizations, potentially only moving objects get synchronized (using setWorldPosition/setWorldOrientation)
|
||||
class btMotionState
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~btMotionState()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual void getWorldTransform(btTransform& worldTrans ) const =0;
|
||||
|
||||
//Bullet only calls the update of worldtransform for active objects
|
||||
virtual void setWorldTransform(const btTransform& worldTrans)=0;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif //BT_MOTIONSTATE_H
|
116
libs/bullet/LinearMath/btPoolAllocator.h
Normal file
116
libs/bullet/LinearMath/btPoolAllocator.h
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
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_POOL_ALLOCATOR_H
|
||||
#define _BT_POOL_ALLOCATOR_H
|
||||
|
||||
#include "btScalar.h"
|
||||
#include "btAlignedAllocator.h"
|
||||
|
||||
///The btPoolAllocator class allows to efficiently allocate a large pool of objects, instead of dynamically allocating them separately.
|
||||
class btPoolAllocator
|
||||
{
|
||||
int m_elemSize;
|
||||
int m_maxElements;
|
||||
int m_freeCount;
|
||||
void* m_firstFree;
|
||||
unsigned char* m_pool;
|
||||
|
||||
public:
|
||||
|
||||
btPoolAllocator(int elemSize, int maxElements)
|
||||
:m_elemSize(elemSize),
|
||||
m_maxElements(maxElements)
|
||||
{
|
||||
m_pool = (unsigned char*) btAlignedAlloc( static_cast<unsigned int>(m_elemSize*m_maxElements),16);
|
||||
|
||||
unsigned char* p = m_pool;
|
||||
m_firstFree = p;
|
||||
m_freeCount = m_maxElements;
|
||||
int count = m_maxElements;
|
||||
while (--count) {
|
||||
*(void**)p = (p + m_elemSize);
|
||||
p += m_elemSize;
|
||||
}
|
||||
*(void**)p = 0;
|
||||
}
|
||||
|
||||
~btPoolAllocator()
|
||||
{
|
||||
btAlignedFree( m_pool);
|
||||
}
|
||||
|
||||
int getFreeCount() const
|
||||
{
|
||||
return m_freeCount;
|
||||
}
|
||||
|
||||
int getUsedCount() const
|
||||
{
|
||||
return m_maxElements - m_freeCount;
|
||||
}
|
||||
|
||||
void* allocate(int size)
|
||||
{
|
||||
// release mode fix
|
||||
(void)size;
|
||||
btAssert(!size || size<=m_elemSize);
|
||||
btAssert(m_freeCount>0);
|
||||
void* result = m_firstFree;
|
||||
m_firstFree = *(void**)m_firstFree;
|
||||
--m_freeCount;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool validPtr(void* ptr)
|
||||
{
|
||||
if (ptr) {
|
||||
if (((unsigned char*)ptr >= m_pool && (unsigned char*)ptr < m_pool + m_maxElements * m_elemSize))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void freeMemory(void* ptr)
|
||||
{
|
||||
if (ptr) {
|
||||
btAssert((unsigned char*)ptr >= m_pool && (unsigned char*)ptr < m_pool + m_maxElements * m_elemSize);
|
||||
|
||||
*(void**)ptr = m_firstFree;
|
||||
m_firstFree = ptr;
|
||||
++m_freeCount;
|
||||
}
|
||||
}
|
||||
|
||||
int getElementSize() const
|
||||
{
|
||||
return m_elemSize;
|
||||
}
|
||||
|
||||
unsigned char* getPoolAddress()
|
||||
{
|
||||
return m_pool;
|
||||
}
|
||||
|
||||
const unsigned char* getPoolAddress() const
|
||||
{
|
||||
return m_pool;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif //_BT_POOL_ALLOCATOR_H
|
180
libs/bullet/LinearMath/btQuadWord.h
Normal file
180
libs/bullet/LinearMath/btQuadWord.h
Normal file
@ -0,0 +1,180 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
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 SIMD_QUADWORD_H
|
||||
#define SIMD_QUADWORD_H
|
||||
|
||||
#include "btScalar.h"
|
||||
#include "btMinMax.h"
|
||||
|
||||
|
||||
#if defined (__CELLOS_LV2) && defined (__SPU__)
|
||||
#include <altivec.h>
|
||||
#endif
|
||||
|
||||
/**@brief The btQuadWord class is base class for btVector3 and btQuaternion.
|
||||
* Some issues under PS3 Linux with IBM 2.1 SDK, gcc compiler prevent from using aligned quadword.
|
||||
*/
|
||||
#ifndef USE_LIBSPE2
|
||||
ATTRIBUTE_ALIGNED16(class) btQuadWord
|
||||
#else
|
||||
class btQuadWord
|
||||
#endif
|
||||
{
|
||||
protected:
|
||||
|
||||
#if defined (__SPU__) && defined (__CELLOS_LV2__)
|
||||
union {
|
||||
vec_float4 mVec128;
|
||||
btScalar m_floats[4];
|
||||
};
|
||||
public:
|
||||
vec_float4 get128() const
|
||||
{
|
||||
return mVec128;
|
||||
}
|
||||
protected:
|
||||
#else //__CELLOS_LV2__ __SPU__
|
||||
btScalar m_floats[4];
|
||||
#endif //__CELLOS_LV2__ __SPU__
|
||||
|
||||
public:
|
||||
|
||||
|
||||
/**@brief Return the x value */
|
||||
SIMD_FORCE_INLINE const btScalar& getX() const { return m_floats[0]; }
|
||||
/**@brief Return the y value */
|
||||
SIMD_FORCE_INLINE const btScalar& getY() const { return m_floats[1]; }
|
||||
/**@brief Return the z value */
|
||||
SIMD_FORCE_INLINE const btScalar& getZ() const { return m_floats[2]; }
|
||||
/**@brief Set the x value */
|
||||
SIMD_FORCE_INLINE void setX(btScalar x) { m_floats[0] = x;};
|
||||
/**@brief Set the y value */
|
||||
SIMD_FORCE_INLINE void setY(btScalar y) { m_floats[1] = y;};
|
||||
/**@brief Set the z value */
|
||||
SIMD_FORCE_INLINE void setZ(btScalar z) { m_floats[2] = z;};
|
||||
/**@brief Set the w value */
|
||||
SIMD_FORCE_INLINE void setW(btScalar w) { m_floats[3] = w;};
|
||||
/**@brief Return the x value */
|
||||
SIMD_FORCE_INLINE const btScalar& x() const { return m_floats[0]; }
|
||||
/**@brief Return the y value */
|
||||
SIMD_FORCE_INLINE const btScalar& y() const { return m_floats[1]; }
|
||||
/**@brief Return the z value */
|
||||
SIMD_FORCE_INLINE const btScalar& z() const { return m_floats[2]; }
|
||||
/**@brief Return the w value */
|
||||
SIMD_FORCE_INLINE const btScalar& w() const { return m_floats[3]; }
|
||||
|
||||
//SIMD_FORCE_INLINE btScalar& operator[](int i) { return (&m_floats[0])[i]; }
|
||||
//SIMD_FORCE_INLINE const btScalar& operator[](int i) const { return (&m_floats[0])[i]; }
|
||||
///operator btScalar*() replaces operator[], using implicit conversion. We added operator != and operator == to avoid pointer comparisons.
|
||||
SIMD_FORCE_INLINE operator btScalar *() { return &m_floats[0]; }
|
||||
SIMD_FORCE_INLINE operator const btScalar *() const { return &m_floats[0]; }
|
||||
|
||||
SIMD_FORCE_INLINE bool operator==(const btQuadWord& other) const
|
||||
{
|
||||
return ((m_floats[3]==other.m_floats[3]) && (m_floats[2]==other.m_floats[2]) && (m_floats[1]==other.m_floats[1]) && (m_floats[0]==other.m_floats[0]));
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE bool operator!=(const btQuadWord& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
/**@brief Set x,y,z and zero w
|
||||
* @param x Value of x
|
||||
* @param y Value of y
|
||||
* @param z Value of z
|
||||
*/
|
||||
SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z)
|
||||
{
|
||||
m_floats[0]=x;
|
||||
m_floats[1]=y;
|
||||
m_floats[2]=z;
|
||||
m_floats[3] = 0.f;
|
||||
}
|
||||
|
||||
/* void getValue(btScalar *m) const
|
||||
{
|
||||
m[0] = m_floats[0];
|
||||
m[1] = m_floats[1];
|
||||
m[2] = m_floats[2];
|
||||
}
|
||||
*/
|
||||
/**@brief Set the values
|
||||
* @param x Value of x
|
||||
* @param y Value of y
|
||||
* @param z Value of z
|
||||
* @param w Value of w
|
||||
*/
|
||||
SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w)
|
||||
{
|
||||
m_floats[0]=x;
|
||||
m_floats[1]=y;
|
||||
m_floats[2]=z;
|
||||
m_floats[3]=w;
|
||||
}
|
||||
/**@brief No initialization constructor */
|
||||
SIMD_FORCE_INLINE btQuadWord()
|
||||
// :m_floats[0](btScalar(0.)),m_floats[1](btScalar(0.)),m_floats[2](btScalar(0.)),m_floats[3](btScalar(0.))
|
||||
{
|
||||
}
|
||||
|
||||
/**@brief Three argument constructor (zeros w)
|
||||
* @param x Value of x
|
||||
* @param y Value of y
|
||||
* @param z Value of z
|
||||
*/
|
||||
SIMD_FORCE_INLINE btQuadWord(const btScalar& x, const btScalar& y, const btScalar& z)
|
||||
{
|
||||
m_floats[0] = x, m_floats[1] = y, m_floats[2] = z, m_floats[3] = 0.0f;
|
||||
}
|
||||
|
||||
/**@brief Initializing constructor
|
||||
* @param x Value of x
|
||||
* @param y Value of y
|
||||
* @param z Value of z
|
||||
* @param w Value of w
|
||||
*/
|
||||
SIMD_FORCE_INLINE btQuadWord(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w)
|
||||
{
|
||||
m_floats[0] = x, m_floats[1] = y, m_floats[2] = z, m_floats[3] = w;
|
||||
}
|
||||
|
||||
/**@brief Set each element to the max of the current values and the values of another btQuadWord
|
||||
* @param other The other btQuadWord to compare with
|
||||
*/
|
||||
SIMD_FORCE_INLINE void setMax(const btQuadWord& other)
|
||||
{
|
||||
btSetMax(m_floats[0], other.m_floats[0]);
|
||||
btSetMax(m_floats[1], other.m_floats[1]);
|
||||
btSetMax(m_floats[2], other.m_floats[2]);
|
||||
btSetMax(m_floats[3], other.m_floats[3]);
|
||||
}
|
||||
/**@brief Set each element to the min of the current values and the values of another btQuadWord
|
||||
* @param other The other btQuadWord to compare with
|
||||
*/
|
||||
SIMD_FORCE_INLINE void setMin(const btQuadWord& other)
|
||||
{
|
||||
btSetMin(m_floats[0], other.m_floats[0]);
|
||||
btSetMin(m_floats[1], other.m_floats[1]);
|
||||
btSetMin(m_floats[2], other.m_floats[2]);
|
||||
btSetMin(m_floats[3], other.m_floats[3]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif //SIMD_QUADWORD_H
|
433
libs/bullet/LinearMath/btQuaternion.h
Normal file
433
libs/bullet/LinearMath/btQuaternion.h
Normal file
@ -0,0 +1,433 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
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 SIMD__QUATERNION_H_
|
||||
#define SIMD__QUATERNION_H_
|
||||
|
||||
|
||||
#include "btVector3.h"
|
||||
#include "btQuadWord.h"
|
||||
|
||||
/**@brief The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatrix3x3, btVector3 and btTransform. */
|
||||
class btQuaternion : public btQuadWord {
|
||||
public:
|
||||
/**@brief No initialization constructor */
|
||||
btQuaternion() {}
|
||||
|
||||
// template <typename btScalar>
|
||||
// explicit Quaternion(const btScalar *v) : Tuple4<btScalar>(v) {}
|
||||
/**@brief Constructor from scalars */
|
||||
btQuaternion(const btScalar& x, const btScalar& y, const btScalar& z, const btScalar& w)
|
||||
: btQuadWord(x, y, z, w)
|
||||
{}
|
||||
/**@brief Axis angle Constructor
|
||||
* @param axis The axis which the rotation is around
|
||||
* @param angle The magnitude of the rotation around the angle (Radians) */
|
||||
btQuaternion(const btVector3& axis, const btScalar& angle)
|
||||
{
|
||||
setRotation(axis, angle);
|
||||
}
|
||||
/**@brief Constructor from Euler angles
|
||||
* @param yaw Angle around Y unless BT_EULER_DEFAULT_ZYX defined then Z
|
||||
* @param pitch Angle around X unless BT_EULER_DEFAULT_ZYX defined then Y
|
||||
* @param roll Angle around Z unless BT_EULER_DEFAULT_ZYX defined then X */
|
||||
btQuaternion(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
|
||||
{
|
||||
#ifndef BT_EULER_DEFAULT_ZYX
|
||||
setEuler(yaw, pitch, roll);
|
||||
#else
|
||||
setEulerZYX(yaw, pitch, roll);
|
||||
#endif
|
||||
}
|
||||
/**@brief Set the rotation using axis angle notation
|
||||
* @param axis The axis around which to rotate
|
||||
* @param angle The magnitude of the rotation in Radians */
|
||||
void setRotation(const btVector3& axis, const btScalar& angle)
|
||||
{
|
||||
btScalar d = axis.length();
|
||||
btAssert(d != btScalar(0.0));
|
||||
btScalar s = btSin(angle * btScalar(0.5)) / d;
|
||||
setValue(axis.x() * s, axis.y() * s, axis.z() * s,
|
||||
btCos(angle * btScalar(0.5)));
|
||||
}
|
||||
/**@brief Set the quaternion using Euler angles
|
||||
* @param yaw Angle around Y
|
||||
* @param pitch Angle around X
|
||||
* @param roll Angle around Z */
|
||||
void setEuler(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
|
||||
{
|
||||
btScalar halfYaw = btScalar(yaw) * btScalar(0.5);
|
||||
btScalar halfPitch = btScalar(pitch) * btScalar(0.5);
|
||||
btScalar halfRoll = btScalar(roll) * btScalar(0.5);
|
||||
btScalar cosYaw = btCos(halfYaw);
|
||||
btScalar sinYaw = btSin(halfYaw);
|
||||
btScalar cosPitch = btCos(halfPitch);
|
||||
btScalar sinPitch = btSin(halfPitch);
|
||||
btScalar cosRoll = btCos(halfRoll);
|
||||
btScalar sinRoll = btSin(halfRoll);
|
||||
setValue(cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw,
|
||||
cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw,
|
||||
sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw,
|
||||
cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw);
|
||||
}
|
||||
/**@brief Set the quaternion using euler angles
|
||||
* @param yaw Angle around Z
|
||||
* @param pitch Angle around Y
|
||||
* @param roll Angle around X */
|
||||
void setEulerZYX(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
|
||||
{
|
||||
btScalar halfYaw = btScalar(yaw) * btScalar(0.5);
|
||||
btScalar halfPitch = btScalar(pitch) * btScalar(0.5);
|
||||
btScalar halfRoll = btScalar(roll) * btScalar(0.5);
|
||||
btScalar cosYaw = btCos(halfYaw);
|
||||
btScalar sinYaw = btSin(halfYaw);
|
||||
btScalar cosPitch = btCos(halfPitch);
|
||||
btScalar sinPitch = btSin(halfPitch);
|
||||
btScalar cosRoll = btCos(halfRoll);
|
||||
btScalar sinRoll = btSin(halfRoll);
|
||||
setValue(sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw, //x
|
||||
cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw, //y
|
||||
cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw, //z
|
||||
cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw); //formerly yzx
|
||||
}
|
||||
/**@brief Add two quaternions
|
||||
* @param q The quaternion to add to this one */
|
||||
SIMD_FORCE_INLINE btQuaternion& operator+=(const btQuaternion& q)
|
||||
{
|
||||
m_floats[0] += q.x(); m_floats[1] += q.y(); m_floats[2] += q.z(); m_floats[3] += q.m_floats[3];
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**@brief Subtract out a quaternion
|
||||
* @param q The quaternion to subtract from this one */
|
||||
btQuaternion& operator-=(const btQuaternion& q)
|
||||
{
|
||||
m_floats[0] -= q.x(); m_floats[1] -= q.y(); m_floats[2] -= q.z(); m_floats[3] -= q.m_floats[3];
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**@brief Scale this quaternion
|
||||
* @param s The scalar to scale by */
|
||||
btQuaternion& operator*=(const btScalar& s)
|
||||
{
|
||||
m_floats[0] *= s; m_floats[1] *= s; m_floats[2] *= s; m_floats[3] *= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**@brief Multiply this quaternion by q on the right
|
||||
* @param q The other quaternion
|
||||
* Equivilant to this = this * q */
|
||||
btQuaternion& operator*=(const btQuaternion& q)
|
||||
{
|
||||
setValue(m_floats[3] * q.x() + m_floats[0] * q.m_floats[3] + m_floats[1] * q.z() - m_floats[2] * q.y(),
|
||||
m_floats[3] * q.y() + m_floats[1] * q.m_floats[3] + m_floats[2] * q.x() - m_floats[0] * q.z(),
|
||||
m_floats[3] * q.z() + m_floats[2] * q.m_floats[3] + m_floats[0] * q.y() - m_floats[1] * q.x(),
|
||||
m_floats[3] * q.m_floats[3] - m_floats[0] * q.x() - m_floats[1] * q.y() - m_floats[2] * q.z());
|
||||
return *this;
|
||||
}
|
||||
/**@brief Return the dot product between this quaternion and another
|
||||
* @param q The other quaternion */
|
||||
btScalar dot(const btQuaternion& q) const
|
||||
{
|
||||
return m_floats[0] * q.x() + m_floats[1] * q.y() + m_floats[2] * q.z() + m_floats[3] * q.m_floats[3];
|
||||
}
|
||||
|
||||
/**@brief Return the length squared of the quaternion */
|
||||
btScalar length2() const
|
||||
{
|
||||
return dot(*this);
|
||||
}
|
||||
|
||||
/**@brief Return the length of the quaternion */
|
||||
btScalar length() const
|
||||
{
|
||||
return btSqrt(length2());
|
||||
}
|
||||
|
||||
/**@brief Normalize the quaternion
|
||||
* Such that x^2 + y^2 + z^2 +w^2 = 1 */
|
||||
btQuaternion& normalize()
|
||||
{
|
||||
return *this /= length();
|
||||
}
|
||||
|
||||
/**@brief Return a scaled version of this quaternion
|
||||
* @param s The scale factor */
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
operator*(const btScalar& s) const
|
||||
{
|
||||
return btQuaternion(x() * s, y() * s, z() * s, m_floats[3] * s);
|
||||
}
|
||||
|
||||
|
||||
/**@brief Return an inversely scaled versionof this quaternion
|
||||
* @param s The inverse scale factor */
|
||||
btQuaternion operator/(const btScalar& s) const
|
||||
{
|
||||
btAssert(s != btScalar(0.0));
|
||||
return *this * (btScalar(1.0) / s);
|
||||
}
|
||||
|
||||
/**@brief Inversely scale this quaternion
|
||||
* @param s The scale factor */
|
||||
btQuaternion& operator/=(const btScalar& s)
|
||||
{
|
||||
btAssert(s != btScalar(0.0));
|
||||
return *this *= btScalar(1.0) / s;
|
||||
}
|
||||
|
||||
/**@brief Return a normalized version of this quaternion */
|
||||
btQuaternion normalized() const
|
||||
{
|
||||
return *this / length();
|
||||
}
|
||||
/**@brief Return the angle between this quaternion and the other
|
||||
* @param q The other quaternion */
|
||||
btScalar angle(const btQuaternion& q) const
|
||||
{
|
||||
btScalar s = btSqrt(length2() * q.length2());
|
||||
btAssert(s != btScalar(0.0));
|
||||
return btAcos(dot(q) / s);
|
||||
}
|
||||
/**@brief Return the angle of rotation represented by this quaternion */
|
||||
btScalar getAngle() const
|
||||
{
|
||||
btScalar s = btScalar(2.) * btAcos(m_floats[3]);
|
||||
return s;
|
||||
}
|
||||
|
||||
/**@brief Return the axis of the rotation represented by this quaternion */
|
||||
btVector3 getAxis() const
|
||||
{
|
||||
btScalar s_squared = btScalar(1.) - btPow(m_floats[3], btScalar(2.));
|
||||
if (s_squared < btScalar(10.) * SIMD_EPSILON) //Check for divide by zero
|
||||
return btVector3(1.0, 0.0, 0.0); // Arbitrary
|
||||
btScalar s = btSqrt(s_squared);
|
||||
return btVector3(m_floats[0] / s, m_floats[1] / s, m_floats[2] / s);
|
||||
}
|
||||
|
||||
/**@brief Return the inverse of this quaternion */
|
||||
btQuaternion inverse() const
|
||||
{
|
||||
return btQuaternion(-m_floats[0], -m_floats[1], -m_floats[2], m_floats[3]);
|
||||
}
|
||||
|
||||
/**@brief Return the sum of this quaternion and the other
|
||||
* @param q2 The other quaternion */
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
operator+(const btQuaternion& q2) const
|
||||
{
|
||||
const btQuaternion& q1 = *this;
|
||||
return btQuaternion(q1.x() + q2.x(), q1.y() + q2.y(), q1.z() + q2.z(), q1.m_floats[3] + q2.m_floats[3]);
|
||||
}
|
||||
|
||||
/**@brief Return the difference between this quaternion and the other
|
||||
* @param q2 The other quaternion */
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
operator-(const btQuaternion& q2) const
|
||||
{
|
||||
const btQuaternion& q1 = *this;
|
||||
return btQuaternion(q1.x() - q2.x(), q1.y() - q2.y(), q1.z() - q2.z(), q1.m_floats[3] - q2.m_floats[3]);
|
||||
}
|
||||
|
||||
/**@brief Return the negative of this quaternion
|
||||
* This simply negates each element */
|
||||
SIMD_FORCE_INLINE btQuaternion operator-() const
|
||||
{
|
||||
const btQuaternion& q2 = *this;
|
||||
return btQuaternion( - q2.x(), - q2.y(), - q2.z(), - q2.m_floats[3]);
|
||||
}
|
||||
/**@todo document this and it's use */
|
||||
SIMD_FORCE_INLINE btQuaternion farthest( const btQuaternion& qd) const
|
||||
{
|
||||
btQuaternion diff,sum;
|
||||
diff = *this - qd;
|
||||
sum = *this + qd;
|
||||
if( diff.dot(diff) > sum.dot(sum) )
|
||||
return qd;
|
||||
return (-qd);
|
||||
}
|
||||
|
||||
/**@todo document this and it's use */
|
||||
SIMD_FORCE_INLINE btQuaternion nearest( const btQuaternion& qd) const
|
||||
{
|
||||
btQuaternion diff,sum;
|
||||
diff = *this - qd;
|
||||
sum = *this + qd;
|
||||
if( diff.dot(diff) < sum.dot(sum) )
|
||||
return qd;
|
||||
return (-qd);
|
||||
}
|
||||
|
||||
|
||||
/**@brief Return the quaternion which is the result of Spherical Linear Interpolation between this and the other quaternion
|
||||
* @param q The other quaternion to interpolate with
|
||||
* @param t The ratio between this and q to interpolate. If t = 0 the result is this, if t=1 the result is q.
|
||||
* Slerp interpolates assuming constant velocity. */
|
||||
btQuaternion slerp(const btQuaternion& q, const btScalar& t) const
|
||||
{
|
||||
btScalar theta = angle(q);
|
||||
if (theta != btScalar(0.0))
|
||||
{
|
||||
btScalar d = btScalar(1.0) / btSin(theta);
|
||||
btScalar s0 = btSin((btScalar(1.0) - t) * theta);
|
||||
btScalar s1 = btSin(t * theta);
|
||||
if (dot(q) < 0) // Take care of long angle case see http://en.wikipedia.org/wiki/Slerp
|
||||
return btQuaternion((m_floats[0] * s0 + -q.x() * s1) * d,
|
||||
(m_floats[1] * s0 + -q.y() * s1) * d,
|
||||
(m_floats[2] * s0 + -q.z() * s1) * d,
|
||||
(m_floats[3] * s0 + -q.m_floats[3] * s1) * d);
|
||||
else
|
||||
return btQuaternion((m_floats[0] * s0 + q.x() * s1) * d,
|
||||
(m_floats[1] * s0 + q.y() * s1) * d,
|
||||
(m_floats[2] * s0 + q.z() * s1) * d,
|
||||
(m_floats[3] * s0 + q.m_floats[3] * s1) * d);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
static const btQuaternion& getIdentity()
|
||||
{
|
||||
static const btQuaternion identityQuat(btScalar(0.),btScalar(0.),btScalar(0.),btScalar(1.));
|
||||
return identityQuat;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE const btScalar& getW() const { return m_floats[3]; }
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**@brief Return the negative of a quaternion */
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
operator-(const btQuaternion& q)
|
||||
{
|
||||
return btQuaternion(-q.x(), -q.y(), -q.z(), -q.w());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**@brief Return the product of two quaternions */
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
operator*(const btQuaternion& q1, const btQuaternion& q2) {
|
||||
return btQuaternion(q1.w() * q2.x() + q1.x() * q2.w() + q1.y() * q2.z() - q1.z() * q2.y(),
|
||||
q1.w() * q2.y() + q1.y() * q2.w() + q1.z() * q2.x() - q1.x() * q2.z(),
|
||||
q1.w() * q2.z() + q1.z() * q2.w() + q1.x() * q2.y() - q1.y() * q2.x(),
|
||||
q1.w() * q2.w() - q1.x() * q2.x() - q1.y() * q2.y() - q1.z() * q2.z());
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
operator*(const btQuaternion& q, const btVector3& w)
|
||||
{
|
||||
return btQuaternion( q.w() * w.x() + q.y() * w.z() - q.z() * w.y(),
|
||||
q.w() * w.y() + q.z() * w.x() - q.x() * w.z(),
|
||||
q.w() * w.z() + q.x() * w.y() - q.y() * w.x(),
|
||||
-q.x() * w.x() - q.y() * w.y() - q.z() * w.z());
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
operator*(const btVector3& w, const btQuaternion& q)
|
||||
{
|
||||
return btQuaternion( w.x() * q.w() + w.y() * q.z() - w.z() * q.y(),
|
||||
w.y() * q.w() + w.z() * q.x() - w.x() * q.z(),
|
||||
w.z() * q.w() + w.x() * q.y() - w.y() * q.x(),
|
||||
-w.x() * q.x() - w.y() * q.y() - w.z() * q.z());
|
||||
}
|
||||
|
||||
/**@brief Calculate the dot product between two quaternions */
|
||||
SIMD_FORCE_INLINE btScalar
|
||||
dot(const btQuaternion& q1, const btQuaternion& q2)
|
||||
{
|
||||
return q1.dot(q2);
|
||||
}
|
||||
|
||||
|
||||
/**@brief Return the length of a quaternion */
|
||||
SIMD_FORCE_INLINE btScalar
|
||||
length(const btQuaternion& q)
|
||||
{
|
||||
return q.length();
|
||||
}
|
||||
|
||||
/**@brief Return the angle between two quaternions*/
|
||||
SIMD_FORCE_INLINE btScalar
|
||||
angle(const btQuaternion& q1, const btQuaternion& q2)
|
||||
{
|
||||
return q1.angle(q2);
|
||||
}
|
||||
|
||||
/**@brief Return the inverse of a quaternion*/
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
inverse(const btQuaternion& q)
|
||||
{
|
||||
return q.inverse();
|
||||
}
|
||||
|
||||
/**@brief Return the result of spherical linear interpolation betwen two quaternions
|
||||
* @param q1 The first quaternion
|
||||
* @param q2 The second quaternion
|
||||
* @param t The ration between q1 and q2. t = 0 return q1, t=1 returns q2
|
||||
* Slerp assumes constant velocity between positions. */
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
slerp(const btQuaternion& q1, const btQuaternion& q2, const btScalar& t)
|
||||
{
|
||||
return q1.slerp(q2, t);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btVector3
|
||||
quatRotate(const btQuaternion& rotation, const btVector3& v)
|
||||
{
|
||||
btQuaternion q = rotation * v;
|
||||
q *= rotation.inverse();
|
||||
return btVector3(q.getX(),q.getY(),q.getZ());
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
shortestArcQuat(const btVector3& v0, const btVector3& v1) // Game Programming Gems 2.10. make sure v0,v1 are normalized
|
||||
{
|
||||
btVector3 c = v0.cross(v1);
|
||||
btScalar d = v0.dot(v1);
|
||||
|
||||
if (d < -1.0 + SIMD_EPSILON)
|
||||
{
|
||||
btVector3 n,unused;
|
||||
btPlaneSpace1(v0,n,unused);
|
||||
return btQuaternion(n.x(),n.y(),n.z(),0.0f); // just pick any vector that is orthogonal to v0
|
||||
}
|
||||
|
||||
btScalar s = btSqrt((1.0f + d) * 2.0f);
|
||||
btScalar rs = 1.0f / s;
|
||||
|
||||
return btQuaternion(c.getX()*rs,c.getY()*rs,c.getZ()*rs,s * 0.5f);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
shortestArcQuatNormalize2(btVector3& v0,btVector3& v1)
|
||||
{
|
||||
v0.normalize();
|
||||
v1.normalize();
|
||||
return shortestArcQuat(v0,v1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
565
libs/bullet/LinearMath/btQuickprof.cpp
Normal file
565
libs/bullet/LinearMath/btQuickprof.cpp
Normal file
@ -0,0 +1,565 @@
|
||||
/*
|
||||
|
||||
***************************************************************************************************
|
||||
**
|
||||
** profile.cpp
|
||||
**
|
||||
** Real-Time Hierarchical Profiling for Game Programming Gems 3
|
||||
**
|
||||
** by Greg Hjelstrom & Byon Garrabrant
|
||||
**
|
||||
***************************************************************************************************/
|
||||
|
||||
// Credits: The Clock class was inspired by the Timer classes in
|
||||
// Ogre (www.ogre3d.org).
|
||||
|
||||
#include "btQuickprof.h"
|
||||
|
||||
#ifndef BT_NO_PROFILE
|
||||
|
||||
|
||||
static btClock gProfileClock;
|
||||
|
||||
|
||||
#ifdef __CELLOS_LV2__
|
||||
#include <sys/sys_time.h>
|
||||
#include <sys/time_util.h>
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if defined (SUNOS) || defined (__SUNOS__)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
|
||||
#define BT_USE_WINDOWS_TIMERS
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define NOWINRES
|
||||
#define NOMCX
|
||||
#define NOIME
|
||||
|
||||
#ifdef _XBOX
|
||||
#include <Xtl.h>
|
||||
#else //_XBOX
|
||||
#include <windows.h>
|
||||
#endif //_XBOX
|
||||
|
||||
#include <time.h>
|
||||
|
||||
|
||||
#else //_WIN32
|
||||
#include <sys/time.h>
|
||||
#endif //_WIN32
|
||||
|
||||
#define mymin(a,b) (a > b ? a : b)
|
||||
|
||||
struct btClockData
|
||||
{
|
||||
|
||||
#ifdef BT_USE_WINDOWS_TIMERS
|
||||
LARGE_INTEGER mClockFrequency;
|
||||
DWORD mStartTick;
|
||||
LONGLONG mPrevElapsedTime;
|
||||
LARGE_INTEGER mStartTime;
|
||||
#else
|
||||
#ifdef __CELLOS_LV2__
|
||||
uint64_t mStartTime;
|
||||
#else
|
||||
struct timeval mStartTime;
|
||||
#endif
|
||||
#endif //__CELLOS_LV2__
|
||||
|
||||
};
|
||||
|
||||
///The btClock is a portable basic clock that measures accurate time in seconds, use for profiling.
|
||||
btClock::btClock()
|
||||
{
|
||||
m_data = new btClockData;
|
||||
#ifdef BT_USE_WINDOWS_TIMERS
|
||||
QueryPerformanceFrequency(&m_data->mClockFrequency);
|
||||
#endif
|
||||
reset();
|
||||
}
|
||||
|
||||
btClock::~btClock()
|
||||
{
|
||||
delete m_data;
|
||||
}
|
||||
|
||||
btClock::btClock(const btClock& other)
|
||||
{
|
||||
m_data = new btClockData;
|
||||
*m_data = *other.m_data;
|
||||
}
|
||||
|
||||
btClock& btClock::operator=(const btClock& other)
|
||||
{
|
||||
*m_data = *other.m_data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/// Resets the initial reference time.
|
||||
void btClock::reset()
|
||||
{
|
||||
#ifdef BT_USE_WINDOWS_TIMERS
|
||||
QueryPerformanceCounter(&m_data->mStartTime);
|
||||
m_data->mStartTick = GetTickCount();
|
||||
m_data->mPrevElapsedTime = 0;
|
||||
#else
|
||||
#ifdef __CELLOS_LV2__
|
||||
|
||||
typedef uint64_t ClockSize;
|
||||
ClockSize newTime;
|
||||
//__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
|
||||
SYS_TIMEBASE_GET( newTime );
|
||||
m_data->mStartTime = newTime;
|
||||
#else
|
||||
gettimeofday(&m_data->mStartTime, 0);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Returns the time in ms since the last call to reset or since
|
||||
/// the btClock was created.
|
||||
unsigned long int btClock::getTimeMilliseconds()
|
||||
{
|
||||
#ifdef BT_USE_WINDOWS_TIMERS
|
||||
LARGE_INTEGER currentTime;
|
||||
QueryPerformanceCounter(¤tTime);
|
||||
LONGLONG elapsedTime = currentTime.QuadPart -
|
||||
m_data->mStartTime.QuadPart;
|
||||
// Compute the number of millisecond ticks elapsed.
|
||||
unsigned long msecTicks = (unsigned long)(1000 * elapsedTime /
|
||||
m_data->mClockFrequency.QuadPart);
|
||||
// Check for unexpected leaps in the Win32 performance counter.
|
||||
// (This is caused by unexpected data across the PCI to ISA
|
||||
// bridge, aka south bridge. See Microsoft KB274323.)
|
||||
unsigned long elapsedTicks = GetTickCount() - m_data->mStartTick;
|
||||
signed long msecOff = (signed long)(msecTicks - elapsedTicks);
|
||||
if (msecOff < -100 || msecOff > 100)
|
||||
{
|
||||
// Adjust the starting time forwards.
|
||||
LONGLONG msecAdjustment = mymin(msecOff *
|
||||
m_data->mClockFrequency.QuadPart / 1000, elapsedTime -
|
||||
m_data->mPrevElapsedTime);
|
||||
m_data->mStartTime.QuadPart += msecAdjustment;
|
||||
elapsedTime -= msecAdjustment;
|
||||
|
||||
// Recompute the number of millisecond ticks elapsed.
|
||||
msecTicks = (unsigned long)(1000 * elapsedTime /
|
||||
m_data->mClockFrequency.QuadPart);
|
||||
}
|
||||
|
||||
// Store the current elapsed time for adjustments next time.
|
||||
m_data->mPrevElapsedTime = elapsedTime;
|
||||
|
||||
return msecTicks;
|
||||
#else
|
||||
|
||||
#ifdef __CELLOS_LV2__
|
||||
uint64_t freq=sys_time_get_timebase_frequency();
|
||||
double dFreq=((double) freq) / 1000.0;
|
||||
typedef uint64_t ClockSize;
|
||||
ClockSize newTime;
|
||||
SYS_TIMEBASE_GET( newTime );
|
||||
//__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
|
||||
|
||||
return (unsigned long int)((double(newTime-m_data->mStartTime)) / dFreq);
|
||||
#else
|
||||
|
||||
struct timeval currentTime;
|
||||
gettimeofday(¤tTime, 0);
|
||||
return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1000 +
|
||||
(currentTime.tv_usec - m_data->mStartTime.tv_usec) / 1000;
|
||||
#endif //__CELLOS_LV2__
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Returns the time in us since the last call to reset or since
|
||||
/// the Clock was created.
|
||||
unsigned long int btClock::getTimeMicroseconds()
|
||||
{
|
||||
#ifdef BT_USE_WINDOWS_TIMERS
|
||||
LARGE_INTEGER currentTime;
|
||||
QueryPerformanceCounter(¤tTime);
|
||||
LONGLONG elapsedTime = currentTime.QuadPart -
|
||||
m_data->mStartTime.QuadPart;
|
||||
|
||||
// Compute the number of millisecond ticks elapsed.
|
||||
unsigned long msecTicks = (unsigned long)(1000 * elapsedTime /
|
||||
m_data->mClockFrequency.QuadPart);
|
||||
|
||||
// Check for unexpected leaps in the Win32 performance counter.
|
||||
// (This is caused by unexpected data across the PCI to ISA
|
||||
// bridge, aka south bridge. See Microsoft KB274323.)
|
||||
unsigned long elapsedTicks = GetTickCount() - m_data->mStartTick;
|
||||
signed long msecOff = (signed long)(msecTicks - elapsedTicks);
|
||||
if (msecOff < -100 || msecOff > 100)
|
||||
{
|
||||
// Adjust the starting time forwards.
|
||||
LONGLONG msecAdjustment = mymin(msecOff *
|
||||
m_data->mClockFrequency.QuadPart / 1000, elapsedTime -
|
||||
m_data->mPrevElapsedTime);
|
||||
m_data->mStartTime.QuadPart += msecAdjustment;
|
||||
elapsedTime -= msecAdjustment;
|
||||
}
|
||||
|
||||
// Store the current elapsed time for adjustments next time.
|
||||
m_data->mPrevElapsedTime = elapsedTime;
|
||||
|
||||
// Convert to microseconds.
|
||||
unsigned long usecTicks = (unsigned long)(1000000 * elapsedTime /
|
||||
m_data->mClockFrequency.QuadPart);
|
||||
|
||||
return usecTicks;
|
||||
#else
|
||||
|
||||
#ifdef __CELLOS_LV2__
|
||||
uint64_t freq=sys_time_get_timebase_frequency();
|
||||
double dFreq=((double) freq)/ 1000000.0;
|
||||
typedef uint64_t ClockSize;
|
||||
ClockSize newTime;
|
||||
//__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
|
||||
SYS_TIMEBASE_GET( newTime );
|
||||
|
||||
return (unsigned long int)((double(newTime-m_data->mStartTime)) / dFreq);
|
||||
#else
|
||||
|
||||
struct timeval currentTime;
|
||||
gettimeofday(¤tTime, 0);
|
||||
return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1000000 +
|
||||
(currentTime.tv_usec - m_data->mStartTime.tv_usec);
|
||||
#endif//__CELLOS_LV2__
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
inline void Profile_Get_Ticks(unsigned long int * ticks)
|
||||
{
|
||||
*ticks = gProfileClock.getTimeMicroseconds();
|
||||
}
|
||||
|
||||
inline float Profile_Get_Tick_Rate(void)
|
||||
{
|
||||
// return 1000000.f;
|
||||
return 1000.f;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
**
|
||||
** CProfileNode
|
||||
**
|
||||
***************************************************************************************************/
|
||||
|
||||
/***********************************************************************************************
|
||||
* INPUT: *
|
||||
* name - pointer to a static string which is the name of this profile node *
|
||||
* parent - parent pointer *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* The name is assumed to be a static pointer, only the pointer is stored and compared for *
|
||||
* efficiency reasons. *
|
||||
*=============================================================================================*/
|
||||
CProfileNode::CProfileNode( const char * name, CProfileNode * parent ) :
|
||||
Name( name ),
|
||||
TotalCalls( 0 ),
|
||||
TotalTime( 0 ),
|
||||
StartTime( 0 ),
|
||||
RecursionCounter( 0 ),
|
||||
Parent( parent ),
|
||||
Child( NULL ),
|
||||
Sibling( NULL )
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
|
||||
void CProfileNode::CleanupMemory()
|
||||
{
|
||||
delete ( Child);
|
||||
Child = NULL;
|
||||
delete ( Sibling);
|
||||
Sibling = NULL;
|
||||
}
|
||||
|
||||
CProfileNode::~CProfileNode( void )
|
||||
{
|
||||
delete ( Child);
|
||||
delete ( Sibling);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* INPUT: *
|
||||
* name - static string pointer to the name of the node we are searching for *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* All profile names are assumed to be static strings so this function uses pointer compares *
|
||||
* to find the named node. *
|
||||
*=============================================================================================*/
|
||||
CProfileNode * CProfileNode::Get_Sub_Node( const char * name )
|
||||
{
|
||||
// Try to find this sub node
|
||||
CProfileNode * child = Child;
|
||||
while ( child ) {
|
||||
if ( child->Name == name ) {
|
||||
return child;
|
||||
}
|
||||
child = child->Sibling;
|
||||
}
|
||||
|
||||
// We didn't find it, so add it
|
||||
|
||||
CProfileNode * node = new CProfileNode( name, this );
|
||||
node->Sibling = Child;
|
||||
Child = node;
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
void CProfileNode::Reset( void )
|
||||
{
|
||||
TotalCalls = 0;
|
||||
TotalTime = 0.0f;
|
||||
|
||||
|
||||
if ( Child ) {
|
||||
Child->Reset();
|
||||
}
|
||||
if ( Sibling ) {
|
||||
Sibling->Reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CProfileNode::Call( void )
|
||||
{
|
||||
TotalCalls++;
|
||||
if (RecursionCounter++ == 0) {
|
||||
Profile_Get_Ticks(&StartTime);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CProfileNode::Return( void )
|
||||
{
|
||||
if ( --RecursionCounter == 0 && TotalCalls != 0 ) {
|
||||
unsigned long int time;
|
||||
Profile_Get_Ticks(&time);
|
||||
time-=StartTime;
|
||||
TotalTime += (float)time / Profile_Get_Tick_Rate();
|
||||
}
|
||||
return ( RecursionCounter == 0 );
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
**
|
||||
** CProfileIterator
|
||||
**
|
||||
***************************************************************************************************/
|
||||
CProfileIterator::CProfileIterator( CProfileNode * start )
|
||||
{
|
||||
CurrentParent = start;
|
||||
CurrentChild = CurrentParent->Get_Child();
|
||||
}
|
||||
|
||||
|
||||
void CProfileIterator::First(void)
|
||||
{
|
||||
CurrentChild = CurrentParent->Get_Child();
|
||||
}
|
||||
|
||||
|
||||
void CProfileIterator::Next(void)
|
||||
{
|
||||
CurrentChild = CurrentChild->Get_Sibling();
|
||||
}
|
||||
|
||||
|
||||
bool CProfileIterator::Is_Done(void)
|
||||
{
|
||||
return CurrentChild == NULL;
|
||||
}
|
||||
|
||||
|
||||
void CProfileIterator::Enter_Child( int index )
|
||||
{
|
||||
CurrentChild = CurrentParent->Get_Child();
|
||||
while ( (CurrentChild != NULL) && (index != 0) ) {
|
||||
index--;
|
||||
CurrentChild = CurrentChild->Get_Sibling();
|
||||
}
|
||||
|
||||
if ( CurrentChild != NULL ) {
|
||||
CurrentParent = CurrentChild;
|
||||
CurrentChild = CurrentParent->Get_Child();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CProfileIterator::Enter_Parent( void )
|
||||
{
|
||||
if ( CurrentParent->Get_Parent() != NULL ) {
|
||||
CurrentParent = CurrentParent->Get_Parent();
|
||||
}
|
||||
CurrentChild = CurrentParent->Get_Child();
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
**
|
||||
** CProfileManager
|
||||
**
|
||||
***************************************************************************************************/
|
||||
|
||||
CProfileNode CProfileManager::Root( "Root", NULL );
|
||||
CProfileNode * CProfileManager::CurrentNode = &CProfileManager::Root;
|
||||
int CProfileManager::FrameCounter = 0;
|
||||
unsigned long int CProfileManager::ResetTime = 0;
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* CProfileManager::Start_Profile -- Begin a named profile *
|
||||
* *
|
||||
* Steps one level deeper into the tree, if a child already exists with the specified name *
|
||||
* then it accumulates the profiling; otherwise a new child node is added to the profile tree. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* name - name of this profiling record *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* The string used is assumed to be a static string; pointer compares are used throughout *
|
||||
* the profiling code for efficiency. *
|
||||
*=============================================================================================*/
|
||||
void CProfileManager::Start_Profile( const char * name )
|
||||
{
|
||||
if (name != CurrentNode->Get_Name()) {
|
||||
CurrentNode = CurrentNode->Get_Sub_Node( name );
|
||||
}
|
||||
|
||||
CurrentNode->Call();
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* CProfileManager::Stop_Profile -- Stop timing and record the results. *
|
||||
*=============================================================================================*/
|
||||
void CProfileManager::Stop_Profile( void )
|
||||
{
|
||||
// Return will indicate whether we should back up to our parent (we may
|
||||
// be profiling a recursive function)
|
||||
if (CurrentNode->Return()) {
|
||||
CurrentNode = CurrentNode->Get_Parent();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* CProfileManager::Reset -- Reset the contents of the profiling system *
|
||||
* *
|
||||
* This resets everything except for the tree structure. All of the timing data is reset. *
|
||||
*=============================================================================================*/
|
||||
void CProfileManager::Reset( void )
|
||||
{
|
||||
gProfileClock.reset();
|
||||
Root.Reset();
|
||||
Root.Call();
|
||||
FrameCounter = 0;
|
||||
Profile_Get_Ticks(&ResetTime);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* CProfileManager::Increment_Frame_Counter -- Increment the frame counter *
|
||||
*=============================================================================================*/
|
||||
void CProfileManager::Increment_Frame_Counter( void )
|
||||
{
|
||||
FrameCounter++;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* CProfileManager::Get_Time_Since_Reset -- returns the elapsed time since last reset *
|
||||
*=============================================================================================*/
|
||||
float CProfileManager::Get_Time_Since_Reset( void )
|
||||
{
|
||||
unsigned long int time;
|
||||
Profile_Get_Ticks(&time);
|
||||
time -= ResetTime;
|
||||
return (float)time / Profile_Get_Tick_Rate();
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void CProfileManager::dumpRecursive(CProfileIterator* profileIterator, int spacing)
|
||||
{
|
||||
profileIterator->First();
|
||||
if (profileIterator->Is_Done())
|
||||
return;
|
||||
|
||||
float accumulated_time=0,parent_time = profileIterator->Is_Root() ? CProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time();
|
||||
int i;
|
||||
int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset();
|
||||
for (i=0;i<spacing;i++) printf(".");
|
||||
printf("----------------------------------\n");
|
||||
for (i=0;i<spacing;i++) printf(".");
|
||||
printf("Profiling: %s (total running time: %.3f ms) ---\n", profileIterator->Get_Current_Parent_Name(), parent_time );
|
||||
float totalTime = 0.f;
|
||||
|
||||
|
||||
int numChildren = 0;
|
||||
|
||||
for (i = 0; !profileIterator->Is_Done(); i++,profileIterator->Next())
|
||||
{
|
||||
numChildren++;
|
||||
float current_total_time = profileIterator->Get_Current_Total_Time();
|
||||
accumulated_time += current_total_time;
|
||||
float fraction = parent_time > SIMD_EPSILON ? (current_total_time / parent_time) * 100 : 0.f;
|
||||
{
|
||||
int i; for (i=0;i<spacing;i++) printf(".");
|
||||
}
|
||||
printf("%d -- %s (%.2f %%) :: %.3f ms / frame (%d calls)\n",i, profileIterator->Get_Current_Name(), fraction,(current_total_time / (double)frames_since_reset),profileIterator->Get_Current_Total_Calls());
|
||||
totalTime += current_total_time;
|
||||
//recurse into children
|
||||
}
|
||||
|
||||
if (parent_time < accumulated_time)
|
||||
{
|
||||
printf("what's wrong\n");
|
||||
}
|
||||
for (i=0;i<spacing;i++) printf(".");
|
||||
printf("%s (%.3f %%) :: %.3f ms\n", "Unaccounted:",parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time);
|
||||
|
||||
for (i=0;i<numChildren;i++)
|
||||
{
|
||||
profileIterator->Enter_Child(i);
|
||||
dumpRecursive(profileIterator,spacing+3);
|
||||
profileIterator->Enter_Parent();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CProfileManager::dumpAll()
|
||||
{
|
||||
CProfileIterator* profileIterator = 0;
|
||||
profileIterator = CProfileManager::Get_Iterator();
|
||||
|
||||
dumpRecursive(profileIterator,0);
|
||||
|
||||
CProfileManager::Release_Iterator(profileIterator);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif //BT_NO_PROFILE
|
196
libs/bullet/LinearMath/btQuickprof.h
Normal file
196
libs/bullet/LinearMath/btQuickprof.h
Normal file
@ -0,0 +1,196 @@
|
||||
|
||||
/***************************************************************************************************
|
||||
**
|
||||
** Real-Time Hierarchical Profiling for Game Programming Gems 3
|
||||
**
|
||||
** by Greg Hjelstrom & Byon Garrabrant
|
||||
**
|
||||
***************************************************************************************************/
|
||||
|
||||
// Credits: The Clock class was inspired by the Timer classes in
|
||||
// Ogre (www.ogre3d.org).
|
||||
|
||||
|
||||
|
||||
#ifndef QUICK_PROF_H
|
||||
#define QUICK_PROF_H
|
||||
|
||||
//To disable built-in profiling, please comment out next line
|
||||
//#define BT_NO_PROFILE 1
|
||||
#ifndef BT_NO_PROFILE
|
||||
#include <stdio.h>//@todo remove this, backwards compatibility
|
||||
#include "btScalar.h"
|
||||
#include "btAlignedAllocator.h"
|
||||
#include <new>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define USE_BT_CLOCK 1
|
||||
|
||||
#ifdef USE_BT_CLOCK
|
||||
|
||||
///The btClock is a portable basic clock that measures accurate time in seconds, use for profiling.
|
||||
class btClock
|
||||
{
|
||||
public:
|
||||
btClock();
|
||||
|
||||
btClock(const btClock& other);
|
||||
btClock& operator=(const btClock& other);
|
||||
|
||||
~btClock();
|
||||
|
||||
/// Resets the initial reference time.
|
||||
void reset();
|
||||
|
||||
/// Returns the time in ms since the last call to reset or since
|
||||
/// the btClock was created.
|
||||
unsigned long int getTimeMilliseconds();
|
||||
|
||||
/// Returns the time in us since the last call to reset or since
|
||||
/// the Clock was created.
|
||||
unsigned long int getTimeMicroseconds();
|
||||
private:
|
||||
struct btClockData* m_data;
|
||||
};
|
||||
|
||||
#endif //USE_BT_CLOCK
|
||||
|
||||
|
||||
|
||||
|
||||
///A node in the Profile Hierarchy Tree
|
||||
class CProfileNode {
|
||||
|
||||
public:
|
||||
CProfileNode( const char * name, CProfileNode * parent );
|
||||
~CProfileNode( void );
|
||||
|
||||
CProfileNode * Get_Sub_Node( const char * name );
|
||||
|
||||
CProfileNode * Get_Parent( void ) { return Parent; }
|
||||
CProfileNode * Get_Sibling( void ) { return Sibling; }
|
||||
CProfileNode * Get_Child( void ) { return Child; }
|
||||
|
||||
void CleanupMemory();
|
||||
void Reset( void );
|
||||
void Call( void );
|
||||
bool Return( void );
|
||||
|
||||
const char * Get_Name( void ) { return Name; }
|
||||
int Get_Total_Calls( void ) { return TotalCalls; }
|
||||
float Get_Total_Time( void ) { return TotalTime; }
|
||||
|
||||
protected:
|
||||
|
||||
const char * Name;
|
||||
int TotalCalls;
|
||||
float TotalTime;
|
||||
unsigned long int StartTime;
|
||||
int RecursionCounter;
|
||||
|
||||
CProfileNode * Parent;
|
||||
CProfileNode * Child;
|
||||
CProfileNode * Sibling;
|
||||
};
|
||||
|
||||
///An iterator to navigate through the tree
|
||||
class CProfileIterator
|
||||
{
|
||||
public:
|
||||
// Access all the children of the current parent
|
||||
void First(void);
|
||||
void Next(void);
|
||||
bool Is_Done(void);
|
||||
bool Is_Root(void) { return (CurrentParent->Get_Parent() == 0); }
|
||||
|
||||
void Enter_Child( int index ); // Make the given child the new parent
|
||||
void Enter_Largest_Child( void ); // Make the largest child the new parent
|
||||
void Enter_Parent( void ); // Make the current parent's parent the new parent
|
||||
|
||||
// Access the current child
|
||||
const char * Get_Current_Name( void ) { return CurrentChild->Get_Name(); }
|
||||
int Get_Current_Total_Calls( void ) { return CurrentChild->Get_Total_Calls(); }
|
||||
float Get_Current_Total_Time( void ) { return CurrentChild->Get_Total_Time(); }
|
||||
|
||||
// Access the current parent
|
||||
const char * Get_Current_Parent_Name( void ) { return CurrentParent->Get_Name(); }
|
||||
int Get_Current_Parent_Total_Calls( void ) { return CurrentParent->Get_Total_Calls(); }
|
||||
float Get_Current_Parent_Total_Time( void ) { return CurrentParent->Get_Total_Time(); }
|
||||
|
||||
protected:
|
||||
|
||||
CProfileNode * CurrentParent;
|
||||
CProfileNode * CurrentChild;
|
||||
|
||||
CProfileIterator( CProfileNode * start );
|
||||
friend class CProfileManager;
|
||||
};
|
||||
|
||||
|
||||
///The Manager for the Profile system
|
||||
class CProfileManager {
|
||||
public:
|
||||
static void Start_Profile( const char * name );
|
||||
static void Stop_Profile( void );
|
||||
|
||||
static void CleanupMemory(void)
|
||||
{
|
||||
Root.CleanupMemory();
|
||||
}
|
||||
|
||||
static void Reset( void );
|
||||
static void Increment_Frame_Counter( void );
|
||||
static int Get_Frame_Count_Since_Reset( void ) { return FrameCounter; }
|
||||
static float Get_Time_Since_Reset( void );
|
||||
|
||||
static CProfileIterator * Get_Iterator( void )
|
||||
{
|
||||
|
||||
return new CProfileIterator( &Root );
|
||||
}
|
||||
static void Release_Iterator( CProfileIterator * iterator ) { delete ( iterator); }
|
||||
|
||||
static void dumpRecursive(CProfileIterator* profileIterator, int spacing);
|
||||
|
||||
static void dumpAll();
|
||||
|
||||
private:
|
||||
static CProfileNode Root;
|
||||
static CProfileNode * CurrentNode;
|
||||
static int FrameCounter;
|
||||
static unsigned long int ResetTime;
|
||||
};
|
||||
|
||||
|
||||
///ProfileSampleClass is a simple way to profile a function's scope
|
||||
///Use the BT_PROFILE macro at the start of scope to time
|
||||
class CProfileSample {
|
||||
public:
|
||||
CProfileSample( const char * name )
|
||||
{
|
||||
CProfileManager::Start_Profile( name );
|
||||
}
|
||||
|
||||
~CProfileSample( void )
|
||||
{
|
||||
CProfileManager::Stop_Profile();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#define BT_PROFILE( name ) CProfileSample __profile( name )
|
||||
|
||||
#else
|
||||
|
||||
#define BT_PROFILE( name )
|
||||
|
||||
#endif //#ifndef BT_NO_PROFILE
|
||||
|
||||
|
||||
|
||||
#endif //QUICK_PROF_H
|
||||
|
||||
|
42
libs/bullet/LinearMath/btRandom.h
Normal file
42
libs/bullet/LinearMath/btRandom.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
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 GEN_RANDOM_H
|
||||
#define GEN_RANDOM_H
|
||||
|
||||
#ifdef MT19937
|
||||
|
||||
#include <limits.h>
|
||||
#include <mt19937.h>
|
||||
|
||||
#define GEN_RAND_MAX UINT_MAX
|
||||
|
||||
SIMD_FORCE_INLINE void GEN_srand(unsigned int seed) { init_genrand(seed); }
|
||||
SIMD_FORCE_INLINE unsigned int GEN_rand() { return genrand_int32(); }
|
||||
|
||||
#else
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define GEN_RAND_MAX RAND_MAX
|
||||
|
||||
SIMD_FORCE_INLINE void GEN_srand(unsigned int seed) { srand(seed); }
|
||||
SIMD_FORCE_INLINE unsigned int GEN_rand() { return rand(); }
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
524
libs/bullet/LinearMath/btScalar.h
Normal file
524
libs/bullet/LinearMath/btScalar.h
Normal file
@ -0,0 +1,524 @@
|
||||
/*
|
||||
Copyright (c) 2003-2009 Erwin Coumans http://bullet.googlecode.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.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef SIMD___SCALAR_H
|
||||
#define SIMD___SCALAR_H
|
||||
|
||||
#ifdef BT_MANAGED_CODE
|
||||
//Aligned data types not supported in managed code
|
||||
#pragma unmanaged
|
||||
#endif
|
||||
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>//size_t for MSVC 6.0
|
||||
#include <cstdlib>
|
||||
#include <cfloat>
|
||||
#include <float.h>
|
||||
|
||||
/* SVN $Revision$ on $Date$ from http://bullet.googlecode.com*/
|
||||
#define BT_BULLET_VERSION 277
|
||||
|
||||
inline int btGetVersion()
|
||||
{
|
||||
return BT_BULLET_VERSION;
|
||||
}
|
||||
|
||||
#if defined(DEBUG) || defined (_DEBUG)
|
||||
#define BT_DEBUG
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#if defined(__MINGW32__) || defined(__CYGWIN__) || (defined (_MSC_VER) && _MSC_VER < 1300)
|
||||
|
||||
#define SIMD_FORCE_INLINE inline
|
||||
#define ATTRIBUTE_ALIGNED16(a) a
|
||||
#define ATTRIBUTE_ALIGNED64(a) a
|
||||
#define ATTRIBUTE_ALIGNED128(a) a
|
||||
#else
|
||||
//#define BT_HAS_ALIGNED_ALLOCATOR
|
||||
#pragma warning(disable : 4324) // disable padding warning
|
||||
// #pragma warning(disable:4530) // Disable the exception disable but used in MSCV Stl warning.
|
||||
// #pragma warning(disable:4996) //Turn off warnings about deprecated C routines
|
||||
// #pragma warning(disable:4786) // Disable the "debug name too long" warning
|
||||
|
||||
#define SIMD_FORCE_INLINE __forceinline
|
||||
#define ATTRIBUTE_ALIGNED16(a) __declspec(align(16)) a
|
||||
#define ATTRIBUTE_ALIGNED64(a) __declspec(align(64)) a
|
||||
#define ATTRIBUTE_ALIGNED128(a) __declspec (align(128)) a
|
||||
#ifdef _XBOX
|
||||
#define BT_USE_VMX128
|
||||
|
||||
#include <ppcintrinsics.h>
|
||||
#define BT_HAVE_NATIVE_FSEL
|
||||
#define btFsel(a,b,c) __fsel((a),(b),(c))
|
||||
#else
|
||||
|
||||
#if (defined (_WIN32) && (_MSC_VER) && _MSC_VER >= 1400) && (!defined (BT_USE_DOUBLE_PRECISION))
|
||||
#define BT_USE_SSE
|
||||
#include <emmintrin.h>
|
||||
#endif
|
||||
|
||||
#endif//_XBOX
|
||||
|
||||
#endif //__MINGW32__
|
||||
|
||||
#include <assert.h>
|
||||
#ifdef BT_DEBUG
|
||||
#define btAssert assert
|
||||
#else
|
||||
#define btAssert(x)
|
||||
#endif
|
||||
//btFullAssert is optional, slows down a lot
|
||||
#define btFullAssert(x)
|
||||
|
||||
#define btLikely(_c) _c
|
||||
#define btUnlikely(_c) _c
|
||||
|
||||
#else
|
||||
|
||||
#if defined (__CELLOS_LV2__)
|
||||
#define SIMD_FORCE_INLINE inline __attribute__((always_inline))
|
||||
#define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
|
||||
#define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
|
||||
#define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
|
||||
#ifndef assert
|
||||
#include <assert.h>
|
||||
#endif
|
||||
#ifdef BT_DEBUG
|
||||
#ifdef __SPU__
|
||||
#include <spu_printf.h>
|
||||
#define printf spu_printf
|
||||
#define btAssert(x) {if(!(x)){printf("Assert "__FILE__ ":%u ("#x")\n", __LINE__);spu_hcmpeq(0,0);}}
|
||||
#else
|
||||
#define btAssert assert
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define btAssert(x)
|
||||
#endif
|
||||
//btFullAssert is optional, slows down a lot
|
||||
#define btFullAssert(x)
|
||||
|
||||
#define btLikely(_c) _c
|
||||
#define btUnlikely(_c) _c
|
||||
|
||||
#else
|
||||
|
||||
#ifdef USE_LIBSPE2
|
||||
|
||||
#define SIMD_FORCE_INLINE __inline
|
||||
#define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
|
||||
#define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
|
||||
#define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
|
||||
#ifndef assert
|
||||
#include <assert.h>
|
||||
#endif
|
||||
#ifdef BT_DEBUG
|
||||
#define btAssert assert
|
||||
#else
|
||||
#define btAssert(x)
|
||||
#endif
|
||||
//btFullAssert is optional, slows down a lot
|
||||
#define btFullAssert(x)
|
||||
|
||||
|
||||
#define btLikely(_c) __builtin_expect((_c), 1)
|
||||
#define btUnlikely(_c) __builtin_expect((_c), 0)
|
||||
|
||||
|
||||
#else
|
||||
//non-windows systems
|
||||
|
||||
#if (defined (__APPLE__) && defined (__i386__) && (!defined (BT_USE_DOUBLE_PRECISION)))
|
||||
#define BT_USE_SSE
|
||||
#include <emmintrin.h>
|
||||
|
||||
#define SIMD_FORCE_INLINE inline
|
||||
///@todo: check out alignment methods for other platforms/compilers
|
||||
#define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
|
||||
#define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
|
||||
#define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
|
||||
#ifndef assert
|
||||
#include <assert.h>
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG) || defined (_DEBUG)
|
||||
#define btAssert assert
|
||||
#else
|
||||
#define btAssert(x)
|
||||
#endif
|
||||
|
||||
//btFullAssert is optional, slows down a lot
|
||||
#define btFullAssert(x)
|
||||
#define btLikely(_c) _c
|
||||
#define btUnlikely(_c) _c
|
||||
|
||||
#else
|
||||
|
||||
#define SIMD_FORCE_INLINE inline
|
||||
///@todo: check out alignment methods for other platforms/compilers
|
||||
///#define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
|
||||
///#define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
|
||||
///#define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
|
||||
#define ATTRIBUTE_ALIGNED16(a) a
|
||||
#define ATTRIBUTE_ALIGNED64(a) a
|
||||
#define ATTRIBUTE_ALIGNED128(a) a
|
||||
#ifndef assert
|
||||
#include <assert.h>
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG) || defined (_DEBUG)
|
||||
#define btAssert assert
|
||||
#else
|
||||
#define btAssert(x)
|
||||
#endif
|
||||
|
||||
//btFullAssert is optional, slows down a lot
|
||||
#define btFullAssert(x)
|
||||
#define btLikely(_c) _c
|
||||
#define btUnlikely(_c) _c
|
||||
#endif //__APPLE__
|
||||
|
||||
#endif // LIBSPE2
|
||||
|
||||
#endif //__CELLOS_LV2__
|
||||
#endif
|
||||
|
||||
|
||||
///The btScalar type abstracts floating point numbers, to easily switch between double and single floating point precision.
|
||||
#if defined(BT_USE_DOUBLE_PRECISION)
|
||||
typedef double btScalar;
|
||||
//this number could be bigger in double precision
|
||||
#define BT_LARGE_FLOAT 1e30
|
||||
#else
|
||||
typedef float btScalar;
|
||||
//keep BT_LARGE_FLOAT*BT_LARGE_FLOAT < FLT_MAX
|
||||
#define BT_LARGE_FLOAT 1e18f
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define BT_DECLARE_ALIGNED_ALLOCATOR() \
|
||||
SIMD_FORCE_INLINE void* operator new(size_t sizeInBytes) { return btAlignedAlloc(sizeInBytes,16); } \
|
||||
SIMD_FORCE_INLINE void operator delete(void* ptr) { btAlignedFree(ptr); } \
|
||||
SIMD_FORCE_INLINE void* operator new(size_t, void* ptr) { return ptr; } \
|
||||
SIMD_FORCE_INLINE void operator delete(void*, void*) { } \
|
||||
SIMD_FORCE_INLINE void* operator new[](size_t sizeInBytes) { return btAlignedAlloc(sizeInBytes,16); } \
|
||||
SIMD_FORCE_INLINE void operator delete[](void* ptr) { btAlignedFree(ptr); } \
|
||||
SIMD_FORCE_INLINE void* operator new[](size_t, void* ptr) { return ptr; } \
|
||||
SIMD_FORCE_INLINE void operator delete[](void*, void*) { } \
|
||||
|
||||
|
||||
|
||||
#if defined(BT_USE_DOUBLE_PRECISION) || defined(BT_FORCE_DOUBLE_FUNCTIONS)
|
||||
|
||||
SIMD_FORCE_INLINE btScalar btSqrt(btScalar x) { return sqrt(x); }
|
||||
SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabs(x); }
|
||||
SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cos(x); }
|
||||
SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sin(x); }
|
||||
SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tan(x); }
|
||||
SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { if (x<btScalar(-1)) x=btScalar(-1); if (x>btScalar(1)) x=btScalar(1); return acos(x); }
|
||||
SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { if (x<btScalar(-1)) x=btScalar(-1); if (x>btScalar(1)) x=btScalar(1); return asin(x); }
|
||||
SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atan(x); }
|
||||
SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2(x, y); }
|
||||
SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return exp(x); }
|
||||
SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return log(x); }
|
||||
SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return pow(x,y); }
|
||||
SIMD_FORCE_INLINE btScalar btFmod(btScalar x,btScalar y) { return fmod(x,y); }
|
||||
|
||||
#else
|
||||
|
||||
SIMD_FORCE_INLINE btScalar btSqrt(btScalar y)
|
||||
{
|
||||
#ifdef USE_APPROXIMATION
|
||||
double x, z, tempf;
|
||||
unsigned long *tfptr = ((unsigned long *)&tempf) + 1;
|
||||
|
||||
tempf = y;
|
||||
*tfptr = (0xbfcdd90a - *tfptr)>>1; /* estimate of 1/sqrt(y) */
|
||||
x = tempf;
|
||||
z = y*btScalar(0.5);
|
||||
x = (btScalar(1.5)*x)-(x*x)*(x*z); /* iteration formula */
|
||||
x = (btScalar(1.5)*x)-(x*x)*(x*z);
|
||||
x = (btScalar(1.5)*x)-(x*x)*(x*z);
|
||||
x = (btScalar(1.5)*x)-(x*x)*(x*z);
|
||||
x = (btScalar(1.5)*x)-(x*x)*(x*z);
|
||||
return x*y;
|
||||
#else
|
||||
return sqrtf(y);
|
||||
#endif
|
||||
}
|
||||
SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabsf(x); }
|
||||
SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cosf(x); }
|
||||
SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sinf(x); }
|
||||
SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tanf(x); }
|
||||
SIMD_FORCE_INLINE btScalar btAcos(btScalar x) {
|
||||
if (x<btScalar(-1))
|
||||
x=btScalar(-1);
|
||||
if (x>btScalar(1))
|
||||
x=btScalar(1);
|
||||
return acosf(x);
|
||||
}
|
||||
SIMD_FORCE_INLINE btScalar btAsin(btScalar x) {
|
||||
if (x<btScalar(-1))
|
||||
x=btScalar(-1);
|
||||
if (x>btScalar(1))
|
||||
x=btScalar(1);
|
||||
return asinf(x);
|
||||
}
|
||||
SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atanf(x); }
|
||||
SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2f(x, y); }
|
||||
SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return expf(x); }
|
||||
SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return logf(x); }
|
||||
SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return powf(x,y); }
|
||||
SIMD_FORCE_INLINE btScalar btFmod(btScalar x,btScalar y) { return fmodf(x,y); }
|
||||
|
||||
#endif
|
||||
|
||||
#define SIMD_2_PI btScalar(6.283185307179586232)
|
||||
#define SIMD_PI (SIMD_2_PI * btScalar(0.5))
|
||||
#define SIMD_HALF_PI (SIMD_2_PI * btScalar(0.25))
|
||||
#define SIMD_RADS_PER_DEG (SIMD_2_PI / btScalar(360.0))
|
||||
#define SIMD_DEGS_PER_RAD (btScalar(360.0) / SIMD_2_PI)
|
||||
#define SIMDSQRT12 btScalar(0.7071067811865475244008443621048490)
|
||||
|
||||
#define btRecipSqrt(x) ((btScalar)(btScalar(1.0)/btSqrt(btScalar(x)))) /* reciprocal square root */
|
||||
|
||||
|
||||
#ifdef BT_USE_DOUBLE_PRECISION
|
||||
#define SIMD_EPSILON DBL_EPSILON
|
||||
#define SIMD_INFINITY DBL_MAX
|
||||
#else
|
||||
#define SIMD_EPSILON FLT_EPSILON
|
||||
#define SIMD_INFINITY FLT_MAX
|
||||
#endif
|
||||
|
||||
SIMD_FORCE_INLINE btScalar btAtan2Fast(btScalar y, btScalar x)
|
||||
{
|
||||
btScalar coeff_1 = SIMD_PI / 4.0f;
|
||||
btScalar coeff_2 = 3.0f * coeff_1;
|
||||
btScalar abs_y = btFabs(y);
|
||||
btScalar angle;
|
||||
if (x >= 0.0f) {
|
||||
btScalar r = (x - abs_y) / (x + abs_y);
|
||||
angle = coeff_1 - coeff_1 * r;
|
||||
} else {
|
||||
btScalar r = (x + abs_y) / (abs_y - x);
|
||||
angle = coeff_2 - coeff_1 * r;
|
||||
}
|
||||
return (y < 0.0f) ? -angle : angle;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE bool btFuzzyZero(btScalar x) { return btFabs(x) < SIMD_EPSILON; }
|
||||
|
||||
SIMD_FORCE_INLINE bool btEqual(btScalar a, btScalar eps) {
|
||||
return (((a) <= eps) && !((a) < -eps));
|
||||
}
|
||||
SIMD_FORCE_INLINE bool btGreaterEqual (btScalar a, btScalar eps) {
|
||||
return (!((a) <= eps));
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE int btIsNegative(btScalar x) {
|
||||
return x < btScalar(0.0) ? 1 : 0;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btScalar btRadians(btScalar x) { return x * SIMD_RADS_PER_DEG; }
|
||||
SIMD_FORCE_INLINE btScalar btDegrees(btScalar x) { return x * SIMD_DEGS_PER_RAD; }
|
||||
|
||||
#define BT_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
|
||||
|
||||
#ifndef btFsel
|
||||
SIMD_FORCE_INLINE btScalar btFsel(btScalar a, btScalar b, btScalar c)
|
||||
{
|
||||
return a >= 0 ? b : c;
|
||||
}
|
||||
#endif
|
||||
#define btFsels(a,b,c) (btScalar)btFsel(a,b,c)
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE bool btMachineIsLittleEndian()
|
||||
{
|
||||
long int i = 1;
|
||||
const char *p = (const char *) &i;
|
||||
if (p[0] == 1) // Lowest address contains the least significant byte
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///btSelect avoids branches, which makes performance much better for consoles like Playstation 3 and XBox 360
|
||||
///Thanks Phil Knight. See also http://www.cellperformance.com/articles/2006/04/more_techniques_for_eliminatin_1.html
|
||||
SIMD_FORCE_INLINE unsigned btSelect(unsigned condition, unsigned valueIfConditionNonZero, unsigned valueIfConditionZero)
|
||||
{
|
||||
// Set testNz to 0xFFFFFFFF if condition is nonzero, 0x00000000 if condition is zero
|
||||
// Rely on positive value or'ed with its negative having sign bit on
|
||||
// and zero value or'ed with its negative (which is still zero) having sign bit off
|
||||
// Use arithmetic shift right, shifting the sign bit through all 32 bits
|
||||
unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31);
|
||||
unsigned testEqz = ~testNz;
|
||||
return ((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz));
|
||||
}
|
||||
SIMD_FORCE_INLINE int btSelect(unsigned condition, int valueIfConditionNonZero, int valueIfConditionZero)
|
||||
{
|
||||
unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31);
|
||||
unsigned testEqz = ~testNz;
|
||||
return static_cast<int>((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz));
|
||||
}
|
||||
SIMD_FORCE_INLINE float btSelect(unsigned condition, float valueIfConditionNonZero, float valueIfConditionZero)
|
||||
{
|
||||
#ifdef BT_HAVE_NATIVE_FSEL
|
||||
return (float)btFsel((btScalar)condition - btScalar(1.0f), valueIfConditionNonZero, valueIfConditionZero);
|
||||
#else
|
||||
return (condition != 0) ? valueIfConditionNonZero : valueIfConditionZero;
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T> SIMD_FORCE_INLINE void btSwap(T& a, T& b)
|
||||
{
|
||||
T tmp = a;
|
||||
a = b;
|
||||
b = tmp;
|
||||
}
|
||||
|
||||
|
||||
//PCK: endian swapping functions
|
||||
SIMD_FORCE_INLINE unsigned btSwapEndian(unsigned val)
|
||||
{
|
||||
return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24));
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE unsigned short btSwapEndian(unsigned short val)
|
||||
{
|
||||
return static_cast<unsigned short>(((val & 0xff00) >> 8) | ((val & 0x00ff) << 8));
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE unsigned btSwapEndian(int val)
|
||||
{
|
||||
return btSwapEndian((unsigned)val);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE unsigned short btSwapEndian(short val)
|
||||
{
|
||||
return btSwapEndian((unsigned short) val);
|
||||
}
|
||||
|
||||
///btSwapFloat uses using char pointers to swap the endianness
|
||||
////btSwapFloat/btSwapDouble will NOT return a float, because the machine might 'correct' invalid floating point values
|
||||
///Not all values of sign/exponent/mantissa are valid floating point numbers according to IEEE 754.
|
||||
///When a floating point unit is faced with an invalid value, it may actually change the value, or worse, throw an exception.
|
||||
///In most systems, running user mode code, you wouldn't get an exception, but instead the hardware/os/runtime will 'fix' the number for you.
|
||||
///so instead of returning a float/double, we return integer/long long integer
|
||||
SIMD_FORCE_INLINE unsigned int btSwapEndianFloat(float d)
|
||||
{
|
||||
unsigned int a = 0;
|
||||
unsigned char *dst = (unsigned char *)&a;
|
||||
unsigned char *src = (unsigned char *)&d;
|
||||
|
||||
dst[0] = src[3];
|
||||
dst[1] = src[2];
|
||||
dst[2] = src[1];
|
||||
dst[3] = src[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
// unswap using char pointers
|
||||
SIMD_FORCE_INLINE float btUnswapEndianFloat(unsigned int a)
|
||||
{
|
||||
float d = 0.0f;
|
||||
unsigned char *src = (unsigned char *)&a;
|
||||
unsigned char *dst = (unsigned char *)&d;
|
||||
|
||||
dst[0] = src[3];
|
||||
dst[1] = src[2];
|
||||
dst[2] = src[1];
|
||||
dst[3] = src[0];
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
// swap using char pointers
|
||||
SIMD_FORCE_INLINE void btSwapEndianDouble(double d, unsigned char* dst)
|
||||
{
|
||||
unsigned char *src = (unsigned char *)&d;
|
||||
|
||||
dst[0] = src[7];
|
||||
dst[1] = src[6];
|
||||
dst[2] = src[5];
|
||||
dst[3] = src[4];
|
||||
dst[4] = src[3];
|
||||
dst[5] = src[2];
|
||||
dst[6] = src[1];
|
||||
dst[7] = src[0];
|
||||
|
||||
}
|
||||
|
||||
// unswap using char pointers
|
||||
SIMD_FORCE_INLINE double btUnswapEndianDouble(const unsigned char *src)
|
||||
{
|
||||
double d = 0.0;
|
||||
unsigned char *dst = (unsigned char *)&d;
|
||||
|
||||
dst[0] = src[7];
|
||||
dst[1] = src[6];
|
||||
dst[2] = src[5];
|
||||
dst[3] = src[4];
|
||||
dst[4] = src[3];
|
||||
dst[5] = src[2];
|
||||
dst[6] = src[1];
|
||||
dst[7] = src[0];
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
// returns normalized value in range [-SIMD_PI, SIMD_PI]
|
||||
SIMD_FORCE_INLINE btScalar btNormalizeAngle(btScalar angleInRadians)
|
||||
{
|
||||
angleInRadians = btFmod(angleInRadians, SIMD_2_PI);
|
||||
if(angleInRadians < -SIMD_PI)
|
||||
{
|
||||
return angleInRadians + SIMD_2_PI;
|
||||
}
|
||||
else if(angleInRadians > SIMD_PI)
|
||||
{
|
||||
return angleInRadians - SIMD_2_PI;
|
||||
}
|
||||
else
|
||||
{
|
||||
return angleInRadians;
|
||||
}
|
||||
}
|
||||
|
||||
///rudimentary class to provide type info
|
||||
struct btTypedObject
|
||||
{
|
||||
btTypedObject(int objectType)
|
||||
:m_objectType(objectType)
|
||||
{
|
||||
}
|
||||
int m_objectType;
|
||||
inline int getObjectType() const
|
||||
{
|
||||
return m_objectType;
|
||||
}
|
||||
};
|
||||
#endif //SIMD___SCALAR_H
|
577
libs/bullet/LinearMath/btSerializer.cpp
Normal file
577
libs/bullet/LinearMath/btSerializer.cpp
Normal file
@ -0,0 +1,577 @@
|
||||
unsigned char sBulletDNAstr64[]= {
|
||||
83,68,78,65,78,65,77,69,-79,0,0,0,109,95,115,105,122,101,0,109,
|
||||
95,99,97,112,97,99,105,116,121,0,42,109,95,100,97,116,97,0,109,95,
|
||||
99,111,108,108,105,115,105,111,110,83,104,97,112,101,115,0,109,95,99,111,
|
||||
108,108,105,115,105,111,110,79,98,106,101,99,116,115,0,109,95,99,111,110,
|
||||
115,116,114,97,105,110,116,115,0,42,102,105,114,115,116,0,42,108,97,115,
|
||||
116,0,109,95,102,108,111,97,116,115,91,52,93,0,109,95,101,108,91,51,
|
||||
93,0,109,95,98,97,115,105,115,0,109,95,111,114,105,103,105,110,0,109,
|
||||
95,114,111,111,116,78,111,100,101,73,110,100,101,120,0,109,95,115,117,98,
|
||||
116,114,101,101,83,105,122,101,0,109,95,113,117,97,110,116,105,122,101,100,
|
||||
65,97,98,98,77,105,110,91,51,93,0,109,95,113,117,97,110,116,105,122,
|
||||
101,100,65,97,98,98,77,97,120,91,51,93,0,109,95,97,97,98,98,77,
|
||||
105,110,79,114,103,0,109,95,97,97,98,98,77,97,120,79,114,103,0,109,
|
||||
95,101,115,99,97,112,101,73,110,100,101,120,0,109,95,115,117,98,80,97,
|
||||
114,116,0,109,95,116,114,105,97,110,103,108,101,73,110,100,101,120,0,109,
|
||||
95,112,97,100,91,52,93,0,109,95,101,115,99,97,112,101,73,110,100,101,
|
||||
120,79,114,84,114,105,97,110,103,108,101,73,110,100,101,120,0,109,95,98,
|
||||
118,104,65,97,98,98,77,105,110,0,109,95,98,118,104,65,97,98,98,77,
|
||||
97,120,0,109,95,98,118,104,81,117,97,110,116,105,122,97,116,105,111,110,
|
||||
0,109,95,99,117,114,78,111,100,101,73,110,100,101,120,0,109,95,117,115,
|
||||
101,81,117,97,110,116,105,122,97,116,105,111,110,0,109,95,110,117,109,67,
|
||||
111,110,116,105,103,117,111,117,115,76,101,97,102,78,111,100,101,115,0,109,
|
||||
95,110,117,109,81,117,97,110,116,105,122,101,100,67,111,110,116,105,103,117,
|
||||
111,117,115,78,111,100,101,115,0,42,109,95,99,111,110,116,105,103,117,111,
|
||||
117,115,78,111,100,101,115,80,116,114,0,42,109,95,113,117,97,110,116,105,
|
||||
122,101,100,67,111,110,116,105,103,117,111,117,115,78,111,100,101,115,80,116,
|
||||
114,0,42,109,95,115,117,98,84,114,101,101,73,110,102,111,80,116,114,0,
|
||||
109,95,116,114,97,118,101,114,115,97,108,77,111,100,101,0,109,95,110,117,
|
||||
109,83,117,98,116,114,101,101,72,101,97,100,101,114,115,0,42,109,95,110,
|
||||
97,109,101,0,109,95,115,104,97,112,101,84,121,112,101,0,109,95,112,97,
|
||||
100,100,105,110,103,91,52,93,0,109,95,99,111,108,108,105,115,105,111,110,
|
||||
83,104,97,112,101,68,97,116,97,0,109,95,108,111,99,97,108,83,99,97,
|
||||
108,105,110,103,0,109,95,112,108,97,110,101,78,111,114,109,97,108,0,109,
|
||||
95,112,108,97,110,101,67,111,110,115,116,97,110,116,0,109,95,105,109,112,
|
||||
108,105,99,105,116,83,104,97,112,101,68,105,109,101,110,115,105,111,110,115,
|
||||
0,109,95,99,111,108,108,105,115,105,111,110,77,97,114,103,105,110,0,109,
|
||||
95,112,97,100,100,105,110,103,0,109,95,112,111,115,0,109,95,114,97,100,
|
||||
105,117,115,0,109,95,99,111,110,118,101,120,73,110,116,101,114,110,97,108,
|
||||
83,104,97,112,101,68,97,116,97,0,42,109,95,108,111,99,97,108,80,111,
|
||||
115,105,116,105,111,110,65,114,114,97,121,80,116,114,0,109,95,108,111,99,
|
||||
97,108,80,111,115,105,116,105,111,110,65,114,114,97,121,83,105,122,101,0,
|
||||
109,95,118,97,108,117,101,0,109,95,112,97,100,91,50,93,0,109,95,118,
|
||||
97,108,117,101,115,91,51,93,0,42,109,95,118,101,114,116,105,99,101,115,
|
||||
51,102,0,42,109,95,118,101,114,116,105,99,101,115,51,100,0,42,109,95,
|
||||
105,110,100,105,99,101,115,51,50,0,42,109,95,51,105,110,100,105,99,101,
|
||||
115,49,54,0,42,109,95,105,110,100,105,99,101,115,49,54,0,109,95,110,
|
||||
117,109,84,114,105,97,110,103,108,101,115,0,109,95,110,117,109,86,101,114,
|
||||
116,105,99,101,115,0,42,109,95,109,101,115,104,80,97,114,116,115,80,116,
|
||||
114,0,109,95,115,99,97,108,105,110,103,0,109,95,110,117,109,77,101,115,
|
||||
104,80,97,114,116,115,0,109,95,109,101,115,104,73,110,116,101,114,102,97,
|
||||
99,101,0,42,109,95,113,117,97,110,116,105,122,101,100,70,108,111,97,116,
|
||||
66,118,104,0,42,109,95,113,117,97,110,116,105,122,101,100,68,111,117,98,
|
||||
108,101,66,118,104,0,42,109,95,116,114,105,97,110,103,108,101,73,110,102,
|
||||
111,77,97,112,0,109,95,112,97,100,51,91,52,93,0,109,95,116,114,97,
|
||||
110,115,102,111,114,109,0,42,109,95,99,104,105,108,100,83,104,97,112,101,
|
||||
0,109,95,99,104,105,108,100,83,104,97,112,101,84,121,112,101,0,109,95,
|
||||
99,104,105,108,100,77,97,114,103,105,110,0,42,109,95,99,104,105,108,100,
|
||||
83,104,97,112,101,80,116,114,0,109,95,110,117,109,67,104,105,108,100,83,
|
||||
104,97,112,101,115,0,109,95,117,112,65,120,105,115,0,109,95,102,108,97,
|
||||
103,115,0,109,95,101,100,103,101,86,48,86,49,65,110,103,108,101,0,109,
|
||||
95,101,100,103,101,86,49,86,50,65,110,103,108,101,0,109,95,101,100,103,
|
||||
101,86,50,86,48,65,110,103,108,101,0,42,109,95,104,97,115,104,84,97,
|
||||
98,108,101,80,116,114,0,42,109,95,110,101,120,116,80,116,114,0,42,109,
|
||||
95,118,97,108,117,101,65,114,114,97,121,80,116,114,0,42,109,95,107,101,
|
||||
121,65,114,114,97,121,80,116,114,0,109,95,99,111,110,118,101,120,69,112,
|
||||
115,105,108,111,110,0,109,95,112,108,97,110,97,114,69,112,115,105,108,111,
|
||||
110,0,109,95,101,113,117,97,108,86,101,114,116,101,120,84,104,114,101,115,
|
||||
104,111,108,100,0,109,95,101,100,103,101,68,105,115,116,97,110,99,101,84,
|
||||
104,114,101,115,104,111,108,100,0,109,95,122,101,114,111,65,114,101,97,84,
|
||||
104,114,101,115,104,111,108,100,0,109,95,110,101,120,116,83,105,122,101,0,
|
||||
109,95,104,97,115,104,84,97,98,108,101,83,105,122,101,0,109,95,110,117,
|
||||
109,86,97,108,117,101,115,0,109,95,110,117,109,75,101,121,115,0,109,95,
|
||||
103,105,109,112,97,99,116,83,117,98,84,121,112,101,0,42,109,95,117,110,
|
||||
115,99,97,108,101,100,80,111,105,110,116,115,70,108,111,97,116,80,116,114,
|
||||
0,42,109,95,117,110,115,99,97,108,101,100,80,111,105,110,116,115,68,111,
|
||||
117,98,108,101,80,116,114,0,109,95,110,117,109,85,110,115,99,97,108,101,
|
||||
100,80,111,105,110,116,115,0,109,95,112,97,100,100,105,110,103,51,91,52,
|
||||
93,0,42,109,95,98,114,111,97,100,112,104,97,115,101,72,97,110,100,108,
|
||||
101,0,42,109,95,99,111,108,108,105,115,105,111,110,83,104,97,112,101,0,
|
||||
42,109,95,114,111,111,116,67,111,108,108,105,115,105,111,110,83,104,97,112,
|
||||
101,0,109,95,119,111,114,108,100,84,114,97,110,115,102,111,114,109,0,109,
|
||||
95,105,110,116,101,114,112,111,108,97,116,105,111,110,87,111,114,108,100,84,
|
||||
114,97,110,115,102,111,114,109,0,109,95,105,110,116,101,114,112,111,108,97,
|
||||
116,105,111,110,76,105,110,101,97,114,86,101,108,111,99,105,116,121,0,109,
|
||||
95,105,110,116,101,114,112,111,108,97,116,105,111,110,65,110,103,117,108,97,
|
||||
114,86,101,108,111,99,105,116,121,0,109,95,97,110,105,115,111,116,114,111,
|
||||
112,105,99,70,114,105,99,116,105,111,110,0,109,95,99,111,110,116,97,99,
|
||||
116,80,114,111,99,101,115,115,105,110,103,84,104,114,101,115,104,111,108,100,
|
||||
0,109,95,100,101,97,99,116,105,118,97,116,105,111,110,84,105,109,101,0,
|
||||
109,95,102,114,105,99,116,105,111,110,0,109,95,114,101,115,116,105,116,117,
|
||||
116,105,111,110,0,109,95,104,105,116,70,114,97,99,116,105,111,110,0,109,
|
||||
95,99,99,100,83,119,101,112,116,83,112,104,101,114,101,82,97,100,105,117,
|
||||
115,0,109,95,99,99,100,77,111,116,105,111,110,84,104,114,101,115,104,111,
|
||||
108,100,0,109,95,104,97,115,65,110,105,115,111,116,114,111,112,105,99,70,
|
||||
114,105,99,116,105,111,110,0,109,95,99,111,108,108,105,115,105,111,110,70,
|
||||
108,97,103,115,0,109,95,105,115,108,97,110,100,84,97,103,49,0,109,95,
|
||||
99,111,109,112,97,110,105,111,110,73,100,0,109,95,97,99,116,105,118,97,
|
||||
116,105,111,110,83,116,97,116,101,49,0,109,95,105,110,116,101,114,110,97,
|
||||
108,84,121,112,101,0,109,95,99,104,101,99,107,67,111,108,108,105,100,101,
|
||||
87,105,116,104,0,109,95,99,111,108,108,105,115,105,111,110,79,98,106,101,
|
||||
99,116,68,97,116,97,0,109,95,105,110,118,73,110,101,114,116,105,97,84,
|
||||
101,110,115,111,114,87,111,114,108,100,0,109,95,108,105,110,101,97,114,86,
|
||||
101,108,111,99,105,116,121,0,109,95,97,110,103,117,108,97,114,86,101,108,
|
||||
111,99,105,116,121,0,109,95,97,110,103,117,108,97,114,70,97,99,116,111,
|
||||
114,0,109,95,108,105,110,101,97,114,70,97,99,116,111,114,0,109,95,103,
|
||||
114,97,118,105,116,121,0,109,95,103,114,97,118,105,116,121,95,97,99,99,
|
||||
101,108,101,114,97,116,105,111,110,0,109,95,105,110,118,73,110,101,114,116,
|
||||
105,97,76,111,99,97,108,0,109,95,116,111,116,97,108,70,111,114,99,101,
|
||||
0,109,95,116,111,116,97,108,84,111,114,113,117,101,0,109,95,105,110,118,
|
||||
101,114,115,101,77,97,115,115,0,109,95,108,105,110,101,97,114,68,97,109,
|
||||
112,105,110,103,0,109,95,97,110,103,117,108,97,114,68,97,109,112,105,110,
|
||||
103,0,109,95,97,100,100,105,116,105,111,110,97,108,68,97,109,112,105,110,
|
||||
103,70,97,99,116,111,114,0,109,95,97,100,100,105,116,105,111,110,97,108,
|
||||
76,105,110,101,97,114,68,97,109,112,105,110,103,84,104,114,101,115,104,111,
|
||||
108,100,83,113,114,0,109,95,97,100,100,105,116,105,111,110,97,108,65,110,
|
||||
103,117,108,97,114,68,97,109,112,105,110,103,84,104,114,101,115,104,111,108,
|
||||
100,83,113,114,0,109,95,97,100,100,105,116,105,111,110,97,108,65,110,103,
|
||||
117,108,97,114,68,97,109,112,105,110,103,70,97,99,116,111,114,0,109,95,
|
||||
108,105,110,101,97,114,83,108,101,101,112,105,110,103,84,104,114,101,115,104,
|
||||
111,108,100,0,109,95,97,110,103,117,108,97,114,83,108,101,101,112,105,110,
|
||||
103,84,104,114,101,115,104,111,108,100,0,109,95,97,100,100,105,116,105,111,
|
||||
110,97,108,68,97,109,112,105,110,103,0,109,95,110,117,109,67,111,110,115,
|
||||
116,114,97,105,110,116,82,111,119,115,0,110,117,98,0,42,109,95,114,98,
|
||||
65,0,42,109,95,114,98,66,0,109,95,111,98,106,101,99,116,84,121,112,
|
||||
101,0,109,95,117,115,101,114,67,111,110,115,116,114,97,105,110,116,84,121,
|
||||
112,101,0,109,95,117,115,101,114,67,111,110,115,116,114,97,105,110,116,73,
|
||||
100,0,109,95,110,101,101,100,115,70,101,101,100,98,97,99,107,0,109,95,
|
||||
97,112,112,108,105,101,100,73,109,112,117,108,115,101,0,109,95,100,98,103,
|
||||
68,114,97,119,83,105,122,101,0,109,95,100,105,115,97,98,108,101,67,111,
|
||||
108,108,105,115,105,111,110,115,66,101,116,119,101,101,110,76,105,110,107,101,
|
||||
100,66,111,100,105,101,115,0,109,95,112,97,100,52,91,52,93,0,109,95,
|
||||
116,121,112,101,67,111,110,115,116,114,97,105,110,116,68,97,116,97,0,109,
|
||||
95,112,105,118,111,116,73,110,65,0,109,95,112,105,118,111,116,73,110,66,
|
||||
0,109,95,114,98,65,70,114,97,109,101,0,109,95,114,98,66,70,114,97,
|
||||
109,101,0,109,95,117,115,101,82,101,102,101,114,101,110,99,101,70,114,97,
|
||||
109,101,65,0,109,95,97,110,103,117,108,97,114,79,110,108,121,0,109,95,
|
||||
101,110,97,98,108,101,65,110,103,117,108,97,114,77,111,116,111,114,0,109,
|
||||
95,109,111,116,111,114,84,97,114,103,101,116,86,101,108,111,99,105,116,121,
|
||||
0,109,95,109,97,120,77,111,116,111,114,73,109,112,117,108,115,101,0,109,
|
||||
95,108,111,119,101,114,76,105,109,105,116,0,109,95,117,112,112,101,114,76,
|
||||
105,109,105,116,0,109,95,108,105,109,105,116,83,111,102,116,110,101,115,115,
|
||||
0,109,95,98,105,97,115,70,97,99,116,111,114,0,109,95,114,101,108,97,
|
||||
120,97,116,105,111,110,70,97,99,116,111,114,0,109,95,115,119,105,110,103,
|
||||
83,112,97,110,49,0,109,95,115,119,105,110,103,83,112,97,110,50,0,109,
|
||||
95,116,119,105,115,116,83,112,97,110,0,109,95,100,97,109,112,105,110,103,
|
||||
0,109,95,108,105,110,101,97,114,85,112,112,101,114,76,105,109,105,116,0,
|
||||
109,95,108,105,110,101,97,114,76,111,119,101,114,76,105,109,105,116,0,109,
|
||||
95,97,110,103,117,108,97,114,85,112,112,101,114,76,105,109,105,116,0,109,
|
||||
95,97,110,103,117,108,97,114,76,111,119,101,114,76,105,109,105,116,0,109,
|
||||
95,117,115,101,76,105,110,101,97,114,82,101,102,101,114,101,110,99,101,70,
|
||||
114,97,109,101,65,0,109,95,117,115,101,79,102,102,115,101,116,70,111,114,
|
||||
67,111,110,115,116,114,97,105,110,116,70,114,97,109,101,0,84,89,80,69,
|
||||
58,0,0,0,99,104,97,114,0,117,99,104,97,114,0,115,104,111,114,116,
|
||||
0,117,115,104,111,114,116,0,105,110,116,0,108,111,110,103,0,117,108,111,
|
||||
110,103,0,102,108,111,97,116,0,100,111,117,98,108,101,0,118,111,105,100,
|
||||
0,80,111,105,110,116,101,114,65,114,114,97,121,0,98,116,80,104,121,115,
|
||||
105,99,115,83,121,115,116,101,109,0,76,105,115,116,66,97,115,101,0,98,
|
||||
116,86,101,99,116,111,114,51,70,108,111,97,116,68,97,116,97,0,98,116,
|
||||
86,101,99,116,111,114,51,68,111,117,98,108,101,68,97,116,97,0,98,116,
|
||||
77,97,116,114,105,120,51,120,51,70,108,111,97,116,68,97,116,97,0,98,
|
||||
116,77,97,116,114,105,120,51,120,51,68,111,117,98,108,101,68,97,116,97,
|
||||
0,98,116,84,114,97,110,115,102,111,114,109,70,108,111,97,116,68,97,116,
|
||||
97,0,98,116,84,114,97,110,115,102,111,114,109,68,111,117,98,108,101,68,
|
||||
97,116,97,0,98,116,66,118,104,83,117,98,116,114,101,101,73,110,102,111,
|
||||
68,97,116,97,0,98,116,79,112,116,105,109,105,122,101,100,66,118,104,78,
|
||||
111,100,101,70,108,111,97,116,68,97,116,97,0,98,116,79,112,116,105,109,
|
||||
105,122,101,100,66,118,104,78,111,100,101,68,111,117,98,108,101,68,97,116,
|
||||
97,0,98,116,81,117,97,110,116,105,122,101,100,66,118,104,78,111,100,101,
|
||||
68,97,116,97,0,98,116,81,117,97,110,116,105,122,101,100,66,118,104,70,
|
||||
108,111,97,116,68,97,116,97,0,98,116,81,117,97,110,116,105,122,101,100,
|
||||
66,118,104,68,111,117,98,108,101,68,97,116,97,0,98,116,67,111,108,108,
|
||||
105,115,105,111,110,83,104,97,112,101,68,97,116,97,0,98,116,83,116,97,
|
||||
116,105,99,80,108,97,110,101,83,104,97,112,101,68,97,116,97,0,98,116,
|
||||
67,111,110,118,101,120,73,110,116,101,114,110,97,108,83,104,97,112,101,68,
|
||||
97,116,97,0,98,116,80,111,115,105,116,105,111,110,65,110,100,82,97,100,
|
||||
105,117,115,0,98,116,77,117,108,116,105,83,112,104,101,114,101,83,104,97,
|
||||
112,101,68,97,116,97,0,98,116,73,110,116,73,110,100,101,120,68,97,116,
|
||||
97,0,98,116,83,104,111,114,116,73,110,116,73,110,100,101,120,68,97,116,
|
||||
97,0,98,116,83,104,111,114,116,73,110,116,73,110,100,101,120,84,114,105,
|
||||
112,108,101,116,68,97,116,97,0,98,116,77,101,115,104,80,97,114,116,68,
|
||||
97,116,97,0,98,116,83,116,114,105,100,105,110,103,77,101,115,104,73,110,
|
||||
116,101,114,102,97,99,101,68,97,116,97,0,98,116,84,114,105,97,110,103,
|
||||
108,101,77,101,115,104,83,104,97,112,101,68,97,116,97,0,98,116,84,114,
|
||||
105,97,110,103,108,101,73,110,102,111,77,97,112,68,97,116,97,0,98,116,
|
||||
67,111,109,112,111,117,110,100,83,104,97,112,101,67,104,105,108,100,68,97,
|
||||
116,97,0,98,116,67,111,109,112,111,117,110,100,83,104,97,112,101,68,97,
|
||||
116,97,0,98,116,67,121,108,105,110,100,101,114,83,104,97,112,101,68,97,
|
||||
116,97,0,98,116,67,97,112,115,117,108,101,83,104,97,112,101,68,97,116,
|
||||
97,0,98,116,84,114,105,97,110,103,108,101,73,110,102,111,68,97,116,97,
|
||||
0,98,116,71,73,109,112,97,99,116,77,101,115,104,83,104,97,112,101,68,
|
||||
97,116,97,0,98,116,67,111,110,118,101,120,72,117,108,108,83,104,97,112,
|
||||
101,68,97,116,97,0,98,116,67,111,108,108,105,115,105,111,110,79,98,106,
|
||||
101,99,116,68,111,117,98,108,101,68,97,116,97,0,98,116,67,111,108,108,
|
||||
105,115,105,111,110,79,98,106,101,99,116,70,108,111,97,116,68,97,116,97,
|
||||
0,98,116,82,105,103,105,100,66,111,100,121,70,108,111,97,116,68,97,116,
|
||||
97,0,98,116,82,105,103,105,100,66,111,100,121,68,111,117,98,108,101,68,
|
||||
97,116,97,0,98,116,67,111,110,115,116,114,97,105,110,116,73,110,102,111,
|
||||
49,0,98,116,84,121,112,101,100,67,111,110,115,116,114,97,105,110,116,68,
|
||||
97,116,97,0,98,116,82,105,103,105,100,66,111,100,121,68,97,116,97,0,
|
||||
98,116,80,111,105,110,116,50,80,111,105,110,116,67,111,110,115,116,114,97,
|
||||
105,110,116,70,108,111,97,116,68,97,116,97,0,98,116,80,111,105,110,116,
|
||||
50,80,111,105,110,116,67,111,110,115,116,114,97,105,110,116,68,111,117,98,
|
||||
108,101,68,97,116,97,0,98,116,72,105,110,103,101,67,111,110,115,116,114,
|
||||
97,105,110,116,68,111,117,98,108,101,68,97,116,97,0,98,116,72,105,110,
|
||||
103,101,67,111,110,115,116,114,97,105,110,116,70,108,111,97,116,68,97,116,
|
||||
97,0,98,116,67,111,110,101,84,119,105,115,116,67,111,110,115,116,114,97,
|
||||
105,110,116,68,97,116,97,0,98,116,71,101,110,101,114,105,99,54,68,111,
|
||||
102,67,111,110,115,116,114,97,105,110,116,68,97,116,97,0,98,116,83,108,
|
||||
105,100,101,114,67,111,110,115,116,114,97,105,110,116,68,97,116,97,0,0,
|
||||
84,76,69,78,1,0,1,0,2,0,2,0,4,0,4,0,4,0,4,0,
|
||||
8,0,0,0,16,0,48,0,16,0,16,0,32,0,48,0,96,0,64,0,
|
||||
-128,0,20,0,48,0,80,0,16,0,96,0,-112,0,16,0,56,0,56,0,
|
||||
20,0,72,0,4,0,4,0,8,0,48,0,32,0,80,0,72,0,80,0,
|
||||
32,0,64,0,64,0,16,0,72,0,80,0,-40,1,8,1,-16,1,-88,3,
|
||||
8,0,56,0,0,0,88,0,120,0,96,1,-32,0,-40,0,0,1,-48,0,
|
||||
83,84,82,67,47,0,0,0,10,0,3,0,4,0,0,0,4,0,1,0,
|
||||
9,0,2,0,11,0,3,0,10,0,3,0,10,0,4,0,10,0,5,0,
|
||||
12,0,2,0,9,0,6,0,9,0,7,0,13,0,1,0,7,0,8,0,
|
||||
14,0,1,0,8,0,8,0,15,0,1,0,13,0,9,0,16,0,1,0,
|
||||
14,0,9,0,17,0,2,0,15,0,10,0,13,0,11,0,18,0,2,0,
|
||||
16,0,10,0,14,0,11,0,19,0,4,0,4,0,12,0,4,0,13,0,
|
||||
2,0,14,0,2,0,15,0,20,0,6,0,13,0,16,0,13,0,17,0,
|
||||
4,0,18,0,4,0,19,0,4,0,20,0,0,0,21,0,21,0,6,0,
|
||||
14,0,16,0,14,0,17,0,4,0,18,0,4,0,19,0,4,0,20,0,
|
||||
0,0,21,0,22,0,3,0,2,0,14,0,2,0,15,0,4,0,22,0,
|
||||
23,0,12,0,13,0,23,0,13,0,24,0,13,0,25,0,4,0,26,0,
|
||||
4,0,27,0,4,0,28,0,4,0,29,0,20,0,30,0,22,0,31,0,
|
||||
19,0,32,0,4,0,33,0,4,0,34,0,24,0,12,0,14,0,23,0,
|
||||
14,0,24,0,14,0,25,0,4,0,26,0,4,0,27,0,4,0,28,0,
|
||||
4,0,29,0,21,0,30,0,22,0,31,0,4,0,33,0,4,0,34,0,
|
||||
19,0,32,0,25,0,3,0,0,0,35,0,4,0,36,0,0,0,37,0,
|
||||
26,0,5,0,25,0,38,0,13,0,39,0,13,0,40,0,7,0,41,0,
|
||||
0,0,21,0,27,0,5,0,25,0,38,0,13,0,39,0,13,0,42,0,
|
||||
7,0,43,0,4,0,44,0,28,0,2,0,13,0,45,0,7,0,46,0,
|
||||
29,0,4,0,27,0,47,0,28,0,48,0,4,0,49,0,0,0,37,0,
|
||||
30,0,1,0,4,0,50,0,31,0,2,0,2,0,50,0,0,0,51,0,
|
||||
32,0,2,0,2,0,52,0,0,0,51,0,33,0,7,0,13,0,53,0,
|
||||
14,0,54,0,30,0,55,0,32,0,56,0,31,0,57,0,4,0,58,0,
|
||||
4,0,59,0,34,0,4,0,33,0,60,0,13,0,61,0,4,0,62,0,
|
||||
0,0,37,0,35,0,7,0,25,0,38,0,34,0,63,0,23,0,64,0,
|
||||
24,0,65,0,36,0,66,0,7,0,43,0,0,0,67,0,37,0,4,0,
|
||||
17,0,68,0,25,0,69,0,4,0,70,0,7,0,71,0,38,0,4,0,
|
||||
25,0,38,0,37,0,72,0,4,0,73,0,7,0,43,0,39,0,3,0,
|
||||
27,0,47,0,4,0,74,0,0,0,37,0,40,0,3,0,27,0,47,0,
|
||||
4,0,74,0,0,0,37,0,41,0,4,0,4,0,75,0,7,0,76,0,
|
||||
7,0,77,0,7,0,78,0,36,0,14,0,4,0,79,0,4,0,80,0,
|
||||
41,0,81,0,4,0,82,0,7,0,83,0,7,0,84,0,7,0,85,0,
|
||||
7,0,86,0,7,0,87,0,4,0,88,0,4,0,89,0,4,0,90,0,
|
||||
4,0,91,0,0,0,37,0,42,0,5,0,25,0,38,0,34,0,63,0,
|
||||
13,0,39,0,7,0,43,0,4,0,92,0,43,0,5,0,27,0,47,0,
|
||||
13,0,93,0,14,0,94,0,4,0,95,0,0,0,96,0,44,0,24,0,
|
||||
9,0,97,0,9,0,98,0,25,0,99,0,0,0,35,0,18,0,100,0,
|
||||
18,0,101,0,14,0,102,0,14,0,103,0,14,0,104,0,8,0,105,0,
|
||||
8,0,106,0,8,0,107,0,8,0,108,0,8,0,109,0,8,0,110,0,
|
||||
8,0,111,0,4,0,112,0,4,0,113,0,4,0,114,0,4,0,115,0,
|
||||
4,0,116,0,4,0,117,0,4,0,118,0,0,0,37,0,45,0,23,0,
|
||||
9,0,97,0,9,0,98,0,25,0,99,0,0,0,35,0,17,0,100,0,
|
||||
17,0,101,0,13,0,102,0,13,0,103,0,13,0,104,0,7,0,105,0,
|
||||
7,0,106,0,7,0,107,0,7,0,108,0,7,0,109,0,7,0,110,0,
|
||||
7,0,111,0,4,0,112,0,4,0,113,0,4,0,114,0,4,0,115,0,
|
||||
4,0,116,0,4,0,117,0,4,0,118,0,46,0,21,0,45,0,119,0,
|
||||
15,0,120,0,13,0,121,0,13,0,122,0,13,0,123,0,13,0,124,0,
|
||||
13,0,125,0,13,0,126,0,13,0,127,0,13,0,-128,0,13,0,-127,0,
|
||||
7,0,-126,0,7,0,-125,0,7,0,-124,0,7,0,-123,0,7,0,-122,0,
|
||||
7,0,-121,0,7,0,-120,0,7,0,-119,0,7,0,-118,0,4,0,-117,0,
|
||||
47,0,22,0,44,0,119,0,16,0,120,0,14,0,121,0,14,0,122,0,
|
||||
14,0,123,0,14,0,124,0,14,0,125,0,14,0,126,0,14,0,127,0,
|
||||
14,0,-128,0,14,0,-127,0,8,0,-126,0,8,0,-125,0,8,0,-124,0,
|
||||
8,0,-123,0,8,0,-122,0,8,0,-121,0,8,0,-120,0,8,0,-119,0,
|
||||
8,0,-118,0,4,0,-117,0,0,0,37,0,48,0,2,0,4,0,-116,0,
|
||||
4,0,-115,0,49,0,11,0,50,0,-114,0,50,0,-113,0,0,0,35,0,
|
||||
4,0,-112,0,4,0,-111,0,4,0,-110,0,4,0,-109,0,7,0,-108,0,
|
||||
7,0,-107,0,4,0,-106,0,0,0,-105,0,51,0,3,0,49,0,-104,0,
|
||||
13,0,-103,0,13,0,-102,0,52,0,3,0,49,0,-104,0,14,0,-103,0,
|
||||
14,0,-102,0,53,0,13,0,49,0,-104,0,18,0,-101,0,18,0,-100,0,
|
||||
4,0,-99,0,4,0,-98,0,4,0,-97,0,7,0,-96,0,7,0,-95,0,
|
||||
7,0,-94,0,7,0,-93,0,7,0,-92,0,7,0,-91,0,7,0,-90,0,
|
||||
54,0,13,0,49,0,-104,0,17,0,-101,0,17,0,-100,0,4,0,-99,0,
|
||||
4,0,-98,0,4,0,-97,0,7,0,-96,0,7,0,-95,0,7,0,-94,0,
|
||||
7,0,-93,0,7,0,-92,0,7,0,-91,0,7,0,-90,0,55,0,11,0,
|
||||
49,0,-104,0,17,0,-101,0,17,0,-100,0,7,0,-89,0,7,0,-88,0,
|
||||
7,0,-87,0,7,0,-92,0,7,0,-91,0,7,0,-90,0,7,0,-86,0,
|
||||
0,0,21,0,56,0,9,0,49,0,-104,0,17,0,-101,0,17,0,-100,0,
|
||||
13,0,-85,0,13,0,-84,0,13,0,-83,0,13,0,-82,0,4,0,-81,0,
|
||||
4,0,-80,0,57,0,9,0,49,0,-104,0,17,0,-101,0,17,0,-100,0,
|
||||
7,0,-85,0,7,0,-84,0,7,0,-83,0,7,0,-82,0,4,0,-81,0,
|
||||
4,0,-80,0,};
|
||||
int sBulletDNAlen64= sizeof(sBulletDNAstr64);
|
||||
|
||||
unsigned char sBulletDNAstr[]= {
|
||||
83,68,78,65,78,65,77,69,-79,0,0,0,109,95,115,105,122,101,0,109,
|
||||
95,99,97,112,97,99,105,116,121,0,42,109,95,100,97,116,97,0,109,95,
|
||||
99,111,108,108,105,115,105,111,110,83,104,97,112,101,115,0,109,95,99,111,
|
||||
108,108,105,115,105,111,110,79,98,106,101,99,116,115,0,109,95,99,111,110,
|
||||
115,116,114,97,105,110,116,115,0,42,102,105,114,115,116,0,42,108,97,115,
|
||||
116,0,109,95,102,108,111,97,116,115,91,52,93,0,109,95,101,108,91,51,
|
||||
93,0,109,95,98,97,115,105,115,0,109,95,111,114,105,103,105,110,0,109,
|
||||
95,114,111,111,116,78,111,100,101,73,110,100,101,120,0,109,95,115,117,98,
|
||||
116,114,101,101,83,105,122,101,0,109,95,113,117,97,110,116,105,122,101,100,
|
||||
65,97,98,98,77,105,110,91,51,93,0,109,95,113,117,97,110,116,105,122,
|
||||
101,100,65,97,98,98,77,97,120,91,51,93,0,109,95,97,97,98,98,77,
|
||||
105,110,79,114,103,0,109,95,97,97,98,98,77,97,120,79,114,103,0,109,
|
||||
95,101,115,99,97,112,101,73,110,100,101,120,0,109,95,115,117,98,80,97,
|
||||
114,116,0,109,95,116,114,105,97,110,103,108,101,73,110,100,101,120,0,109,
|
||||
95,112,97,100,91,52,93,0,109,95,101,115,99,97,112,101,73,110,100,101,
|
||||
120,79,114,84,114,105,97,110,103,108,101,73,110,100,101,120,0,109,95,98,
|
||||
118,104,65,97,98,98,77,105,110,0,109,95,98,118,104,65,97,98,98,77,
|
||||
97,120,0,109,95,98,118,104,81,117,97,110,116,105,122,97,116,105,111,110,
|
||||
0,109,95,99,117,114,78,111,100,101,73,110,100,101,120,0,109,95,117,115,
|
||||
101,81,117,97,110,116,105,122,97,116,105,111,110,0,109,95,110,117,109,67,
|
||||
111,110,116,105,103,117,111,117,115,76,101,97,102,78,111,100,101,115,0,109,
|
||||
95,110,117,109,81,117,97,110,116,105,122,101,100,67,111,110,116,105,103,117,
|
||||
111,117,115,78,111,100,101,115,0,42,109,95,99,111,110,116,105,103,117,111,
|
||||
117,115,78,111,100,101,115,80,116,114,0,42,109,95,113,117,97,110,116,105,
|
||||
122,101,100,67,111,110,116,105,103,117,111,117,115,78,111,100,101,115,80,116,
|
||||
114,0,42,109,95,115,117,98,84,114,101,101,73,110,102,111,80,116,114,0,
|
||||
109,95,116,114,97,118,101,114,115,97,108,77,111,100,101,0,109,95,110,117,
|
||||
109,83,117,98,116,114,101,101,72,101,97,100,101,114,115,0,42,109,95,110,
|
||||
97,109,101,0,109,95,115,104,97,112,101,84,121,112,101,0,109,95,112,97,
|
||||
100,100,105,110,103,91,52,93,0,109,95,99,111,108,108,105,115,105,111,110,
|
||||
83,104,97,112,101,68,97,116,97,0,109,95,108,111,99,97,108,83,99,97,
|
||||
108,105,110,103,0,109,95,112,108,97,110,101,78,111,114,109,97,108,0,109,
|
||||
95,112,108,97,110,101,67,111,110,115,116,97,110,116,0,109,95,105,109,112,
|
||||
108,105,99,105,116,83,104,97,112,101,68,105,109,101,110,115,105,111,110,115,
|
||||
0,109,95,99,111,108,108,105,115,105,111,110,77,97,114,103,105,110,0,109,
|
||||
95,112,97,100,100,105,110,103,0,109,95,112,111,115,0,109,95,114,97,100,
|
||||
105,117,115,0,109,95,99,111,110,118,101,120,73,110,116,101,114,110,97,108,
|
||||
83,104,97,112,101,68,97,116,97,0,42,109,95,108,111,99,97,108,80,111,
|
||||
115,105,116,105,111,110,65,114,114,97,121,80,116,114,0,109,95,108,111,99,
|
||||
97,108,80,111,115,105,116,105,111,110,65,114,114,97,121,83,105,122,101,0,
|
||||
109,95,118,97,108,117,101,0,109,95,112,97,100,91,50,93,0,109,95,118,
|
||||
97,108,117,101,115,91,51,93,0,42,109,95,118,101,114,116,105,99,101,115,
|
||||
51,102,0,42,109,95,118,101,114,116,105,99,101,115,51,100,0,42,109,95,
|
||||
105,110,100,105,99,101,115,51,50,0,42,109,95,51,105,110,100,105,99,101,
|
||||
115,49,54,0,42,109,95,105,110,100,105,99,101,115,49,54,0,109,95,110,
|
||||
117,109,84,114,105,97,110,103,108,101,115,0,109,95,110,117,109,86,101,114,
|
||||
116,105,99,101,115,0,42,109,95,109,101,115,104,80,97,114,116,115,80,116,
|
||||
114,0,109,95,115,99,97,108,105,110,103,0,109,95,110,117,109,77,101,115,
|
||||
104,80,97,114,116,115,0,109,95,109,101,115,104,73,110,116,101,114,102,97,
|
||||
99,101,0,42,109,95,113,117,97,110,116,105,122,101,100,70,108,111,97,116,
|
||||
66,118,104,0,42,109,95,113,117,97,110,116,105,122,101,100,68,111,117,98,
|
||||
108,101,66,118,104,0,42,109,95,116,114,105,97,110,103,108,101,73,110,102,
|
||||
111,77,97,112,0,109,95,112,97,100,51,91,52,93,0,109,95,116,114,97,
|
||||
110,115,102,111,114,109,0,42,109,95,99,104,105,108,100,83,104,97,112,101,
|
||||
0,109,95,99,104,105,108,100,83,104,97,112,101,84,121,112,101,0,109,95,
|
||||
99,104,105,108,100,77,97,114,103,105,110,0,42,109,95,99,104,105,108,100,
|
||||
83,104,97,112,101,80,116,114,0,109,95,110,117,109,67,104,105,108,100,83,
|
||||
104,97,112,101,115,0,109,95,117,112,65,120,105,115,0,109,95,102,108,97,
|
||||
103,115,0,109,95,101,100,103,101,86,48,86,49,65,110,103,108,101,0,109,
|
||||
95,101,100,103,101,86,49,86,50,65,110,103,108,101,0,109,95,101,100,103,
|
||||
101,86,50,86,48,65,110,103,108,101,0,42,109,95,104,97,115,104,84,97,
|
||||
98,108,101,80,116,114,0,42,109,95,110,101,120,116,80,116,114,0,42,109,
|
||||
95,118,97,108,117,101,65,114,114,97,121,80,116,114,0,42,109,95,107,101,
|
||||
121,65,114,114,97,121,80,116,114,0,109,95,99,111,110,118,101,120,69,112,
|
||||
115,105,108,111,110,0,109,95,112,108,97,110,97,114,69,112,115,105,108,111,
|
||||
110,0,109,95,101,113,117,97,108,86,101,114,116,101,120,84,104,114,101,115,
|
||||
104,111,108,100,0,109,95,101,100,103,101,68,105,115,116,97,110,99,101,84,
|
||||
104,114,101,115,104,111,108,100,0,109,95,122,101,114,111,65,114,101,97,84,
|
||||
104,114,101,115,104,111,108,100,0,109,95,110,101,120,116,83,105,122,101,0,
|
||||
109,95,104,97,115,104,84,97,98,108,101,83,105,122,101,0,109,95,110,117,
|
||||
109,86,97,108,117,101,115,0,109,95,110,117,109,75,101,121,115,0,109,95,
|
||||
103,105,109,112,97,99,116,83,117,98,84,121,112,101,0,42,109,95,117,110,
|
||||
115,99,97,108,101,100,80,111,105,110,116,115,70,108,111,97,116,80,116,114,
|
||||
0,42,109,95,117,110,115,99,97,108,101,100,80,111,105,110,116,115,68,111,
|
||||
117,98,108,101,80,116,114,0,109,95,110,117,109,85,110,115,99,97,108,101,
|
||||
100,80,111,105,110,116,115,0,109,95,112,97,100,100,105,110,103,51,91,52,
|
||||
93,0,42,109,95,98,114,111,97,100,112,104,97,115,101,72,97,110,100,108,
|
||||
101,0,42,109,95,99,111,108,108,105,115,105,111,110,83,104,97,112,101,0,
|
||||
42,109,95,114,111,111,116,67,111,108,108,105,115,105,111,110,83,104,97,112,
|
||||
101,0,109,95,119,111,114,108,100,84,114,97,110,115,102,111,114,109,0,109,
|
||||
95,105,110,116,101,114,112,111,108,97,116,105,111,110,87,111,114,108,100,84,
|
||||
114,97,110,115,102,111,114,109,0,109,95,105,110,116,101,114,112,111,108,97,
|
||||
116,105,111,110,76,105,110,101,97,114,86,101,108,111,99,105,116,121,0,109,
|
||||
95,105,110,116,101,114,112,111,108,97,116,105,111,110,65,110,103,117,108,97,
|
||||
114,86,101,108,111,99,105,116,121,0,109,95,97,110,105,115,111,116,114,111,
|
||||
112,105,99,70,114,105,99,116,105,111,110,0,109,95,99,111,110,116,97,99,
|
||||
116,80,114,111,99,101,115,115,105,110,103,84,104,114,101,115,104,111,108,100,
|
||||
0,109,95,100,101,97,99,116,105,118,97,116,105,111,110,84,105,109,101,0,
|
||||
109,95,102,114,105,99,116,105,111,110,0,109,95,114,101,115,116,105,116,117,
|
||||
116,105,111,110,0,109,95,104,105,116,70,114,97,99,116,105,111,110,0,109,
|
||||
95,99,99,100,83,119,101,112,116,83,112,104,101,114,101,82,97,100,105,117,
|
||||
115,0,109,95,99,99,100,77,111,116,105,111,110,84,104,114,101,115,104,111,
|
||||
108,100,0,109,95,104,97,115,65,110,105,115,111,116,114,111,112,105,99,70,
|
||||
114,105,99,116,105,111,110,0,109,95,99,111,108,108,105,115,105,111,110,70,
|
||||
108,97,103,115,0,109,95,105,115,108,97,110,100,84,97,103,49,0,109,95,
|
||||
99,111,109,112,97,110,105,111,110,73,100,0,109,95,97,99,116,105,118,97,
|
||||
116,105,111,110,83,116,97,116,101,49,0,109,95,105,110,116,101,114,110,97,
|
||||
108,84,121,112,101,0,109,95,99,104,101,99,107,67,111,108,108,105,100,101,
|
||||
87,105,116,104,0,109,95,99,111,108,108,105,115,105,111,110,79,98,106,101,
|
||||
99,116,68,97,116,97,0,109,95,105,110,118,73,110,101,114,116,105,97,84,
|
||||
101,110,115,111,114,87,111,114,108,100,0,109,95,108,105,110,101,97,114,86,
|
||||
101,108,111,99,105,116,121,0,109,95,97,110,103,117,108,97,114,86,101,108,
|
||||
111,99,105,116,121,0,109,95,97,110,103,117,108,97,114,70,97,99,116,111,
|
||||
114,0,109,95,108,105,110,101,97,114,70,97,99,116,111,114,0,109,95,103,
|
||||
114,97,118,105,116,121,0,109,95,103,114,97,118,105,116,121,95,97,99,99,
|
||||
101,108,101,114,97,116,105,111,110,0,109,95,105,110,118,73,110,101,114,116,
|
||||
105,97,76,111,99,97,108,0,109,95,116,111,116,97,108,70,111,114,99,101,
|
||||
0,109,95,116,111,116,97,108,84,111,114,113,117,101,0,109,95,105,110,118,
|
||||
101,114,115,101,77,97,115,115,0,109,95,108,105,110,101,97,114,68,97,109,
|
||||
112,105,110,103,0,109,95,97,110,103,117,108,97,114,68,97,109,112,105,110,
|
||||
103,0,109,95,97,100,100,105,116,105,111,110,97,108,68,97,109,112,105,110,
|
||||
103,70,97,99,116,111,114,0,109,95,97,100,100,105,116,105,111,110,97,108,
|
||||
76,105,110,101,97,114,68,97,109,112,105,110,103,84,104,114,101,115,104,111,
|
||||
108,100,83,113,114,0,109,95,97,100,100,105,116,105,111,110,97,108,65,110,
|
||||
103,117,108,97,114,68,97,109,112,105,110,103,84,104,114,101,115,104,111,108,
|
||||
100,83,113,114,0,109,95,97,100,100,105,116,105,111,110,97,108,65,110,103,
|
||||
117,108,97,114,68,97,109,112,105,110,103,70,97,99,116,111,114,0,109,95,
|
||||
108,105,110,101,97,114,83,108,101,101,112,105,110,103,84,104,114,101,115,104,
|
||||
111,108,100,0,109,95,97,110,103,117,108,97,114,83,108,101,101,112,105,110,
|
||||
103,84,104,114,101,115,104,111,108,100,0,109,95,97,100,100,105,116,105,111,
|
||||
110,97,108,68,97,109,112,105,110,103,0,109,95,110,117,109,67,111,110,115,
|
||||
116,114,97,105,110,116,82,111,119,115,0,110,117,98,0,42,109,95,114,98,
|
||||
65,0,42,109,95,114,98,66,0,109,95,111,98,106,101,99,116,84,121,112,
|
||||
101,0,109,95,117,115,101,114,67,111,110,115,116,114,97,105,110,116,84,121,
|
||||
112,101,0,109,95,117,115,101,114,67,111,110,115,116,114,97,105,110,116,73,
|
||||
100,0,109,95,110,101,101,100,115,70,101,101,100,98,97,99,107,0,109,95,
|
||||
97,112,112,108,105,101,100,73,109,112,117,108,115,101,0,109,95,100,98,103,
|
||||
68,114,97,119,83,105,122,101,0,109,95,100,105,115,97,98,108,101,67,111,
|
||||
108,108,105,115,105,111,110,115,66,101,116,119,101,101,110,76,105,110,107,101,
|
||||
100,66,111,100,105,101,115,0,109,95,112,97,100,52,91,52,93,0,109,95,
|
||||
116,121,112,101,67,111,110,115,116,114,97,105,110,116,68,97,116,97,0,109,
|
||||
95,112,105,118,111,116,73,110,65,0,109,95,112,105,118,111,116,73,110,66,
|
||||
0,109,95,114,98,65,70,114,97,109,101,0,109,95,114,98,66,70,114,97,
|
||||
109,101,0,109,95,117,115,101,82,101,102,101,114,101,110,99,101,70,114,97,
|
||||
109,101,65,0,109,95,97,110,103,117,108,97,114,79,110,108,121,0,109,95,
|
||||
101,110,97,98,108,101,65,110,103,117,108,97,114,77,111,116,111,114,0,109,
|
||||
95,109,111,116,111,114,84,97,114,103,101,116,86,101,108,111,99,105,116,121,
|
||||
0,109,95,109,97,120,77,111,116,111,114,73,109,112,117,108,115,101,0,109,
|
||||
95,108,111,119,101,114,76,105,109,105,116,0,109,95,117,112,112,101,114,76,
|
||||
105,109,105,116,0,109,95,108,105,109,105,116,83,111,102,116,110,101,115,115,
|
||||
0,109,95,98,105,97,115,70,97,99,116,111,114,0,109,95,114,101,108,97,
|
||||
120,97,116,105,111,110,70,97,99,116,111,114,0,109,95,115,119,105,110,103,
|
||||
83,112,97,110,49,0,109,95,115,119,105,110,103,83,112,97,110,50,0,109,
|
||||
95,116,119,105,115,116,83,112,97,110,0,109,95,100,97,109,112,105,110,103,
|
||||
0,109,95,108,105,110,101,97,114,85,112,112,101,114,76,105,109,105,116,0,
|
||||
109,95,108,105,110,101,97,114,76,111,119,101,114,76,105,109,105,116,0,109,
|
||||
95,97,110,103,117,108,97,114,85,112,112,101,114,76,105,109,105,116,0,109,
|
||||
95,97,110,103,117,108,97,114,76,111,119,101,114,76,105,109,105,116,0,109,
|
||||
95,117,115,101,76,105,110,101,97,114,82,101,102,101,114,101,110,99,101,70,
|
||||
114,97,109,101,65,0,109,95,117,115,101,79,102,102,115,101,116,70,111,114,
|
||||
67,111,110,115,116,114,97,105,110,116,70,114,97,109,101,0,84,89,80,69,
|
||||
58,0,0,0,99,104,97,114,0,117,99,104,97,114,0,115,104,111,114,116,
|
||||
0,117,115,104,111,114,116,0,105,110,116,0,108,111,110,103,0,117,108,111,
|
||||
110,103,0,102,108,111,97,116,0,100,111,117,98,108,101,0,118,111,105,100,
|
||||
0,80,111,105,110,116,101,114,65,114,114,97,121,0,98,116,80,104,121,115,
|
||||
105,99,115,83,121,115,116,101,109,0,76,105,115,116,66,97,115,101,0,98,
|
||||
116,86,101,99,116,111,114,51,70,108,111,97,116,68,97,116,97,0,98,116,
|
||||
86,101,99,116,111,114,51,68,111,117,98,108,101,68,97,116,97,0,98,116,
|
||||
77,97,116,114,105,120,51,120,51,70,108,111,97,116,68,97,116,97,0,98,
|
||||
116,77,97,116,114,105,120,51,120,51,68,111,117,98,108,101,68,97,116,97,
|
||||
0,98,116,84,114,97,110,115,102,111,114,109,70,108,111,97,116,68,97,116,
|
||||
97,0,98,116,84,114,97,110,115,102,111,114,109,68,111,117,98,108,101,68,
|
||||
97,116,97,0,98,116,66,118,104,83,117,98,116,114,101,101,73,110,102,111,
|
||||
68,97,116,97,0,98,116,79,112,116,105,109,105,122,101,100,66,118,104,78,
|
||||
111,100,101,70,108,111,97,116,68,97,116,97,0,98,116,79,112,116,105,109,
|
||||
105,122,101,100,66,118,104,78,111,100,101,68,111,117,98,108,101,68,97,116,
|
||||
97,0,98,116,81,117,97,110,116,105,122,101,100,66,118,104,78,111,100,101,
|
||||
68,97,116,97,0,98,116,81,117,97,110,116,105,122,101,100,66,118,104,70,
|
||||
108,111,97,116,68,97,116,97,0,98,116,81,117,97,110,116,105,122,101,100,
|
||||
66,118,104,68,111,117,98,108,101,68,97,116,97,0,98,116,67,111,108,108,
|
||||
105,115,105,111,110,83,104,97,112,101,68,97,116,97,0,98,116,83,116,97,
|
||||
116,105,99,80,108,97,110,101,83,104,97,112,101,68,97,116,97,0,98,116,
|
||||
67,111,110,118,101,120,73,110,116,101,114,110,97,108,83,104,97,112,101,68,
|
||||
97,116,97,0,98,116,80,111,115,105,116,105,111,110,65,110,100,82,97,100,
|
||||
105,117,115,0,98,116,77,117,108,116,105,83,112,104,101,114,101,83,104,97,
|
||||
112,101,68,97,116,97,0,98,116,73,110,116,73,110,100,101,120,68,97,116,
|
||||
97,0,98,116,83,104,111,114,116,73,110,116,73,110,100,101,120,68,97,116,
|
||||
97,0,98,116,83,104,111,114,116,73,110,116,73,110,100,101,120,84,114,105,
|
||||
112,108,101,116,68,97,116,97,0,98,116,77,101,115,104,80,97,114,116,68,
|
||||
97,116,97,0,98,116,83,116,114,105,100,105,110,103,77,101,115,104,73,110,
|
||||
116,101,114,102,97,99,101,68,97,116,97,0,98,116,84,114,105,97,110,103,
|
||||
108,101,77,101,115,104,83,104,97,112,101,68,97,116,97,0,98,116,84,114,
|
||||
105,97,110,103,108,101,73,110,102,111,77,97,112,68,97,116,97,0,98,116,
|
||||
67,111,109,112,111,117,110,100,83,104,97,112,101,67,104,105,108,100,68,97,
|
||||
116,97,0,98,116,67,111,109,112,111,117,110,100,83,104,97,112,101,68,97,
|
||||
116,97,0,98,116,67,121,108,105,110,100,101,114,83,104,97,112,101,68,97,
|
||||
116,97,0,98,116,67,97,112,115,117,108,101,83,104,97,112,101,68,97,116,
|
||||
97,0,98,116,84,114,105,97,110,103,108,101,73,110,102,111,68,97,116,97,
|
||||
0,98,116,71,73,109,112,97,99,116,77,101,115,104,83,104,97,112,101,68,
|
||||
97,116,97,0,98,116,67,111,110,118,101,120,72,117,108,108,83,104,97,112,
|
||||
101,68,97,116,97,0,98,116,67,111,108,108,105,115,105,111,110,79,98,106,
|
||||
101,99,116,68,111,117,98,108,101,68,97,116,97,0,98,116,67,111,108,108,
|
||||
105,115,105,111,110,79,98,106,101,99,116,70,108,111,97,116,68,97,116,97,
|
||||
0,98,116,82,105,103,105,100,66,111,100,121,70,108,111,97,116,68,97,116,
|
||||
97,0,98,116,82,105,103,105,100,66,111,100,121,68,111,117,98,108,101,68,
|
||||
97,116,97,0,98,116,67,111,110,115,116,114,97,105,110,116,73,110,102,111,
|
||||
49,0,98,116,84,121,112,101,100,67,111,110,115,116,114,97,105,110,116,68,
|
||||
97,116,97,0,98,116,82,105,103,105,100,66,111,100,121,68,97,116,97,0,
|
||||
98,116,80,111,105,110,116,50,80,111,105,110,116,67,111,110,115,116,114,97,
|
||||
105,110,116,70,108,111,97,116,68,97,116,97,0,98,116,80,111,105,110,116,
|
||||
50,80,111,105,110,116,67,111,110,115,116,114,97,105,110,116,68,111,117,98,
|
||||
108,101,68,97,116,97,0,98,116,72,105,110,103,101,67,111,110,115,116,114,
|
||||
97,105,110,116,68,111,117,98,108,101,68,97,116,97,0,98,116,72,105,110,
|
||||
103,101,67,111,110,115,116,114,97,105,110,116,70,108,111,97,116,68,97,116,
|
||||
97,0,98,116,67,111,110,101,84,119,105,115,116,67,111,110,115,116,114,97,
|
||||
105,110,116,68,97,116,97,0,98,116,71,101,110,101,114,105,99,54,68,111,
|
||||
102,67,111,110,115,116,114,97,105,110,116,68,97,116,97,0,98,116,83,108,
|
||||
105,100,101,114,67,111,110,115,116,114,97,105,110,116,68,97,116,97,0,0,
|
||||
84,76,69,78,1,0,1,0,2,0,2,0,4,0,4,0,4,0,4,0,
|
||||
8,0,0,0,12,0,36,0,8,0,16,0,32,0,48,0,96,0,64,0,
|
||||
-128,0,20,0,48,0,80,0,16,0,84,0,-124,0,12,0,52,0,52,0,
|
||||
20,0,64,0,4,0,4,0,8,0,28,0,28,0,60,0,56,0,76,0,
|
||||
24,0,60,0,60,0,16,0,64,0,68,0,-56,1,-8,0,-32,1,-104,3,
|
||||
8,0,44,0,0,0,76,0,108,0,84,1,-44,0,-52,0,-12,0,-60,0,
|
||||
83,84,82,67,47,0,0,0,10,0,3,0,4,0,0,0,4,0,1,0,
|
||||
9,0,2,0,11,0,3,0,10,0,3,0,10,0,4,0,10,0,5,0,
|
||||
12,0,2,0,9,0,6,0,9,0,7,0,13,0,1,0,7,0,8,0,
|
||||
14,0,1,0,8,0,8,0,15,0,1,0,13,0,9,0,16,0,1,0,
|
||||
14,0,9,0,17,0,2,0,15,0,10,0,13,0,11,0,18,0,2,0,
|
||||
16,0,10,0,14,0,11,0,19,0,4,0,4,0,12,0,4,0,13,0,
|
||||
2,0,14,0,2,0,15,0,20,0,6,0,13,0,16,0,13,0,17,0,
|
||||
4,0,18,0,4,0,19,0,4,0,20,0,0,0,21,0,21,0,6,0,
|
||||
14,0,16,0,14,0,17,0,4,0,18,0,4,0,19,0,4,0,20,0,
|
||||
0,0,21,0,22,0,3,0,2,0,14,0,2,0,15,0,4,0,22,0,
|
||||
23,0,12,0,13,0,23,0,13,0,24,0,13,0,25,0,4,0,26,0,
|
||||
4,0,27,0,4,0,28,0,4,0,29,0,20,0,30,0,22,0,31,0,
|
||||
19,0,32,0,4,0,33,0,4,0,34,0,24,0,12,0,14,0,23,0,
|
||||
14,0,24,0,14,0,25,0,4,0,26,0,4,0,27,0,4,0,28,0,
|
||||
4,0,29,0,21,0,30,0,22,0,31,0,4,0,33,0,4,0,34,0,
|
||||
19,0,32,0,25,0,3,0,0,0,35,0,4,0,36,0,0,0,37,0,
|
||||
26,0,5,0,25,0,38,0,13,0,39,0,13,0,40,0,7,0,41,0,
|
||||
0,0,21,0,27,0,5,0,25,0,38,0,13,0,39,0,13,0,42,0,
|
||||
7,0,43,0,4,0,44,0,28,0,2,0,13,0,45,0,7,0,46,0,
|
||||
29,0,4,0,27,0,47,0,28,0,48,0,4,0,49,0,0,0,37,0,
|
||||
30,0,1,0,4,0,50,0,31,0,2,0,2,0,50,0,0,0,51,0,
|
||||
32,0,2,0,2,0,52,0,0,0,51,0,33,0,7,0,13,0,53,0,
|
||||
14,0,54,0,30,0,55,0,32,0,56,0,31,0,57,0,4,0,58,0,
|
||||
4,0,59,0,34,0,4,0,33,0,60,0,13,0,61,0,4,0,62,0,
|
||||
0,0,37,0,35,0,7,0,25,0,38,0,34,0,63,0,23,0,64,0,
|
||||
24,0,65,0,36,0,66,0,7,0,43,0,0,0,67,0,37,0,4,0,
|
||||
17,0,68,0,25,0,69,0,4,0,70,0,7,0,71,0,38,0,4,0,
|
||||
25,0,38,0,37,0,72,0,4,0,73,0,7,0,43,0,39,0,3,0,
|
||||
27,0,47,0,4,0,74,0,0,0,37,0,40,0,3,0,27,0,47,0,
|
||||
4,0,74,0,0,0,37,0,41,0,4,0,4,0,75,0,7,0,76,0,
|
||||
7,0,77,0,7,0,78,0,36,0,14,0,4,0,79,0,4,0,80,0,
|
||||
41,0,81,0,4,0,82,0,7,0,83,0,7,0,84,0,7,0,85,0,
|
||||
7,0,86,0,7,0,87,0,4,0,88,0,4,0,89,0,4,0,90,0,
|
||||
4,0,91,0,0,0,37,0,42,0,5,0,25,0,38,0,34,0,63,0,
|
||||
13,0,39,0,7,0,43,0,4,0,92,0,43,0,5,0,27,0,47,0,
|
||||
13,0,93,0,14,0,94,0,4,0,95,0,0,0,96,0,44,0,24,0,
|
||||
9,0,97,0,9,0,98,0,25,0,99,0,0,0,35,0,18,0,100,0,
|
||||
18,0,101,0,14,0,102,0,14,0,103,0,14,0,104,0,8,0,105,0,
|
||||
8,0,106,0,8,0,107,0,8,0,108,0,8,0,109,0,8,0,110,0,
|
||||
8,0,111,0,4,0,112,0,4,0,113,0,4,0,114,0,4,0,115,0,
|
||||
4,0,116,0,4,0,117,0,4,0,118,0,0,0,37,0,45,0,23,0,
|
||||
9,0,97,0,9,0,98,0,25,0,99,0,0,0,35,0,17,0,100,0,
|
||||
17,0,101,0,13,0,102,0,13,0,103,0,13,0,104,0,7,0,105,0,
|
||||
7,0,106,0,7,0,107,0,7,0,108,0,7,0,109,0,7,0,110,0,
|
||||
7,0,111,0,4,0,112,0,4,0,113,0,4,0,114,0,4,0,115,0,
|
||||
4,0,116,0,4,0,117,0,4,0,118,0,46,0,21,0,45,0,119,0,
|
||||
15,0,120,0,13,0,121,0,13,0,122,0,13,0,123,0,13,0,124,0,
|
||||
13,0,125,0,13,0,126,0,13,0,127,0,13,0,-128,0,13,0,-127,0,
|
||||
7,0,-126,0,7,0,-125,0,7,0,-124,0,7,0,-123,0,7,0,-122,0,
|
||||
7,0,-121,0,7,0,-120,0,7,0,-119,0,7,0,-118,0,4,0,-117,0,
|
||||
47,0,22,0,44,0,119,0,16,0,120,0,14,0,121,0,14,0,122,0,
|
||||
14,0,123,0,14,0,124,0,14,0,125,0,14,0,126,0,14,0,127,0,
|
||||
14,0,-128,0,14,0,-127,0,8,0,-126,0,8,0,-125,0,8,0,-124,0,
|
||||
8,0,-123,0,8,0,-122,0,8,0,-121,0,8,0,-120,0,8,0,-119,0,
|
||||
8,0,-118,0,4,0,-117,0,0,0,37,0,48,0,2,0,4,0,-116,0,
|
||||
4,0,-115,0,49,0,11,0,50,0,-114,0,50,0,-113,0,0,0,35,0,
|
||||
4,0,-112,0,4,0,-111,0,4,0,-110,0,4,0,-109,0,7,0,-108,0,
|
||||
7,0,-107,0,4,0,-106,0,0,0,-105,0,51,0,3,0,49,0,-104,0,
|
||||
13,0,-103,0,13,0,-102,0,52,0,3,0,49,0,-104,0,14,0,-103,0,
|
||||
14,0,-102,0,53,0,13,0,49,0,-104,0,18,0,-101,0,18,0,-100,0,
|
||||
4,0,-99,0,4,0,-98,0,4,0,-97,0,7,0,-96,0,7,0,-95,0,
|
||||
7,0,-94,0,7,0,-93,0,7,0,-92,0,7,0,-91,0,7,0,-90,0,
|
||||
54,0,13,0,49,0,-104,0,17,0,-101,0,17,0,-100,0,4,0,-99,0,
|
||||
4,0,-98,0,4,0,-97,0,7,0,-96,0,7,0,-95,0,7,0,-94,0,
|
||||
7,0,-93,0,7,0,-92,0,7,0,-91,0,7,0,-90,0,55,0,11,0,
|
||||
49,0,-104,0,17,0,-101,0,17,0,-100,0,7,0,-89,0,7,0,-88,0,
|
||||
7,0,-87,0,7,0,-92,0,7,0,-91,0,7,0,-90,0,7,0,-86,0,
|
||||
0,0,21,0,56,0,9,0,49,0,-104,0,17,0,-101,0,17,0,-100,0,
|
||||
13,0,-85,0,13,0,-84,0,13,0,-83,0,13,0,-82,0,4,0,-81,0,
|
||||
4,0,-80,0,57,0,9,0,49,0,-104,0,17,0,-101,0,17,0,-100,0,
|
||||
7,0,-85,0,7,0,-84,0,7,0,-83,0,7,0,-82,0,4,0,-81,0,
|
||||
4,0,-80,0,};
|
||||
int sBulletDNAlen= sizeof(sBulletDNAstr);
|
606
libs/bullet/LinearMath/btSerializer.h
Normal file
606
libs/bullet/LinearMath/btSerializer.h
Normal file
@ -0,0 +1,606 @@
|
||||
/*
|
||||
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"
|
||||
#include "btHashMap.h"
|
||||
|
||||
#if !defined( __CELLOS_LV2__) && !defined(__MWERKS__)
|
||||
#include <memory.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
|
||||
|
||||
///only the 32bit versions for now
|
||||
extern unsigned char sBulletDNAstr[];
|
||||
extern int sBulletDNAlen;
|
||||
extern unsigned char sBulletDNAstr64[];
|
||||
extern int sBulletDNAlen64;
|
||||
|
||||
SIMD_FORCE_INLINE int btStrLen(const char* str)
|
||||
{
|
||||
if (!str)
|
||||
return(0);
|
||||
int len = 0;
|
||||
|
||||
while (*str != 0)
|
||||
{
|
||||
str++;
|
||||
len++;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
class btChunk
|
||||
{
|
||||
public:
|
||||
int m_chunkCode;
|
||||
int m_length;
|
||||
void *m_oldPtr;
|
||||
int m_dna_nr;
|
||||
int m_number;
|
||||
};
|
||||
|
||||
enum btSerializationFlags
|
||||
{
|
||||
BT_SERIALIZE_NO_BVH = 1,
|
||||
BT_SERIALIZE_NO_TRIANGLEINFOMAP = 2,
|
||||
BT_SERIALIZE_NO_DUPLICATE_ASSERT = 4
|
||||
};
|
||||
|
||||
class btSerializer
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
virtual ~btSerializer() {}
|
||||
|
||||
virtual const unsigned char* getBufferPointer() const = 0;
|
||||
|
||||
virtual int getCurrentBufferSize() const = 0;
|
||||
|
||||
virtual btChunk* allocate(size_t size, int numElements) = 0;
|
||||
|
||||
virtual void finalizeChunk(btChunk* chunk, const char* structType, int chunkCode,void* oldPtr)= 0;
|
||||
|
||||
virtual void* findPointer(void* oldPtr) = 0;
|
||||
|
||||
virtual void* getUniquePointer(void*oldPtr) = 0;
|
||||
|
||||
virtual void startSerialization() = 0;
|
||||
|
||||
virtual void finishSerialization() = 0;
|
||||
|
||||
virtual const char* findNameForPointer(const void* ptr) const = 0;
|
||||
|
||||
virtual void registerNameForPointer(const void* ptr, const char* name) = 0;
|
||||
|
||||
virtual void serializeName(const char* ptr) = 0;
|
||||
|
||||
virtual int getSerializationFlags() const = 0;
|
||||
|
||||
virtual void setSerializationFlags(int flags) = 0;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define BT_HEADER_LENGTH 12
|
||||
#if defined(__sgi) || defined (__sparc) || defined (__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__)
|
||||
# define MAKE_ID(a,b,c,d) ( (int)(a)<<24 | (int)(b)<<16 | (c)<<8 | (d) )
|
||||
#else
|
||||
# define MAKE_ID(a,b,c,d) ( (int)(d)<<24 | (int)(c)<<16 | (b)<<8 | (a) )
|
||||
#endif
|
||||
|
||||
#define BT_COLLISIONOBJECT_CODE MAKE_ID('C','O','B','J')
|
||||
#define BT_RIGIDBODY_CODE MAKE_ID('R','B','D','Y')
|
||||
#define BT_CONSTRAINT_CODE MAKE_ID('C','O','N','S')
|
||||
#define BT_BOXSHAPE_CODE MAKE_ID('B','O','X','S')
|
||||
#define BT_QUANTIZED_BVH_CODE MAKE_ID('Q','B','V','H')
|
||||
#define BT_TRIANLGE_INFO_MAP MAKE_ID('T','M','A','P')
|
||||
#define BT_SHAPE_CODE MAKE_ID('S','H','A','P')
|
||||
#define BT_ARRAY_CODE MAKE_ID('A','R','A','Y')
|
||||
#define BT_DNA_CODE MAKE_ID('D','N','A','1')
|
||||
|
||||
|
||||
|
||||
struct btPointerUid
|
||||
{
|
||||
union
|
||||
{
|
||||
void* m_ptr;
|
||||
int m_uniqueIds[2];
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
class btDefaultSerializer : public btSerializer
|
||||
{
|
||||
|
||||
|
||||
btAlignedObjectArray<char*> mTypes;
|
||||
btAlignedObjectArray<short*> mStructs;
|
||||
btAlignedObjectArray<short> mTlens;
|
||||
btHashMap<btHashInt, int> mStructReverse;
|
||||
btHashMap<btHashString,int> mTypeLookup;
|
||||
|
||||
|
||||
btHashMap<btHashPtr,void*> m_chunkP;
|
||||
|
||||
btHashMap<btHashPtr,const char*> m_nameMap;
|
||||
|
||||
btHashMap<btHashPtr,btPointerUid> m_uniquePointers;
|
||||
int m_uniqueIdGenerator;
|
||||
|
||||
int m_totalSize;
|
||||
unsigned char* m_buffer;
|
||||
int m_currentSize;
|
||||
void* m_dna;
|
||||
int m_dnaLength;
|
||||
|
||||
int m_serializationFlags;
|
||||
|
||||
|
||||
btAlignedObjectArray<btChunk*> m_chunkPtrs;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void* findPointer(void* oldPtr)
|
||||
{
|
||||
void** ptr = m_chunkP.find(oldPtr);
|
||||
if (ptr && *ptr)
|
||||
return *ptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void writeDNA()
|
||||
{
|
||||
btChunk* dnaChunk = allocate(m_dnaLength,1);
|
||||
memcpy(dnaChunk->m_oldPtr,m_dna,m_dnaLength);
|
||||
finalizeChunk(dnaChunk,"DNA1",BT_DNA_CODE, m_dna);
|
||||
}
|
||||
|
||||
int getReverseType(const char *type) const
|
||||
{
|
||||
|
||||
btHashString key(type);
|
||||
const int* valuePtr = mTypeLookup.find(key);
|
||||
if (valuePtr)
|
||||
return *valuePtr;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void initDNA(const char* bdnaOrg,int dnalen)
|
||||
{
|
||||
///was already initialized
|
||||
if (m_dna)
|
||||
return;
|
||||
|
||||
int littleEndian= 1;
|
||||
littleEndian= ((char*)&littleEndian)[0];
|
||||
|
||||
|
||||
m_dna = btAlignedAlloc(dnalen,16);
|
||||
memcpy(m_dna,bdnaOrg,dnalen);
|
||||
m_dnaLength = dnalen;
|
||||
|
||||
int *intPtr=0;
|
||||
short *shtPtr=0;
|
||||
char *cp = 0;int dataLen =0;long nr=0;
|
||||
intPtr = (int*)m_dna;
|
||||
|
||||
/*
|
||||
SDNA (4 bytes) (magic number)
|
||||
NAME (4 bytes)
|
||||
<nr> (4 bytes) amount of names (int)
|
||||
<string>
|
||||
<string>
|
||||
*/
|
||||
|
||||
if (strncmp((const char*)m_dna, "SDNA", 4)==0)
|
||||
{
|
||||
// skip ++ NAME
|
||||
intPtr++; intPtr++;
|
||||
}
|
||||
|
||||
// Parse names
|
||||
if (!littleEndian)
|
||||
*intPtr = btSwapEndian(*intPtr);
|
||||
|
||||
dataLen = *intPtr;
|
||||
|
||||
intPtr++;
|
||||
|
||||
cp = (char*)intPtr;
|
||||
int i;
|
||||
for ( 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++;
|
||||
|
||||
if (!littleEndian)
|
||||
*intPtr = btSwapEndian(*intPtr);
|
||||
|
||||
dataLen = *intPtr;
|
||||
intPtr++;
|
||||
|
||||
|
||||
cp = (char*)intPtr;
|
||||
for (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 (i=0; i<dataLen; i++, shtPtr++)
|
||||
{
|
||||
if (!littleEndian)
|
||||
shtPtr[0] = btSwapEndian(shtPtr[0]);
|
||||
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++;
|
||||
|
||||
if (!littleEndian)
|
||||
*intPtr = btSwapEndian(*intPtr);
|
||||
dataLen = *intPtr ;
|
||||
intPtr++;
|
||||
|
||||
|
||||
shtPtr = (short*)intPtr;
|
||||
for (i=0; i<dataLen; i++)
|
||||
{
|
||||
mStructs.push_back (shtPtr);
|
||||
|
||||
if (!littleEndian)
|
||||
{
|
||||
shtPtr[0]= btSwapEndian(shtPtr[0]);
|
||||
shtPtr[1]= btSwapEndian(shtPtr[1]);
|
||||
|
||||
int len = shtPtr[1];
|
||||
shtPtr+= 2;
|
||||
|
||||
for (int a=0; a<len; a++, shtPtr+=2)
|
||||
{
|
||||
shtPtr[0]= btSwapEndian(shtPtr[0]);
|
||||
shtPtr[1]= btSwapEndian(shtPtr[1]);
|
||||
}
|
||||
|
||||
} else
|
||||
{
|
||||
shtPtr+= (2*shtPtr[1])+2;
|
||||
}
|
||||
}
|
||||
|
||||
// build reverse lookups
|
||||
for (i=0; i<(int)mStructs.size(); i++)
|
||||
{
|
||||
short *strc = mStructs.at(i);
|
||||
mStructReverse.insert(strc[0], i);
|
||||
mTypeLookup.insert(btHashString(mTypes[strc[0]]),i);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
|
||||
|
||||
|
||||
btDefaultSerializer(int totalSize)
|
||||
:m_totalSize(totalSize),
|
||||
m_currentSize(0),
|
||||
m_dna(0),
|
||||
m_dnaLength(0),
|
||||
m_serializationFlags(0)
|
||||
{
|
||||
m_buffer = (unsigned char*)btAlignedAlloc(totalSize, 16);
|
||||
|
||||
const bool VOID_IS_8 = ((sizeof(void*)==8));
|
||||
|
||||
#ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
|
||||
if (VOID_IS_8)
|
||||
{
|
||||
#if _WIN64
|
||||
initDNA((const char*)sBulletDNAstr64,sBulletDNAlen64);
|
||||
#else
|
||||
btAssert(0);
|
||||
#endif
|
||||
} else
|
||||
{
|
||||
#ifndef _WIN64
|
||||
initDNA((const char*)sBulletDNAstr,sBulletDNAlen);
|
||||
#else
|
||||
btAssert(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
#else //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
|
||||
if (VOID_IS_8)
|
||||
{
|
||||
initDNA((const char*)sBulletDNAstr64,sBulletDNAlen64);
|
||||
} else
|
||||
{
|
||||
initDNA((const char*)sBulletDNAstr,sBulletDNAlen);
|
||||
}
|
||||
#endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
|
||||
|
||||
}
|
||||
|
||||
virtual ~btDefaultSerializer()
|
||||
{
|
||||
if (m_buffer)
|
||||
btAlignedFree(m_buffer);
|
||||
if (m_dna)
|
||||
btAlignedFree(m_dna);
|
||||
}
|
||||
|
||||
virtual void startSerialization()
|
||||
{
|
||||
m_uniqueIdGenerator= 1;
|
||||
|
||||
m_currentSize = BT_HEADER_LENGTH;
|
||||
|
||||
#ifdef BT_USE_DOUBLE_PRECISION
|
||||
memcpy(m_buffer, "BULLETd", 7);
|
||||
#else
|
||||
memcpy(m_buffer, "BULLETf", 7);
|
||||
#endif //BT_USE_DOUBLE_PRECISION
|
||||
|
||||
int littleEndian= 1;
|
||||
littleEndian= ((char*)&littleEndian)[0];
|
||||
|
||||
if (sizeof(void*)==8)
|
||||
{
|
||||
m_buffer[7] = '-';
|
||||
} else
|
||||
{
|
||||
m_buffer[7] = '_';
|
||||
}
|
||||
|
||||
if (littleEndian)
|
||||
{
|
||||
m_buffer[8]='v';
|
||||
} else
|
||||
{
|
||||
m_buffer[8]='V';
|
||||
}
|
||||
|
||||
|
||||
m_buffer[9] = '2';
|
||||
m_buffer[10] = '7';
|
||||
m_buffer[11] = '7';
|
||||
|
||||
|
||||
}
|
||||
|
||||
virtual void finishSerialization()
|
||||
{
|
||||
writeDNA();
|
||||
|
||||
|
||||
mTypes.clear();
|
||||
mStructs.clear();
|
||||
mTlens.clear();
|
||||
mStructReverse.clear();
|
||||
mTypeLookup.clear();
|
||||
m_chunkP.clear();
|
||||
m_nameMap.clear();
|
||||
m_uniquePointers.clear();
|
||||
}
|
||||
|
||||
virtual void* getUniquePointer(void*oldPtr)
|
||||
{
|
||||
if (!oldPtr)
|
||||
return 0;
|
||||
|
||||
btPointerUid* uptr = (btPointerUid*)m_uniquePointers.find(oldPtr);
|
||||
if (uptr)
|
||||
{
|
||||
return uptr->m_ptr;
|
||||
}
|
||||
m_uniqueIdGenerator++;
|
||||
|
||||
btPointerUid uid;
|
||||
uid.m_uniqueIds[0] = m_uniqueIdGenerator;
|
||||
uid.m_uniqueIds[1] = m_uniqueIdGenerator;
|
||||
m_uniquePointers.insert(oldPtr,uid);
|
||||
return uid.m_ptr;
|
||||
|
||||
}
|
||||
|
||||
virtual const unsigned char* getBufferPointer() const
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
virtual int getCurrentBufferSize() const
|
||||
{
|
||||
return m_currentSize;
|
||||
}
|
||||
|
||||
virtual void finalizeChunk(btChunk* chunk, const char* structType, int chunkCode,void* oldPtr)
|
||||
{
|
||||
if (!(m_serializationFlags&BT_SERIALIZE_NO_DUPLICATE_ASSERT))
|
||||
{
|
||||
btAssert(!findPointer(oldPtr));
|
||||
}
|
||||
|
||||
chunk->m_dna_nr = getReverseType(structType);
|
||||
|
||||
chunk->m_chunkCode = chunkCode;
|
||||
|
||||
void* uniquePtr = getUniquePointer(oldPtr);
|
||||
|
||||
m_chunkP.insert(oldPtr,uniquePtr);//chunk->m_oldPtr);
|
||||
chunk->m_oldPtr = uniquePtr;//oldPtr;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
virtual btChunk* allocate(size_t size, int numElements)
|
||||
{
|
||||
|
||||
unsigned char* ptr = m_buffer+m_currentSize;
|
||||
m_currentSize += int(size)*numElements+sizeof(btChunk);
|
||||
btAssert(m_currentSize<m_totalSize);
|
||||
|
||||
unsigned char* data = ptr + sizeof(btChunk);
|
||||
|
||||
btChunk* chunk = (btChunk*)ptr;
|
||||
chunk->m_chunkCode = 0;
|
||||
chunk->m_oldPtr = data;
|
||||
chunk->m_length = int(size)*numElements;
|
||||
chunk->m_number = numElements;
|
||||
|
||||
m_chunkPtrs.push_back(chunk);
|
||||
|
||||
|
||||
return chunk;
|
||||
}
|
||||
|
||||
virtual const char* findNameForPointer(const void* ptr) const
|
||||
{
|
||||
const char*const * namePtr = m_nameMap.find(ptr);
|
||||
if (namePtr && *namePtr)
|
||||
return *namePtr;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
virtual void registerNameForPointer(const void* ptr, const char* name)
|
||||
{
|
||||
m_nameMap.insert(ptr,name);
|
||||
}
|
||||
|
||||
virtual void serializeName(const char* name)
|
||||
{
|
||||
if (name)
|
||||
{
|
||||
//don't serialize name twice
|
||||
if (findPointer((void*)name))
|
||||
return;
|
||||
|
||||
int len = btStrLen(name);
|
||||
if (len)
|
||||
{
|
||||
|
||||
int newLen = len+1;
|
||||
int padding = ((newLen+3)&~3)-newLen;
|
||||
newLen += padding;
|
||||
|
||||
//serialize name string now
|
||||
btChunk* chunk = allocate(sizeof(char),newLen);
|
||||
char* destinationName = (char*)chunk->m_oldPtr;
|
||||
for (int i=0;i<len;i++)
|
||||
{
|
||||
destinationName[i] = name[i];
|
||||
}
|
||||
destinationName[len] = 0;
|
||||
finalizeChunk(chunk,"char",BT_ARRAY_CODE,(void*)name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual int getSerializationFlags() const
|
||||
{
|
||||
return m_serializationFlags;
|
||||
}
|
||||
|
||||
virtual void setSerializationFlags(int flags)
|
||||
{
|
||||
m_serializationFlags = flags;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //BT_SERIALIZER_H
|
||||
|
116
libs/bullet/LinearMath/btStackAlloc.h
Normal file
116
libs/bullet/LinearMath/btStackAlloc.h
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
StackAlloc extracted from GJK-EPA collision solver by Nathanael Presson
|
||||
Nov.2006
|
||||
*/
|
||||
|
||||
#ifndef BT_STACK_ALLOC
|
||||
#define BT_STACK_ALLOC
|
||||
|
||||
#include "btScalar.h" //for btAssert
|
||||
#include "btAlignedAllocator.h"
|
||||
|
||||
///The btBlock class is an internal structure for the btStackAlloc memory allocator.
|
||||
struct btBlock
|
||||
{
|
||||
btBlock* previous;
|
||||
unsigned char* address;
|
||||
};
|
||||
|
||||
///The StackAlloc class provides some fast stack-based memory allocator (LIFO last-in first-out)
|
||||
class btStackAlloc
|
||||
{
|
||||
public:
|
||||
|
||||
btStackAlloc(unsigned int size) { ctor();create(size); }
|
||||
~btStackAlloc() { destroy(); }
|
||||
|
||||
inline void create(unsigned int size)
|
||||
{
|
||||
destroy();
|
||||
data = (unsigned char*) btAlignedAlloc(size,16);
|
||||
totalsize = size;
|
||||
}
|
||||
inline void destroy()
|
||||
{
|
||||
btAssert(usedsize==0);
|
||||
//Raise(L"StackAlloc is still in use");
|
||||
|
||||
if(usedsize==0)
|
||||
{
|
||||
if(!ischild && data)
|
||||
btAlignedFree(data);
|
||||
|
||||
data = 0;
|
||||
usedsize = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int getAvailableMemory() const
|
||||
{
|
||||
return static_cast<int>(totalsize - usedsize);
|
||||
}
|
||||
|
||||
unsigned char* allocate(unsigned int size)
|
||||
{
|
||||
const unsigned int nus(usedsize+size);
|
||||
if(nus<totalsize)
|
||||
{
|
||||
usedsize=nus;
|
||||
return(data+(usedsize-size));
|
||||
}
|
||||
btAssert(0);
|
||||
//&& (L"Not enough memory"));
|
||||
|
||||
return(0);
|
||||
}
|
||||
SIMD_FORCE_INLINE btBlock* beginBlock()
|
||||
{
|
||||
btBlock* pb = (btBlock*)allocate(sizeof(btBlock));
|
||||
pb->previous = current;
|
||||
pb->address = data+usedsize;
|
||||
current = pb;
|
||||
return(pb);
|
||||
}
|
||||
SIMD_FORCE_INLINE void endBlock(btBlock* block)
|
||||
{
|
||||
btAssert(block==current);
|
||||
//Raise(L"Unmatched blocks");
|
||||
if(block==current)
|
||||
{
|
||||
current = block->previous;
|
||||
usedsize = (unsigned int)((block->address-data)-sizeof(btBlock));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void ctor()
|
||||
{
|
||||
data = 0;
|
||||
totalsize = 0;
|
||||
usedsize = 0;
|
||||
current = 0;
|
||||
ischild = false;
|
||||
}
|
||||
unsigned char* data;
|
||||
unsigned int totalsize;
|
||||
unsigned int usedsize;
|
||||
btBlock* current;
|
||||
bool ischild;
|
||||
};
|
||||
|
||||
#endif //BT_STACK_ALLOC
|
307
libs/bullet/LinearMath/btTransform.h
Normal file
307
libs/bullet/LinearMath/btTransform.h
Normal file
@ -0,0 +1,307 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
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 btTransform_H
|
||||
#define btTransform_H
|
||||
|
||||
|
||||
#include "btMatrix3x3.h"
|
||||
|
||||
#ifdef BT_USE_DOUBLE_PRECISION
|
||||
#define btTransformData btTransformDoubleData
|
||||
#else
|
||||
#define btTransformData btTransformFloatData
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/**@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:
|
||||
|
||||
/**@brief No initialization constructor */
|
||||
btTransform() {}
|
||||
/**@brief Constructor from btQuaternion (optional btVector3 )
|
||||
* @param q Rotation from quaternion
|
||||
* @param c Translation from Vector (default 0,0,0) */
|
||||
explicit SIMD_FORCE_INLINE btTransform(const btQuaternion& q,
|
||||
const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0)))
|
||||
: m_basis(q),
|
||||
m_origin(c)
|
||||
{}
|
||||
|
||||
/**@brief Constructor from btMatrix3x3 (optional btVector3)
|
||||
* @param b Rotation from Matrix
|
||||
* @param c Translation from Vector default (0,0,0)*/
|
||||
explicit SIMD_FORCE_INLINE btTransform(const btMatrix3x3& b,
|
||||
const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0)))
|
||||
: m_basis(b),
|
||||
m_origin(c)
|
||||
{}
|
||||
/**@brief Copy constructor */
|
||||
SIMD_FORCE_INLINE btTransform (const btTransform& other)
|
||||
: m_basis(other.m_basis),
|
||||
m_origin(other.m_origin)
|
||||
{
|
||||
}
|
||||
/**@brief Assignment Operator */
|
||||
SIMD_FORCE_INLINE btTransform& operator=(const btTransform& other)
|
||||
{
|
||||
m_basis = other.m_basis;
|
||||
m_origin = other.m_origin;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Set the current transform as the value of the product of two transforms
|
||||
* @param t1 Transform 1
|
||||
* @param t2 Transform 2
|
||||
* This = Transform1 * Transform2 */
|
||||
SIMD_FORCE_INLINE void mult(const btTransform& t1, const btTransform& t2) {
|
||||
m_basis = t1.m_basis * t2.m_basis;
|
||||
m_origin = t1(t2.m_origin);
|
||||
}
|
||||
|
||||
/* void multInverseLeft(const btTransform& t1, const btTransform& t2) {
|
||||
btVector3 v = t2.m_origin - t1.m_origin;
|
||||
m_basis = btMultTransposeLeft(t1.m_basis, t2.m_basis);
|
||||
m_origin = v * t1.m_basis;
|
||||
}
|
||||
*/
|
||||
|
||||
/**@brief Return the transform of the vector */
|
||||
SIMD_FORCE_INLINE btVector3 operator()(const btVector3& x) const
|
||||
{
|
||||
return btVector3(m_basis[0].dot(x) + m_origin.x(),
|
||||
m_basis[1].dot(x) + m_origin.y(),
|
||||
m_basis[2].dot(x) + m_origin.z());
|
||||
}
|
||||
|
||||
/**@brief Return the transform of the vector */
|
||||
SIMD_FORCE_INLINE btVector3 operator*(const btVector3& x) const
|
||||
{
|
||||
return (*this)(x);
|
||||
}
|
||||
|
||||
/**@brief Return the transform of the btQuaternion */
|
||||
SIMD_FORCE_INLINE btQuaternion operator*(const btQuaternion& q) const
|
||||
{
|
||||
return getRotation() * q;
|
||||
}
|
||||
|
||||
/**@brief Return the basis matrix for the rotation */
|
||||
SIMD_FORCE_INLINE btMatrix3x3& getBasis() { return m_basis; }
|
||||
/**@brief Return the basis matrix for the rotation */
|
||||
SIMD_FORCE_INLINE const btMatrix3x3& getBasis() const { return m_basis; }
|
||||
|
||||
/**@brief Return the origin vector translation */
|
||||
SIMD_FORCE_INLINE btVector3& getOrigin() { return m_origin; }
|
||||
/**@brief Return the origin vector translation */
|
||||
SIMD_FORCE_INLINE const btVector3& getOrigin() const { return m_origin; }
|
||||
|
||||
/**@brief Return a quaternion representing the rotation */
|
||||
btQuaternion getRotation() const {
|
||||
btQuaternion q;
|
||||
m_basis.getRotation(q);
|
||||
return q;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Set from an array
|
||||
* @param m A pointer to a 15 element array (12 rotation(row major padded on the right by 1), and 3 translation */
|
||||
void setFromOpenGLMatrix(const btScalar *m)
|
||||
{
|
||||
m_basis.setFromOpenGLSubMatrix(m);
|
||||
m_origin.setValue(m[12],m[13],m[14]);
|
||||
}
|
||||
|
||||
/**@brief Fill an array representation
|
||||
* @param m A pointer to a 15 element array (12 rotation(row major padded on the right by 1), and 3 translation */
|
||||
void getOpenGLMatrix(btScalar *m) const
|
||||
{
|
||||
m_basis.getOpenGLSubMatrix(m);
|
||||
m[12] = m_origin.x();
|
||||
m[13] = m_origin.y();
|
||||
m[14] = m_origin.z();
|
||||
m[15] = btScalar(1.0);
|
||||
}
|
||||
|
||||
/**@brief Set the translational element
|
||||
* @param origin The vector to set the translation to */
|
||||
SIMD_FORCE_INLINE void setOrigin(const btVector3& origin)
|
||||
{
|
||||
m_origin = origin;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btVector3 invXform(const btVector3& inVec) const;
|
||||
|
||||
|
||||
/**@brief Set the rotational element by btMatrix3x3 */
|
||||
SIMD_FORCE_INLINE void setBasis(const btMatrix3x3& basis)
|
||||
{
|
||||
m_basis = basis;
|
||||
}
|
||||
|
||||
/**@brief Set the rotational element by btQuaternion */
|
||||
SIMD_FORCE_INLINE void setRotation(const btQuaternion& q)
|
||||
{
|
||||
m_basis.setRotation(q);
|
||||
}
|
||||
|
||||
|
||||
/**@brief Set this transformation to the identity */
|
||||
void setIdentity()
|
||||
{
|
||||
m_basis.setIdentity();
|
||||
m_origin.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
|
||||
}
|
||||
|
||||
/**@brief Multiply this Transform by another(this = this * another)
|
||||
* @param t The other transform */
|
||||
btTransform& operator*=(const btTransform& t)
|
||||
{
|
||||
m_origin += m_basis * t.m_origin;
|
||||
m_basis *= t.m_basis;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**@brief Return the inverse of this transform */
|
||||
btTransform inverse() const
|
||||
{
|
||||
btMatrix3x3 inv = m_basis.transpose();
|
||||
return btTransform(inv, inv * -m_origin);
|
||||
}
|
||||
|
||||
/**@brief Return the inverse of this transform times the other transform
|
||||
* @param t The other transform
|
||||
* return this.inverse() * the other */
|
||||
btTransform inverseTimes(const btTransform& t) const;
|
||||
|
||||
/**@brief Return the product of this transform and the other */
|
||||
btTransform operator*(const btTransform& t) const;
|
||||
|
||||
/**@brief Return an identity transform */
|
||||
static const btTransform& getIdentity()
|
||||
{
|
||||
static const btTransform identityTransform(btMatrix3x3::getIdentity());
|
||||
return identityTransform;
|
||||
}
|
||||
|
||||
void serialize(struct btTransformData& dataOut) const;
|
||||
|
||||
void serializeFloat(struct btTransformFloatData& dataOut) const;
|
||||
|
||||
void deSerialize(const struct btTransformData& dataIn);
|
||||
|
||||
void deSerializeDouble(const struct btTransformDoubleData& dataIn);
|
||||
|
||||
void deSerializeFloat(const struct btTransformFloatData& dataIn);
|
||||
|
||||
};
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE btVector3
|
||||
btTransform::invXform(const btVector3& inVec) const
|
||||
{
|
||||
btVector3 v = inVec - m_origin;
|
||||
return (m_basis.transpose() * v);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btTransform
|
||||
btTransform::inverseTimes(const btTransform& t) const
|
||||
{
|
||||
btVector3 v = t.getOrigin() - m_origin;
|
||||
return btTransform(m_basis.transposeTimes(t.m_basis),
|
||||
v * m_basis);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btTransform
|
||||
btTransform::operator*(const btTransform& t) const
|
||||
{
|
||||
return btTransform(m_basis * t.m_basis,
|
||||
(*this)(t.m_origin));
|
||||
}
|
||||
|
||||
/**@brief Test if two transforms have all elements equal */
|
||||
SIMD_FORCE_INLINE bool operator==(const btTransform& t1, const btTransform& t2)
|
||||
{
|
||||
return ( t1.getBasis() == t2.getBasis() &&
|
||||
t1.getOrigin() == t2.getOrigin() );
|
||||
}
|
||||
|
||||
|
||||
///for serialization
|
||||
struct btTransformFloatData
|
||||
{
|
||||
btMatrix3x3FloatData m_basis;
|
||||
btVector3FloatData m_origin;
|
||||
};
|
||||
|
||||
struct btTransformDoubleData
|
||||
{
|
||||
btMatrix3x3DoubleData m_basis;
|
||||
btVector3DoubleData 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::serializeFloat(btTransformFloatData& dataOut) const
|
||||
{
|
||||
m_basis.serializeFloat(dataOut.m_basis);
|
||||
m_origin.serializeFloat(dataOut.m_origin);
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE void btTransform::deSerialize(const btTransformData& dataIn)
|
||||
{
|
||||
m_basis.deSerialize(dataIn.m_basis);
|
||||
m_origin.deSerialize(dataIn.m_origin);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void btTransform::deSerializeFloat(const btTransformFloatData& dataIn)
|
||||
{
|
||||
m_basis.deSerializeFloat(dataIn.m_basis);
|
||||
m_origin.deSerializeFloat(dataIn.m_origin);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void btTransform::deSerializeDouble(const btTransformDoubleData& dataIn)
|
||||
{
|
||||
m_basis.deSerializeDouble(dataIn.m_basis);
|
||||
m_origin.deSerializeDouble(dataIn.m_origin);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
228
libs/bullet/LinearMath/btTransformUtil.h
Normal file
228
libs/bullet/LinearMath/btTransformUtil.h
Normal file
@ -0,0 +1,228 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
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 SIMD_TRANSFORM_UTIL_H
|
||||
#define SIMD_TRANSFORM_UTIL_H
|
||||
|
||||
#include "btTransform.h"
|
||||
#define ANGULAR_MOTION_THRESHOLD btScalar(0.5)*SIMD_HALF_PI
|
||||
|
||||
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE btVector3 btAabbSupport(const btVector3& halfExtents,const btVector3& supportDir)
|
||||
{
|
||||
return btVector3(supportDir.x() < btScalar(0.0) ? -halfExtents.x() : halfExtents.x(),
|
||||
supportDir.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(),
|
||||
supportDir.z() < btScalar(0.0) ? -halfExtents.z() : halfExtents.z());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// Utils related to temporal transforms
|
||||
class btTransformUtil
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
static void integrateTransform(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep,btTransform& predictedTransform)
|
||||
{
|
||||
predictedTransform.setOrigin(curTrans.getOrigin() + linvel * timeStep);
|
||||
// #define QUATERNION_DERIVATIVE
|
||||
#ifdef QUATERNION_DERIVATIVE
|
||||
btQuaternion predictedOrn = curTrans.getRotation();
|
||||
predictedOrn += (angvel * predictedOrn) * (timeStep * btScalar(0.5));
|
||||
predictedOrn.normalize();
|
||||
#else
|
||||
//Exponential map
|
||||
//google for "Practical Parameterization of Rotations Using the Exponential Map", F. Sebastian Grassia
|
||||
|
||||
btVector3 axis;
|
||||
btScalar fAngle = angvel.length();
|
||||
//limit the angular motion
|
||||
if (fAngle*timeStep > ANGULAR_MOTION_THRESHOLD)
|
||||
{
|
||||
fAngle = ANGULAR_MOTION_THRESHOLD / timeStep;
|
||||
}
|
||||
|
||||
if ( fAngle < btScalar(0.001) )
|
||||
{
|
||||
// use Taylor's expansions of sync function
|
||||
axis = angvel*( btScalar(0.5)*timeStep-(timeStep*timeStep*timeStep)*(btScalar(0.020833333333))*fAngle*fAngle );
|
||||
}
|
||||
else
|
||||
{
|
||||
// sync(fAngle) = sin(c*fAngle)/t
|
||||
axis = angvel*( btSin(btScalar(0.5)*fAngle*timeStep)/fAngle );
|
||||
}
|
||||
btQuaternion dorn (axis.x(),axis.y(),axis.z(),btCos( fAngle*timeStep*btScalar(0.5) ));
|
||||
btQuaternion orn0 = curTrans.getRotation();
|
||||
|
||||
btQuaternion predictedOrn = dorn * orn0;
|
||||
predictedOrn.normalize();
|
||||
#endif
|
||||
predictedTransform.setRotation(predictedOrn);
|
||||
}
|
||||
|
||||
static void calculateVelocityQuaternion(const btVector3& pos0,const btVector3& pos1,const btQuaternion& orn0,const btQuaternion& orn1,btScalar timeStep,btVector3& linVel,btVector3& angVel)
|
||||
{
|
||||
linVel = (pos1 - pos0) / timeStep;
|
||||
btVector3 axis;
|
||||
btScalar angle;
|
||||
if (orn0 != orn1)
|
||||
{
|
||||
calculateDiffAxisAngleQuaternion(orn0,orn1,axis,angle);
|
||||
angVel = axis * angle / timeStep;
|
||||
} else
|
||||
{
|
||||
angVel.setValue(0,0,0);
|
||||
}
|
||||
}
|
||||
|
||||
static void calculateDiffAxisAngleQuaternion(const btQuaternion& orn0,const btQuaternion& orn1a,btVector3& axis,btScalar& angle)
|
||||
{
|
||||
btQuaternion orn1 = orn0.nearest(orn1a);
|
||||
btQuaternion dorn = orn1 * orn0.inverse();
|
||||
angle = dorn.getAngle();
|
||||
axis = btVector3(dorn.x(),dorn.y(),dorn.z());
|
||||
axis[3] = btScalar(0.);
|
||||
//check for axis length
|
||||
btScalar len = axis.length2();
|
||||
if (len < SIMD_EPSILON*SIMD_EPSILON)
|
||||
axis = btVector3(btScalar(1.),btScalar(0.),btScalar(0.));
|
||||
else
|
||||
axis /= btSqrt(len);
|
||||
}
|
||||
|
||||
static void calculateVelocity(const btTransform& transform0,const btTransform& transform1,btScalar timeStep,btVector3& linVel,btVector3& angVel)
|
||||
{
|
||||
linVel = (transform1.getOrigin() - transform0.getOrigin()) / timeStep;
|
||||
btVector3 axis;
|
||||
btScalar angle;
|
||||
calculateDiffAxisAngle(transform0,transform1,axis,angle);
|
||||
angVel = axis * angle / timeStep;
|
||||
}
|
||||
|
||||
static void calculateDiffAxisAngle(const btTransform& transform0,const btTransform& transform1,btVector3& axis,btScalar& angle)
|
||||
{
|
||||
btMatrix3x3 dmat = transform1.getBasis() * transform0.getBasis().inverse();
|
||||
btQuaternion dorn;
|
||||
dmat.getRotation(dorn);
|
||||
|
||||
///floating point inaccuracy can lead to w component > 1..., which breaks
|
||||
dorn.normalize();
|
||||
|
||||
angle = dorn.getAngle();
|
||||
axis = btVector3(dorn.x(),dorn.y(),dorn.z());
|
||||
axis[3] = btScalar(0.);
|
||||
//check for axis length
|
||||
btScalar len = axis.length2();
|
||||
if (len < SIMD_EPSILON*SIMD_EPSILON)
|
||||
axis = btVector3(btScalar(1.),btScalar(0.),btScalar(0.));
|
||||
else
|
||||
axis /= btSqrt(len);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
///The btConvexSeparatingDistanceUtil can help speed up convex collision detection
|
||||
///by conservatively updating a cached separating distance/vector instead of re-calculating the closest distance
|
||||
class btConvexSeparatingDistanceUtil
|
||||
{
|
||||
btQuaternion m_ornA;
|
||||
btQuaternion m_ornB;
|
||||
btVector3 m_posA;
|
||||
btVector3 m_posB;
|
||||
|
||||
btVector3 m_separatingNormal;
|
||||
|
||||
btScalar m_boundingRadiusA;
|
||||
btScalar m_boundingRadiusB;
|
||||
btScalar m_separatingDistance;
|
||||
|
||||
public:
|
||||
|
||||
btConvexSeparatingDistanceUtil(btScalar boundingRadiusA,btScalar boundingRadiusB)
|
||||
:m_boundingRadiusA(boundingRadiusA),
|
||||
m_boundingRadiusB(boundingRadiusB),
|
||||
m_separatingDistance(0.f)
|
||||
{
|
||||
}
|
||||
|
||||
btScalar getConservativeSeparatingDistance()
|
||||
{
|
||||
return m_separatingDistance;
|
||||
}
|
||||
|
||||
void updateSeparatingDistance(const btTransform& transA,const btTransform& transB)
|
||||
{
|
||||
const btVector3& toPosA = transA.getOrigin();
|
||||
const btVector3& toPosB = transB.getOrigin();
|
||||
btQuaternion toOrnA = transA.getRotation();
|
||||
btQuaternion toOrnB = transB.getRotation();
|
||||
|
||||
if (m_separatingDistance>0.f)
|
||||
{
|
||||
|
||||
|
||||
btVector3 linVelA,angVelA,linVelB,angVelB;
|
||||
btTransformUtil::calculateVelocityQuaternion(m_posA,toPosA,m_ornA,toOrnA,btScalar(1.),linVelA,angVelA);
|
||||
btTransformUtil::calculateVelocityQuaternion(m_posB,toPosB,m_ornB,toOrnB,btScalar(1.),linVelB,angVelB);
|
||||
btScalar maxAngularProjectedVelocity = angVelA.length() * m_boundingRadiusA + angVelB.length() * m_boundingRadiusB;
|
||||
btVector3 relLinVel = (linVelB-linVelA);
|
||||
btScalar relLinVelocLength = relLinVel.dot(m_separatingNormal);
|
||||
if (relLinVelocLength<0.f)
|
||||
{
|
||||
relLinVelocLength = 0.f;
|
||||
}
|
||||
|
||||
btScalar projectedMotion = maxAngularProjectedVelocity +relLinVelocLength;
|
||||
m_separatingDistance -= projectedMotion;
|
||||
}
|
||||
|
||||
m_posA = toPosA;
|
||||
m_posB = toPosB;
|
||||
m_ornA = toOrnA;
|
||||
m_ornB = toOrnB;
|
||||
}
|
||||
|
||||
void initSeparatingDistance(const btVector3& separatingVector,btScalar separatingDistance,const btTransform& transA,const btTransform& transB)
|
||||
{
|
||||
m_separatingDistance = separatingDistance;
|
||||
|
||||
if (m_separatingDistance>0.f)
|
||||
{
|
||||
m_separatingNormal = separatingVector;
|
||||
|
||||
const btVector3& toPosA = transA.getOrigin();
|
||||
const btVector3& toPosB = transB.getOrigin();
|
||||
btQuaternion toOrnA = transA.getRotation();
|
||||
btQuaternion toOrnB = transB.getRotation();
|
||||
m_posA = toPosA;
|
||||
m_posB = toPosB;
|
||||
m_ornA = toOrnA;
|
||||
m_ornB = toOrnB;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //SIMD_TRANSFORM_UTIL_H
|
||||
|
766
libs/bullet/LinearMath/btVector3.h
Normal file
766
libs/bullet/LinearMath/btVector3.h
Normal file
@ -0,0 +1,766 @@
|
||||
/*
|
||||
Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
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 SIMD__VECTOR3_H
|
||||
#define SIMD__VECTOR3_H
|
||||
|
||||
|
||||
#include "btScalar.h"
|
||||
#include "btMinMax.h"
|
||||
|
||||
#ifdef BT_USE_DOUBLE_PRECISION
|
||||
#define btVector3Data btVector3DoubleData
|
||||
#define btVector3DataName "btVector3DoubleData"
|
||||
#else
|
||||
#define btVector3Data btVector3FloatData
|
||||
#define btVector3DataName "btVector3FloatData"
|
||||
#endif //BT_USE_DOUBLE_PRECISION
|
||||
|
||||
|
||||
|
||||
|
||||
/**@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:
|
||||
|
||||
#if defined (__SPU__) && defined (__CELLOS_LV2__)
|
||||
btScalar m_floats[4];
|
||||
public:
|
||||
SIMD_FORCE_INLINE const vec_float4& get128() const
|
||||
{
|
||||
return *((const vec_float4*)&m_floats[0]);
|
||||
}
|
||||
public:
|
||||
#else //__CELLOS_LV2__ __SPU__
|
||||
#ifdef BT_USE_SSE // _WIN32
|
||||
union {
|
||||
__m128 mVec128;
|
||||
btScalar m_floats[4];
|
||||
};
|
||||
SIMD_FORCE_INLINE __m128 get128() const
|
||||
{
|
||||
return mVec128;
|
||||
}
|
||||
SIMD_FORCE_INLINE void set128(__m128 v128)
|
||||
{
|
||||
mVec128 = v128;
|
||||
}
|
||||
#else
|
||||
btScalar m_floats[4];
|
||||
#endif
|
||||
#endif //__CELLOS_LV2__ __SPU__
|
||||
|
||||
public:
|
||||
|
||||
/**@brief No initialization constructor */
|
||||
SIMD_FORCE_INLINE btVector3() {}
|
||||
|
||||
|
||||
|
||||
/**@brief Constructor from scalars
|
||||
* @param x X value
|
||||
* @param y Y value
|
||||
* @param z Z value
|
||||
*/
|
||||
SIMD_FORCE_INLINE btVector3(const btScalar& x, const btScalar& y, const btScalar& z)
|
||||
{
|
||||
m_floats[0] = x;
|
||||
m_floats[1] = y;
|
||||
m_floats[2] = z;
|
||||
m_floats[3] = btScalar(0.);
|
||||
}
|
||||
|
||||
|
||||
/**@brief Add a vector to this one
|
||||
* @param The vector to add to this one */
|
||||
SIMD_FORCE_INLINE btVector3& operator+=(const btVector3& v)
|
||||
{
|
||||
|
||||
m_floats[0] += v.m_floats[0]; m_floats[1] += v.m_floats[1];m_floats[2] += v.m_floats[2];
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Subtract a vector from this one
|
||||
* @param The vector to subtract */
|
||||
SIMD_FORCE_INLINE btVector3& operator-=(const btVector3& v)
|
||||
{
|
||||
m_floats[0] -= v.m_floats[0]; m_floats[1] -= v.m_floats[1];m_floats[2] -= v.m_floats[2];
|
||||
return *this;
|
||||
}
|
||||
/**@brief Scale the vector
|
||||
* @param s Scale factor */
|
||||
SIMD_FORCE_INLINE btVector3& operator*=(const btScalar& s)
|
||||
{
|
||||
m_floats[0] *= s; m_floats[1] *= s;m_floats[2] *= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**@brief Inversely scale the vector
|
||||
* @param s Scale factor to divide by */
|
||||
SIMD_FORCE_INLINE btVector3& operator/=(const btScalar& s)
|
||||
{
|
||||
btFullAssert(s != btScalar(0.0));
|
||||
return *this *= btScalar(1.0) / s;
|
||||
}
|
||||
|
||||
/**@brief Return the dot product
|
||||
* @param v The other vector in the dot product */
|
||||
SIMD_FORCE_INLINE btScalar dot(const btVector3& v) const
|
||||
{
|
||||
return m_floats[0] * v.m_floats[0] + m_floats[1] * v.m_floats[1] +m_floats[2] * v.m_floats[2];
|
||||
}
|
||||
|
||||
/**@brief Return the length of the vector squared */
|
||||
SIMD_FORCE_INLINE btScalar length2() const
|
||||
{
|
||||
return dot(*this);
|
||||
}
|
||||
|
||||
/**@brief Return the length of the vector */
|
||||
SIMD_FORCE_INLINE btScalar length() const
|
||||
{
|
||||
return btSqrt(length2());
|
||||
}
|
||||
|
||||
/**@brief Return the distance squared between the ends of this and another vector
|
||||
* This is symantically treating the vector like a point */
|
||||
SIMD_FORCE_INLINE btScalar distance2(const btVector3& v) const;
|
||||
|
||||
/**@brief Return the distance between the ends of this and another vector
|
||||
* This is symantically treating the vector like a point */
|
||||
SIMD_FORCE_INLINE btScalar distance(const btVector3& v) const;
|
||||
|
||||
SIMD_FORCE_INLINE btVector3& safeNormalize()
|
||||
{
|
||||
btVector3 absVec = this->absolute();
|
||||
int maxIndex = absVec.maxAxis();
|
||||
if (absVec[maxIndex]>0)
|
||||
{
|
||||
*this /= absVec[maxIndex];
|
||||
return *this /= length();
|
||||
}
|
||||
setValue(1,0,0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**@brief Normalize this vector
|
||||
* x^2 + y^2 + z^2 = 1 */
|
||||
SIMD_FORCE_INLINE btVector3& normalize()
|
||||
{
|
||||
return *this /= length();
|
||||
}
|
||||
|
||||
/**@brief Return a normalized version of this vector */
|
||||
SIMD_FORCE_INLINE btVector3 normalized() const;
|
||||
|
||||
/**@brief Return a rotated version of this vector
|
||||
* @param wAxis The axis to rotate about
|
||||
* @param angle The angle to rotate by */
|
||||
SIMD_FORCE_INLINE btVector3 rotate( const btVector3& wAxis, const btScalar angle ) const;
|
||||
|
||||
/**@brief Return the angle between this and another vector
|
||||
* @param v The other vector */
|
||||
SIMD_FORCE_INLINE btScalar angle(const btVector3& v) const
|
||||
{
|
||||
btScalar s = btSqrt(length2() * v.length2());
|
||||
btFullAssert(s != btScalar(0.0));
|
||||
return btAcos(dot(v) / s);
|
||||
}
|
||||
/**@brief Return a vector will the absolute values of each element */
|
||||
SIMD_FORCE_INLINE btVector3 absolute() const
|
||||
{
|
||||
return btVector3(
|
||||
btFabs(m_floats[0]),
|
||||
btFabs(m_floats[1]),
|
||||
btFabs(m_floats[2]));
|
||||
}
|
||||
/**@brief Return the cross product between this and another vector
|
||||
* @param v The other vector */
|
||||
SIMD_FORCE_INLINE btVector3 cross(const btVector3& v) const
|
||||
{
|
||||
return btVector3(
|
||||
m_floats[1] * v.m_floats[2] -m_floats[2] * v.m_floats[1],
|
||||
m_floats[2] * v.m_floats[0] - m_floats[0] * v.m_floats[2],
|
||||
m_floats[0] * v.m_floats[1] - m_floats[1] * v.m_floats[0]);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btScalar triple(const btVector3& v1, const btVector3& v2) const
|
||||
{
|
||||
return m_floats[0] * (v1.m_floats[1] * v2.m_floats[2] - v1.m_floats[2] * v2.m_floats[1]) +
|
||||
m_floats[1] * (v1.m_floats[2] * v2.m_floats[0] - v1.m_floats[0] * v2.m_floats[2]) +
|
||||
m_floats[2] * (v1.m_floats[0] * v2.m_floats[1] - v1.m_floats[1] * v2.m_floats[0]);
|
||||
}
|
||||
|
||||
/**@brief Return the axis with the smallest value
|
||||
* Note return values are 0,1,2 for x, y, or z */
|
||||
SIMD_FORCE_INLINE int minAxis() const
|
||||
{
|
||||
return m_floats[0] < m_floats[1] ? (m_floats[0] <m_floats[2] ? 0 : 2) : (m_floats[1] <m_floats[2] ? 1 : 2);
|
||||
}
|
||||
|
||||
/**@brief Return the axis with the largest value
|
||||
* Note return values are 0,1,2 for x, y, or z */
|
||||
SIMD_FORCE_INLINE int maxAxis() const
|
||||
{
|
||||
return m_floats[0] < m_floats[1] ? (m_floats[1] <m_floats[2] ? 2 : 1) : (m_floats[0] <m_floats[2] ? 2 : 0);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE int furthestAxis() const
|
||||
{
|
||||
return absolute().minAxis();
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE int closestAxis() const
|
||||
{
|
||||
return absolute().maxAxis();
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void setInterpolate3(const btVector3& v0, const btVector3& v1, btScalar rt)
|
||||
{
|
||||
btScalar s = btScalar(1.0) - rt;
|
||||
m_floats[0] = s * v0.m_floats[0] + rt * v1.m_floats[0];
|
||||
m_floats[1] = s * v0.m_floats[1] + rt * v1.m_floats[1];
|
||||
m_floats[2] = s * v0.m_floats[2] + rt * v1.m_floats[2];
|
||||
//don't do the unused w component
|
||||
// m_co[3] = s * v0[3] + rt * v1[3];
|
||||
}
|
||||
|
||||
/**@brief Return the linear interpolation between this and another vector
|
||||
* @param v The other vector
|
||||
* @param t The ration of this to v (t = 0 => return this, t=1 => return other) */
|
||||
SIMD_FORCE_INLINE btVector3 lerp(const btVector3& v, const btScalar& t) const
|
||||
{
|
||||
return btVector3(m_floats[0] + (v.m_floats[0] - m_floats[0]) * t,
|
||||
m_floats[1] + (v.m_floats[1] - m_floats[1]) * t,
|
||||
m_floats[2] + (v.m_floats[2] -m_floats[2]) * t);
|
||||
}
|
||||
|
||||
/**@brief Elementwise multiply this vector by the other
|
||||
* @param v The other vector */
|
||||
SIMD_FORCE_INLINE btVector3& operator*=(const btVector3& v)
|
||||
{
|
||||
m_floats[0] *= v.m_floats[0]; m_floats[1] *= v.m_floats[1];m_floats[2] *= v.m_floats[2];
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**@brief Return the x value */
|
||||
SIMD_FORCE_INLINE const btScalar& getX() const { return m_floats[0]; }
|
||||
/**@brief Return the y value */
|
||||
SIMD_FORCE_INLINE const btScalar& getY() const { return m_floats[1]; }
|
||||
/**@brief Return the z value */
|
||||
SIMD_FORCE_INLINE const btScalar& getZ() const { return m_floats[2]; }
|
||||
/**@brief Set the x value */
|
||||
SIMD_FORCE_INLINE void setX(btScalar x) { m_floats[0] = x;};
|
||||
/**@brief Set the y value */
|
||||
SIMD_FORCE_INLINE void setY(btScalar y) { m_floats[1] = y;};
|
||||
/**@brief Set the z value */
|
||||
SIMD_FORCE_INLINE void setZ(btScalar z) {m_floats[2] = z;};
|
||||
/**@brief Set the w value */
|
||||
SIMD_FORCE_INLINE void setW(btScalar w) { m_floats[3] = w;};
|
||||
/**@brief Return the x value */
|
||||
SIMD_FORCE_INLINE const btScalar& x() const { return m_floats[0]; }
|
||||
/**@brief Return the y value */
|
||||
SIMD_FORCE_INLINE const btScalar& y() const { return m_floats[1]; }
|
||||
/**@brief Return the z value */
|
||||
SIMD_FORCE_INLINE const btScalar& z() const { return m_floats[2]; }
|
||||
/**@brief Return the w value */
|
||||
SIMD_FORCE_INLINE const btScalar& w() const { return m_floats[3]; }
|
||||
|
||||
//SIMD_FORCE_INLINE btScalar& operator[](int i) { return (&m_floats[0])[i]; }
|
||||
//SIMD_FORCE_INLINE const btScalar& operator[](int i) const { return (&m_floats[0])[i]; }
|
||||
///operator btScalar*() replaces operator[], using implicit conversion. We added operator != and operator == to avoid pointer comparisons.
|
||||
SIMD_FORCE_INLINE operator btScalar *() { return &m_floats[0]; }
|
||||
SIMD_FORCE_INLINE operator const btScalar *() const { return &m_floats[0]; }
|
||||
|
||||
SIMD_FORCE_INLINE bool operator==(const btVector3& other) const
|
||||
{
|
||||
return ((m_floats[3]==other.m_floats[3]) && (m_floats[2]==other.m_floats[2]) && (m_floats[1]==other.m_floats[1]) && (m_floats[0]==other.m_floats[0]));
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE bool operator!=(const btVector3& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
/**@brief Set each element to the max of the current values and the values of another btVector3
|
||||
* @param other The other btVector3 to compare with
|
||||
*/
|
||||
SIMD_FORCE_INLINE void setMax(const btVector3& other)
|
||||
{
|
||||
btSetMax(m_floats[0], other.m_floats[0]);
|
||||
btSetMax(m_floats[1], other.m_floats[1]);
|
||||
btSetMax(m_floats[2], other.m_floats[2]);
|
||||
btSetMax(m_floats[3], other.w());
|
||||
}
|
||||
/**@brief Set each element to the min of the current values and the values of another btVector3
|
||||
* @param other The other btVector3 to compare with
|
||||
*/
|
||||
SIMD_FORCE_INLINE void setMin(const btVector3& other)
|
||||
{
|
||||
btSetMin(m_floats[0], other.m_floats[0]);
|
||||
btSetMin(m_floats[1], other.m_floats[1]);
|
||||
btSetMin(m_floats[2], other.m_floats[2]);
|
||||
btSetMin(m_floats[3], other.w());
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z)
|
||||
{
|
||||
m_floats[0]=x;
|
||||
m_floats[1]=y;
|
||||
m_floats[2]=z;
|
||||
m_floats[3] = btScalar(0.);
|
||||
}
|
||||
|
||||
void getSkewSymmetricMatrix(btVector3* v0,btVector3* v1,btVector3* v2) const
|
||||
{
|
||||
v0->setValue(0. ,-z() ,y());
|
||||
v1->setValue(z() ,0. ,-x());
|
||||
v2->setValue(-y() ,x() ,0.);
|
||||
}
|
||||
|
||||
void setZero()
|
||||
{
|
||||
setValue(btScalar(0.),btScalar(0.),btScalar(0.));
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE bool isZero() const
|
||||
{
|
||||
return m_floats[0] == btScalar(0) && m_floats[1] == btScalar(0) && m_floats[2] == btScalar(0);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE bool fuzzyZero() const
|
||||
{
|
||||
return length2() < SIMD_EPSILON;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void serialize(struct btVector3Data& dataOut) const;
|
||||
|
||||
SIMD_FORCE_INLINE void deSerialize(const struct btVector3Data& dataIn);
|
||||
|
||||
SIMD_FORCE_INLINE void serializeFloat(struct btVector3FloatData& dataOut) const;
|
||||
|
||||
SIMD_FORCE_INLINE void deSerializeFloat(const struct btVector3FloatData& dataIn);
|
||||
|
||||
SIMD_FORCE_INLINE void serializeDouble(struct btVector3DoubleData& dataOut) const;
|
||||
|
||||
SIMD_FORCE_INLINE void deSerializeDouble(const struct btVector3DoubleData& dataIn);
|
||||
|
||||
};
|
||||
|
||||
/**@brief Return the sum of two vectors (Point symantics)*/
|
||||
SIMD_FORCE_INLINE btVector3
|
||||
operator+(const btVector3& v1, const btVector3& v2)
|
||||
{
|
||||
return btVector3(v1.m_floats[0] + v2.m_floats[0], v1.m_floats[1] + v2.m_floats[1], v1.m_floats[2] + v2.m_floats[2]);
|
||||
}
|
||||
|
||||
/**@brief Return the elementwise product of two vectors */
|
||||
SIMD_FORCE_INLINE btVector3
|
||||
operator*(const btVector3& v1, const btVector3& v2)
|
||||
{
|
||||
return btVector3(v1.m_floats[0] * v2.m_floats[0], v1.m_floats[1] * v2.m_floats[1], v1.m_floats[2] * v2.m_floats[2]);
|
||||
}
|
||||
|
||||
/**@brief Return the difference between two vectors */
|
||||
SIMD_FORCE_INLINE btVector3
|
||||
operator-(const btVector3& v1, const btVector3& v2)
|
||||
{
|
||||
return btVector3(v1.m_floats[0] - v2.m_floats[0], v1.m_floats[1] - v2.m_floats[1], v1.m_floats[2] - v2.m_floats[2]);
|
||||
}
|
||||
/**@brief Return the negative of the vector */
|
||||
SIMD_FORCE_INLINE btVector3
|
||||
operator-(const btVector3& v)
|
||||
{
|
||||
return btVector3(-v.m_floats[0], -v.m_floats[1], -v.m_floats[2]);
|
||||
}
|
||||
|
||||
/**@brief Return the vector scaled by s */
|
||||
SIMD_FORCE_INLINE btVector3
|
||||
operator*(const btVector3& v, const btScalar& s)
|
||||
{
|
||||
return btVector3(v.m_floats[0] * s, v.m_floats[1] * s, v.m_floats[2] * s);
|
||||
}
|
||||
|
||||
/**@brief Return the vector scaled by s */
|
||||
SIMD_FORCE_INLINE btVector3
|
||||
operator*(const btScalar& s, const btVector3& v)
|
||||
{
|
||||
return v * s;
|
||||
}
|
||||
|
||||
/**@brief Return the vector inversely scaled by s */
|
||||
SIMD_FORCE_INLINE btVector3
|
||||
operator/(const btVector3& v, const btScalar& s)
|
||||
{
|
||||
btFullAssert(s != btScalar(0.0));
|
||||
return v * (btScalar(1.0) / s);
|
||||
}
|
||||
|
||||
/**@brief Return the vector inversely scaled by s */
|
||||
SIMD_FORCE_INLINE btVector3
|
||||
operator/(const btVector3& v1, const btVector3& v2)
|
||||
{
|
||||
return btVector3(v1.m_floats[0] / v2.m_floats[0],v1.m_floats[1] / v2.m_floats[1],v1.m_floats[2] / v2.m_floats[2]);
|
||||
}
|
||||
|
||||
/**@brief Return the dot product between two vectors */
|
||||
SIMD_FORCE_INLINE btScalar
|
||||
btDot(const btVector3& v1, const btVector3& v2)
|
||||
{
|
||||
return v1.dot(v2);
|
||||
}
|
||||
|
||||
|
||||
/**@brief Return the distance squared between two vectors */
|
||||
SIMD_FORCE_INLINE btScalar
|
||||
btDistance2(const btVector3& v1, const btVector3& v2)
|
||||
{
|
||||
return v1.distance2(v2);
|
||||
}
|
||||
|
||||
|
||||
/**@brief Return the distance between two vectors */
|
||||
SIMD_FORCE_INLINE btScalar
|
||||
btDistance(const btVector3& v1, const btVector3& v2)
|
||||
{
|
||||
return v1.distance(v2);
|
||||
}
|
||||
|
||||
/**@brief Return the angle between two vectors */
|
||||
SIMD_FORCE_INLINE btScalar
|
||||
btAngle(const btVector3& v1, const btVector3& v2)
|
||||
{
|
||||
return v1.angle(v2);
|
||||
}
|
||||
|
||||
/**@brief Return the cross product of two vectors */
|
||||
SIMD_FORCE_INLINE btVector3
|
||||
btCross(const btVector3& v1, const btVector3& v2)
|
||||
{
|
||||
return v1.cross(v2);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btScalar
|
||||
btTriple(const btVector3& v1, const btVector3& v2, const btVector3& v3)
|
||||
{
|
||||
return v1.triple(v2, v3);
|
||||
}
|
||||
|
||||
/**@brief Return the linear interpolation between two vectors
|
||||
* @param v1 One vector
|
||||
* @param v2 The other vector
|
||||
* @param t The ration of this to v (t = 0 => return v1, t=1 => return v2) */
|
||||
SIMD_FORCE_INLINE btVector3
|
||||
lerp(const btVector3& v1, const btVector3& v2, const btScalar& t)
|
||||
{
|
||||
return v1.lerp(v2, t);
|
||||
}
|
||||
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE btScalar btVector3::distance2(const btVector3& v) const
|
||||
{
|
||||
return (v - *this).length2();
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btScalar btVector3::distance(const btVector3& v) const
|
||||
{
|
||||
return (v - *this).length();
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btVector3 btVector3::normalized() const
|
||||
{
|
||||
return *this / length();
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btVector3 btVector3::rotate( const btVector3& wAxis, const btScalar angle ) const
|
||||
{
|
||||
// wAxis must be a unit lenght vector
|
||||
|
||||
btVector3 o = wAxis * wAxis.dot( *this );
|
||||
btVector3 x = *this - o;
|
||||
btVector3 y;
|
||||
|
||||
y = wAxis.cross( *this );
|
||||
|
||||
return ( o + x * btCos( angle ) + y * btSin( angle ) );
|
||||
}
|
||||
|
||||
class btVector4 : public btVector3
|
||||
{
|
||||
public:
|
||||
|
||||
SIMD_FORCE_INLINE btVector4() {}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE btVector4(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w)
|
||||
: btVector3(x,y,z)
|
||||
{
|
||||
m_floats[3] = w;
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE btVector4 absolute4() const
|
||||
{
|
||||
return btVector4(
|
||||
btFabs(m_floats[0]),
|
||||
btFabs(m_floats[1]),
|
||||
btFabs(m_floats[2]),
|
||||
btFabs(m_floats[3]));
|
||||
}
|
||||
|
||||
|
||||
|
||||
btScalar getW() const { return m_floats[3];}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE int maxAxis4() const
|
||||
{
|
||||
int maxIndex = -1;
|
||||
btScalar maxVal = btScalar(-BT_LARGE_FLOAT);
|
||||
if (m_floats[0] > maxVal)
|
||||
{
|
||||
maxIndex = 0;
|
||||
maxVal = m_floats[0];
|
||||
}
|
||||
if (m_floats[1] > maxVal)
|
||||
{
|
||||
maxIndex = 1;
|
||||
maxVal = m_floats[1];
|
||||
}
|
||||
if (m_floats[2] > maxVal)
|
||||
{
|
||||
maxIndex = 2;
|
||||
maxVal =m_floats[2];
|
||||
}
|
||||
if (m_floats[3] > maxVal)
|
||||
{
|
||||
maxIndex = 3;
|
||||
maxVal = m_floats[3];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return maxIndex;
|
||||
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE int minAxis4() const
|
||||
{
|
||||
int minIndex = -1;
|
||||
btScalar minVal = btScalar(BT_LARGE_FLOAT);
|
||||
if (m_floats[0] < minVal)
|
||||
{
|
||||
minIndex = 0;
|
||||
minVal = m_floats[0];
|
||||
}
|
||||
if (m_floats[1] < minVal)
|
||||
{
|
||||
minIndex = 1;
|
||||
minVal = m_floats[1];
|
||||
}
|
||||
if (m_floats[2] < minVal)
|
||||
{
|
||||
minIndex = 2;
|
||||
minVal =m_floats[2];
|
||||
}
|
||||
if (m_floats[3] < minVal)
|
||||
{
|
||||
minIndex = 3;
|
||||
minVal = m_floats[3];
|
||||
}
|
||||
|
||||
return minIndex;
|
||||
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE int closestAxis4() const
|
||||
{
|
||||
return absolute4().maxAxis4();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**@brief Set x,y,z and zero w
|
||||
* @param x Value of x
|
||||
* @param y Value of y
|
||||
* @param z Value of z
|
||||
*/
|
||||
|
||||
|
||||
/* void getValue(btScalar *m) const
|
||||
{
|
||||
m[0] = m_floats[0];
|
||||
m[1] = m_floats[1];
|
||||
m[2] =m_floats[2];
|
||||
}
|
||||
*/
|
||||
/**@brief Set the values
|
||||
* @param x Value of x
|
||||
* @param y Value of y
|
||||
* @param z Value of z
|
||||
* @param w Value of w
|
||||
*/
|
||||
SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w)
|
||||
{
|
||||
m_floats[0]=x;
|
||||
m_floats[1]=y;
|
||||
m_floats[2]=z;
|
||||
m_floats[3]=w;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
///btSwapVector3Endian swaps vector endianness, useful for network and cross-platform serialization
|
||||
SIMD_FORCE_INLINE void btSwapScalarEndian(const btScalar& sourceVal, btScalar& destVal)
|
||||
{
|
||||
#ifdef BT_USE_DOUBLE_PRECISION
|
||||
unsigned char* dest = (unsigned char*) &destVal;
|
||||
unsigned char* src = (unsigned char*) &sourceVal;
|
||||
dest[0] = src[7];
|
||||
dest[1] = src[6];
|
||||
dest[2] = src[5];
|
||||
dest[3] = src[4];
|
||||
dest[4] = src[3];
|
||||
dest[5] = src[2];
|
||||
dest[6] = src[1];
|
||||
dest[7] = src[0];
|
||||
#else
|
||||
unsigned char* dest = (unsigned char*) &destVal;
|
||||
unsigned char* src = (unsigned char*) &sourceVal;
|
||||
dest[0] = src[3];
|
||||
dest[1] = src[2];
|
||||
dest[2] = src[1];
|
||||
dest[3] = src[0];
|
||||
#endif //BT_USE_DOUBLE_PRECISION
|
||||
}
|
||||
///btSwapVector3Endian swaps vector endianness, useful for network and cross-platform serialization
|
||||
SIMD_FORCE_INLINE void btSwapVector3Endian(const btVector3& sourceVec, btVector3& destVec)
|
||||
{
|
||||
for (int i=0;i<4;i++)
|
||||
{
|
||||
btSwapScalarEndian(sourceVec[i],destVec[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
///btUnSwapVector3Endian swaps vector endianness, useful for network and cross-platform serialization
|
||||
SIMD_FORCE_INLINE void btUnSwapVector3Endian(btVector3& vector)
|
||||
{
|
||||
|
||||
btVector3 swappedVec;
|
||||
for (int i=0;i<4;i++)
|
||||
{
|
||||
btSwapScalarEndian(vector[i],swappedVec[i]);
|
||||
}
|
||||
vector = swappedVec;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
SIMD_FORCE_INLINE void btPlaneSpace1 (const T& n, T& p, T& q)
|
||||
{
|
||||
if (btFabs(n[2]) > SIMDSQRT12) {
|
||||
// choose p in y-z plane
|
||||
btScalar a = n[1]*n[1] + n[2]*n[2];
|
||||
btScalar k = btRecipSqrt (a);
|
||||
p[0] = 0;
|
||||
p[1] = -n[2]*k;
|
||||
p[2] = n[1]*k;
|
||||
// set q = n x p
|
||||
q[0] = a*k;
|
||||
q[1] = -n[0]*p[2];
|
||||
q[2] = n[0]*p[1];
|
||||
}
|
||||
else {
|
||||
// choose p in x-y plane
|
||||
btScalar a = n[0]*n[0] + n[1]*n[1];
|
||||
btScalar k = btRecipSqrt (a);
|
||||
p[0] = -n[1]*k;
|
||||
p[1] = n[0]*k;
|
||||
p[2] = 0;
|
||||
// set q = n x p
|
||||
q[0] = -n[2]*p[1];
|
||||
q[1] = n[2]*p[0];
|
||||
q[2] = a*k;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct btVector3FloatData
|
||||
{
|
||||
float m_floats[4];
|
||||
};
|
||||
|
||||
struct btVector3DoubleData
|
||||
{
|
||||
double m_floats[4];
|
||||
|
||||
};
|
||||
|
||||
SIMD_FORCE_INLINE void btVector3::serializeFloat(struct btVector3FloatData& dataOut) const
|
||||
{
|
||||
///could also do a memcpy, check if it is worth it
|
||||
for (int i=0;i<4;i++)
|
||||
dataOut.m_floats[i] = float(m_floats[i]);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void btVector3::deSerializeFloat(const struct btVector3FloatData& dataIn)
|
||||
{
|
||||
for (int i=0;i<4;i++)
|
||||
m_floats[i] = btScalar(dataIn.m_floats[i]);
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE void btVector3::serializeDouble(struct btVector3DoubleData& dataOut) const
|
||||
{
|
||||
///could also do a memcpy, check if it is worth it
|
||||
for (int i=0;i<4;i++)
|
||||
dataOut.m_floats[i] = double(m_floats[i]);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void btVector3::deSerializeDouble(const struct btVector3DoubleData& dataIn)
|
||||
{
|
||||
for (int i=0;i<4;i++)
|
||||
m_floats[i] = btScalar(dataIn.m_floats[i]);
|
||||
}
|
||||
|
||||
|
||||
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