Code-style consistency improvement:
Apply clang-format-all.sh using the _clang-format file through all the cpp/.h files. make sure not to apply it to certain serialization structures, since some parser expects the * as part of the name, instead of type. This commit contains no other changes aside from adding and applying clang-format-all.sh
This commit is contained in:
@@ -17,7 +17,7 @@ subject to the following restrictions:
|
||||
|
||||
int b3g_numAlignedAllocs = 0;
|
||||
int b3g_numAlignedFree = 0;
|
||||
int b3g_totalBytesAlignedAllocs = 0;//detect memory leaks
|
||||
int b3g_totalBytesAlignedAllocs = 0; //detect memory leaks
|
||||
|
||||
static void *b3AllocDefault(size_t size)
|
||||
{
|
||||
@@ -29,12 +29,10 @@ static void b3FreeDefault(void *ptr)
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
static b3AllocFunc* b3s_allocFunc = b3AllocDefault;
|
||||
static b3FreeFunc* b3s_freeFunc = b3FreeDefault;
|
||||
static b3AllocFunc *b3s_allocFunc = b3AllocDefault;
|
||||
static b3FreeFunc *b3s_freeFunc = b3FreeDefault;
|
||||
|
||||
|
||||
|
||||
#if defined (B3_HAS_ALIGNED_ALLOCATOR)
|
||||
#if defined(B3_HAS_ALIGNED_ALLOCATOR)
|
||||
#include <malloc.h>
|
||||
static void *b3AlignedAllocDefault(size_t size, int alignment)
|
||||
{
|
||||
@@ -59,113 +57,114 @@ static inline void b3AlignedFreeDefault(void *ptr)
|
||||
}
|
||||
#else
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static inline void *b3AlignedAllocDefault(size_t size, int alignment)
|
||||
{
|
||||
void *ret;
|
||||
char *real;
|
||||
real = (char *)b3s_allocFunc(size + sizeof(void *) + (alignment-1));
|
||||
if (real) {
|
||||
ret = b3AlignPointer(real + sizeof(void *),alignment);
|
||||
*((void **)(ret)-1) = (void *)(real);
|
||||
} else {
|
||||
ret = (void *)(real);
|
||||
}
|
||||
return (ret);
|
||||
void *ret;
|
||||
char *real;
|
||||
real = (char *)b3s_allocFunc(size + sizeof(void *) + (alignment - 1));
|
||||
if (real)
|
||||
{
|
||||
ret = b3AlignPointer(real + sizeof(void *), alignment);
|
||||
*((void **)(ret)-1) = (void *)(real);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = (void *)(real);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static inline void b3AlignedFreeDefault(void *ptr)
|
||||
{
|
||||
void* real;
|
||||
void *real;
|
||||
|
||||
if (ptr) {
|
||||
real = *((void **)(ptr)-1);
|
||||
b3s_freeFunc(real);
|
||||
}
|
||||
if (ptr)
|
||||
{
|
||||
real = *((void **)(ptr)-1);
|
||||
b3s_freeFunc(real);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static b3AlignedAllocFunc* b3s_alignedAllocFunc = b3AlignedAllocDefault;
|
||||
static b3AlignedFreeFunc* b3s_alignedFreeFunc = b3AlignedFreeDefault;
|
||||
static b3AlignedAllocFunc *b3s_alignedAllocFunc = b3AlignedAllocDefault;
|
||||
static b3AlignedFreeFunc *b3s_alignedFreeFunc = b3AlignedFreeDefault;
|
||||
|
||||
void b3AlignedAllocSetCustomAligned(b3AlignedAllocFunc *allocFunc, b3AlignedFreeFunc *freeFunc)
|
||||
{
|
||||
b3s_alignedAllocFunc = allocFunc ? allocFunc : b3AlignedAllocDefault;
|
||||
b3s_alignedFreeFunc = freeFunc ? freeFunc : b3AlignedFreeDefault;
|
||||
b3s_alignedAllocFunc = allocFunc ? allocFunc : b3AlignedAllocDefault;
|
||||
b3s_alignedFreeFunc = freeFunc ? freeFunc : b3AlignedFreeDefault;
|
||||
}
|
||||
|
||||
void b3AlignedAllocSetCustom(b3AllocFunc *allocFunc, b3FreeFunc *freeFunc)
|
||||
{
|
||||
b3s_allocFunc = allocFunc ? allocFunc : b3AllocDefault;
|
||||
b3s_freeFunc = freeFunc ? freeFunc : b3FreeDefault;
|
||||
b3s_allocFunc = allocFunc ? allocFunc : b3AllocDefault;
|
||||
b3s_freeFunc = freeFunc ? freeFunc : b3FreeDefault;
|
||||
}
|
||||
|
||||
#ifdef B3_DEBUG_MEMORY_ALLOCATIONS
|
||||
//this generic allocator provides the total allocated number of bytes
|
||||
#include <stdio.h>
|
||||
|
||||
void* b3AlignedAllocInternal (size_t size, int alignment,int line,char* filename)
|
||||
void *b3AlignedAllocInternal(size_t size, int alignment, int line, char *filename)
|
||||
{
|
||||
void *ret;
|
||||
char *real;
|
||||
void *ret;
|
||||
char *real;
|
||||
|
||||
b3g_totalBytesAlignedAllocs += size;
|
||||
b3g_numAlignedAllocs++;
|
||||
b3g_totalBytesAlignedAllocs += size;
|
||||
b3g_numAlignedAllocs++;
|
||||
|
||||
|
||||
real = (char *)b3s_allocFunc(size + 2*sizeof(void *) + (alignment-1));
|
||||
if (real) {
|
||||
ret = (void*) b3AlignPointer(real + 2*sizeof(void *), alignment);
|
||||
*((void **)(ret)-1) = (void *)(real);
|
||||
*((int*)(ret)-2) = size;
|
||||
real = (char *)b3s_allocFunc(size + 2 * sizeof(void *) + (alignment - 1));
|
||||
if (real)
|
||||
{
|
||||
ret = (void *)b3AlignPointer(real + 2 * sizeof(void *), alignment);
|
||||
*((void **)(ret)-1) = (void *)(real);
|
||||
*((int *)(ret)-2) = size;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = (void *)(real); //??
|
||||
}
|
||||
|
||||
} else {
|
||||
ret = (void *)(real);//??
|
||||
}
|
||||
b3Printf("allocation#%d at address %x, from %s,line %d, size %d\n", b3g_numAlignedAllocs, real, filename, line, size);
|
||||
|
||||
b3Printf("allocation#%d at address %x, from %s,line %d, size %d\n",b3g_numAlignedAllocs,real, filename,line,size);
|
||||
|
||||
int* ptr = (int*)ret;
|
||||
*ptr = 12;
|
||||
return (ret);
|
||||
int *ptr = (int *)ret;
|
||||
*ptr = 12;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void b3AlignedFreeInternal (void* ptr,int line,char* filename)
|
||||
void b3AlignedFreeInternal(void *ptr, int line, char *filename)
|
||||
{
|
||||
void *real;
|
||||
b3g_numAlignedFree++;
|
||||
|
||||
void* real;
|
||||
b3g_numAlignedFree++;
|
||||
if (ptr)
|
||||
{
|
||||
real = *((void **)(ptr)-1);
|
||||
int size = *((int *)(ptr)-2);
|
||||
b3g_totalBytesAlignedAllocs -= size;
|
||||
|
||||
if (ptr) {
|
||||
real = *((void **)(ptr)-1);
|
||||
int size = *((int*)(ptr)-2);
|
||||
b3g_totalBytesAlignedAllocs -= size;
|
||||
b3Printf("free #%d at address %x, from %s,line %d, size %d\n", b3g_numAlignedFree, real, filename, line, size);
|
||||
|
||||
b3Printf("free #%d at address %x, from %s,line %d, size %d\n",b3g_numAlignedFree,real, filename,line,size);
|
||||
|
||||
b3s_freeFunc(real);
|
||||
} else
|
||||
{
|
||||
b3Printf("NULL ptr\n");
|
||||
}
|
||||
b3s_freeFunc(real);
|
||||
}
|
||||
else
|
||||
{
|
||||
b3Printf("NULL ptr\n");
|
||||
}
|
||||
}
|
||||
|
||||
#else //B3_DEBUG_MEMORY_ALLOCATIONS
|
||||
#else //B3_DEBUG_MEMORY_ALLOCATIONS
|
||||
|
||||
void* b3AlignedAllocInternal (size_t size, int alignment)
|
||||
void *b3AlignedAllocInternal(size_t size, int alignment)
|
||||
{
|
||||
b3g_numAlignedAllocs++;
|
||||
void* ptr;
|
||||
void *ptr;
|
||||
ptr = b3s_alignedAllocFunc(size, alignment);
|
||||
// b3Printf("b3AlignedAllocInternal %d, %x\n",size,ptr);
|
||||
// b3Printf("b3AlignedAllocInternal %d, %x\n",size,ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void b3AlignedFreeInternal (void* ptr)
|
||||
void b3AlignedFreeInternal(void *ptr)
|
||||
{
|
||||
if (!ptr)
|
||||
{
|
||||
@@ -173,9 +172,8 @@ void b3AlignedFreeInternal (void* ptr)
|
||||
}
|
||||
|
||||
b3g_numAlignedFree++;
|
||||
// b3Printf("b3AlignedFreeInternal %x\n",ptr);
|
||||
// b3Printf("b3AlignedFreeInternal %x\n",ptr);
|
||||
b3s_alignedFreeFunc(ptr);
|
||||
}
|
||||
|
||||
#endif //B3_DEBUG_MEMORY_ALLOCATIONS
|
||||
|
||||
#endif //B3_DEBUG_MEMORY_ALLOCATIONS
|
||||
|
||||
@@ -24,84 +24,87 @@ subject to the following restrictions:
|
||||
//#define B3_DEBUG_MEMORY_ALLOCATIONS 1
|
||||
#ifdef B3_DEBUG_MEMORY_ALLOCATIONS
|
||||
|
||||
#define b3AlignedAlloc(a,b) \
|
||||
b3AlignedAllocInternal(a,b,__LINE__,__FILE__)
|
||||
#define b3AlignedAlloc(a, b) \
|
||||
b3AlignedAllocInternal(a, b, __LINE__, __FILE__)
|
||||
|
||||
#define b3AlignedFree(ptr) \
|
||||
b3AlignedFreeInternal(ptr,__LINE__,__FILE__)
|
||||
b3AlignedFreeInternal(ptr, __LINE__, __FILE__)
|
||||
|
||||
void* b3AlignedAllocInternal (size_t size, int alignment,int line,char* filename);
|
||||
void* b3AlignedAllocInternal(size_t size, int alignment, int line, char* filename);
|
||||
|
||||
void b3AlignedFreeInternal (void* ptr,int line,char* filename);
|
||||
void b3AlignedFreeInternal(void* ptr, int line, char* filename);
|
||||
|
||||
#else
|
||||
void* b3AlignedAllocInternal (size_t size, int alignment);
|
||||
void b3AlignedFreeInternal (void* ptr);
|
||||
void* b3AlignedAllocInternal(size_t size, int alignment);
|
||||
void b3AlignedFreeInternal(void* ptr);
|
||||
|
||||
#define b3AlignedAlloc(size,alignment) b3AlignedAllocInternal(size,alignment)
|
||||
#define b3AlignedFree(ptr) b3AlignedFreeInternal(ptr)
|
||||
#define b3AlignedAlloc(size, alignment) b3AlignedAllocInternal(size, alignment)
|
||||
#define b3AlignedFree(ptr) b3AlignedFreeInternal(ptr)
|
||||
|
||||
#endif
|
||||
typedef int btSizeType;
|
||||
typedef int btSizeType;
|
||||
|
||||
typedef void *(b3AlignedAllocFunc)(size_t size, int alignment);
|
||||
typedef void (b3AlignedFreeFunc)(void *memblock);
|
||||
typedef void *(b3AllocFunc)(size_t size);
|
||||
typedef void (b3FreeFunc)(void *memblock);
|
||||
typedef void*(b3AlignedAllocFunc)(size_t size, int alignment);
|
||||
typedef void(b3AlignedFreeFunc)(void* memblock);
|
||||
typedef void*(b3AllocFunc)(size_t size);
|
||||
typedef void(b3FreeFunc)(void* memblock);
|
||||
|
||||
///The developer can let all Bullet memory allocations go through a custom memory allocator, using b3AlignedAllocSetCustom
|
||||
void b3AlignedAllocSetCustom(b3AllocFunc *allocFunc, b3FreeFunc *freeFunc);
|
||||
void b3AlignedAllocSetCustom(b3AllocFunc* allocFunc, b3FreeFunc* freeFunc);
|
||||
///If the developer has already an custom aligned allocator, then b3AlignedAllocSetCustomAligned can be used. The default aligned allocator pre-allocates extra memory using the non-aligned allocator, and instruments it.
|
||||
void b3AlignedAllocSetCustomAligned(b3AlignedAllocFunc *allocFunc, b3AlignedFreeFunc *freeFunc);
|
||||
|
||||
void b3AlignedAllocSetCustomAligned(b3AlignedAllocFunc* allocFunc, b3AlignedFreeFunc* freeFunc);
|
||||
|
||||
///The b3AlignedAllocator is a portable class for aligned memory allocations.
|
||||
///Default implementations for unaligned and aligned allocations can be overridden by a custom allocator using b3AlignedAllocSetCustom and b3AlignedAllocSetCustomAligned.
|
||||
template < typename T , unsigned Alignment >
|
||||
class b3AlignedAllocator {
|
||||
|
||||
typedef b3AlignedAllocator< T , Alignment > self_type;
|
||||
|
||||
public:
|
||||
template <typename T, unsigned Alignment>
|
||||
class b3AlignedAllocator
|
||||
{
|
||||
typedef b3AlignedAllocator<T, Alignment> self_type;
|
||||
|
||||
public:
|
||||
//just going down a list:
|
||||
b3AlignedAllocator() {}
|
||||
/*
|
||||
b3AlignedAllocator( const self_type & ) {}
|
||||
*/
|
||||
|
||||
template < typename Other >
|
||||
b3AlignedAllocator( const b3AlignedAllocator< Other , Alignment > & ) {}
|
||||
template <typename Other>
|
||||
b3AlignedAllocator(const b3AlignedAllocator<Other, Alignment>&)
|
||||
{
|
||||
}
|
||||
|
||||
typedef const T* const_pointer;
|
||||
typedef const T& const_reference;
|
||||
typedef T* pointer;
|
||||
typedef T& reference;
|
||||
typedef T value_type;
|
||||
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 ( btSizeType n , const_pointer * hint = 0 ) {
|
||||
pointer address(reference ref) const { return &ref; }
|
||||
const_pointer address(const_reference ref) const { return &ref; }
|
||||
pointer allocate(btSizeType n, const_pointer* hint = 0)
|
||||
{
|
||||
(void)hint;
|
||||
return reinterpret_cast< pointer >(b3AlignedAlloc( sizeof(value_type) * n , Alignment ));
|
||||
return reinterpret_cast<pointer>(b3AlignedAlloc(sizeof(value_type) * n, Alignment));
|
||||
}
|
||||
void construct ( pointer ptr , const value_type & value ) { new (ptr) value_type( value ); }
|
||||
void deallocate( pointer ptr ) {
|
||||
b3AlignedFree( reinterpret_cast< void * >( ptr ) );
|
||||
void construct(pointer ptr, const value_type& value) { new (ptr) value_type(value); }
|
||||
void deallocate(pointer ptr)
|
||||
{
|
||||
b3AlignedFree(reinterpret_cast<void*>(ptr));
|
||||
}
|
||||
void destroy ( pointer ptr ) { ptr->~value_type(); }
|
||||
|
||||
void destroy(pointer ptr) { ptr->~value_type(); }
|
||||
|
||||
template < typename O > struct rebind {
|
||||
typedef b3AlignedAllocator< O , Alignment > other;
|
||||
template <typename O>
|
||||
struct rebind
|
||||
{
|
||||
typedef b3AlignedAllocator<O, Alignment> other;
|
||||
};
|
||||
template < typename O >
|
||||
self_type & operator=( const b3AlignedAllocator< O , Alignment > & ) { return *this; }
|
||||
template <typename O>
|
||||
self_type& operator=(const b3AlignedAllocator<O, Alignment>&)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend bool operator==( const self_type & , const self_type & ) { return true; }
|
||||
friend bool operator==(const self_type&, const self_type&) { return true; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //B3_ALIGNED_ALLOCATOR
|
||||
|
||||
#endif //B3_ALIGNED_ALLOCATOR
|
||||
|
||||
@@ -13,11 +13,10 @@ subject to the following restrictions:
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef B3_OBJECT_ARRAY__
|
||||
#define B3_OBJECT_ARRAY__
|
||||
|
||||
#include "b3Scalar.h" // has definitions like B3_FORCE_INLINE
|
||||
#include "b3Scalar.h" // has definitions like B3_FORCE_INLINE
|
||||
#include "b3AlignedAllocator.h"
|
||||
|
||||
///If the platform doesn't support placement new, you can disable B3_USE_PLACEMENT_NEW
|
||||
@@ -28,402 +27,386 @@ subject to the following restrictions:
|
||||
|
||||
#define B3_USE_PLACEMENT_NEW 1
|
||||
//#define B3_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...
|
||||
#define B3_ALLOW_ARRAY_COPY_OPERATOR // enabling this can accidently perform deep copies of data if you are not careful
|
||||
#define B3_ALLOW_ARRAY_COPY_OPERATOR // enabling this can accidently perform deep copies of data if you are not careful
|
||||
|
||||
#ifdef B3_USE_MEMCPY
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#endif //B3_USE_MEMCPY
|
||||
#endif //B3_USE_MEMCPY
|
||||
|
||||
#ifdef B3_USE_PLACEMENT_NEW
|
||||
#include <new> //for placement new
|
||||
#endif //B3_USE_PLACEMENT_NEW
|
||||
|
||||
#include <new> //for placement new
|
||||
#endif //B3_USE_PLACEMENT_NEW
|
||||
|
||||
///The b3AlignedObjectArray 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>
|
||||
template <typename T>
|
||||
//template <class T>
|
||||
class b3AlignedObjectArray
|
||||
{
|
||||
b3AlignedAllocator<T , 16> m_allocator;
|
||||
b3AlignedAllocator<T, 16> m_allocator;
|
||||
|
||||
int m_size;
|
||||
int m_capacity;
|
||||
T* m_data;
|
||||
int m_size;
|
||||
int m_capacity;
|
||||
T* m_data;
|
||||
//PCK: added this line
|
||||
bool m_ownsMemory;
|
||||
bool m_ownsMemory;
|
||||
|
||||
#ifdef B3_ALLOW_ARRAY_COPY_OPERATOR
|
||||
public:
|
||||
B3_FORCE_INLINE b3AlignedObjectArray<T>& operator=(const b3AlignedObjectArray<T> &other)
|
||||
B3_FORCE_INLINE b3AlignedObjectArray<T>& operator=(const b3AlignedObjectArray<T>& other)
|
||||
{
|
||||
copyFromArray(other);
|
||||
return *this;
|
||||
}
|
||||
#else//B3_ALLOW_ARRAY_COPY_OPERATOR
|
||||
#else //B3_ALLOW_ARRAY_COPY_OPERATOR
|
||||
private:
|
||||
B3_FORCE_INLINE b3AlignedObjectArray<T>& operator=(const b3AlignedObjectArray<T> &other);
|
||||
#endif//B3_ALLOW_ARRAY_COPY_OPERATOR
|
||||
B3_FORCE_INLINE b3AlignedObjectArray<T>& operator=(const b3AlignedObjectArray<T>& other);
|
||||
#endif //B3_ALLOW_ARRAY_COPY_OPERATOR
|
||||
|
||||
protected:
|
||||
B3_FORCE_INLINE int allocSize(int size)
|
||||
{
|
||||
return (size ? size*2 : 1);
|
||||
}
|
||||
B3_FORCE_INLINE void copy(int start,int end, T* dest) const
|
||||
{
|
||||
int i;
|
||||
for (i=start;i<end;++i)
|
||||
B3_FORCE_INLINE int allocSize(int size)
|
||||
{
|
||||
return (size ? size * 2 : 1);
|
||||
}
|
||||
B3_FORCE_INLINE void copy(int start, int end, T* dest) const
|
||||
{
|
||||
int i;
|
||||
for (i = start; i < end; ++i)
|
||||
#ifdef B3_USE_PLACEMENT_NEW
|
||||
new (&dest[i]) T(m_data[i]);
|
||||
new (&dest[i]) T(m_data[i]);
|
||||
#else
|
||||
dest[i] = m_data[i];
|
||||
#endif //B3_USE_PLACEMENT_NEW
|
||||
}
|
||||
dest[i] = m_data[i];
|
||||
#endif //B3_USE_PLACEMENT_NEW
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE void init()
|
||||
B3_FORCE_INLINE void init()
|
||||
{
|
||||
//PCK: added this line
|
||||
m_ownsMemory = true;
|
||||
m_data = 0;
|
||||
m_size = 0;
|
||||
m_capacity = 0;
|
||||
}
|
||||
B3_FORCE_INLINE void destroy(int first, int last)
|
||||
{
|
||||
int i;
|
||||
for (i = first; i < last; i++)
|
||||
{
|
||||
//PCK: added this line
|
||||
m_ownsMemory = true;
|
||||
m_data = 0;
|
||||
m_size = 0;
|
||||
m_capacity = 0;
|
||||
m_data[i].~T();
|
||||
}
|
||||
B3_FORCE_INLINE void destroy(int first,int last)
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE void* allocate(int size)
|
||||
{
|
||||
if (size)
|
||||
return m_allocator.allocate(size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE void deallocate()
|
||||
{
|
||||
if (m_data)
|
||||
{
|
||||
int i;
|
||||
for (i=first; i<last;i++)
|
||||
//PCK: enclosed the deallocation in this block
|
||||
if (m_ownsMemory)
|
||||
{
|
||||
m_allocator.deallocate(m_data);
|
||||
}
|
||||
m_data = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
b3AlignedObjectArray()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
~b3AlignedObjectArray()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
///Generally it is best to avoid using the copy constructor of an b3AlignedObjectArray, and use a (const) reference to the array instead.
|
||||
b3AlignedObjectArray(const b3AlignedObjectArray& otherArray)
|
||||
{
|
||||
init();
|
||||
|
||||
int otherSize = otherArray.size();
|
||||
resize(otherSize);
|
||||
otherArray.copy(0, otherSize, m_data);
|
||||
}
|
||||
|
||||
/// return the number of elements in the array
|
||||
B3_FORCE_INLINE int size() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE const T& at(int n) const
|
||||
{
|
||||
b3Assert(n >= 0);
|
||||
b3Assert(n < size());
|
||||
return m_data[n];
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE T& at(int n)
|
||||
{
|
||||
b3Assert(n >= 0);
|
||||
b3Assert(n < size());
|
||||
return m_data[n];
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE const T& operator[](int n) const
|
||||
{
|
||||
b3Assert(n >= 0);
|
||||
b3Assert(n < size());
|
||||
return m_data[n];
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE T& operator[](int n)
|
||||
{
|
||||
b3Assert(n >= 0);
|
||||
b3Assert(n < size());
|
||||
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.
|
||||
B3_FORCE_INLINE void clear()
|
||||
{
|
||||
destroy(0, size());
|
||||
|
||||
deallocate();
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE void pop_back()
|
||||
{
|
||||
b3Assert(m_size > 0);
|
||||
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.
|
||||
B3_FORCE_INLINE void resizeNoInitialize(int newsize)
|
||||
{
|
||||
int curSize = size();
|
||||
|
||||
if (newsize < curSize)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (newsize > size())
|
||||
{
|
||||
reserve(newsize);
|
||||
}
|
||||
//leave this uninitialized
|
||||
}
|
||||
m_size = newsize;
|
||||
}
|
||||
|
||||
B3_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();
|
||||
}
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE void* allocate(int size)
|
||||
else
|
||||
{
|
||||
if (size)
|
||||
return m_allocator.allocate(size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
B3_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;
|
||||
if (newsize > size())
|
||||
{
|
||||
reserve(newsize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public:
|
||||
|
||||
b3AlignedObjectArray()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
~b3AlignedObjectArray()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
///Generally it is best to avoid using the copy constructor of an b3AlignedObjectArray, and use a (const) reference to the array instead.
|
||||
b3AlignedObjectArray(const b3AlignedObjectArray& otherArray)
|
||||
{
|
||||
init();
|
||||
|
||||
int otherSize = otherArray.size();
|
||||
resize (otherSize);
|
||||
otherArray.copy(0, otherSize, m_data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// return the number of elements in the array
|
||||
B3_FORCE_INLINE int size() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE const T& at(int n) const
|
||||
{
|
||||
b3Assert(n>=0);
|
||||
b3Assert(n<size());
|
||||
return m_data[n];
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE T& at(int n)
|
||||
{
|
||||
b3Assert(n>=0);
|
||||
b3Assert(n<size());
|
||||
return m_data[n];
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE const T& operator[](int n) const
|
||||
{
|
||||
b3Assert(n>=0);
|
||||
b3Assert(n<size());
|
||||
return m_data[n];
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE T& operator[](int n)
|
||||
{
|
||||
b3Assert(n>=0);
|
||||
b3Assert(n<size());
|
||||
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.
|
||||
B3_FORCE_INLINE void clear()
|
||||
{
|
||||
destroy(0,size());
|
||||
|
||||
deallocate();
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE void pop_back()
|
||||
{
|
||||
b3Assert(m_size>0);
|
||||
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.
|
||||
B3_FORCE_INLINE void resizeNoInitialize(int newsize)
|
||||
{
|
||||
int curSize = size();
|
||||
|
||||
if (newsize < curSize)
|
||||
{
|
||||
} else
|
||||
{
|
||||
if (newsize > size())
|
||||
{
|
||||
reserve(newsize);
|
||||
}
|
||||
//leave this uninitialized
|
||||
}
|
||||
m_size = newsize;
|
||||
}
|
||||
|
||||
B3_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 B3_USE_PLACEMENT_NEW
|
||||
for (int i=curSize;i<newsize;i++)
|
||||
{
|
||||
new ( &m_data[i]) T(fillData);
|
||||
}
|
||||
#endif //B3_USE_PLACEMENT_NEW
|
||||
|
||||
}
|
||||
|
||||
m_size = newsize;
|
||||
}
|
||||
B3_FORCE_INLINE T& expandNonInitializing( )
|
||||
{
|
||||
int sz = size();
|
||||
if( sz == capacity() )
|
||||
for (int i = curSize; i < newsize; i++)
|
||||
{
|
||||
reserve( allocSize(size()) );
|
||||
new (&m_data[i]) T(fillData);
|
||||
}
|
||||
m_size++;
|
||||
|
||||
return m_data[sz];
|
||||
#endif //B3_USE_PLACEMENT_NEW
|
||||
}
|
||||
|
||||
m_size = newsize;
|
||||
}
|
||||
B3_FORCE_INLINE T& expandNonInitializing()
|
||||
{
|
||||
int sz = size();
|
||||
if (sz == capacity())
|
||||
{
|
||||
reserve(allocSize(size()));
|
||||
}
|
||||
m_size++;
|
||||
|
||||
B3_FORCE_INLINE T& expand( const T& fillValue=T())
|
||||
{
|
||||
int sz = size();
|
||||
if( sz == capacity() )
|
||||
{
|
||||
reserve( allocSize(size()) );
|
||||
}
|
||||
m_size++;
|
||||
return m_data[sz];
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE T& expand(const T& fillValue = T())
|
||||
{
|
||||
int sz = size();
|
||||
if (sz == capacity())
|
||||
{
|
||||
reserve(allocSize(size()));
|
||||
}
|
||||
m_size++;
|
||||
#ifdef B3_USE_PLACEMENT_NEW
|
||||
new (&m_data[sz]) T(fillValue); //use the in-place new (not really allocating heap memory)
|
||||
new (&m_data[sz]) T(fillValue); //use the in-place new (not really allocating heap memory)
|
||||
#endif
|
||||
|
||||
return m_data[sz];
|
||||
return m_data[sz];
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE void push_back(const T& _Val)
|
||||
{
|
||||
int sz = size();
|
||||
if (sz == capacity())
|
||||
{
|
||||
reserve(allocSize(size()));
|
||||
}
|
||||
|
||||
|
||||
B3_FORCE_INLINE void push_back(const T& _Val)
|
||||
{
|
||||
int sz = size();
|
||||
if( sz == capacity() )
|
||||
{
|
||||
reserve( allocSize(size()) );
|
||||
}
|
||||
|
||||
#ifdef B3_USE_PLACEMENT_NEW
|
||||
new ( &m_data[m_size] ) T(_Val);
|
||||
new (&m_data[m_size]) T(_Val);
|
||||
#else
|
||||
m_data[size()] = _Val;
|
||||
#endif //B3_USE_PLACEMENT_NEW
|
||||
m_data[size()] = _Val;
|
||||
#endif //B3_USE_PLACEMENT_NEW
|
||||
|
||||
m_size++;
|
||||
}
|
||||
m_size++;
|
||||
}
|
||||
|
||||
|
||||
/// return the pre-allocated (reserved) elements, this is at least as large as the total number of elements,see size() and reserve()
|
||||
B3_FORCE_INLINE int capacity() const
|
||||
{
|
||||
return m_capacity;
|
||||
}
|
||||
|
||||
B3_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);
|
||||
b3Assert(s);
|
||||
if (s==0)
|
||||
{
|
||||
b3Error("b3AlignedObjectArray reserve out-of-memory\n");
|
||||
_Count=0;
|
||||
m_size=0;
|
||||
}
|
||||
copy(0, size(), s);
|
||||
|
||||
destroy(0,size());
|
||||
|
||||
deallocate();
|
||||
|
||||
//PCK: added this line
|
||||
m_ownsMemory = true;
|
||||
|
||||
m_data = s;
|
||||
|
||||
m_capacity = _Count;
|
||||
/// return the pre-allocated (reserved) elements, this is at least as large as the total number of elements,see size() and reserve()
|
||||
B3_FORCE_INLINE int capacity() const
|
||||
{
|
||||
return m_capacity;
|
||||
}
|
||||
|
||||
B3_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);
|
||||
b3Assert(s);
|
||||
if (s == 0)
|
||||
{
|
||||
b3Error("b3AlignedObjectArray reserve out-of-memory\n");
|
||||
_Count = 0;
|
||||
m_size = 0;
|
||||
}
|
||||
copy(0, size(), s);
|
||||
|
||||
destroy(0, size());
|
||||
|
||||
deallocate();
|
||||
|
||||
//PCK: added this line
|
||||
m_ownsMemory = true;
|
||||
|
||||
m_data = s;
|
||||
|
||||
m_capacity = _Count;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class less
|
||||
class less
|
||||
{
|
||||
public:
|
||||
bool operator()(const T& a, const T& b)
|
||||
{
|
||||
public:
|
||||
return (a < b);
|
||||
}
|
||||
};
|
||||
|
||||
bool operator() ( const T& a, const T& b )
|
||||
{
|
||||
return ( a < b );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename L>
|
||||
void quickSortInternal(const L& CompareFunc,int lo, int hi)
|
||||
{
|
||||
template <typename L>
|
||||
void quickSortInternal(const 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];
|
||||
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(const L& CompareFunc)
|
||||
// partition
|
||||
do
|
||||
{
|
||||
//don't sort 0 or 1 elements
|
||||
if (size()>1)
|
||||
while (CompareFunc(m_data[i], x))
|
||||
i++;
|
||||
while (CompareFunc(x, m_data[j]))
|
||||
j--;
|
||||
if (i <= j)
|
||||
{
|
||||
quickSortInternal(CompareFunc,0,size()-1);
|
||||
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(const 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, const 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*/
|
||||
|
||||
|
||||
///heap sort from http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Sort/Heap/
|
||||
template <typename L>
|
||||
void downHeap(T *pArr, int k, int n, const 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)
|
||||
{
|
||||
void swap(int index0, int index1)
|
||||
{
|
||||
#ifdef B3_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));
|
||||
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 //B3_USE_PLACEMENT_NEW
|
||||
|
||||
}
|
||||
T temp = m_data[index0];
|
||||
m_data[index0] = m_data[index1];
|
||||
m_data[index1] = temp;
|
||||
#endif //B3_USE_PLACEMENT_NEW
|
||||
}
|
||||
|
||||
template <typename L>
|
||||
void heapSort(const L& CompareFunc)
|
||||
@@ -431,49 +414,48 @@ protected:
|
||||
/* sort a[0..N-1], N.B. 0 to N-1 */
|
||||
int k;
|
||||
int n = m_size;
|
||||
for (k = n/2; k > 0; k--)
|
||||
for (k = n / 2; k > 0; k--)
|
||||
{
|
||||
downHeap(m_data, k, n, CompareFunc);
|
||||
}
|
||||
|
||||
/* a[1..N] is now a heap */
|
||||
while ( n>=1 )
|
||||
while (n >= 1)
|
||||
{
|
||||
swap(0,n-1); /* largest of a[0..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 findBinarySearch(const T& key) const
|
||||
{
|
||||
int first = 0;
|
||||
int last = size()-1;
|
||||
int last = size() - 1;
|
||||
|
||||
//assume sorted array
|
||||
while (first <= last) {
|
||||
while (first <= last)
|
||||
{
|
||||
int mid = (first + last) / 2; // compute mid point.
|
||||
if (key > m_data[mid])
|
||||
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 if (key < m_data[mid])
|
||||
last = mid - 1; // repeat search in bottom half.
|
||||
else
|
||||
return mid; // found it. return position /////
|
||||
return mid; // found it. return position /////
|
||||
}
|
||||
return size(); // failed to find key
|
||||
return size(); // failed to find key
|
||||
}
|
||||
|
||||
|
||||
int findLinearSearch(const T& key) const
|
||||
int findLinearSearch(const T& key) const
|
||||
{
|
||||
int index=size();
|
||||
int index = size();
|
||||
int i;
|
||||
|
||||
for (i=0;i<size();i++)
|
||||
for (i = 0; i < size(); i++)
|
||||
{
|
||||
if (m_data[i] == key)
|
||||
{
|
||||
@@ -483,36 +465,35 @@ protected:
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
int findLinearSearch2(const T& key) const
|
||||
{
|
||||
int index=-1;
|
||||
int i;
|
||||
|
||||
for (i=0;i<size();i++)
|
||||
{
|
||||
if (m_data[i] == key)
|
||||
{
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
void remove(const T& key)
|
||||
int findLinearSearch2(const T& key) const
|
||||
{
|
||||
int index = -1;
|
||||
int i;
|
||||
|
||||
int findIndex = findLinearSearch(key);
|
||||
if (findIndex<size())
|
||||
for (i = 0; i < size(); i++)
|
||||
{
|
||||
swap( findIndex,size()-1);
|
||||
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)
|
||||
void initializeFromBuffer(void* buffer, int size, int capacity)
|
||||
{
|
||||
clear();
|
||||
m_ownsMemory = false;
|
||||
@@ -524,18 +505,18 @@ protected:
|
||||
void copyFromArray(const b3AlignedObjectArray& otherArray)
|
||||
{
|
||||
int otherSize = otherArray.size();
|
||||
resize (otherSize);
|
||||
resize(otherSize);
|
||||
otherArray.copy(0, otherSize, m_data);
|
||||
}
|
||||
|
||||
void removeAtIndex(int index)
|
||||
{
|
||||
if (index<size())
|
||||
{
|
||||
swap( index,size()-1);
|
||||
pop_back();
|
||||
}
|
||||
}
|
||||
{
|
||||
if (index < size())
|
||||
{
|
||||
swap(index, size() - 1);
|
||||
pop_back();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif //B3_OBJECT_ARRAY__
|
||||
#endif //B3_OBJECT_ARRAY__
|
||||
|
||||
@@ -12,51 +12,54 @@
|
||||
class b3CommandLineArgs
|
||||
{
|
||||
protected:
|
||||
|
||||
std::map<std::string, std::string> pairs;
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
b3CommandLineArgs(int argc, char **argv)
|
||||
{
|
||||
addArgs(argc,argv);
|
||||
addArgs(argc, argv);
|
||||
}
|
||||
|
||||
void addArgs(int argc, char**argv)
|
||||
void addArgs(int argc, char **argv)
|
||||
{
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
std::string arg = argv[i];
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
std::string arg = argv[i];
|
||||
|
||||
if ((arg.length() < 2) || (arg[0] != '-') || (arg[1] != '-')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string::size_type pos;
|
||||
std::string key, val;
|
||||
if ((pos = arg.find( '=')) == std::string::npos) {
|
||||
key = std::string(arg, 2, arg.length() - 2);
|
||||
val = "";
|
||||
} else {
|
||||
key = std::string(arg, 2, pos - 2);
|
||||
val = std::string(arg, pos + 1, arg.length() - 1);
|
||||
}
|
||||
|
||||
//only add new keys, don't replace existing
|
||||
if(pairs.find(key) == pairs.end())
|
||||
if ((arg.length() < 2) || (arg[0] != '-') || (arg[1] != '-'))
|
||||
{
|
||||
pairs[key] = val;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
std::string::size_type pos;
|
||||
std::string key, val;
|
||||
if ((pos = arg.find('=')) == std::string::npos)
|
||||
{
|
||||
key = std::string(arg, 2, arg.length() - 2);
|
||||
val = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
key = std::string(arg, 2, pos - 2);
|
||||
val = std::string(arg, pos + 1, arg.length() - 1);
|
||||
}
|
||||
|
||||
//only add new keys, don't replace existing
|
||||
if (pairs.find(key) == pairs.end())
|
||||
{
|
||||
pairs[key] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CheckCmdLineFlag(const char* arg_name)
|
||||
bool CheckCmdLineFlag(const char *arg_name)
|
||||
{
|
||||
std::map<std::string, std::string>::iterator itr;
|
||||
if ((itr = pairs.find(arg_name)) != pairs.end()) {
|
||||
if ((itr = pairs.find(arg_name)) != pairs.end())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -73,29 +76,31 @@ template <typename T>
|
||||
inline bool b3CommandLineArgs::GetCmdLineArgument(const char *arg_name, T &val)
|
||||
{
|
||||
std::map<std::string, std::string>::iterator itr;
|
||||
if ((itr = pairs.find(arg_name)) != pairs.end()) {
|
||||
if ((itr = pairs.find(arg_name)) != pairs.end())
|
||||
{
|
||||
std::istringstream strstream(itr->second);
|
||||
strstream >> val;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool b3CommandLineArgs::GetCmdLineArgument<char*>(const char* arg_name, char* &val)
|
||||
{
|
||||
std::map<std::string, std::string>::iterator itr;
|
||||
if ((itr = pairs.find(arg_name)) != pairs.end()) {
|
||||
|
||||
std::string s = itr->second;
|
||||
val = (char*) malloc(sizeof(char) * (s.length() + 1));
|
||||
std::strcpy(val, s.c_str());
|
||||
return true;
|
||||
} else {
|
||||
val = NULL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool b3CommandLineArgs::GetCmdLineArgument<char *>(const char *arg_name, char *&val)
|
||||
{
|
||||
std::map<std::string, std::string>::iterator itr;
|
||||
if ((itr = pairs.find(arg_name)) != pairs.end())
|
||||
{
|
||||
std::string s = itr->second;
|
||||
val = (char *)malloc(sizeof(char) * (s.length() + 1));
|
||||
std::strcpy(val, s.c_str());
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
val = NULL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif //COMMAND_LINE_ARGS_H
|
||||
#endif //COMMAND_LINE_ARGS_H
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include "b3Scalar.h"
|
||||
#include <stddef.h>//ptrdiff_h
|
||||
#include <stddef.h> //ptrdiff_h
|
||||
#include <string.h>
|
||||
|
||||
struct b3FileUtils
|
||||
@@ -17,42 +17,42 @@ struct b3FileUtils
|
||||
|
||||
static bool findFile(const char* orgFileName, char* relativeFileName, int maxRelativeFileNameMaxLen)
|
||||
{
|
||||
FILE* f=0;
|
||||
f = fopen(orgFileName,"rb");
|
||||
if (f)
|
||||
{
|
||||
FILE* f = 0;
|
||||
f = fopen(orgFileName, "rb");
|
||||
if (f)
|
||||
{
|
||||
//printf("original file found: [%s]\n", orgFileName);
|
||||
sprintf(relativeFileName,"%s", orgFileName);
|
||||
sprintf(relativeFileName, "%s", orgFileName);
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
|
||||
//printf("Trying various directories, relative to current working directory\n");
|
||||
const char* prefix[]={"./","./data/","../data/","../../data/","../../../data/","../../../../data/"};
|
||||
int numPrefixes = sizeof(prefix)/sizeof(const char*);
|
||||
|
||||
f=0;
|
||||
bool fileFound = false;
|
||||
//printf("Trying various directories, relative to current working directory\n");
|
||||
const char* prefix[] = {"./", "./data/", "../data/", "../../data/", "../../../data/", "../../../../data/"};
|
||||
int numPrefixes = sizeof(prefix) / sizeof(const char*);
|
||||
|
||||
for (int i=0;!f && i<numPrefixes;i++)
|
||||
{
|
||||
f = 0;
|
||||
bool fileFound = false;
|
||||
|
||||
for (int i = 0; !f && i < numPrefixes; i++)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
sprintf_s(relativeFileName,maxRelativeFileNameMaxLen,"%s%s",prefix[i],orgFileName);
|
||||
sprintf_s(relativeFileName, maxRelativeFileNameMaxLen, "%s%s", prefix[i], orgFileName);
|
||||
#else
|
||||
sprintf(relativeFileName,"%s%s",prefix[i],orgFileName);
|
||||
sprintf(relativeFileName, "%s%s", prefix[i], orgFileName);
|
||||
#endif
|
||||
f = fopen(relativeFileName,"rb");
|
||||
if (f)
|
||||
{
|
||||
fileFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
f = fopen(relativeFileName, "rb");
|
||||
if (f)
|
||||
{
|
||||
fclose(f);
|
||||
fileFound = true;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
if (f)
|
||||
{
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
return fileFound;
|
||||
}
|
||||
|
||||
@@ -60,8 +60,8 @@ struct b3FileUtils
|
||||
{
|
||||
size_t const patlen = strlen(pattern);
|
||||
size_t patcnt = 0;
|
||||
const char * oriptr;
|
||||
const char * patloc;
|
||||
const char* oriptr;
|
||||
const char* patloc;
|
||||
// find how many times the pattern occurs in the original string
|
||||
for (oriptr = name; (patloc = strstr(oriptr, pattern)); oriptr = patloc + patlen)
|
||||
{
|
||||
@@ -70,29 +70,27 @@ struct b3FileUtils
|
||||
return oriptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int extractPath(const char* fileName, char* path, int maxPathLength)
|
||||
{
|
||||
const char* stripped = strip2(fileName, "/");
|
||||
stripped = strip2(stripped, "\\");
|
||||
|
||||
ptrdiff_t len = stripped-fileName;
|
||||
b3Assert((len+1)<maxPathLength);
|
||||
ptrdiff_t len = stripped - fileName;
|
||||
b3Assert((len + 1) < maxPathLength);
|
||||
|
||||
if (len && ((len+1)<maxPathLength))
|
||||
if (len && ((len + 1) < maxPathLength))
|
||||
{
|
||||
|
||||
for (int i=0;i<len;i++)
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
path[i] = fileName[i];
|
||||
}
|
||||
path[len]=0;
|
||||
} else
|
||||
path[len] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 0;
|
||||
b3Assert(maxPathLength>0);
|
||||
if (maxPathLength>0)
|
||||
b3Assert(maxPathLength > 0);
|
||||
if (maxPathLength > 0)
|
||||
{
|
||||
path[len] = 0;
|
||||
}
|
||||
@@ -102,23 +100,21 @@ struct b3FileUtils
|
||||
|
||||
static char toLowerChar(const char t)
|
||||
{
|
||||
if (t>=(char)'A' && t<=(char)'Z')
|
||||
if (t >= (char)'A' && t <= (char)'Z')
|
||||
return t + ((char)'a' - (char)'A');
|
||||
else
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
static void toLower(char* str)
|
||||
{
|
||||
int len=strlen(str);
|
||||
for (int i=0;i<len;i++)
|
||||
int len = strlen(str);
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
str[i] = toLowerChar(str[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*static const char* strip2(const char* name, const char* pattern)
|
||||
{
|
||||
size_t const patlen = strlen(pattern);
|
||||
@@ -133,6 +129,5 @@ struct b3FileUtils
|
||||
return oriptr;
|
||||
}
|
||||
*/
|
||||
|
||||
};
|
||||
#endif //B3_FILE_UTILS_H
|
||||
#endif //B3_FILE_UTILS_H
|
||||
|
||||
@@ -13,86 +13,80 @@ subject to the following restrictions:
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef B3_HASH_MAP_H
|
||||
#define B3_HASH_MAP_H
|
||||
|
||||
#include "b3AlignedObjectArray.h"
|
||||
|
||||
|
||||
#include <string>
|
||||
|
||||
///very basic hashable string implementation, compatible with b3HashMap
|
||||
struct b3HashString
|
||||
{
|
||||
std::string m_string;
|
||||
unsigned int m_hash;
|
||||
unsigned int m_hash;
|
||||
|
||||
B3_FORCE_INLINE unsigned int getHash()const
|
||||
B3_FORCE_INLINE unsigned int getHash() const
|
||||
{
|
||||
return m_hash;
|
||||
}
|
||||
|
||||
|
||||
b3HashString(const char* name)
|
||||
:m_string(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 InitialFNV = 2166136261u;
|
||||
static const unsigned int FNVMultiple = 16777619u;
|
||||
|
||||
/* Fowler / Noll / Vo (FNV) Hash */
|
||||
unsigned int hash = InitialFNV;
|
||||
int len = m_string.length();
|
||||
for(int i = 0; i<len; i++)
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
hash = hash ^ (m_string[i]); /* xor the low 8 bits */
|
||||
hash = hash * FNVMultiple; /* multiply by the magic number */
|
||||
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 portableStringCompare(const char* src, const char* dst) const
|
||||
{
|
||||
int ret = 0 ;
|
||||
int ret = 0;
|
||||
|
||||
while( ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
|
||||
++src, ++dst;
|
||||
while (!(ret = *(unsigned char*)src - *(unsigned char*)dst) && *dst)
|
||||
++src, ++dst;
|
||||
|
||||
if ( ret < 0 )
|
||||
ret = -1 ;
|
||||
else if ( ret > 0 )
|
||||
ret = 1 ;
|
||||
if (ret < 0)
|
||||
ret = -1;
|
||||
else if (ret > 0)
|
||||
ret = 1;
|
||||
|
||||
return( ret );
|
||||
return (ret);
|
||||
}
|
||||
|
||||
bool equals(const b3HashString& other) const
|
||||
{
|
||||
return (m_string == other.m_string);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
const int B3_HASH_NULL=0xffffffff;
|
||||
|
||||
const int B3_HASH_NULL = 0xffffffff;
|
||||
|
||||
class b3HashInt
|
||||
{
|
||||
int m_uid;
|
||||
int m_uid;
|
||||
|
||||
public:
|
||||
b3HashInt(int uid) :m_uid(uid)
|
||||
b3HashInt(int uid) : m_uid(uid)
|
||||
{
|
||||
}
|
||||
|
||||
int getUid1() const
|
||||
int getUid1() const
|
||||
{
|
||||
return m_uid;
|
||||
}
|
||||
|
||||
void setUid1(int uid)
|
||||
void setUid1(int uid)
|
||||
{
|
||||
m_uid = uid;
|
||||
}
|
||||
@@ -102,34 +96,34 @@ public:
|
||||
return getUid1() == other.getUid1();
|
||||
}
|
||||
//to our success
|
||||
B3_FORCE_INLINE unsigned int getHash()const
|
||||
B3_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);
|
||||
key += ~(key << 15);
|
||||
key ^= (key >> 10);
|
||||
key += (key << 3);
|
||||
key ^= (key >> 6);
|
||||
key += ~(key << 11);
|
||||
key ^= (key >> 16);
|
||||
return key;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
class b3HashPtr
|
||||
{
|
||||
|
||||
union
|
||||
{
|
||||
const void* m_pointer;
|
||||
int m_hashValues[2];
|
||||
union {
|
||||
const void* m_pointer;
|
||||
int m_hashValues[2];
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
b3HashPtr(const void* ptr)
|
||||
:m_pointer(ptr)
|
||||
: m_pointer(ptr)
|
||||
{
|
||||
}
|
||||
|
||||
const void* getPointer() const
|
||||
const void* getPointer() const
|
||||
{
|
||||
return m_pointer;
|
||||
}
|
||||
@@ -140,65 +134,69 @@ public:
|
||||
}
|
||||
|
||||
//to our success
|
||||
B3_FORCE_INLINE unsigned int getHash()const
|
||||
B3_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];
|
||||
|
||||
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);
|
||||
key += ~(key << 15);
|
||||
key ^= (key >> 10);
|
||||
key += (key << 3);
|
||||
key ^= (key >> 6);
|
||||
key += ~(key << 11);
|
||||
key ^= (key >> 16);
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
template <class Value>
|
||||
class b3HashKeyPtr
|
||||
{
|
||||
int m_uid;
|
||||
int m_uid;
|
||||
|
||||
public:
|
||||
b3HashKeyPtr(int uid) : m_uid(uid)
|
||||
{
|
||||
}
|
||||
|
||||
b3HashKeyPtr(int uid) :m_uid(uid)
|
||||
{
|
||||
}
|
||||
int getUid1() const
|
||||
{
|
||||
return m_uid;
|
||||
}
|
||||
|
||||
int getUid1() const
|
||||
{
|
||||
return m_uid;
|
||||
}
|
||||
bool equals(const b3HashKeyPtr<Value>& other) const
|
||||
{
|
||||
return getUid1() == other.getUid1();
|
||||
}
|
||||
|
||||
bool equals(const b3HashKeyPtr<Value>& other) const
|
||||
{
|
||||
return getUid1() == other.getUid1();
|
||||
}
|
||||
|
||||
//to our success
|
||||
B3_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;
|
||||
}
|
||||
|
||||
|
||||
//to our success
|
||||
B3_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 b3HashKey
|
||||
{
|
||||
int m_uid;
|
||||
public:
|
||||
int m_uid;
|
||||
|
||||
b3HashKey(int uid) :m_uid(uid)
|
||||
public:
|
||||
b3HashKey(int uid) : m_uid(uid)
|
||||
{
|
||||
}
|
||||
|
||||
int getUid1() const
|
||||
int getUid1() const
|
||||
{
|
||||
return m_uid;
|
||||
}
|
||||
@@ -208,30 +206,33 @@ public:
|
||||
return getUid1() == other.getUid1();
|
||||
}
|
||||
//to our success
|
||||
B3_FORCE_INLINE unsigned int getHash()const
|
||||
B3_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);
|
||||
key += ~(key << 15);
|
||||
key ^= (key >> 10);
|
||||
key += (key << 3);
|
||||
key ^= (key >> 6);
|
||||
key += ~(key << 11);
|
||||
key ^= (key >> 16);
|
||||
return key;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
///The b3HashMap template class implements a generic and lightweight hashmap.
|
||||
///A basic sample of how to use b3HashMap is located in Demos\BasicDemo\main.cpp
|
||||
template <class Key, class Value>
|
||||
class b3HashMap
|
||||
{
|
||||
|
||||
protected:
|
||||
b3AlignedObjectArray<int> m_hashTable;
|
||||
b3AlignedObjectArray<int> m_next;
|
||||
|
||||
b3AlignedObjectArray<Value> m_valueArray;
|
||||
b3AlignedObjectArray<Key> m_keyArray;
|
||||
b3AlignedObjectArray<int> m_hashTable;
|
||||
b3AlignedObjectArray<int> m_next;
|
||||
|
||||
void growTables(const Key& /*key*/)
|
||||
b3AlignedObjectArray<Value> m_valueArray;
|
||||
b3AlignedObjectArray<Key> m_keyArray;
|
||||
|
||||
void growTables(const Key& /*key*/)
|
||||
{
|
||||
int newCapacity = m_valueArray.capacity();
|
||||
|
||||
@@ -245,7 +246,7 @@ protected:
|
||||
|
||||
int i;
|
||||
|
||||
for (i= 0; i < newCapacity; ++i)
|
||||
for (i = 0; i < newCapacity; ++i)
|
||||
{
|
||||
m_hashTable[i] = B3_HASH_NULL;
|
||||
}
|
||||
@@ -254,30 +255,28 @@ protected:
|
||||
m_next[i] = B3_HASH_NULL;
|
||||
}
|
||||
|
||||
for(i=0;i<curHashtableSize;i++)
|
||||
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
|
||||
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);
|
||||
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 != B3_HASH_NULL)
|
||||
{
|
||||
m_valueArray[index]=value;
|
||||
m_valueArray[index] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -291,19 +290,19 @@ protected:
|
||||
{
|
||||
growTables(key);
|
||||
//hash with new capacity
|
||||
hash = key.getHash() & (m_valueArray.capacity()-1);
|
||||
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);
|
||||
void remove(const Key& key)
|
||||
{
|
||||
int hash = key.getHash() & (m_valueArray.capacity() - 1);
|
||||
|
||||
int pairIndex = findIndex(key);
|
||||
|
||||
if (pairIndex ==B3_HASH_NULL)
|
||||
|
||||
if (pairIndex == B3_HASH_NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -344,7 +343,7 @@ protected:
|
||||
}
|
||||
|
||||
// Remove the last pair from the hash table.
|
||||
int lastHash = m_keyArray[lastPairIndex].getHash() & (m_valueArray.capacity()-1);
|
||||
int lastHash = m_keyArray[lastPairIndex].getHash() & (m_valueArray.capacity() - 1);
|
||||
|
||||
index = m_hashTable[lastHash];
|
||||
b3Assert(index != B3_HASH_NULL);
|
||||
@@ -376,10 +375,8 @@ protected:
|
||||
|
||||
m_valueArray.pop_back();
|
||||
m_keyArray.pop_back();
|
||||
|
||||
}
|
||||
|
||||
|
||||
int size() const
|
||||
{
|
||||
return m_valueArray.size();
|
||||
@@ -399,23 +396,24 @@ protected:
|
||||
return &m_valueArray[index];
|
||||
}
|
||||
|
||||
Key getKeyAtIndex(int index)
|
||||
{
|
||||
b3Assert(index < m_keyArray.size());
|
||||
return m_keyArray[index];
|
||||
}
|
||||
|
||||
const Key getKeyAtIndex(int index) const
|
||||
{
|
||||
b3Assert(index < m_keyArray.size());
|
||||
return m_keyArray[index];
|
||||
}
|
||||
Key getKeyAtIndex(int index)
|
||||
{
|
||||
b3Assert(index < m_keyArray.size());
|
||||
return m_keyArray[index];
|
||||
}
|
||||
|
||||
Value* operator[](const Key& key) {
|
||||
const Key getKeyAtIndex(int index) const
|
||||
{
|
||||
b3Assert(index < m_keyArray.size());
|
||||
return m_keyArray[index];
|
||||
}
|
||||
|
||||
Value* operator[](const Key& key)
|
||||
{
|
||||
return find(key);
|
||||
}
|
||||
|
||||
const Value* find(const Key& key) const
|
||||
const Value* find(const Key& key) const
|
||||
{
|
||||
int index = findIndex(key);
|
||||
if (index == B3_HASH_NULL)
|
||||
@@ -425,7 +423,7 @@ protected:
|
||||
return &m_valueArray[index];
|
||||
}
|
||||
|
||||
Value* find(const Key& key)
|
||||
Value* find(const Key& key)
|
||||
{
|
||||
int index = findIndex(key);
|
||||
if (index == B3_HASH_NULL)
|
||||
@@ -435,10 +433,9 @@ protected:
|
||||
return &m_valueArray[index];
|
||||
}
|
||||
|
||||
|
||||
int findIndex(const Key& key) const
|
||||
int findIndex(const Key& key) const
|
||||
{
|
||||
unsigned int hash = key.getHash() & (m_valueArray.capacity()-1);
|
||||
unsigned int hash = key.getHash() & (m_valueArray.capacity() - 1);
|
||||
|
||||
if (hash >= (unsigned int)m_hashTable.size())
|
||||
{
|
||||
@@ -453,14 +450,13 @@ protected:
|
||||
return index;
|
||||
}
|
||||
|
||||
void clear()
|
||||
void clear()
|
||||
{
|
||||
m_hashTable.clear();
|
||||
m_next.clear();
|
||||
m_valueArray.clear();
|
||||
m_keyArray.clear();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif //B3_HASH_MAP_H
|
||||
#endif //B3_HASH_MAP_H
|
||||
|
||||
@@ -20,17 +20,16 @@ subject to the following restrictions:
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif //_WIN32
|
||||
|
||||
#endif //_WIN32
|
||||
|
||||
void b3PrintfFuncDefault(const char* msg)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
OutputDebugStringA(msg);
|
||||
#endif
|
||||
printf("%s",msg);
|
||||
//is this portable?
|
||||
fflush(stdout);
|
||||
printf("%s", msg);
|
||||
//is this portable?
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void b3WarningMessageFuncDefault(const char* msg)
|
||||
@@ -38,32 +37,26 @@ void b3WarningMessageFuncDefault(const char* msg)
|
||||
#ifdef _WIN32
|
||||
OutputDebugStringA(msg);
|
||||
#endif
|
||||
printf("%s",msg);
|
||||
//is this portable?
|
||||
fflush(stdout);
|
||||
|
||||
printf("%s", msg);
|
||||
//is this portable?
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
|
||||
void b3ErrorMessageFuncDefault(const char* msg)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
OutputDebugStringA(msg);
|
||||
#endif
|
||||
printf("%s",msg);
|
||||
printf("%s", msg);
|
||||
|
||||
//is this portable?
|
||||
fflush(stdout);
|
||||
|
||||
//is this portable?
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static b3PrintfFunc* b3s_printfFunc = b3PrintfFuncDefault;
|
||||
static b3WarningMessageFunc* b3s_warningMessageFunc = b3WarningMessageFuncDefault;
|
||||
static b3ErrorMessageFunc* b3s_errorMessageFunc = b3ErrorMessageFuncDefault;
|
||||
|
||||
|
||||
///The developer can route b3Printf output using their own implementation
|
||||
void b3SetCustomPrintfFunc(b3PrintfFunc* printfFunc)
|
||||
{
|
||||
@@ -81,54 +74,50 @@ void b3SetCustomErrorMessageFunc(b3PrintfFunc* errorMessageFunc)
|
||||
//#define B3_MAX_DEBUG_STRING_LENGTH 2048
|
||||
#define B3_MAX_DEBUG_STRING_LENGTH 32768
|
||||
|
||||
|
||||
void b3OutputPrintfVarArgsInternal(const char *str, ...)
|
||||
void b3OutputPrintfVarArgsInternal(const char* str, ...)
|
||||
{
|
||||
char strDebug[B3_MAX_DEBUG_STRING_LENGTH]={0};
|
||||
va_list argList;
|
||||
va_start(argList, str);
|
||||
char strDebug[B3_MAX_DEBUG_STRING_LENGTH] = {0};
|
||||
va_list argList;
|
||||
va_start(argList, str);
|
||||
#ifdef _MSC_VER
|
||||
vsprintf_s(strDebug,B3_MAX_DEBUG_STRING_LENGTH,str,argList);
|
||||
vsprintf_s(strDebug, B3_MAX_DEBUG_STRING_LENGTH, str, argList);
|
||||
#else
|
||||
vsnprintf(strDebug,B3_MAX_DEBUG_STRING_LENGTH,str,argList);
|
||||
vsnprintf(strDebug, B3_MAX_DEBUG_STRING_LENGTH, str, argList);
|
||||
#endif
|
||||
(b3s_printfFunc)(strDebug);
|
||||
va_end(argList);
|
||||
(b3s_printfFunc)(strDebug);
|
||||
va_end(argList);
|
||||
}
|
||||
void b3OutputWarningMessageVarArgsInternal(const char *str, ...)
|
||||
void b3OutputWarningMessageVarArgsInternal(const char* str, ...)
|
||||
{
|
||||
char strDebug[B3_MAX_DEBUG_STRING_LENGTH]={0};
|
||||
va_list argList;
|
||||
va_start(argList, str);
|
||||
char strDebug[B3_MAX_DEBUG_STRING_LENGTH] = {0};
|
||||
va_list argList;
|
||||
va_start(argList, str);
|
||||
#ifdef _MSC_VER
|
||||
vsprintf_s(strDebug,B3_MAX_DEBUG_STRING_LENGTH,str,argList);
|
||||
vsprintf_s(strDebug, B3_MAX_DEBUG_STRING_LENGTH, str, argList);
|
||||
#else
|
||||
vsnprintf(strDebug,B3_MAX_DEBUG_STRING_LENGTH,str,argList);
|
||||
vsnprintf(strDebug, B3_MAX_DEBUG_STRING_LENGTH, str, argList);
|
||||
#endif
|
||||
(b3s_warningMessageFunc)(strDebug);
|
||||
va_end(argList);
|
||||
(b3s_warningMessageFunc)(strDebug);
|
||||
va_end(argList);
|
||||
}
|
||||
void b3OutputErrorMessageVarArgsInternal(const char *str, ...)
|
||||
void b3OutputErrorMessageVarArgsInternal(const char* str, ...)
|
||||
{
|
||||
|
||||
char strDebug[B3_MAX_DEBUG_STRING_LENGTH]={0};
|
||||
va_list argList;
|
||||
va_start(argList, str);
|
||||
char strDebug[B3_MAX_DEBUG_STRING_LENGTH] = {0};
|
||||
va_list argList;
|
||||
va_start(argList, str);
|
||||
#ifdef _MSC_VER
|
||||
vsprintf_s(strDebug,B3_MAX_DEBUG_STRING_LENGTH,str,argList);
|
||||
vsprintf_s(strDebug, B3_MAX_DEBUG_STRING_LENGTH, str, argList);
|
||||
#else
|
||||
vsnprintf(strDebug,B3_MAX_DEBUG_STRING_LENGTH,str,argList);
|
||||
vsnprintf(strDebug, B3_MAX_DEBUG_STRING_LENGTH, str, argList);
|
||||
#endif
|
||||
(b3s_errorMessageFunc)(strDebug);
|
||||
va_end(argList);
|
||||
|
||||
(b3s_errorMessageFunc)(strDebug);
|
||||
va_end(argList);
|
||||
}
|
||||
|
||||
|
||||
void b3EnterProfileZoneDefault(const char* name)
|
||||
void b3EnterProfileZoneDefault(const char* name)
|
||||
{
|
||||
}
|
||||
void b3LeaveProfileZoneDefault()
|
||||
void b3LeaveProfileZoneDefault()
|
||||
{
|
||||
}
|
||||
static b3EnterProfileZoneFunc* b3s_enterFunc = b3EnterProfileZoneDefault;
|
||||
@@ -151,10 +140,6 @@ void b3SetCustomLeaveProfileZoneFunc(b3LeaveProfileZoneFunc* leaveFunc)
|
||||
b3s_leaveFunc = leaveFunc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#undef vsprintf_s
|
||||
#endif
|
||||
|
||||
|
||||
@@ -3,75 +3,84 @@
|
||||
#define B3_LOGGING_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
///We add the do/while so that the statement "if (condition) b3Printf("test"); else {...}" would fail
|
||||
///You can also customize the message by uncommenting out a different line below
|
||||
#define b3Printf(...) b3OutputPrintfVarArgsInternal(__VA_ARGS__)
|
||||
//#define b3Printf(...) do {b3OutputPrintfVarArgsInternal("b3Printf[%s,%d]:",__FILE__,__LINE__);b3OutputPrintfVarArgsInternal(__VA_ARGS__); } while(0)
|
||||
//#define b3Printf b3OutputPrintfVarArgsInternal
|
||||
//#define b3Printf(...) printf(__VA_ARGS__)
|
||||
//#define b3Printf(...)
|
||||
|
||||
#define b3Warning(...) do {b3OutputWarningMessageVarArgsInternal("b3Warning[%s,%d]:\n",__FILE__,__LINE__);b3OutputWarningMessageVarArgsInternal(__VA_ARGS__); }while(0)
|
||||
#define b3Error(...) do {b3OutputErrorMessageVarArgsInternal("b3Error[%s,%d]:\n",__FILE__,__LINE__);b3OutputErrorMessageVarArgsInternal(__VA_ARGS__); } while(0)
|
||||
//#define b3Printf(...) do {b3OutputPrintfVarArgsInternal("b3Printf[%s,%d]:",__FILE__,__LINE__);b3OutputPrintfVarArgsInternal(__VA_ARGS__); } while(0)
|
||||
//#define b3Printf b3OutputPrintfVarArgsInternal
|
||||
//#define b3Printf(...) printf(__VA_ARGS__)
|
||||
//#define b3Printf(...)
|
||||
|
||||
#define b3Warning(...) \
|
||||
do \
|
||||
{ \
|
||||
b3OutputWarningMessageVarArgsInternal("b3Warning[%s,%d]:\n", __FILE__, __LINE__); \
|
||||
b3OutputWarningMessageVarArgsInternal(__VA_ARGS__); \
|
||||
} while (0)
|
||||
#define b3Error(...) \
|
||||
do \
|
||||
{ \
|
||||
b3OutputErrorMessageVarArgsInternal("b3Error[%s,%d]:\n", __FILE__, __LINE__); \
|
||||
b3OutputErrorMessageVarArgsInternal(__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#ifndef B3_NO_PROFILE
|
||||
|
||||
void b3EnterProfileZone(const char* name);
|
||||
void b3LeaveProfileZone();
|
||||
void b3EnterProfileZone(const char* name);
|
||||
void b3LeaveProfileZone();
|
||||
#ifdef __cplusplus
|
||||
|
||||
class b3ProfileZone
|
||||
{
|
||||
public:
|
||||
b3ProfileZone(const char* name)
|
||||
{
|
||||
b3EnterProfileZone( name );
|
||||
}
|
||||
class b3ProfileZone
|
||||
{
|
||||
public:
|
||||
b3ProfileZone(const char* name)
|
||||
{
|
||||
b3EnterProfileZone(name);
|
||||
}
|
||||
|
||||
~b3ProfileZone()
|
||||
{
|
||||
b3LeaveProfileZone();
|
||||
}
|
||||
};
|
||||
~b3ProfileZone()
|
||||
{
|
||||
b3LeaveProfileZone();
|
||||
}
|
||||
};
|
||||
|
||||
#define B3_PROFILE( name ) b3ProfileZone __profile( name )
|
||||
#define B3_PROFILE(name) b3ProfileZone __profile(name)
|
||||
#endif
|
||||
|
||||
#else //B3_NO_PROFILE
|
||||
#else //B3_NO_PROFILE
|
||||
|
||||
#define B3_PROFILE( name )
|
||||
#define B3_PROFILE(name)
|
||||
#define b3StartProfile(a)
|
||||
#define b3StopProfile
|
||||
|
||||
#endif //#ifndef B3_NO_PROFILE
|
||||
#endif //#ifndef B3_NO_PROFILE
|
||||
|
||||
typedef void(b3PrintfFunc)(const char* msg);
|
||||
typedef void(b3WarningMessageFunc)(const char* msg);
|
||||
typedef void(b3ErrorMessageFunc)(const char* msg);
|
||||
typedef void(b3EnterProfileZoneFunc)(const char* msg);
|
||||
typedef void(b3LeaveProfileZoneFunc)();
|
||||
|
||||
typedef void (b3PrintfFunc)(const char* msg);
|
||||
typedef void (b3WarningMessageFunc)(const char* msg);
|
||||
typedef void (b3ErrorMessageFunc)(const char* msg);
|
||||
typedef void (b3EnterProfileZoneFunc)(const char* msg);
|
||||
typedef void (b3LeaveProfileZoneFunc)();
|
||||
///The developer can route b3Printf output using their own implementation
|
||||
void b3SetCustomPrintfFunc(b3PrintfFunc* printfFunc);
|
||||
void b3SetCustomWarningMessageFunc(b3WarningMessageFunc* warningMsgFunc);
|
||||
void b3SetCustomErrorMessageFunc(b3ErrorMessageFunc* errorMsgFunc);
|
||||
|
||||
///The developer can route b3Printf output using their own implementation
|
||||
void b3SetCustomPrintfFunc(b3PrintfFunc* printfFunc);
|
||||
void b3SetCustomWarningMessageFunc(b3WarningMessageFunc* warningMsgFunc);
|
||||
void b3SetCustomErrorMessageFunc(b3ErrorMessageFunc* errorMsgFunc);
|
||||
///Set custom profile zone functions (zones can be nested)
|
||||
void b3SetCustomEnterProfileZoneFunc(b3EnterProfileZoneFunc* enterFunc);
|
||||
void b3SetCustomLeaveProfileZoneFunc(b3LeaveProfileZoneFunc* leaveFunc);
|
||||
|
||||
///Set custom profile zone functions (zones can be nested)
|
||||
void b3SetCustomEnterProfileZoneFunc(b3EnterProfileZoneFunc* enterFunc);
|
||||
void b3SetCustomLeaveProfileZoneFunc(b3LeaveProfileZoneFunc* leaveFunc);
|
||||
|
||||
///Don't use those internal functions directly, use the b3Printf or b3SetCustomPrintfFunc instead (or warning/error version)
|
||||
void b3OutputPrintfVarArgsInternal(const char *str, ...);
|
||||
void b3OutputWarningMessageVarArgsInternal(const char *str, ...);
|
||||
void b3OutputErrorMessageVarArgsInternal(const char *str, ...);
|
||||
///Don't use those internal functions directly, use the b3Printf or b3SetCustomPrintfFunc instead (or warning/error version)
|
||||
void b3OutputPrintfVarArgsInternal(const char* str, ...);
|
||||
void b3OutputWarningMessageVarArgsInternal(const char* str, ...);
|
||||
void b3OutputErrorMessageVarArgsInternal(const char* str, ...);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif//B3_LOGGING_H
|
||||
#endif //B3_LOGGING_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,60 +12,58 @@ subject to the following restrictions:
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef B3_GEN_MINMAX_H
|
||||
#define B3_GEN_MINMAX_H
|
||||
|
||||
#include "b3Scalar.h"
|
||||
|
||||
template <class T>
|
||||
B3_FORCE_INLINE const T& b3Min(const T& a, const T& b)
|
||||
B3_FORCE_INLINE const T& b3Min(const T& a, const T& b)
|
||||
{
|
||||
return a < b ? a : b ;
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
B3_FORCE_INLINE const T& b3Max(const T& a, const T& b)
|
||||
B3_FORCE_INLINE const T& b3Max(const T& a, const T& b)
|
||||
{
|
||||
return a > b ? a : b;
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
B3_FORCE_INLINE const T& b3Clamped(const T& a, const T& lb, const T& ub)
|
||||
B3_FORCE_INLINE const T& b3Clamped(const T& a, const T& lb, const T& ub)
|
||||
{
|
||||
return a < lb ? lb : (ub < a ? ub : a);
|
||||
return a < lb ? lb : (ub < a ? ub : a);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
B3_FORCE_INLINE void b3SetMin(T& a, const T& b)
|
||||
B3_FORCE_INLINE void b3SetMin(T& a, const T& b)
|
||||
{
|
||||
if (b < a)
|
||||
if (b < a)
|
||||
{
|
||||
a = b;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
B3_FORCE_INLINE void b3SetMax(T& a, const T& b)
|
||||
B3_FORCE_INLINE void b3SetMax(T& a, const T& b)
|
||||
{
|
||||
if (a < b)
|
||||
if (a < b)
|
||||
{
|
||||
a = b;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
B3_FORCE_INLINE void b3Clamp(T& a, const T& lb, const T& ub)
|
||||
B3_FORCE_INLINE void b3Clamp(T& a, const T& lb, const T& ub)
|
||||
{
|
||||
if (a < lb)
|
||||
if (a < lb)
|
||||
{
|
||||
a = lb;
|
||||
a = lb;
|
||||
}
|
||||
else if (ub < a)
|
||||
else if (ub < a)
|
||||
{
|
||||
a = ub;
|
||||
}
|
||||
}
|
||||
|
||||
#endif //B3_GEN_MINMAX_H
|
||||
#endif //B3_GEN_MINMAX_H
|
||||
|
||||
@@ -12,7 +12,6 @@ subject to the following restrictions:
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _BT_POOL_ALLOCATOR_H
|
||||
#define _BT_POOL_ALLOCATOR_H
|
||||
|
||||
@@ -22,37 +21,37 @@ subject to the following restrictions:
|
||||
///The b3PoolAllocator class allows to efficiently allocate a large pool of objects, instead of dynamically allocating them separately.
|
||||
class b3PoolAllocator
|
||||
{
|
||||
int m_elemSize;
|
||||
int m_maxElements;
|
||||
int m_freeCount;
|
||||
void* m_firstFree;
|
||||
unsigned char* m_pool;
|
||||
int m_elemSize;
|
||||
int m_maxElements;
|
||||
int m_freeCount;
|
||||
void* m_firstFree;
|
||||
unsigned char* m_pool;
|
||||
|
||||
public:
|
||||
|
||||
b3PoolAllocator(int elemSize, int maxElements)
|
||||
:m_elemSize(elemSize),
|
||||
m_maxElements(maxElements)
|
||||
: m_elemSize(elemSize),
|
||||
m_maxElements(maxElements)
|
||||
{
|
||||
m_pool = (unsigned char*) b3AlignedAlloc( static_cast<unsigned int>(m_elemSize*m_maxElements),16);
|
||||
m_pool = (unsigned char*)b3AlignedAlloc(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;
|
||||
}
|
||||
m_firstFree = p;
|
||||
m_freeCount = m_maxElements;
|
||||
int count = m_maxElements;
|
||||
while (--count)
|
||||
{
|
||||
*(void**)p = (p + m_elemSize);
|
||||
p += m_elemSize;
|
||||
}
|
||||
*(void**)p = 0;
|
||||
}
|
||||
|
||||
~b3PoolAllocator()
|
||||
{
|
||||
b3AlignedFree( m_pool);
|
||||
b3AlignedFree(m_pool);
|
||||
}
|
||||
|
||||
int getFreeCount() const
|
||||
int getFreeCount() const
|
||||
{
|
||||
return m_freeCount;
|
||||
}
|
||||
@@ -67,21 +66,22 @@ public:
|
||||
return m_maxElements;
|
||||
}
|
||||
|
||||
void* allocate(int size)
|
||||
void* allocate(int size)
|
||||
{
|
||||
// release mode fix
|
||||
(void)size;
|
||||
b3Assert(!size || size<=m_elemSize);
|
||||
b3Assert(m_freeCount>0);
|
||||
void* result = m_firstFree;
|
||||
m_firstFree = *(void**)m_firstFree;
|
||||
--m_freeCount;
|
||||
return result;
|
||||
b3Assert(!size || size <= m_elemSize);
|
||||
b3Assert(m_freeCount > 0);
|
||||
void* result = m_firstFree;
|
||||
m_firstFree = *(void**)m_firstFree;
|
||||
--m_freeCount;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool validPtr(void* ptr)
|
||||
{
|
||||
if (ptr) {
|
||||
if (ptr)
|
||||
{
|
||||
if (((unsigned char*)ptr >= m_pool && (unsigned char*)ptr < m_pool + m_maxElements * m_elemSize))
|
||||
{
|
||||
return true;
|
||||
@@ -90,32 +90,32 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
void freeMemory(void* ptr)
|
||||
void freeMemory(void* ptr)
|
||||
{
|
||||
if (ptr) {
|
||||
b3Assert((unsigned char*)ptr >= m_pool && (unsigned char*)ptr < m_pool + m_maxElements * m_elemSize);
|
||||
if (ptr)
|
||||
{
|
||||
b3Assert((unsigned char*)ptr >= m_pool && (unsigned char*)ptr < m_pool + m_maxElements * m_elemSize);
|
||||
|
||||
*(void**)ptr = m_firstFree;
|
||||
m_firstFree = ptr;
|
||||
++m_freeCount;
|
||||
}
|
||||
*(void**)ptr = m_firstFree;
|
||||
m_firstFree = ptr;
|
||||
++m_freeCount;
|
||||
}
|
||||
}
|
||||
|
||||
int getElementSize() const
|
||||
int getElementSize() const
|
||||
{
|
||||
return m_elemSize;
|
||||
}
|
||||
|
||||
unsigned char* getPoolAddress()
|
||||
unsigned char* getPoolAddress()
|
||||
{
|
||||
return m_pool;
|
||||
}
|
||||
|
||||
const unsigned char* getPoolAddress() const
|
||||
const unsigned char* getPoolAddress() const
|
||||
{
|
||||
return m_pool;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif //_BT_POOL_ALLOCATOR_H
|
||||
#endif //_BT_POOL_ALLOCATOR_H
|
||||
|
||||
@@ -12,18 +12,13 @@ subject to the following restrictions:
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef B3_SIMD_QUADWORD_H
|
||||
#define B3_SIMD_QUADWORD_H
|
||||
|
||||
#include "b3Scalar.h"
|
||||
#include "b3MinMax.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#if defined (__CELLOS_LV2) && defined (__SPU__)
|
||||
#if defined(__CELLOS_LV2) && defined(__SPU__)
|
||||
#include <altivec.h>
|
||||
#endif
|
||||
|
||||
@@ -31,58 +26,64 @@ subject to the following restrictions:
|
||||
* Some issues under PS3 Linux with IBM 2.1 SDK, gcc compiler prevent from using aligned quadword.
|
||||
*/
|
||||
#ifndef USE_LIBSPE2
|
||||
B3_ATTRIBUTE_ALIGNED16(class) b3QuadWord
|
||||
B3_ATTRIBUTE_ALIGNED16(class)
|
||||
b3QuadWord
|
||||
#else
|
||||
class b3QuadWord
|
||||
#endif
|
||||
{
|
||||
protected:
|
||||
|
||||
#if defined (__SPU__) && defined (__CELLOS_LV2__)
|
||||
#if defined(__SPU__) && defined(__CELLOS_LV2__)
|
||||
union {
|
||||
vec_float4 mVec128;
|
||||
b3Scalar m_floats[4];
|
||||
b3Scalar m_floats[4];
|
||||
};
|
||||
|
||||
public:
|
||||
vec_float4 get128() const
|
||||
vec_float4 get128() const
|
||||
{
|
||||
return mVec128;
|
||||
}
|
||||
|
||||
#else //__CELLOS_LV2__ __SPU__
|
||||
#else //__CELLOS_LV2__ __SPU__
|
||||
|
||||
#if defined(B3_USE_SSE) || defined(B3_USE_NEON)
|
||||
#if defined(B3_USE_SSE) || defined(B3_USE_NEON)
|
||||
public:
|
||||
union {
|
||||
b3SimdFloat4 mVec128;
|
||||
b3Scalar m_floats[4];
|
||||
struct {b3Scalar x,y,z,w;};
|
||||
b3Scalar m_floats[4];
|
||||
struct
|
||||
{
|
||||
b3Scalar x, y, z, w;
|
||||
};
|
||||
};
|
||||
|
||||
public:
|
||||
B3_FORCE_INLINE b3SimdFloat4 get128() const
|
||||
B3_FORCE_INLINE b3SimdFloat4 get128() const
|
||||
{
|
||||
return mVec128;
|
||||
}
|
||||
B3_FORCE_INLINE void set128(b3SimdFloat4 v128)
|
||||
B3_FORCE_INLINE void set128(b3SimdFloat4 v128)
|
||||
{
|
||||
mVec128 = v128;
|
||||
}
|
||||
#else
|
||||
public:
|
||||
union
|
||||
{
|
||||
b3Scalar m_floats[4];
|
||||
struct {b3Scalar x,y,z,w;};
|
||||
union {
|
||||
b3Scalar m_floats[4];
|
||||
struct
|
||||
{
|
||||
b3Scalar x, y, z, w;
|
||||
};
|
||||
};
|
||||
#endif // B3_USE_SSE
|
||||
#endif // B3_USE_SSE
|
||||
|
||||
#endif //__CELLOS_LV2__ __SPU__
|
||||
#endif //__CELLOS_LV2__ __SPU__
|
||||
|
||||
public:
|
||||
|
||||
public:
|
||||
#if defined(B3_USE_SSE) || defined(B3_USE_NEON)
|
||||
|
||||
// Set Vector
|
||||
// Set Vector
|
||||
B3_FORCE_INLINE b3QuadWord(const b3SimdFloat4 vec)
|
||||
{
|
||||
mVec128 = vec;
|
||||
@@ -95,151 +96,147 @@ public:
|
||||
}
|
||||
|
||||
// Assignment Operator
|
||||
B3_FORCE_INLINE b3QuadWord&
|
||||
operator=(const b3QuadWord& v)
|
||||
B3_FORCE_INLINE b3QuadWord&
|
||||
operator=(const b3QuadWord& v)
|
||||
{
|
||||
mVec128 = v.mVec128;
|
||||
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/**@brief Return the x value */
|
||||
B3_FORCE_INLINE const b3Scalar& getX() const { return m_floats[0]; }
|
||||
/**@brief Return the y value */
|
||||
B3_FORCE_INLINE const b3Scalar& getY() const { return m_floats[1]; }
|
||||
/**@brief Return the z value */
|
||||
B3_FORCE_INLINE const b3Scalar& getZ() const { return m_floats[2]; }
|
||||
/**@brief Set the x value */
|
||||
B3_FORCE_INLINE void setX(b3Scalar _x) { m_floats[0] = _x;};
|
||||
/**@brief Set the y value */
|
||||
B3_FORCE_INLINE void setY(b3Scalar _y) { m_floats[1] = _y;};
|
||||
/**@brief Set the z value */
|
||||
B3_FORCE_INLINE void setZ(b3Scalar _z) { m_floats[2] = _z;};
|
||||
/**@brief Set the w value */
|
||||
B3_FORCE_INLINE void setW(b3Scalar _w) { m_floats[3] = _w;};
|
||||
/**@brief Return the x value */
|
||||
/**@brief Return the x value */
|
||||
B3_FORCE_INLINE const b3Scalar& getX() const { return m_floats[0]; }
|
||||
/**@brief Return the y value */
|
||||
B3_FORCE_INLINE const b3Scalar& getY() const { return m_floats[1]; }
|
||||
/**@brief Return the z value */
|
||||
B3_FORCE_INLINE const b3Scalar& getZ() const { return m_floats[2]; }
|
||||
/**@brief Set the x value */
|
||||
B3_FORCE_INLINE void setX(b3Scalar _x) { m_floats[0] = _x; };
|
||||
/**@brief Set the y value */
|
||||
B3_FORCE_INLINE void setY(b3Scalar _y) { m_floats[1] = _y; };
|
||||
/**@brief Set the z value */
|
||||
B3_FORCE_INLINE void setZ(b3Scalar _z) { m_floats[2] = _z; };
|
||||
/**@brief Set the w value */
|
||||
B3_FORCE_INLINE void setW(b3Scalar _w) { m_floats[3] = _w; };
|
||||
/**@brief Return the x value */
|
||||
|
||||
|
||||
//B3_FORCE_INLINE b3Scalar& operator[](int i) { return (&m_floats[0])[i]; }
|
||||
//B3_FORCE_INLINE b3Scalar& operator[](int i) { return (&m_floats[0])[i]; }
|
||||
//B3_FORCE_INLINE const b3Scalar& operator[](int i) const { return (&m_floats[0])[i]; }
|
||||
///operator b3Scalar*() replaces operator[], using implicit conversion. We added operator != and operator == to avoid pointer comparisons.
|
||||
B3_FORCE_INLINE operator b3Scalar *() { return &m_floats[0]; }
|
||||
B3_FORCE_INLINE operator const b3Scalar *() const { return &m_floats[0]; }
|
||||
B3_FORCE_INLINE operator b3Scalar*() { return &m_floats[0]; }
|
||||
B3_FORCE_INLINE operator const b3Scalar*() const { return &m_floats[0]; }
|
||||
|
||||
B3_FORCE_INLINE bool operator==(const b3QuadWord& other) const
|
||||
B3_FORCE_INLINE bool operator==(const b3QuadWord& other) const
|
||||
{
|
||||
#ifdef B3_USE_SSE
|
||||
return (0xf == _mm_movemask_ps((__m128)_mm_cmpeq_ps(mVec128, other.mVec128)));
|
||||
#else
|
||||
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]));
|
||||
return (0xf == _mm_movemask_ps((__m128)_mm_cmpeq_ps(mVec128, other.mVec128)));
|
||||
#else
|
||||
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]));
|
||||
#endif
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE bool operator!=(const b3QuadWord& other) const
|
||||
B3_FORCE_INLINE bool operator!=(const b3QuadWord& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
/**@brief Set x,y,z and zero w
|
||||
/**@brief Set x,y,z and zero w
|
||||
* @param x Value of x
|
||||
* @param y Value of y
|
||||
* @param z Value of z
|
||||
*/
|
||||
B3_FORCE_INLINE void setValue(const b3Scalar& _x, const b3Scalar& _y, const b3Scalar& _z)
|
||||
{
|
||||
m_floats[0]=_x;
|
||||
m_floats[1]=_y;
|
||||
m_floats[2]=_z;
|
||||
m_floats[3] = 0.f;
|
||||
}
|
||||
B3_FORCE_INLINE void setValue(const b3Scalar& _x, const b3Scalar& _y, const b3Scalar& _z)
|
||||
{
|
||||
m_floats[0] = _x;
|
||||
m_floats[1] = _y;
|
||||
m_floats[2] = _z;
|
||||
m_floats[3] = 0.f;
|
||||
}
|
||||
|
||||
/* void getValue(b3Scalar *m) const
|
||||
/* void getValue(b3Scalar *m) const
|
||||
{
|
||||
m[0] = m_floats[0];
|
||||
m[1] = m_floats[1];
|
||||
m[2] = m_floats[2];
|
||||
}
|
||||
*/
|
||||
/**@brief Set the values
|
||||
/**@brief Set the values
|
||||
* @param x Value of x
|
||||
* @param y Value of y
|
||||
* @param z Value of z
|
||||
* @param w Value of w
|
||||
*/
|
||||
B3_FORCE_INLINE void setValue(const b3Scalar& _x, const b3Scalar& _y, const b3Scalar& _z,const b3Scalar& _w)
|
||||
{
|
||||
m_floats[0]=_x;
|
||||
m_floats[1]=_y;
|
||||
m_floats[2]=_z;
|
||||
m_floats[3]=_w;
|
||||
}
|
||||
/**@brief No initialization constructor */
|
||||
B3_FORCE_INLINE b3QuadWord()
|
||||
// :m_floats[0](b3Scalar(0.)),m_floats[1](b3Scalar(0.)),m_floats[2](b3Scalar(0.)),m_floats[3](b3Scalar(0.))
|
||||
{
|
||||
}
|
||||
|
||||
/**@brief Three argument constructor (zeros w)
|
||||
B3_FORCE_INLINE void setValue(const b3Scalar& _x, const b3Scalar& _y, const b3Scalar& _z, const b3Scalar& _w)
|
||||
{
|
||||
m_floats[0] = _x;
|
||||
m_floats[1] = _y;
|
||||
m_floats[2] = _z;
|
||||
m_floats[3] = _w;
|
||||
}
|
||||
/**@brief No initialization constructor */
|
||||
B3_FORCE_INLINE b3QuadWord()
|
||||
// :m_floats[0](b3Scalar(0.)),m_floats[1](b3Scalar(0.)),m_floats[2](b3Scalar(0.)),m_floats[3](b3Scalar(0.))
|
||||
{
|
||||
}
|
||||
|
||||
/**@brief Three argument constructor (zeros w)
|
||||
* @param x Value of x
|
||||
* @param y Value of y
|
||||
* @param z Value of z
|
||||
*/
|
||||
B3_FORCE_INLINE b3QuadWord(const b3Scalar& _x, const b3Scalar& _y, const b3Scalar& _z)
|
||||
{
|
||||
m_floats[0] = _x, m_floats[1] = _y, m_floats[2] = _z, m_floats[3] = 0.0f;
|
||||
}
|
||||
B3_FORCE_INLINE b3QuadWord(const b3Scalar& _x, const b3Scalar& _y, const b3Scalar& _z)
|
||||
{
|
||||
m_floats[0] = _x, m_floats[1] = _y, m_floats[2] = _z, m_floats[3] = 0.0f;
|
||||
}
|
||||
|
||||
/**@brief Initializing constructor
|
||||
/**@brief Initializing constructor
|
||||
* @param x Value of x
|
||||
* @param y Value of y
|
||||
* @param z Value of z
|
||||
* @param w Value of w
|
||||
*/
|
||||
B3_FORCE_INLINE b3QuadWord(const b3Scalar& _x, const b3Scalar& _y, const b3Scalar& _z,const b3Scalar& _w)
|
||||
{
|
||||
m_floats[0] = _x, m_floats[1] = _y, m_floats[2] = _z, m_floats[3] = _w;
|
||||
}
|
||||
B3_FORCE_INLINE b3QuadWord(const b3Scalar& _x, const b3Scalar& _y, const b3Scalar& _z, const b3Scalar& _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 b3QuadWord
|
||||
/**@brief Set each element to the max of the current values and the values of another b3QuadWord
|
||||
* @param other The other b3QuadWord to compare with
|
||||
*/
|
||||
B3_FORCE_INLINE void setMax(const b3QuadWord& other)
|
||||
{
|
||||
#ifdef B3_USE_SSE
|
||||
mVec128 = _mm_max_ps(mVec128, other.mVec128);
|
||||
#elif defined(B3_USE_NEON)
|
||||
mVec128 = vmaxq_f32(mVec128, other.mVec128);
|
||||
#else
|
||||
b3SetMax(m_floats[0], other.m_floats[0]);
|
||||
b3SetMax(m_floats[1], other.m_floats[1]);
|
||||
b3SetMax(m_floats[2], other.m_floats[2]);
|
||||
b3SetMax(m_floats[3], other.m_floats[3]);
|
||||
#endif
|
||||
}
|
||||
/**@brief Set each element to the min of the current values and the values of another b3QuadWord
|
||||
B3_FORCE_INLINE void setMax(const b3QuadWord& other)
|
||||
{
|
||||
#ifdef B3_USE_SSE
|
||||
mVec128 = _mm_max_ps(mVec128, other.mVec128);
|
||||
#elif defined(B3_USE_NEON)
|
||||
mVec128 = vmaxq_f32(mVec128, other.mVec128);
|
||||
#else
|
||||
b3SetMax(m_floats[0], other.m_floats[0]);
|
||||
b3SetMax(m_floats[1], other.m_floats[1]);
|
||||
b3SetMax(m_floats[2], other.m_floats[2]);
|
||||
b3SetMax(m_floats[3], other.m_floats[3]);
|
||||
#endif
|
||||
}
|
||||
/**@brief Set each element to the min of the current values and the values of another b3QuadWord
|
||||
* @param other The other b3QuadWord to compare with
|
||||
*/
|
||||
B3_FORCE_INLINE void setMin(const b3QuadWord& other)
|
||||
{
|
||||
#ifdef B3_USE_SSE
|
||||
mVec128 = _mm_min_ps(mVec128, other.mVec128);
|
||||
#elif defined(B3_USE_NEON)
|
||||
mVec128 = vminq_f32(mVec128, other.mVec128);
|
||||
#else
|
||||
b3SetMin(m_floats[0], other.m_floats[0]);
|
||||
b3SetMin(m_floats[1], other.m_floats[1]);
|
||||
b3SetMin(m_floats[2], other.m_floats[2]);
|
||||
b3SetMin(m_floats[3], other.m_floats[3]);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
B3_FORCE_INLINE void setMin(const b3QuadWord& other)
|
||||
{
|
||||
#ifdef B3_USE_SSE
|
||||
mVec128 = _mm_min_ps(mVec128, other.mVec128);
|
||||
#elif defined(B3_USE_NEON)
|
||||
mVec128 = vminq_f32(mVec128, other.mVec128);
|
||||
#else
|
||||
b3SetMin(m_floats[0], other.m_floats[0]);
|
||||
b3SetMin(m_floats[1], other.m_floats[1]);
|
||||
b3SetMin(m_floats[2], other.m_floats[2]);
|
||||
b3SetMin(m_floats[3], other.m_floats[3]);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
#endif //B3_SIMD_QUADWORD_H
|
||||
#endif //B3_SIMD_QUADWORD_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,8 +12,6 @@ subject to the following restrictions:
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef B3_GEN_RANDOM_H
|
||||
#define B3_GEN_RANDOM_H
|
||||
|
||||
@@ -26,8 +24,8 @@ subject to the following restrictions:
|
||||
|
||||
#define B3_RAND_MAX UINT_MAX
|
||||
|
||||
B3_FORCE_INLINE void b3Srand(unsigned int seed) { init_genrand(seed); }
|
||||
B3_FORCE_INLINE unsigned int b3rand() { return genrand_int32(); }
|
||||
B3_FORCE_INLINE void b3Srand(unsigned int seed) { init_genrand(seed); }
|
||||
B3_FORCE_INLINE unsigned int b3rand() { return genrand_int32(); }
|
||||
|
||||
#else
|
||||
|
||||
@@ -35,8 +33,8 @@ B3_FORCE_INLINE unsigned int b3rand() { return genrand_int32()
|
||||
|
||||
#define B3_RAND_MAX RAND_MAX
|
||||
|
||||
B3_FORCE_INLINE void b3Srand(unsigned int seed) { srand(seed); }
|
||||
B3_FORCE_INLINE unsigned int b3rand() { return rand(); }
|
||||
B3_FORCE_INLINE void b3Srand(unsigned int seed) { srand(seed); }
|
||||
B3_FORCE_INLINE unsigned int b3rand() { return rand(); }
|
||||
|
||||
#endif
|
||||
|
||||
@@ -45,6 +43,4 @@ inline b3Scalar b3RandRange(b3Scalar minRange, b3Scalar maxRange)
|
||||
return (b3rand() / (b3Scalar(B3_RAND_MAX) + b3Scalar(1.0))) * (maxRange - minRange) + minRange;
|
||||
}
|
||||
|
||||
|
||||
#endif //B3_GEN_RANDOM_H
|
||||
|
||||
#endif //B3_GEN_RANDOM_H
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
|
||||
#include "Bullet3Common/b3AlignedObjectArray.h"
|
||||
|
||||
enum
|
||||
enum
|
||||
{
|
||||
B3_POOL_HANDLE_TERMINAL_FREE=-1,
|
||||
B3_POOL_HANDLE_TERMINAL_USED =-2
|
||||
B3_POOL_HANDLE_TERMINAL_FREE = -1,
|
||||
B3_POOL_HANDLE_TERMINAL_USED = -2
|
||||
};
|
||||
|
||||
template <typename U>
|
||||
@@ -20,25 +20,23 @@ struct b3PoolBodyHandle : public U
|
||||
{
|
||||
m_nextFreeHandle = next;
|
||||
}
|
||||
int getNextFree() const
|
||||
int getNextFree() const
|
||||
{
|
||||
return m_nextFreeHandle;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
template <typename T>
|
||||
class b3ResizablePool
|
||||
{
|
||||
|
||||
protected:
|
||||
b3AlignedObjectArray<T> m_bodyHandles;
|
||||
int m_numUsedHandles; // number of active handles
|
||||
int m_firstFreeHandle; // free handles list
|
||||
b3AlignedObjectArray<T> m_bodyHandles;
|
||||
int m_numUsedHandles; // number of active handles
|
||||
int m_firstFreeHandle; // free handles list
|
||||
|
||||
T* getHandleInternal(int handle)
|
||||
{
|
||||
return &m_bodyHandles[handle];
|
||||
|
||||
}
|
||||
const T* getHandleInternal(int handle) const
|
||||
{
|
||||
@@ -46,17 +44,16 @@ protected:
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
b3ResizablePool()
|
||||
{
|
||||
initHandles();
|
||||
}
|
||||
|
||||
|
||||
virtual ~b3ResizablePool()
|
||||
{
|
||||
exitHandles();
|
||||
}
|
||||
///handle management
|
||||
///handle management
|
||||
|
||||
int getNumHandles() const
|
||||
{
|
||||
@@ -65,44 +62,40 @@ public:
|
||||
|
||||
void getUsedHandles(b3AlignedObjectArray<int>& usedHandles) const
|
||||
{
|
||||
|
||||
for (int i=0;i<m_bodyHandles.size();i++)
|
||||
for (int i = 0; i < m_bodyHandles.size(); i++)
|
||||
{
|
||||
if (m_bodyHandles[i].getNextFree()==B3_POOL_HANDLE_TERMINAL_USED)
|
||||
if (m_bodyHandles[i].getNextFree() == B3_POOL_HANDLE_TERMINAL_USED)
|
||||
{
|
||||
usedHandles.push_back(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
T* getHandle(int handle)
|
||||
{
|
||||
b3Assert(handle>=0);
|
||||
b3Assert(handle<m_bodyHandles.size());
|
||||
if ((handle<0) || (handle>=m_bodyHandles.size()))
|
||||
b3Assert(handle >= 0);
|
||||
b3Assert(handle < m_bodyHandles.size());
|
||||
if ((handle < 0) || (handle >= m_bodyHandles.size()))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (m_bodyHandles[handle].getNextFree()==B3_POOL_HANDLE_TERMINAL_USED)
|
||||
if (m_bodyHandles[handle].getNextFree() == B3_POOL_HANDLE_TERMINAL_USED)
|
||||
{
|
||||
return &m_bodyHandles[handle];
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
const T* getHandle(int handle) const
|
||||
{
|
||||
b3Assert(handle>=0);
|
||||
b3Assert(handle<m_bodyHandles.size());
|
||||
if ((handle<0) || (handle>=m_bodyHandles.size()))
|
||||
b3Assert(handle >= 0);
|
||||
b3Assert(handle < m_bodyHandles.size());
|
||||
if ((handle < 0) || (handle >= m_bodyHandles.size()))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (m_bodyHandles[handle].getNextFree()==B3_POOL_HANDLE_TERMINAL_USED)
|
||||
if (m_bodyHandles[handle].getNextFree() == B3_POOL_HANDLE_TERMINAL_USED)
|
||||
{
|
||||
return &m_bodyHandles[handle];
|
||||
}
|
||||
@@ -120,7 +113,6 @@ public:
|
||||
for (int i = curCapacity; i < newCapacity; i++)
|
||||
m_bodyHandles[i].setNextFree(i + 1);
|
||||
|
||||
|
||||
m_bodyHandles[newCapacity - 1].setNextFree(-1);
|
||||
}
|
||||
m_firstFreeHandle = curCapacity;
|
||||
@@ -142,19 +134,18 @@ public:
|
||||
|
||||
int allocHandle()
|
||||
{
|
||||
b3Assert(m_firstFreeHandle>=0);
|
||||
b3Assert(m_firstFreeHandle >= 0);
|
||||
|
||||
int handle = m_firstFreeHandle;
|
||||
m_firstFreeHandle = getHandleInternal(handle)->getNextFree();
|
||||
m_numUsedHandles++;
|
||||
|
||||
if (m_firstFreeHandle<0)
|
||||
if (m_firstFreeHandle < 0)
|
||||
{
|
||||
//int curCapacity = m_bodyHandles.size();
|
||||
int additionalCapacity= m_bodyHandles.size();
|
||||
int additionalCapacity = m_bodyHandles.size();
|
||||
increaseHandleCapacity(additionalCapacity);
|
||||
|
||||
|
||||
getHandleInternal(handle)->setNextFree(m_firstFreeHandle);
|
||||
}
|
||||
getHandleInternal(handle)->setNextFree(B3_POOL_HANDLE_TERMINAL_USED);
|
||||
@@ -162,12 +153,11 @@ public:
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
||||
void freeHandle(int handle)
|
||||
{
|
||||
b3Assert(handle >= 0);
|
||||
|
||||
if (m_bodyHandles[handle].getNextFree()==B3_POOL_HANDLE_TERMINAL_USED)
|
||||
if (m_bodyHandles[handle].getNextFree() == B3_POOL_HANDLE_TERMINAL_USED)
|
||||
{
|
||||
getHandleInternal(handle)->clear();
|
||||
getHandleInternal(handle)->setNextFree(m_firstFreeHandle);
|
||||
@@ -176,7 +166,6 @@ public:
|
||||
}
|
||||
}
|
||||
};
|
||||
///end handle management
|
||||
|
||||
#endif //B3_RESIZABLE_POOL_H
|
||||
|
||||
///end handle management
|
||||
|
||||
#endif //B3_RESIZABLE_POOL_H
|
||||
|
||||
@@ -12,8 +12,6 @@ subject to the following restrictions:
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef B3_SCALAR_H
|
||||
#define B3_SCALAR_H
|
||||
|
||||
@@ -22,238 +20,252 @@ subject to the following restrictions:
|
||||
#pragma unmanaged
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>//size_t for MSVC 6.0
|
||||
#include <stdlib.h> //size_t for MSVC 6.0
|
||||
#include <float.h>
|
||||
|
||||
//Original repository is at http://github.com/erwincoumans/bullet3
|
||||
#define B3_BULLET_VERSION 300
|
||||
|
||||
inline int b3GetVersion()
|
||||
inline int b3GetVersion()
|
||||
{
|
||||
return B3_BULLET_VERSION;
|
||||
}
|
||||
|
||||
#if defined(DEBUG) || defined (_DEBUG)
|
||||
#if defined(DEBUG) || defined(_DEBUG)
|
||||
#define B3_DEBUG
|
||||
#endif
|
||||
|
||||
#include "b3Logging.h"//for b3Error
|
||||
|
||||
#include "b3Logging.h" //for b3Error
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#if defined(__MINGW32__) || defined(__CYGWIN__) || (defined (_MSC_VER) && _MSC_VER < 1300)
|
||||
#if defined(__MINGW32__) || defined(__CYGWIN__) || (defined(_MSC_VER) && _MSC_VER < 1300)
|
||||
|
||||
#define B3_FORCE_INLINE inline
|
||||
#define B3_ATTRIBUTE_ALIGNED16(a) a
|
||||
#define B3_ATTRIBUTE_ALIGNED64(a) a
|
||||
#define B3_ATTRIBUTE_ALIGNED128(a) a
|
||||
#else
|
||||
//#define B3_HAS_ALIGNED_ALLOCATOR
|
||||
#pragma warning(disable : 4324) // disable padding warning
|
||||
#define B3_FORCE_INLINE inline
|
||||
#define B3_ATTRIBUTE_ALIGNED16(a) a
|
||||
#define B3_ATTRIBUTE_ALIGNED64(a) a
|
||||
#define B3_ATTRIBUTE_ALIGNED128(a) a
|
||||
#else
|
||||
//#define B3_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 : 4996) //Turn off warnings about deprecated C routines
|
||||
// #pragma warning(disable:4786) // Disable the "debug name too long" warning
|
||||
|
||||
#define B3_FORCE_INLINE __forceinline
|
||||
#define B3_ATTRIBUTE_ALIGNED16(a) __declspec(align(16)) a
|
||||
#define B3_ATTRIBUTE_ALIGNED64(a) __declspec(align(64)) a
|
||||
#define B3_ATTRIBUTE_ALIGNED128(a) __declspec (align(128)) a
|
||||
#ifdef _XBOX
|
||||
#define B3_USE_VMX128
|
||||
#define B3_FORCE_INLINE __forceinline
|
||||
#define B3_ATTRIBUTE_ALIGNED16(a) __declspec(align(16)) a
|
||||
#define B3_ATTRIBUTE_ALIGNED64(a) __declspec(align(64)) a
|
||||
#define B3_ATTRIBUTE_ALIGNED128(a) __declspec(align(128)) a
|
||||
#ifdef _XBOX
|
||||
#define B3_USE_VMX128
|
||||
|
||||
#include <ppcintrinsics.h>
|
||||
#define B3_HAVE_NATIVE_FSEL
|
||||
#define b3Fsel(a,b,c) __fsel((a),(b),(c))
|
||||
#else
|
||||
#include <ppcintrinsics.h>
|
||||
#define B3_HAVE_NATIVE_FSEL
|
||||
#define b3Fsel(a, b, c) __fsel((a), (b), (c))
|
||||
#else
|
||||
|
||||
#if (defined (_WIN32) && (_MSC_VER) && _MSC_VER >= 1400) && (!defined (B3_USE_DOUBLE_PRECISION))
|
||||
#if (defined (_M_IX86) || defined (_M_X64))
|
||||
#define B3_USE_SSE
|
||||
#ifdef B3_USE_SSE
|
||||
//B3_USE_SSE_IN_API is disabled under Windows by default, because
|
||||
//it makes it harder to integrate Bullet into your application under Windows
|
||||
//(structured embedding Bullet structs/classes need to be 16-byte aligned)
|
||||
//with relatively little performance gain
|
||||
//If you are not embedded Bullet data in your classes, or make sure that you align those classes on 16-byte boundaries
|
||||
//you can manually enable this line or set it in the build system for a bit of performance gain (a few percent, dependent on usage)
|
||||
//#define B3_USE_SSE_IN_API
|
||||
#endif //B3_USE_SSE
|
||||
#include <emmintrin.h>
|
||||
#endif
|
||||
#if (defined(_WIN32) && (_MSC_VER) && _MSC_VER >= 1400) && (!defined(B3_USE_DOUBLE_PRECISION))
|
||||
#if (defined(_M_IX86) || defined(_M_X64))
|
||||
#define B3_USE_SSE
|
||||
#ifdef B3_USE_SSE
|
||||
//B3_USE_SSE_IN_API is disabled under Windows by default, because
|
||||
//it makes it harder to integrate Bullet into your application under Windows
|
||||
//(structured embedding Bullet structs/classes need to be 16-byte aligned)
|
||||
//with relatively little performance gain
|
||||
//If you are not embedded Bullet data in your classes, or make sure that you align those classes on 16-byte boundaries
|
||||
//you can manually enable this line or set it in the build system for a bit of performance gain (a few percent, dependent on usage)
|
||||
//#define B3_USE_SSE_IN_API
|
||||
#endif //B3_USE_SSE
|
||||
#include <emmintrin.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif//_XBOX
|
||||
#endif //_XBOX
|
||||
|
||||
#endif //__MINGW32__
|
||||
#endif //__MINGW32__
|
||||
|
||||
#ifdef B3_DEBUG
|
||||
#ifdef _MSC_VER
|
||||
#include <stdio.h>
|
||||
#define b3Assert(x) { if(!(x)){b3Error("Assert "__FILE__ ":%u ("#x")\n", __LINE__);__debugbreak(); }}
|
||||
#else//_MSC_VER
|
||||
#include <assert.h>
|
||||
#define b3Assert assert
|
||||
#endif//_MSC_VER
|
||||
#ifdef _MSC_VER
|
||||
#include <stdio.h>
|
||||
#define b3Assert(x) \
|
||||
{ \
|
||||
if (!(x)) \
|
||||
{ \
|
||||
b3Error( \
|
||||
"Assert "__FILE__ \
|
||||
":%u (" #x ")\n", \
|
||||
__LINE__); \
|
||||
__debugbreak(); \
|
||||
} \
|
||||
}
|
||||
#else //_MSC_VER
|
||||
#include <assert.h>
|
||||
#define b3Assert assert
|
||||
#endif //_MSC_VER
|
||||
#else
|
||||
#define b3Assert(x)
|
||||
#define b3Assert(x)
|
||||
#endif
|
||||
//b3FullAssert is optional, slows down a lot
|
||||
#define b3FullAssert(x)
|
||||
//b3FullAssert is optional, slows down a lot
|
||||
#define b3FullAssert(x)
|
||||
|
||||
#define b3Likely(_c) _c
|
||||
#define b3Unlikely(_c) _c
|
||||
#define b3Likely(_c) _c
|
||||
#define b3Unlikely(_c) _c
|
||||
|
||||
#else
|
||||
|
||||
#if defined (__CELLOS_LV2__)
|
||||
#define B3_FORCE_INLINE inline __attribute__((always_inline))
|
||||
#define B3_ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
|
||||
#define B3_ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
|
||||
#define B3_ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
|
||||
#ifndef assert
|
||||
#include <assert.h>
|
||||
#endif
|
||||
|
||||
#if defined(__CELLOS_LV2__)
|
||||
#define B3_FORCE_INLINE inline __attribute__((always_inline))
|
||||
#define B3_ATTRIBUTE_ALIGNED16(a) a __attribute__((aligned(16)))
|
||||
#define B3_ATTRIBUTE_ALIGNED64(a) a __attribute__((aligned(64)))
|
||||
#define B3_ATTRIBUTE_ALIGNED128(a) a __attribute__((aligned(128)))
|
||||
#ifndef assert
|
||||
#include <assert.h>
|
||||
#endif
|
||||
#ifdef B3_DEBUG
|
||||
#ifdef __SPU__
|
||||
#include <spu_printf.h>
|
||||
#define printf spu_printf
|
||||
#define b3Assert(x) {if(!(x)){b3Error("Assert "__FILE__ ":%u ("#x")\n", __LINE__);spu_hcmpeq(0,0);}}
|
||||
#define b3Assert(x) \
|
||||
{ \
|
||||
if (!(x)) \
|
||||
{ \
|
||||
b3Error( \
|
||||
"Assert "__FILE__ \
|
||||
":%u (" #x ")\n", \
|
||||
__LINE__); \
|
||||
spu_hcmpeq(0, 0); \
|
||||
} \
|
||||
}
|
||||
#else
|
||||
#define b3Assert assert
|
||||
#define b3Assert assert
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define b3Assert(x)
|
||||
#endif
|
||||
//b3FullAssert is optional, slows down a lot
|
||||
#define b3FullAssert(x)
|
||||
|
||||
#define b3Likely(_c) _c
|
||||
#define b3Unlikely(_c) _c
|
||||
#else
|
||||
#define b3Assert(x)
|
||||
#endif
|
||||
//b3FullAssert is optional, slows down a lot
|
||||
#define b3FullAssert(x)
|
||||
|
||||
#define b3Likely(_c) _c
|
||||
#define b3Unlikely(_c) _c
|
||||
|
||||
#else
|
||||
|
||||
#ifdef USE_LIBSPE2
|
||||
|
||||
#define B3_FORCE_INLINE __inline
|
||||
#define B3_ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
|
||||
#define B3_ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
|
||||
#define B3_ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
|
||||
#ifndef assert
|
||||
#include <assert.h>
|
||||
#endif
|
||||
#define B3_FORCE_INLINE __inline
|
||||
#define B3_ATTRIBUTE_ALIGNED16(a) a __attribute__((aligned(16)))
|
||||
#define B3_ATTRIBUTE_ALIGNED64(a) a __attribute__((aligned(64)))
|
||||
#define B3_ATTRIBUTE_ALIGNED128(a) a __attribute__((aligned(128)))
|
||||
#ifndef assert
|
||||
#include <assert.h>
|
||||
#endif
|
||||
#ifdef B3_DEBUG
|
||||
#define b3Assert assert
|
||||
#define b3Assert assert
|
||||
#else
|
||||
#define b3Assert(x)
|
||||
#define b3Assert(x)
|
||||
#endif
|
||||
//b3FullAssert is optional, slows down a lot
|
||||
#define b3FullAssert(x)
|
||||
//b3FullAssert is optional, slows down a lot
|
||||
#define b3FullAssert(x)
|
||||
|
||||
|
||||
#define b3Likely(_c) __builtin_expect((_c), 1)
|
||||
#define b3Unlikely(_c) __builtin_expect((_c), 0)
|
||||
|
||||
#define b3Likely(_c) __builtin_expect((_c), 1)
|
||||
#define b3Unlikely(_c) __builtin_expect((_c), 0)
|
||||
|
||||
#else
|
||||
//non-windows systems
|
||||
//non-windows systems
|
||||
|
||||
#if (defined (__APPLE__) && (!defined (B3_USE_DOUBLE_PRECISION)))
|
||||
#if defined (__i386__) || defined (__x86_64__)
|
||||
#define B3_USE_SSE
|
||||
//B3_USE_SSE_IN_API is enabled on Mac OSX by default, because memory is automatically aligned on 16-byte boundaries
|
||||
//if apps run into issues, we will disable the next line
|
||||
#define B3_USE_SSE_IN_API
|
||||
#ifdef B3_USE_SSE
|
||||
// include appropriate SSE level
|
||||
#if defined (__SSE4_1__)
|
||||
#include <smmintrin.h>
|
||||
#elif defined (__SSSE3__)
|
||||
#include <tmmintrin.h>
|
||||
#elif defined (__SSE3__)
|
||||
#include <pmmintrin.h>
|
||||
#else
|
||||
#include <emmintrin.h>
|
||||
#endif
|
||||
#endif //B3_USE_SSE
|
||||
#elif defined( __armv7__ )
|
||||
#ifdef __clang__
|
||||
#define B3_USE_NEON 1
|
||||
#if (defined(__APPLE__) && (!defined(B3_USE_DOUBLE_PRECISION)))
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
#define B3_USE_SSE
|
||||
//B3_USE_SSE_IN_API is enabled on Mac OSX by default, because memory is automatically aligned on 16-byte boundaries
|
||||
//if apps run into issues, we will disable the next line
|
||||
#define B3_USE_SSE_IN_API
|
||||
#ifdef B3_USE_SSE
|
||||
// include appropriate SSE level
|
||||
#if defined(__SSE4_1__)
|
||||
#include <smmintrin.h>
|
||||
#elif defined(__SSSE3__)
|
||||
#include <tmmintrin.h>
|
||||
#elif defined(__SSE3__)
|
||||
#include <pmmintrin.h>
|
||||
#else
|
||||
#include <emmintrin.h>
|
||||
#endif
|
||||
#endif //B3_USE_SSE
|
||||
#elif defined(__armv7__)
|
||||
#ifdef __clang__
|
||||
#define B3_USE_NEON 1
|
||||
|
||||
#if defined B3_USE_NEON && defined (__clang__)
|
||||
#include <arm_neon.h>
|
||||
#endif//B3_USE_NEON
|
||||
#endif //__clang__
|
||||
#endif//__arm__
|
||||
#if defined B3_USE_NEON && defined(__clang__)
|
||||
#include <arm_neon.h>
|
||||
#endif //B3_USE_NEON
|
||||
#endif //__clang__
|
||||
#endif //__arm__
|
||||
|
||||
#define B3_FORCE_INLINE inline __attribute__ ((always_inline))
|
||||
#define B3_FORCE_INLINE inline __attribute__((always_inline))
|
||||
///@todo: check out alignment methods for other platforms/compilers
|
||||
#define B3_ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
|
||||
#define B3_ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
|
||||
#define B3_ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
|
||||
#ifndef assert
|
||||
#include <assert.h>
|
||||
#endif
|
||||
#define B3_ATTRIBUTE_ALIGNED16(a) a __attribute__((aligned(16)))
|
||||
#define B3_ATTRIBUTE_ALIGNED64(a) a __attribute__((aligned(64)))
|
||||
#define B3_ATTRIBUTE_ALIGNED128(a) a __attribute__((aligned(128)))
|
||||
#ifndef assert
|
||||
#include <assert.h>
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG) || defined (_DEBUG)
|
||||
#if defined (__i386__) || defined (__x86_64__)
|
||||
#include <stdio.h>
|
||||
#define b3Assert(x)\
|
||||
{\
|
||||
if(!(x))\
|
||||
{\
|
||||
b3Error("Assert %s in line %d, file %s\n",#x, __LINE__, __FILE__);\
|
||||
asm volatile ("int3");\
|
||||
}\
|
||||
#if defined(DEBUG) || defined(_DEBUG)
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
#include <stdio.h>
|
||||
#define b3Assert(x) \
|
||||
{ \
|
||||
if (!(x)) \
|
||||
{ \
|
||||
b3Error("Assert %s in line %d, file %s\n", #x, __LINE__, __FILE__); \
|
||||
asm volatile("int3"); \
|
||||
} \
|
||||
}
|
||||
#else//defined (__i386__) || defined (__x86_64__)
|
||||
#define b3Assert assert
|
||||
#endif//defined (__i386__) || defined (__x86_64__)
|
||||
#else//defined(DEBUG) || defined (_DEBUG)
|
||||
#define b3Assert(x)
|
||||
#endif//defined(DEBUG) || defined (_DEBUG)
|
||||
#else //defined (__i386__) || defined (__x86_64__)
|
||||
#define b3Assert assert
|
||||
#endif //defined (__i386__) || defined (__x86_64__)
|
||||
#else //defined(DEBUG) || defined (_DEBUG)
|
||||
#define b3Assert(x)
|
||||
#endif //defined(DEBUG) || defined (_DEBUG)
|
||||
|
||||
//b3FullAssert is optional, slows down a lot
|
||||
#define b3FullAssert(x)
|
||||
#define b3Likely(_c) _c
|
||||
#define b3Unlikely(_c) _c
|
||||
//b3FullAssert is optional, slows down a lot
|
||||
#define b3FullAssert(x)
|
||||
#define b3Likely(_c) _c
|
||||
#define b3Unlikely(_c) _c
|
||||
|
||||
#else
|
||||
|
||||
#define B3_FORCE_INLINE inline
|
||||
///@todo: check out alignment methods for other platforms/compilers
|
||||
#define B3_ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
|
||||
#define B3_ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
|
||||
#define B3_ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
|
||||
///#define B3_ATTRIBUTE_ALIGNED16(a) a
|
||||
///#define B3_ATTRIBUTE_ALIGNED64(a) a
|
||||
///#define B3_ATTRIBUTE_ALIGNED128(a) a
|
||||
#ifndef assert
|
||||
#include <assert.h>
|
||||
#endif
|
||||
#define B3_FORCE_INLINE inline
|
||||
///@todo: check out alignment methods for other platforms/compilers
|
||||
#define B3_ATTRIBUTE_ALIGNED16(a) a __attribute__((aligned(16)))
|
||||
#define B3_ATTRIBUTE_ALIGNED64(a) a __attribute__((aligned(64)))
|
||||
#define B3_ATTRIBUTE_ALIGNED128(a) a __attribute__((aligned(128)))
|
||||
///#define B3_ATTRIBUTE_ALIGNED16(a) a
|
||||
///#define B3_ATTRIBUTE_ALIGNED64(a) a
|
||||
///#define B3_ATTRIBUTE_ALIGNED128(a) a
|
||||
#ifndef assert
|
||||
#include <assert.h>
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG) || defined (_DEBUG)
|
||||
#define b3Assert assert
|
||||
#if defined(DEBUG) || defined(_DEBUG)
|
||||
#define b3Assert assert
|
||||
#else
|
||||
#define b3Assert(x)
|
||||
#define b3Assert(x)
|
||||
#endif
|
||||
|
||||
//b3FullAssert is optional, slows down a lot
|
||||
#define b3FullAssert(x)
|
||||
#define b3Likely(_c) _c
|
||||
#define b3Unlikely(_c) _c
|
||||
#endif //__APPLE__
|
||||
//b3FullAssert is optional, slows down a lot
|
||||
#define b3FullAssert(x)
|
||||
#define b3Likely(_c) _c
|
||||
#define b3Unlikely(_c) _c
|
||||
#endif //__APPLE__
|
||||
|
||||
#endif // LIBSPE2
|
||||
#endif // LIBSPE2
|
||||
|
||||
#endif //__CELLOS_LV2__
|
||||
#endif //__CELLOS_LV2__
|
||||
#endif
|
||||
|
||||
|
||||
///The b3Scalar type abstracts floating point numbers, to easily switch between double and single floating point precision.
|
||||
#if defined(B3_USE_DOUBLE_PRECISION)
|
||||
typedef double b3Scalar;
|
||||
@@ -267,34 +279,34 @@ typedef float b3Scalar;
|
||||
|
||||
#ifdef B3_USE_SSE
|
||||
typedef __m128 b3SimdFloat4;
|
||||
#endif//B3_USE_SSE
|
||||
#endif //B3_USE_SSE
|
||||
|
||||
#if defined B3_USE_SSE_IN_API && defined (B3_USE_SSE)
|
||||
#if defined B3_USE_SSE_IN_API && defined(B3_USE_SSE)
|
||||
#ifdef _WIN32
|
||||
|
||||
#ifndef B3_NAN
|
||||
static int b3NanMask = 0x7F800001;
|
||||
#define B3_NAN (*(float*)&b3NanMask)
|
||||
#define B3_NAN (*(float *)&b3NanMask)
|
||||
#endif
|
||||
|
||||
#ifndef B3_INFINITY_MASK
|
||||
static int b3InfinityMask = 0x7F800000;
|
||||
#define B3_INFINITY_MASK (*(float*)&b3InfinityMask)
|
||||
static int b3InfinityMask = 0x7F800000;
|
||||
#define B3_INFINITY_MASK (*(float *)&b3InfinityMask)
|
||||
#endif
|
||||
|
||||
inline __m128 operator + (const __m128 A, const __m128 B)
|
||||
inline __m128 operator+(const __m128 A, const __m128 B)
|
||||
{
|
||||
return _mm_add_ps(A, B);
|
||||
return _mm_add_ps(A, B);
|
||||
}
|
||||
|
||||
inline __m128 operator - (const __m128 A, const __m128 B)
|
||||
inline __m128 operator-(const __m128 A, const __m128 B)
|
||||
{
|
||||
return _mm_sub_ps(A, B);
|
||||
return _mm_sub_ps(A, B);
|
||||
}
|
||||
|
||||
inline __m128 operator * (const __m128 A, const __m128 B)
|
||||
inline __m128 operator*(const __m128 A, const __m128 B)
|
||||
{
|
||||
return _mm_mul_ps(A, B);
|
||||
return _mm_mul_ps(A, B);
|
||||
}
|
||||
|
||||
#define b3CastfTo128i(a) (_mm_castps_si128(a))
|
||||
@@ -302,18 +314,19 @@ inline __m128 operator * (const __m128 A, const __m128 B)
|
||||
#define b3CastiTo128f(a) (_mm_castsi128_ps(a))
|
||||
#define b3CastdTo128f(a) (_mm_castpd_ps(a))
|
||||
#define b3CastdTo128i(a) (_mm_castpd_si128(a))
|
||||
#define b3Assign128(r0,r1,r2,r3) _mm_setr_ps(r0,r1,r2,r3)
|
||||
#define b3Assign128(r0, r1, r2, r3) _mm_setr_ps(r0, r1, r2, r3)
|
||||
|
||||
#else//_WIN32
|
||||
#else //_WIN32
|
||||
|
||||
#define b3CastfTo128i(a) ((__m128i)(a))
|
||||
#define b3CastfTo128d(a) ((__m128d)(a))
|
||||
#define b3CastiTo128f(a) ((__m128) (a))
|
||||
#define b3CastdTo128f(a) ((__m128) (a))
|
||||
#define b3CastiTo128f(a) ((__m128)(a))
|
||||
#define b3CastdTo128f(a) ((__m128)(a))
|
||||
#define b3CastdTo128i(a) ((__m128i)(a))
|
||||
#define b3Assign128(r0,r1,r2,r3) (__m128){r0,r1,r2,r3}
|
||||
#endif//_WIN32
|
||||
#endif //B3_USE_SSE_IN_API
|
||||
#define b3Assign128(r0, r1, r2, r3) \
|
||||
(__m128) { r0, r1, r2, r3 }
|
||||
#endif //_WIN32
|
||||
#endif //B3_USE_SSE_IN_API
|
||||
|
||||
#ifdef B3_USE_NEON
|
||||
#include <arm_neon.h>
|
||||
@@ -321,142 +334,160 @@ inline __m128 operator * (const __m128 A, const __m128 B)
|
||||
typedef float32x4_t b3SimdFloat4;
|
||||
#define B3_INFINITY INFINITY
|
||||
#define B3_NAN NAN
|
||||
#define b3Assign128(r0,r1,r2,r3) (float32x4_t){r0,r1,r2,r3}
|
||||
#define b3Assign128(r0, r1, r2, r3) \
|
||||
(float32x4_t) { r0, r1, r2, r3 }
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define B3_DECLARE_ALIGNED_ALLOCATOR() \
|
||||
B3_FORCE_INLINE void* operator new(size_t sizeInBytes) { return b3AlignedAlloc(sizeInBytes,16); } \
|
||||
B3_FORCE_INLINE void operator delete(void* ptr) { b3AlignedFree(ptr); } \
|
||||
B3_FORCE_INLINE void* operator new(size_t, void* ptr) { return ptr; } \
|
||||
B3_FORCE_INLINE void operator delete(void*, void*) { } \
|
||||
B3_FORCE_INLINE void* operator new[](size_t sizeInBytes) { return b3AlignedAlloc(sizeInBytes,16); } \
|
||||
B3_FORCE_INLINE void operator delete[](void* ptr) { b3AlignedFree(ptr); } \
|
||||
B3_FORCE_INLINE void* operator new[](size_t, void* ptr) { return ptr; } \
|
||||
B3_FORCE_INLINE void operator delete[](void*, void*) { } \
|
||||
|
||||
|
||||
#define B3_DECLARE_ALIGNED_ALLOCATOR() \
|
||||
B3_FORCE_INLINE void *operator new(size_t sizeInBytes) { return b3AlignedAlloc(sizeInBytes, 16); } \
|
||||
B3_FORCE_INLINE void operator delete(void *ptr) { b3AlignedFree(ptr); } \
|
||||
B3_FORCE_INLINE void *operator new(size_t, void *ptr) { return ptr; } \
|
||||
B3_FORCE_INLINE void operator delete(void *, void *) {} \
|
||||
B3_FORCE_INLINE void *operator new[](size_t sizeInBytes) { return b3AlignedAlloc(sizeInBytes, 16); } \
|
||||
B3_FORCE_INLINE void operator delete[](void *ptr) { b3AlignedFree(ptr); } \
|
||||
B3_FORCE_INLINE void *operator new[](size_t, void *ptr) { return ptr; } \
|
||||
B3_FORCE_INLINE void operator delete[](void *, void *) {}
|
||||
|
||||
#if defined(B3_USE_DOUBLE_PRECISION) || defined(B3_FORCE_DOUBLE_FUNCTIONS)
|
||||
|
||||
B3_FORCE_INLINE b3Scalar b3Sqrt(b3Scalar x) { return sqrt(x); }
|
||||
|
||||
B3_FORCE_INLINE b3Scalar b3Sqrt(b3Scalar x)
|
||||
{
|
||||
return sqrt(x);
|
||||
}
|
||||
B3_FORCE_INLINE b3Scalar b3Fabs(b3Scalar x) { return fabs(x); }
|
||||
B3_FORCE_INLINE b3Scalar b3Cos(b3Scalar x) { return cos(x); }
|
||||
B3_FORCE_INLINE b3Scalar b3Sin(b3Scalar x) { return sin(x); }
|
||||
B3_FORCE_INLINE b3Scalar b3Tan(b3Scalar x) { return tan(x); }
|
||||
B3_FORCE_INLINE b3Scalar b3Acos(b3Scalar x) { if (x<b3Scalar(-1)) x=b3Scalar(-1); if (x>b3Scalar(1)) x=b3Scalar(1); return acos(x); }
|
||||
B3_FORCE_INLINE b3Scalar b3Asin(b3Scalar x) { if (x<b3Scalar(-1)) x=b3Scalar(-1); if (x>b3Scalar(1)) x=b3Scalar(1); return asin(x); }
|
||||
B3_FORCE_INLINE b3Scalar b3Acos(b3Scalar x)
|
||||
{
|
||||
if (x < b3Scalar(-1)) x = b3Scalar(-1);
|
||||
if (x > b3Scalar(1)) x = b3Scalar(1);
|
||||
return acos(x);
|
||||
}
|
||||
B3_FORCE_INLINE b3Scalar b3Asin(b3Scalar x)
|
||||
{
|
||||
if (x < b3Scalar(-1)) x = b3Scalar(-1);
|
||||
if (x > b3Scalar(1)) x = b3Scalar(1);
|
||||
return asin(x);
|
||||
}
|
||||
B3_FORCE_INLINE b3Scalar b3Atan(b3Scalar x) { return atan(x); }
|
||||
B3_FORCE_INLINE b3Scalar b3Atan2(b3Scalar x, b3Scalar y) { return atan2(x, y); }
|
||||
B3_FORCE_INLINE b3Scalar b3Exp(b3Scalar x) { return exp(x); }
|
||||
B3_FORCE_INLINE b3Scalar b3Log(b3Scalar x) { return log(x); }
|
||||
B3_FORCE_INLINE b3Scalar b3Pow(b3Scalar x,b3Scalar y) { return pow(x,y); }
|
||||
B3_FORCE_INLINE b3Scalar b3Fmod(b3Scalar x,b3Scalar y) { return fmod(x,y); }
|
||||
B3_FORCE_INLINE b3Scalar b3Pow(b3Scalar x, b3Scalar y) { return pow(x, y); }
|
||||
B3_FORCE_INLINE b3Scalar b3Fmod(b3Scalar x, b3Scalar y) { return fmod(x, y); }
|
||||
|
||||
#else
|
||||
|
||||
B3_FORCE_INLINE b3Scalar b3Sqrt(b3Scalar y)
|
||||
{
|
||||
|
||||
B3_FORCE_INLINE b3Scalar b3Sqrt(b3Scalar y)
|
||||
{
|
||||
#ifdef USE_APPROXIMATION
|
||||
double x, z, tempf;
|
||||
unsigned long *tfptr = ((unsigned long *)&tempf) + 1;
|
||||
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*b3Scalar(0.5);
|
||||
x = (b3Scalar(1.5)*x)-(x*x)*(x*z); /* iteration formula */
|
||||
x = (b3Scalar(1.5)*x)-(x*x)*(x*z);
|
||||
x = (b3Scalar(1.5)*x)-(x*x)*(x*z);
|
||||
x = (b3Scalar(1.5)*x)-(x*x)*(x*z);
|
||||
x = (b3Scalar(1.5)*x)-(x*x)*(x*z);
|
||||
return x*y;
|
||||
*tfptr = (0xbfcdd90a - *tfptr) >> 1; /* estimate of 1/sqrt(y) */
|
||||
x = tempf;
|
||||
z = y * b3Scalar(0.5);
|
||||
x = (b3Scalar(1.5) * x) - (x * x) * (x * z); /* iteration formula */
|
||||
x = (b3Scalar(1.5) * x) - (x * x) * (x * z);
|
||||
x = (b3Scalar(1.5) * x) - (x * x) * (x * z);
|
||||
x = (b3Scalar(1.5) * x) - (x * x) * (x * z);
|
||||
x = (b3Scalar(1.5) * x) - (x * x) * (x * z);
|
||||
return x * y;
|
||||
#else
|
||||
return sqrtf(y);
|
||||
return sqrtf(y);
|
||||
#endif
|
||||
}
|
||||
B3_FORCE_INLINE b3Scalar b3Fabs(b3Scalar x) { return fabsf(x); }
|
||||
B3_FORCE_INLINE b3Scalar b3Cos(b3Scalar x) { return cosf(x); }
|
||||
B3_FORCE_INLINE b3Scalar b3Sin(b3Scalar x) { return sinf(x); }
|
||||
B3_FORCE_INLINE b3Scalar b3Tan(b3Scalar x) { return tanf(x); }
|
||||
B3_FORCE_INLINE b3Scalar b3Acos(b3Scalar x) {
|
||||
if (x<b3Scalar(-1))
|
||||
x=b3Scalar(-1);
|
||||
if (x>b3Scalar(1))
|
||||
x=b3Scalar(1);
|
||||
return acosf(x);
|
||||
B3_FORCE_INLINE b3Scalar b3Acos(b3Scalar x)
|
||||
{
|
||||
if (x < b3Scalar(-1))
|
||||
x = b3Scalar(-1);
|
||||
if (x > b3Scalar(1))
|
||||
x = b3Scalar(1);
|
||||
return acosf(x);
|
||||
}
|
||||
B3_FORCE_INLINE b3Scalar b3Asin(b3Scalar x) {
|
||||
if (x<b3Scalar(-1))
|
||||
x=b3Scalar(-1);
|
||||
if (x>b3Scalar(1))
|
||||
x=b3Scalar(1);
|
||||
return asinf(x);
|
||||
B3_FORCE_INLINE b3Scalar b3Asin(b3Scalar x)
|
||||
{
|
||||
if (x < b3Scalar(-1))
|
||||
x = b3Scalar(-1);
|
||||
if (x > b3Scalar(1))
|
||||
x = b3Scalar(1);
|
||||
return asinf(x);
|
||||
}
|
||||
B3_FORCE_INLINE b3Scalar b3Atan(b3Scalar x) { return atanf(x); }
|
||||
B3_FORCE_INLINE b3Scalar b3Atan2(b3Scalar x, b3Scalar y) { return atan2f(x, y); }
|
||||
B3_FORCE_INLINE b3Scalar b3Exp(b3Scalar x) { return expf(x); }
|
||||
B3_FORCE_INLINE b3Scalar b3Log(b3Scalar x) { return logf(x); }
|
||||
B3_FORCE_INLINE b3Scalar b3Pow(b3Scalar x,b3Scalar y) { return powf(x,y); }
|
||||
B3_FORCE_INLINE b3Scalar b3Fmod(b3Scalar x,b3Scalar y) { return fmodf(x,y); }
|
||||
|
||||
B3_FORCE_INLINE b3Scalar b3Pow(b3Scalar x, b3Scalar y) { return powf(x, y); }
|
||||
B3_FORCE_INLINE b3Scalar b3Fmod(b3Scalar x, b3Scalar y) { return fmodf(x, y); }
|
||||
|
||||
#endif
|
||||
|
||||
#define B3_2_PI b3Scalar(6.283185307179586232)
|
||||
#define B3_PI (B3_2_PI * b3Scalar(0.5))
|
||||
#define B3_HALF_PI (B3_2_PI * b3Scalar(0.25))
|
||||
#define B3_2_PI b3Scalar(6.283185307179586232)
|
||||
#define B3_PI (B3_2_PI * b3Scalar(0.5))
|
||||
#define B3_HALF_PI (B3_2_PI * b3Scalar(0.25))
|
||||
#define B3_RADS_PER_DEG (B3_2_PI / b3Scalar(360.0))
|
||||
#define B3_DEGS_PER_RAD (b3Scalar(360.0) / B3_2_PI)
|
||||
#define B3_DEGS_PER_RAD (b3Scalar(360.0) / B3_2_PI)
|
||||
#define B3_SQRT12 b3Scalar(0.7071067811865475244008443621048490)
|
||||
|
||||
#define b3RecipSqrt(x) ((b3Scalar)(b3Scalar(1.0)/b3Sqrt(b3Scalar(x)))) /* reciprocal square root */
|
||||
|
||||
#define b3RecipSqrt(x) ((b3Scalar)(b3Scalar(1.0) / b3Sqrt(b3Scalar(x)))) /* reciprocal square root */
|
||||
|
||||
#ifdef B3_USE_DOUBLE_PRECISION
|
||||
#define B3_EPSILON DBL_EPSILON
|
||||
#define B3_INFINITY DBL_MAX
|
||||
#define B3_EPSILON DBL_EPSILON
|
||||
#define B3_INFINITY DBL_MAX
|
||||
#else
|
||||
#define B3_EPSILON FLT_EPSILON
|
||||
#define B3_INFINITY FLT_MAX
|
||||
#define B3_EPSILON FLT_EPSILON
|
||||
#define B3_INFINITY FLT_MAX
|
||||
#endif
|
||||
|
||||
B3_FORCE_INLINE b3Scalar b3Atan2Fast(b3Scalar y, b3Scalar x)
|
||||
B3_FORCE_INLINE b3Scalar b3Atan2Fast(b3Scalar y, b3Scalar x)
|
||||
{
|
||||
b3Scalar coeff_1 = B3_PI / 4.0f;
|
||||
b3Scalar coeff_2 = 3.0f * coeff_1;
|
||||
b3Scalar abs_y = b3Fabs(y);
|
||||
b3Scalar angle;
|
||||
if (x >= 0.0f) {
|
||||
if (x >= 0.0f)
|
||||
{
|
||||
b3Scalar r = (x - abs_y) / (x + abs_y);
|
||||
angle = coeff_1 - coeff_1 * r;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
b3Scalar r = (x + abs_y) / (abs_y - x);
|
||||
angle = coeff_2 - coeff_1 * r;
|
||||
}
|
||||
return (y < 0.0f) ? -angle : angle;
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE bool b3FuzzyZero(b3Scalar x) { return b3Fabs(x) < B3_EPSILON; }
|
||||
B3_FORCE_INLINE bool b3FuzzyZero(b3Scalar x) { return b3Fabs(x) < B3_EPSILON; }
|
||||
|
||||
B3_FORCE_INLINE bool b3Equal(b3Scalar a, b3Scalar eps) {
|
||||
B3_FORCE_INLINE bool b3Equal(b3Scalar a, b3Scalar eps)
|
||||
{
|
||||
return (((a) <= eps) && !((a) < -eps));
|
||||
}
|
||||
B3_FORCE_INLINE bool b3GreaterEqual (b3Scalar a, b3Scalar eps) {
|
||||
B3_FORCE_INLINE bool b3GreaterEqual(b3Scalar a, b3Scalar eps)
|
||||
{
|
||||
return (!((a) <= eps));
|
||||
}
|
||||
|
||||
|
||||
B3_FORCE_INLINE int b3IsNegative(b3Scalar x) {
|
||||
return x < b3Scalar(0.0) ? 1 : 0;
|
||||
B3_FORCE_INLINE int b3IsNegative(b3Scalar x)
|
||||
{
|
||||
return x < b3Scalar(0.0) ? 1 : 0;
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE b3Scalar b3Radians(b3Scalar x) { return x * B3_RADS_PER_DEG; }
|
||||
B3_FORCE_INLINE b3Scalar b3Degrees(b3Scalar x) { return x * B3_DEGS_PER_RAD; }
|
||||
|
||||
#define B3_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
|
||||
#define B3_DECLARE_HANDLE(name) \
|
||||
typedef struct name##__ \
|
||||
{ \
|
||||
int unused; \
|
||||
} * name
|
||||
|
||||
#ifndef b3Fsel
|
||||
B3_FORCE_INLINE b3Scalar b3Fsel(b3Scalar a, b3Scalar b, b3Scalar c)
|
||||
@@ -464,60 +495,57 @@ B3_FORCE_INLINE b3Scalar b3Fsel(b3Scalar a, b3Scalar b, b3Scalar c)
|
||||
return a >= 0 ? b : c;
|
||||
}
|
||||
#endif
|
||||
#define b3Fsels(a,b,c) (b3Scalar)b3Fsel(a,b,c)
|
||||
|
||||
#define b3Fsels(a, b, c) (b3Scalar) b3Fsel(a, b, c)
|
||||
|
||||
B3_FORCE_INLINE bool b3MachineIsLittleEndian()
|
||||
{
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///b3Select 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
|
||||
B3_FORCE_INLINE unsigned b3Select(unsigned condition, unsigned valueIfConditionNonZero, unsigned valueIfConditionZero)
|
||||
B3_FORCE_INLINE unsigned b3Select(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));
|
||||
// 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));
|
||||
}
|
||||
B3_FORCE_INLINE int b3Select(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));
|
||||
unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31);
|
||||
unsigned testEqz = ~testNz;
|
||||
return static_cast<int>((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz));
|
||||
}
|
||||
B3_FORCE_INLINE float b3Select(unsigned condition, float valueIfConditionNonZero, float valueIfConditionZero)
|
||||
{
|
||||
#ifdef B3_HAVE_NATIVE_FSEL
|
||||
return (float)b3Fsel((b3Scalar)condition - b3Scalar(1.0f), valueIfConditionNonZero, valueIfConditionZero);
|
||||
return (float)b3Fsel((b3Scalar)condition - b3Scalar(1.0f), valueIfConditionNonZero, valueIfConditionZero);
|
||||
#else
|
||||
return (condition != 0) ? valueIfConditionNonZero : valueIfConditionZero;
|
||||
return (condition != 0) ? valueIfConditionNonZero : valueIfConditionZero;
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T> B3_FORCE_INLINE void b3Swap(T& a, T& b)
|
||||
template <typename T>
|
||||
B3_FORCE_INLINE void b3Swap(T &a, T &b)
|
||||
{
|
||||
T tmp = a;
|
||||
a = b;
|
||||
b = tmp;
|
||||
}
|
||||
|
||||
|
||||
//PCK: endian swapping functions
|
||||
B3_FORCE_INLINE unsigned b3SwapEndian(unsigned val)
|
||||
{
|
||||
return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24));
|
||||
return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24));
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE unsigned short b3SwapEndian(unsigned short val)
|
||||
@@ -532,87 +560,85 @@ B3_FORCE_INLINE unsigned b3SwapEndian(int val)
|
||||
|
||||
B3_FORCE_INLINE unsigned short b3SwapEndian(short val)
|
||||
{
|
||||
return b3SwapEndian((unsigned short) val);
|
||||
return b3SwapEndian((unsigned short)val);
|
||||
}
|
||||
|
||||
///b3SwapFloat uses using char pointers to swap the endianness
|
||||
////b3SwapFloat/b3SwapDouble 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.
|
||||
///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
|
||||
B3_FORCE_INLINE unsigned int b3SwapEndianFloat(float d)
|
||||
B3_FORCE_INLINE unsigned int b3SwapEndianFloat(float d)
|
||||
{
|
||||
unsigned int a = 0;
|
||||
unsigned char *dst = (unsigned char *)&a;
|
||||
unsigned char *src = (unsigned char *)&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;
|
||||
dst[0] = src[3];
|
||||
dst[1] = src[2];
|
||||
dst[2] = src[1];
|
||||
dst[3] = src[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
// unswap using char pointers
|
||||
B3_FORCE_INLINE float b3UnswapEndianFloat(unsigned int a)
|
||||
B3_FORCE_INLINE float b3UnswapEndianFloat(unsigned int a)
|
||||
{
|
||||
float d = 0.0f;
|
||||
unsigned char *src = (unsigned char *)&a;
|
||||
unsigned char *dst = (unsigned char *)&d;
|
||||
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];
|
||||
dst[0] = src[3];
|
||||
dst[1] = src[2];
|
||||
dst[2] = src[1];
|
||||
dst[3] = src[0];
|
||||
|
||||
return d;
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
// swap using char pointers
|
||||
B3_FORCE_INLINE void b3SwapEndianDouble(double d, unsigned char* dst)
|
||||
B3_FORCE_INLINE void b3SwapEndianDouble(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];
|
||||
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
|
||||
B3_FORCE_INLINE double b3UnswapEndianDouble(const unsigned char *src)
|
||||
B3_FORCE_INLINE double b3UnswapEndianDouble(const unsigned char *src)
|
||||
{
|
||||
double d = 0.0;
|
||||
unsigned char *dst = (unsigned char *)&d;
|
||||
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];
|
||||
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 [-B3_PI, B3_PI]
|
||||
B3_FORCE_INLINE b3Scalar b3NormalizeAngle(b3Scalar angleInRadians)
|
||||
B3_FORCE_INLINE b3Scalar b3NormalizeAngle(b3Scalar angleInRadians)
|
||||
{
|
||||
angleInRadians = b3Fmod(angleInRadians, B3_2_PI);
|
||||
if(angleInRadians < -B3_PI)
|
||||
if (angleInRadians < -B3_PI)
|
||||
{
|
||||
return angleInRadians + B3_2_PI;
|
||||
}
|
||||
else if(angleInRadians > B3_PI)
|
||||
else if (angleInRadians > B3_PI)
|
||||
{
|
||||
return angleInRadians - B3_2_PI;
|
||||
}
|
||||
@@ -626,38 +652,34 @@ B3_FORCE_INLINE b3Scalar b3NormalizeAngle(b3Scalar angleInRadians)
|
||||
struct b3TypedObject
|
||||
{
|
||||
b3TypedObject(int objectType)
|
||||
:m_objectType(objectType)
|
||||
: m_objectType(objectType)
|
||||
{
|
||||
}
|
||||
int m_objectType;
|
||||
int m_objectType;
|
||||
inline int getObjectType() const
|
||||
{
|
||||
return m_objectType;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
///align a pointer to the provided alignment, upwards
|
||||
template <typename T>T* b3AlignPointer(T* unalignedPtr, size_t alignment)
|
||||
template <typename T>
|
||||
T *b3AlignPointer(T *unalignedPtr, size_t alignment)
|
||||
{
|
||||
|
||||
struct b3ConvertPointerSizeT
|
||||
{
|
||||
union
|
||||
{
|
||||
T* ptr;
|
||||
size_t integer;
|
||||
union {
|
||||
T *ptr;
|
||||
size_t integer;
|
||||
};
|
||||
};
|
||||
b3ConvertPointerSizeT converter;
|
||||
|
||||
|
||||
b3ConvertPointerSizeT converter;
|
||||
|
||||
const size_t bit_mask = ~(alignment - 1);
|
||||
converter.ptr = unalignedPtr;
|
||||
converter.integer += alignment-1;
|
||||
converter.ptr = unalignedPtr;
|
||||
converter.integer += alignment - 1;
|
||||
converter.integer &= bit_mask;
|
||||
return converter.ptr;
|
||||
}
|
||||
|
||||
#endif //B3_SCALAR_H
|
||||
#endif //B3_SCALAR_H
|
||||
|
||||
@@ -20,97 +20,99 @@ Nov.2006
|
||||
#ifndef B3_STACK_ALLOC
|
||||
#define B3_STACK_ALLOC
|
||||
|
||||
#include "b3Scalar.h" //for b3Assert
|
||||
#include "b3Scalar.h" //for b3Assert
|
||||
#include "b3AlignedAllocator.h"
|
||||
|
||||
///The b3Block class is an internal structure for the b3StackAlloc memory allocator.
|
||||
struct b3Block
|
||||
{
|
||||
b3Block* previous;
|
||||
unsigned char* address;
|
||||
b3Block* previous;
|
||||
unsigned char* address;
|
||||
};
|
||||
|
||||
///The StackAlloc class provides some fast stack-based memory allocator (LIFO last-in first-out)
|
||||
class b3StackAlloc
|
||||
{
|
||||
public:
|
||||
b3StackAlloc(unsigned int size)
|
||||
{
|
||||
ctor();
|
||||
create(size);
|
||||
}
|
||||
~b3StackAlloc() { destroy(); }
|
||||
|
||||
b3StackAlloc(unsigned int size) { ctor();create(size); }
|
||||
~b3StackAlloc() { destroy(); }
|
||||
|
||||
inline void create(unsigned int size)
|
||||
inline void create(unsigned int size)
|
||||
{
|
||||
destroy();
|
||||
data = (unsigned char*) b3AlignedAlloc(size,16);
|
||||
totalsize = size;
|
||||
data = (unsigned char*)b3AlignedAlloc(size, 16);
|
||||
totalsize = size;
|
||||
}
|
||||
inline void destroy()
|
||||
inline void destroy()
|
||||
{
|
||||
b3Assert(usedsize==0);
|
||||
b3Assert(usedsize == 0);
|
||||
//Raise(L"StackAlloc is still in use");
|
||||
|
||||
if(usedsize==0)
|
||||
if (usedsize == 0)
|
||||
{
|
||||
if(!ischild && data)
|
||||
if (!ischild && data)
|
||||
b3AlignedFree(data);
|
||||
|
||||
data = 0;
|
||||
usedsize = 0;
|
||||
data = 0;
|
||||
usedsize = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int getAvailableMemory() const
|
||||
int getAvailableMemory() const
|
||||
{
|
||||
return static_cast<int>(totalsize - usedsize);
|
||||
}
|
||||
|
||||
unsigned char* allocate(unsigned int size)
|
||||
unsigned char* allocate(unsigned int size)
|
||||
{
|
||||
const unsigned int nus(usedsize+size);
|
||||
if(nus<totalsize)
|
||||
const unsigned int nus(usedsize + size);
|
||||
if (nus < totalsize)
|
||||
{
|
||||
usedsize=nus;
|
||||
return(data+(usedsize-size));
|
||||
usedsize = nus;
|
||||
return (data + (usedsize - size));
|
||||
}
|
||||
b3Assert(0);
|
||||
//&& (L"Not enough memory"));
|
||||
|
||||
return(0);
|
||||
|
||||
return (0);
|
||||
}
|
||||
B3_FORCE_INLINE b3Block* beginBlock()
|
||||
B3_FORCE_INLINE b3Block* beginBlock()
|
||||
{
|
||||
b3Block* pb = (b3Block*)allocate(sizeof(b3Block));
|
||||
pb->previous = current;
|
||||
pb->address = data+usedsize;
|
||||
current = pb;
|
||||
return(pb);
|
||||
b3Block* pb = (b3Block*)allocate(sizeof(b3Block));
|
||||
pb->previous = current;
|
||||
pb->address = data + usedsize;
|
||||
current = pb;
|
||||
return (pb);
|
||||
}
|
||||
B3_FORCE_INLINE void endBlock(b3Block* block)
|
||||
B3_FORCE_INLINE void endBlock(b3Block* block)
|
||||
{
|
||||
b3Assert(block==current);
|
||||
b3Assert(block == current);
|
||||
//Raise(L"Unmatched blocks");
|
||||
if(block==current)
|
||||
if (block == current)
|
||||
{
|
||||
current = block->previous;
|
||||
usedsize = (unsigned int)((block->address-data)-sizeof(b3Block));
|
||||
current = block->previous;
|
||||
usedsize = (unsigned int)((block->address - data) - sizeof(b3Block));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void ctor()
|
||||
void ctor()
|
||||
{
|
||||
data = 0;
|
||||
totalsize = 0;
|
||||
usedsize = 0;
|
||||
current = 0;
|
||||
ischild = false;
|
||||
data = 0;
|
||||
totalsize = 0;
|
||||
usedsize = 0;
|
||||
current = 0;
|
||||
ischild = false;
|
||||
}
|
||||
unsigned char* data;
|
||||
unsigned int totalsize;
|
||||
unsigned int usedsize;
|
||||
b3Block* current;
|
||||
bool ischild;
|
||||
unsigned char* data;
|
||||
unsigned int totalsize;
|
||||
unsigned int usedsize;
|
||||
b3Block* current;
|
||||
bool ischild;
|
||||
};
|
||||
|
||||
#endif //B3_STACK_ALLOC
|
||||
#endif //B3_STACK_ALLOC
|
||||
|
||||
@@ -12,11 +12,9 @@ subject to the following restrictions:
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef B3_TRANSFORM_H
|
||||
#define B3_TRANSFORM_H
|
||||
|
||||
|
||||
#include "b3Matrix3x3.h"
|
||||
|
||||
#ifdef B3_USE_DOUBLE_PRECISION
|
||||
@@ -25,46 +23,45 @@ subject to the following restrictions:
|
||||
#define b3TransformData b3TransformFloatData
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/**@brief The b3Transform class supports rigid transforms with only translation and rotation and no scaling/shear.
|
||||
*It can be used in combination with b3Vector3, b3Quaternion and b3Matrix3x3 linear algebra classes. */
|
||||
B3_ATTRIBUTE_ALIGNED16(class) b3Transform {
|
||||
|
||||
///Storage for the rotation
|
||||
B3_ATTRIBUTE_ALIGNED16(class)
|
||||
b3Transform
|
||||
{
|
||||
///Storage for the rotation
|
||||
b3Matrix3x3 m_basis;
|
||||
///Storage for the translation
|
||||
b3Vector3 m_origin;
|
||||
///Storage for the translation
|
||||
b3Vector3 m_origin;
|
||||
|
||||
public:
|
||||
|
||||
/**@brief No initialization constructor */
|
||||
/**@brief No initialization constructor */
|
||||
b3Transform() {}
|
||||
/**@brief Constructor from b3Quaternion (optional b3Vector3 )
|
||||
/**@brief Constructor from b3Quaternion (optional b3Vector3 )
|
||||
* @param q Rotation from quaternion
|
||||
* @param c Translation from Vector (default 0,0,0) */
|
||||
explicit B3_FORCE_INLINE b3Transform(const b3Quaternion& q,
|
||||
const b3Vector3& c = b3MakeVector3(b3Scalar(0), b3Scalar(0), b3Scalar(0)))
|
||||
explicit B3_FORCE_INLINE b3Transform(const b3Quaternion& q,
|
||||
const b3Vector3& c = b3MakeVector3(b3Scalar(0), b3Scalar(0), b3Scalar(0)))
|
||||
: m_basis(q),
|
||||
m_origin(c)
|
||||
{}
|
||||
|
||||
/**@brief Constructor from b3Matrix3x3 (optional b3Vector3)
|
||||
* @param b Rotation from Matrix
|
||||
* @param c Translation from Vector default (0,0,0)*/
|
||||
explicit B3_FORCE_INLINE b3Transform(const b3Matrix3x3& b,
|
||||
const b3Vector3& c = b3MakeVector3(b3Scalar(0), b3Scalar(0), b3Scalar(0)))
|
||||
: m_basis(b),
|
||||
m_origin(c)
|
||||
{}
|
||||
/**@brief Copy constructor */
|
||||
B3_FORCE_INLINE b3Transform (const b3Transform& other)
|
||||
: m_basis(other.m_basis),
|
||||
m_origin(other.m_origin)
|
||||
m_origin(c)
|
||||
{
|
||||
}
|
||||
/**@brief Assignment Operator */
|
||||
|
||||
/**@brief Constructor from b3Matrix3x3 (optional b3Vector3)
|
||||
* @param b Rotation from Matrix
|
||||
* @param c Translation from Vector default (0,0,0)*/
|
||||
explicit B3_FORCE_INLINE b3Transform(const b3Matrix3x3& b,
|
||||
const b3Vector3& c = b3MakeVector3(b3Scalar(0), b3Scalar(0), b3Scalar(0)))
|
||||
: m_basis(b),
|
||||
m_origin(c)
|
||||
{
|
||||
}
|
||||
/**@brief Copy constructor */
|
||||
B3_FORCE_INLINE b3Transform(const b3Transform& other)
|
||||
: m_basis(other.m_basis),
|
||||
m_origin(other.m_origin)
|
||||
{
|
||||
}
|
||||
/**@brief Assignment Operator */
|
||||
B3_FORCE_INLINE b3Transform& operator=(const b3Transform& other)
|
||||
{
|
||||
m_basis = other.m_basis;
|
||||
@@ -72,70 +69,70 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Set the current transform as the value of the product of two transforms
|
||||
/**@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 */
|
||||
B3_FORCE_INLINE void mult(const b3Transform& t1, const b3Transform& t2) {
|
||||
m_basis = t1.m_basis * t2.m_basis;
|
||||
m_origin = t1(t2.m_origin);
|
||||
}
|
||||
B3_FORCE_INLINE void mult(const b3Transform& t1, const b3Transform& t2)
|
||||
{
|
||||
m_basis = t1.m_basis * t2.m_basis;
|
||||
m_origin = t1(t2.m_origin);
|
||||
}
|
||||
|
||||
/* void multInverseLeft(const b3Transform& t1, const b3Transform& t2) {
|
||||
/* void multInverseLeft(const b3Transform& t1, const b3Transform& t2) {
|
||||
b3Vector3 v = t2.m_origin - t1.m_origin;
|
||||
m_basis = b3MultTransposeLeft(t1.m_basis, t2.m_basis);
|
||||
m_origin = v * t1.m_basis;
|
||||
}
|
||||
*/
|
||||
|
||||
/**@brief Return the transform of the vector */
|
||||
/**@brief Return the transform of the vector */
|
||||
B3_FORCE_INLINE b3Vector3 operator()(const b3Vector3& x) const
|
||||
{
|
||||
return x.dot3(m_basis[0], m_basis[1], m_basis[2]) + m_origin;
|
||||
return x.dot3(m_basis[0], m_basis[1], m_basis[2]) + m_origin;
|
||||
}
|
||||
|
||||
/**@brief Return the transform of the vector */
|
||||
/**@brief Return the transform of the vector */
|
||||
B3_FORCE_INLINE b3Vector3 operator*(const b3Vector3& x) const
|
||||
{
|
||||
return (*this)(x);
|
||||
}
|
||||
|
||||
/**@brief Return the transform of the b3Quaternion */
|
||||
/**@brief Return the transform of the b3Quaternion */
|
||||
B3_FORCE_INLINE b3Quaternion operator*(const b3Quaternion& q) const
|
||||
{
|
||||
return getRotation() * q;
|
||||
}
|
||||
|
||||
/**@brief Return the basis matrix for the rotation */
|
||||
B3_FORCE_INLINE b3Matrix3x3& getBasis() { return m_basis; }
|
||||
/**@brief Return the basis matrix for the rotation */
|
||||
B3_FORCE_INLINE const b3Matrix3x3& getBasis() const { return m_basis; }
|
||||
/**@brief Return the basis matrix for the rotation */
|
||||
B3_FORCE_INLINE b3Matrix3x3& getBasis() { return m_basis; }
|
||||
/**@brief Return the basis matrix for the rotation */
|
||||
B3_FORCE_INLINE const b3Matrix3x3& getBasis() const { return m_basis; }
|
||||
|
||||
/**@brief Return the origin vector translation */
|
||||
B3_FORCE_INLINE b3Vector3& getOrigin() { return m_origin; }
|
||||
/**@brief Return the origin vector translation */
|
||||
B3_FORCE_INLINE const b3Vector3& getOrigin() const { return m_origin; }
|
||||
/**@brief Return the origin vector translation */
|
||||
B3_FORCE_INLINE b3Vector3& getOrigin() { return m_origin; }
|
||||
/**@brief Return the origin vector translation */
|
||||
B3_FORCE_INLINE const b3Vector3& getOrigin() const { return m_origin; }
|
||||
|
||||
/**@brief Return a quaternion representing the rotation */
|
||||
b3Quaternion getRotation() const {
|
||||
/**@brief Return a quaternion representing the rotation */
|
||||
b3Quaternion getRotation() const
|
||||
{
|
||||
b3Quaternion q;
|
||||
m_basis.getRotation(q);
|
||||
return q;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Set from an array
|
||||
|
||||
/**@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 b3Scalar *m)
|
||||
void setFromOpenGLMatrix(const b3Scalar* m)
|
||||
{
|
||||
m_basis.setFromOpenGLSubMatrix(m);
|
||||
m_origin.setValue(m[12],m[13],m[14]);
|
||||
m_origin.setValue(m[12], m[13], m[14]);
|
||||
}
|
||||
|
||||
/**@brief Fill an array representation
|
||||
/**@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(b3Scalar *m) const
|
||||
void getOpenGLMatrix(b3Scalar * m) const
|
||||
{
|
||||
m_basis.getOpenGLSubMatrix(m);
|
||||
m[12] = m_origin.getX();
|
||||
@@ -144,80 +141,76 @@ public:
|
||||
m[15] = b3Scalar(1.0);
|
||||
}
|
||||
|
||||
/**@brief Set the translational element
|
||||
/**@brief Set the translational element
|
||||
* @param origin The vector to set the translation to */
|
||||
B3_FORCE_INLINE void setOrigin(const b3Vector3& origin)
|
||||
{
|
||||
B3_FORCE_INLINE void setOrigin(const b3Vector3& origin)
|
||||
{
|
||||
m_origin = origin;
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE b3Vector3 invXform(const b3Vector3& inVec) const;
|
||||
|
||||
|
||||
/**@brief Set the rotational element by b3Matrix3x3 */
|
||||
/**@brief Set the rotational element by b3Matrix3x3 */
|
||||
B3_FORCE_INLINE void setBasis(const b3Matrix3x3& basis)
|
||||
{
|
||||
{
|
||||
m_basis = basis;
|
||||
}
|
||||
|
||||
/**@brief Set the rotational element by b3Quaternion */
|
||||
/**@brief Set the rotational element by b3Quaternion */
|
||||
B3_FORCE_INLINE void setRotation(const b3Quaternion& q)
|
||||
{
|
||||
m_basis.setRotation(q);
|
||||
}
|
||||
|
||||
|
||||
/**@brief Set this transformation to the identity */
|
||||
/**@brief Set this transformation to the identity */
|
||||
void setIdentity()
|
||||
{
|
||||
m_basis.setIdentity();
|
||||
m_origin.setValue(b3Scalar(0.0), b3Scalar(0.0), b3Scalar(0.0));
|
||||
}
|
||||
|
||||
/**@brief Multiply this Transform by another(this = this * another)
|
||||
/**@brief Multiply this Transform by another(this = this * another)
|
||||
* @param t The other transform */
|
||||
b3Transform& operator*=(const b3Transform& t)
|
||||
b3Transform& operator*=(const b3Transform& t)
|
||||
{
|
||||
m_origin += m_basis * t.m_origin;
|
||||
m_basis *= t.m_basis;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**@brief Return the inverse of this transform */
|
||||
/**@brief Return the inverse of this transform */
|
||||
b3Transform inverse() const
|
||||
{
|
||||
{
|
||||
b3Matrix3x3 inv = m_basis.transpose();
|
||||
return b3Transform(inv, inv * -m_origin);
|
||||
}
|
||||
|
||||
/**@brief Return the inverse of this transform times the other transform
|
||||
/**@brief Return the inverse of this transform times the other transform
|
||||
* @param t The other transform
|
||||
* return this.inverse() * the other */
|
||||
b3Transform inverseTimes(const b3Transform& t) const;
|
||||
b3Transform inverseTimes(const b3Transform& t) const;
|
||||
|
||||
/**@brief Return the product of this transform and the other */
|
||||
/**@brief Return the product of this transform and the other */
|
||||
b3Transform operator*(const b3Transform& t) const;
|
||||
|
||||
/**@brief Return an identity transform */
|
||||
static const b3Transform& getIdentity()
|
||||
/**@brief Return an identity transform */
|
||||
static const b3Transform& getIdentity()
|
||||
{
|
||||
static const b3Transform identityTransform(b3Matrix3x3::getIdentity());
|
||||
return identityTransform;
|
||||
}
|
||||
|
||||
void serialize(struct b3TransformData& dataOut) const;
|
||||
void serialize(struct b3TransformData & dataOut) const;
|
||||
|
||||
void serializeFloat(struct b3TransformFloatData& dataOut) const;
|
||||
void serializeFloat(struct b3TransformFloatData & dataOut) const;
|
||||
|
||||
void deSerialize(const struct b3TransformData& dataIn);
|
||||
void deSerialize(const struct b3TransformData& dataIn);
|
||||
|
||||
void deSerializeDouble(const struct b3TransformDoubleData& dataIn);
|
||||
|
||||
void deSerializeFloat(const struct b3TransformFloatData& dataIn);
|
||||
void deSerializeDouble(const struct b3TransformDoubleData& dataIn);
|
||||
|
||||
void deSerializeFloat(const struct b3TransformFloatData& dataIn);
|
||||
};
|
||||
|
||||
|
||||
B3_FORCE_INLINE b3Vector3
|
||||
b3Transform::invXform(const b3Vector3& inVec) const
|
||||
{
|
||||
@@ -225,80 +218,69 @@ b3Transform::invXform(const b3Vector3& inVec) const
|
||||
return (m_basis.transpose() * v);
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE b3Transform
|
||||
b3Transform::inverseTimes(const b3Transform& t) const
|
||||
B3_FORCE_INLINE b3Transform
|
||||
b3Transform::inverseTimes(const b3Transform& t) const
|
||||
{
|
||||
b3Vector3 v = t.getOrigin() - m_origin;
|
||||
return b3Transform(m_basis.transposeTimes(t.m_basis),
|
||||
v * m_basis);
|
||||
return b3Transform(m_basis.transposeTimes(t.m_basis),
|
||||
v * m_basis);
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE b3Transform
|
||||
b3Transform::operator*(const b3Transform& t) const
|
||||
B3_FORCE_INLINE b3Transform
|
||||
b3Transform::operator*(const b3Transform& t) const
|
||||
{
|
||||
return b3Transform(m_basis * t.m_basis,
|
||||
(*this)(t.m_origin));
|
||||
return b3Transform(m_basis * t.m_basis,
|
||||
(*this)(t.m_origin));
|
||||
}
|
||||
|
||||
/**@brief Test if two transforms have all elements equal */
|
||||
B3_FORCE_INLINE bool operator==(const b3Transform& t1, const b3Transform& t2)
|
||||
{
|
||||
return ( t1.getBasis() == t2.getBasis() &&
|
||||
t1.getOrigin() == t2.getOrigin() );
|
||||
return (t1.getBasis() == t2.getBasis() &&
|
||||
t1.getOrigin() == t2.getOrigin());
|
||||
}
|
||||
|
||||
|
||||
///for serialization
|
||||
struct b3TransformFloatData
|
||||
struct b3TransformFloatData
|
||||
{
|
||||
b3Matrix3x3FloatData m_basis;
|
||||
b3Vector3FloatData m_origin;
|
||||
b3Matrix3x3FloatData m_basis;
|
||||
b3Vector3FloatData m_origin;
|
||||
};
|
||||
|
||||
struct b3TransformDoubleData
|
||||
struct b3TransformDoubleData
|
||||
{
|
||||
b3Matrix3x3DoubleData m_basis;
|
||||
b3Vector3DoubleData m_origin;
|
||||
b3Matrix3x3DoubleData m_basis;
|
||||
b3Vector3DoubleData m_origin;
|
||||
};
|
||||
|
||||
|
||||
|
||||
B3_FORCE_INLINE void b3Transform::serialize(b3TransformData& dataOut) const
|
||||
B3_FORCE_INLINE void b3Transform::serialize(b3TransformData& dataOut) const
|
||||
{
|
||||
m_basis.serialize(dataOut.m_basis);
|
||||
m_origin.serialize(dataOut.m_origin);
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE void b3Transform::serializeFloat(b3TransformFloatData& dataOut) const
|
||||
B3_FORCE_INLINE void b3Transform::serializeFloat(b3TransformFloatData& dataOut) const
|
||||
{
|
||||
m_basis.serializeFloat(dataOut.m_basis);
|
||||
m_origin.serializeFloat(dataOut.m_origin);
|
||||
}
|
||||
|
||||
|
||||
B3_FORCE_INLINE void b3Transform::deSerialize(const b3TransformData& dataIn)
|
||||
B3_FORCE_INLINE void b3Transform::deSerialize(const b3TransformData& dataIn)
|
||||
{
|
||||
m_basis.deSerialize(dataIn.m_basis);
|
||||
m_origin.deSerialize(dataIn.m_origin);
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE void b3Transform::deSerializeFloat(const b3TransformFloatData& dataIn)
|
||||
B3_FORCE_INLINE void b3Transform::deSerializeFloat(const b3TransformFloatData& dataIn)
|
||||
{
|
||||
m_basis.deSerializeFloat(dataIn.m_basis);
|
||||
m_origin.deSerializeFloat(dataIn.m_origin);
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE void b3Transform::deSerializeDouble(const b3TransformDoubleData& dataIn)
|
||||
B3_FORCE_INLINE void b3Transform::deSerializeDouble(const b3TransformDoubleData& dataIn)
|
||||
{
|
||||
m_basis.deSerializeDouble(dataIn.m_basis);
|
||||
m_origin.deSerializeDouble(dataIn.m_origin);
|
||||
}
|
||||
|
||||
|
||||
#endif //B3_TRANSFORM_H
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif //B3_TRANSFORM_H
|
||||
|
||||
@@ -12,204 +12,189 @@ subject to the following restrictions:
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef B3_TRANSFORM_UTIL_H
|
||||
#define B3_TRANSFORM_UTIL_H
|
||||
|
||||
#include "b3Transform.h"
|
||||
#define B3_ANGULAR_MOTION_THRESHOLD b3Scalar(0.5)*B3_HALF_PI
|
||||
#define B3_ANGULAR_MOTION_THRESHOLD b3Scalar(0.5) * B3_HALF_PI
|
||||
|
||||
|
||||
|
||||
|
||||
B3_FORCE_INLINE b3Vector3 b3AabbSupport(const b3Vector3& halfExtents,const b3Vector3& supportDir)
|
||||
B3_FORCE_INLINE b3Vector3 b3AabbSupport(const b3Vector3& halfExtents, const b3Vector3& supportDir)
|
||||
{
|
||||
return b3MakeVector3(supportDir.getX() < b3Scalar(0.0) ? -halfExtents.getX() : halfExtents.getX(),
|
||||
supportDir.getY() < b3Scalar(0.0) ? -halfExtents.getY() : halfExtents.getY(),
|
||||
supportDir.getZ() < b3Scalar(0.0) ? -halfExtents.getZ() : halfExtents.getZ());
|
||||
supportDir.getY() < b3Scalar(0.0) ? -halfExtents.getY() : halfExtents.getY(),
|
||||
supportDir.getZ() < b3Scalar(0.0) ? -halfExtents.getZ() : halfExtents.getZ());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// Utils related to temporal transforms
|
||||
class b3TransformUtil
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
static void integrateTransform(const b3Transform& curTrans,const b3Vector3& linvel,const b3Vector3& angvel,b3Scalar timeStep,b3Transform& predictedTransform)
|
||||
static void integrateTransform(const b3Transform& curTrans, const b3Vector3& linvel, const b3Vector3& angvel, b3Scalar timeStep, b3Transform& predictedTransform)
|
||||
{
|
||||
predictedTransform.setOrigin(curTrans.getOrigin() + linvel * timeStep);
|
||||
// #define QUATERNION_DERIVATIVE
|
||||
#ifdef QUATERNION_DERIVATIVE
|
||||
// #define QUATERNION_DERIVATIVE
|
||||
#ifdef QUATERNION_DERIVATIVE
|
||||
b3Quaternion predictedOrn = curTrans.getRotation();
|
||||
predictedOrn += (angvel * predictedOrn) * (timeStep * b3Scalar(0.5));
|
||||
predictedOrn.normalize();
|
||||
#else
|
||||
#else
|
||||
//Exponential map
|
||||
//google for "Practical Parameterization of Rotations Using the Exponential Map", F. Sebastian Grassia
|
||||
|
||||
b3Vector3 axis;
|
||||
b3Scalar fAngle = angvel.length();
|
||||
b3Scalar fAngle = angvel.length();
|
||||
//limit the angular motion
|
||||
if (fAngle*timeStep > B3_ANGULAR_MOTION_THRESHOLD)
|
||||
if (fAngle * timeStep > B3_ANGULAR_MOTION_THRESHOLD)
|
||||
{
|
||||
fAngle = B3_ANGULAR_MOTION_THRESHOLD / timeStep;
|
||||
}
|
||||
|
||||
if ( fAngle < b3Scalar(0.001) )
|
||||
if (fAngle < b3Scalar(0.001))
|
||||
{
|
||||
// use Taylor's expansions of sync function
|
||||
axis = angvel*( b3Scalar(0.5)*timeStep-(timeStep*timeStep*timeStep)*(b3Scalar(0.020833333333))*fAngle*fAngle );
|
||||
axis = angvel * (b3Scalar(0.5) * timeStep - (timeStep * timeStep * timeStep) * (b3Scalar(0.020833333333)) * fAngle * fAngle);
|
||||
}
|
||||
else
|
||||
{
|
||||
// sync(fAngle) = sin(c*fAngle)/t
|
||||
axis = angvel*( b3Sin(b3Scalar(0.5)*fAngle*timeStep)/fAngle );
|
||||
axis = angvel * (b3Sin(b3Scalar(0.5) * fAngle * timeStep) / fAngle);
|
||||
}
|
||||
b3Quaternion dorn (axis.getX(),axis.getY(),axis.getZ(),b3Cos( fAngle*timeStep*b3Scalar(0.5) ));
|
||||
b3Quaternion dorn(axis.getX(), axis.getY(), axis.getZ(), b3Cos(fAngle * timeStep * b3Scalar(0.5)));
|
||||
b3Quaternion orn0 = curTrans.getRotation();
|
||||
|
||||
b3Quaternion predictedOrn = dorn * orn0;
|
||||
predictedOrn.normalize();
|
||||
#endif
|
||||
#endif
|
||||
predictedTransform.setRotation(predictedOrn);
|
||||
}
|
||||
|
||||
static void calculateVelocityQuaternion(const b3Vector3& pos0,const b3Vector3& pos1,const b3Quaternion& orn0,const b3Quaternion& orn1,b3Scalar timeStep,b3Vector3& linVel,b3Vector3& angVel)
|
||||
static void calculateVelocityQuaternion(const b3Vector3& pos0, const b3Vector3& pos1, const b3Quaternion& orn0, const b3Quaternion& orn1, b3Scalar timeStep, b3Vector3& linVel, b3Vector3& angVel)
|
||||
{
|
||||
linVel = (pos1 - pos0) / timeStep;
|
||||
b3Vector3 axis;
|
||||
b3Scalar angle;
|
||||
b3Scalar angle;
|
||||
if (orn0 != orn1)
|
||||
{
|
||||
calculateDiffAxisAngleQuaternion(orn0,orn1,axis,angle);
|
||||
calculateDiffAxisAngleQuaternion(orn0, orn1, axis, angle);
|
||||
angVel = axis * angle / timeStep;
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
angVel.setValue(0,0,0);
|
||||
angVel.setValue(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void calculateDiffAxisAngleQuaternion(const b3Quaternion& orn0,const b3Quaternion& orn1a,b3Vector3& axis,b3Scalar& angle)
|
||||
static void calculateDiffAxisAngleQuaternion(const b3Quaternion& orn0, const b3Quaternion& orn1a, b3Vector3& axis, b3Scalar& angle)
|
||||
{
|
||||
b3Quaternion orn1 = orn0.nearest(orn1a);
|
||||
b3Quaternion dorn = orn1 * orn0.inverse();
|
||||
angle = dorn.getAngle();
|
||||
axis = b3MakeVector3(dorn.getX(),dorn.getY(),dorn.getZ());
|
||||
axis = b3MakeVector3(dorn.getX(), dorn.getY(), dorn.getZ());
|
||||
axis[3] = b3Scalar(0.);
|
||||
//check for axis length
|
||||
b3Scalar len = axis.length2();
|
||||
if (len < B3_EPSILON*B3_EPSILON)
|
||||
axis = b3MakeVector3(b3Scalar(1.),b3Scalar(0.),b3Scalar(0.));
|
||||
if (len < B3_EPSILON * B3_EPSILON)
|
||||
axis = b3MakeVector3(b3Scalar(1.), b3Scalar(0.), b3Scalar(0.));
|
||||
else
|
||||
axis /= b3Sqrt(len);
|
||||
}
|
||||
|
||||
static void calculateVelocity(const b3Transform& transform0,const b3Transform& transform1,b3Scalar timeStep,b3Vector3& linVel,b3Vector3& angVel)
|
||||
static void calculateVelocity(const b3Transform& transform0, const b3Transform& transform1, b3Scalar timeStep, b3Vector3& linVel, b3Vector3& angVel)
|
||||
{
|
||||
linVel = (transform1.getOrigin() - transform0.getOrigin()) / timeStep;
|
||||
b3Vector3 axis;
|
||||
b3Scalar angle;
|
||||
calculateDiffAxisAngle(transform0,transform1,axis,angle);
|
||||
b3Scalar angle;
|
||||
calculateDiffAxisAngle(transform0, transform1, axis, angle);
|
||||
angVel = axis * angle / timeStep;
|
||||
}
|
||||
|
||||
static void calculateDiffAxisAngle(const b3Transform& transform0,const b3Transform& transform1,b3Vector3& axis,b3Scalar& angle)
|
||||
static void calculateDiffAxisAngle(const b3Transform& transform0, const b3Transform& transform1, b3Vector3& axis, b3Scalar& angle)
|
||||
{
|
||||
b3Matrix3x3 dmat = transform1.getBasis() * transform0.getBasis().inverse();
|
||||
b3Quaternion dorn;
|
||||
dmat.getRotation(dorn);
|
||||
|
||||
///floating point inaccuracy can lead to w component > 1..., which breaks
|
||||
///floating point inaccuracy can lead to w component > 1..., which breaks
|
||||
dorn.normalize();
|
||||
|
||||
|
||||
angle = dorn.getAngle();
|
||||
axis = b3MakeVector3(dorn.getX(),dorn.getY(),dorn.getZ());
|
||||
axis = b3MakeVector3(dorn.getX(), dorn.getY(), dorn.getZ());
|
||||
axis[3] = b3Scalar(0.);
|
||||
//check for axis length
|
||||
b3Scalar len = axis.length2();
|
||||
if (len < B3_EPSILON*B3_EPSILON)
|
||||
axis = b3MakeVector3(b3Scalar(1.),b3Scalar(0.),b3Scalar(0.));
|
||||
if (len < B3_EPSILON * B3_EPSILON)
|
||||
axis = b3MakeVector3(b3Scalar(1.), b3Scalar(0.), b3Scalar(0.));
|
||||
else
|
||||
axis /= b3Sqrt(len);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
///The b3ConvexSeparatingDistanceUtil can help speed up convex collision detection
|
||||
///The b3ConvexSeparatingDistanceUtil can help speed up convex collision detection
|
||||
///by conservatively updating a cached separating distance/vector instead of re-calculating the closest distance
|
||||
class b3ConvexSeparatingDistanceUtil
|
||||
class b3ConvexSeparatingDistanceUtil
|
||||
{
|
||||
b3Quaternion m_ornA;
|
||||
b3Quaternion m_ornB;
|
||||
b3Vector3 m_posA;
|
||||
b3Vector3 m_posB;
|
||||
|
||||
b3Vector3 m_separatingNormal;
|
||||
b3Quaternion m_ornA;
|
||||
b3Quaternion m_ornB;
|
||||
b3Vector3 m_posA;
|
||||
b3Vector3 m_posB;
|
||||
|
||||
b3Scalar m_boundingRadiusA;
|
||||
b3Scalar m_boundingRadiusB;
|
||||
b3Scalar m_separatingDistance;
|
||||
b3Vector3 m_separatingNormal;
|
||||
|
||||
b3Scalar m_boundingRadiusA;
|
||||
b3Scalar m_boundingRadiusB;
|
||||
b3Scalar m_separatingDistance;
|
||||
|
||||
public:
|
||||
|
||||
b3ConvexSeparatingDistanceUtil(b3Scalar boundingRadiusA,b3Scalar boundingRadiusB)
|
||||
:m_boundingRadiusA(boundingRadiusA),
|
||||
m_boundingRadiusB(boundingRadiusB),
|
||||
m_separatingDistance(0.f)
|
||||
b3ConvexSeparatingDistanceUtil(b3Scalar boundingRadiusA, b3Scalar boundingRadiusB)
|
||||
: m_boundingRadiusA(boundingRadiusA),
|
||||
m_boundingRadiusB(boundingRadiusB),
|
||||
m_separatingDistance(0.f)
|
||||
{
|
||||
}
|
||||
|
||||
b3Scalar getConservativeSeparatingDistance()
|
||||
b3Scalar getConservativeSeparatingDistance()
|
||||
{
|
||||
return m_separatingDistance;
|
||||
}
|
||||
|
||||
void updateSeparatingDistance(const b3Transform& transA,const b3Transform& transB)
|
||||
void updateSeparatingDistance(const b3Transform& transA, const b3Transform& transB)
|
||||
{
|
||||
const b3Vector3& toPosA = transA.getOrigin();
|
||||
const b3Vector3& toPosB = transB.getOrigin();
|
||||
b3Quaternion toOrnA = transA.getRotation();
|
||||
b3Quaternion toOrnB = transB.getRotation();
|
||||
|
||||
if (m_separatingDistance>0.f)
|
||||
if (m_separatingDistance > 0.f)
|
||||
{
|
||||
|
||||
|
||||
b3Vector3 linVelA,angVelA,linVelB,angVelB;
|
||||
b3TransformUtil::calculateVelocityQuaternion(m_posA,toPosA,m_ornA,toOrnA,b3Scalar(1.),linVelA,angVelA);
|
||||
b3TransformUtil::calculateVelocityQuaternion(m_posB,toPosB,m_ornB,toOrnB,b3Scalar(1.),linVelB,angVelB);
|
||||
b3Vector3 linVelA, angVelA, linVelB, angVelB;
|
||||
b3TransformUtil::calculateVelocityQuaternion(m_posA, toPosA, m_ornA, toOrnA, b3Scalar(1.), linVelA, angVelA);
|
||||
b3TransformUtil::calculateVelocityQuaternion(m_posB, toPosB, m_ornB, toOrnB, b3Scalar(1.), linVelB, angVelB);
|
||||
b3Scalar maxAngularProjectedVelocity = angVelA.length() * m_boundingRadiusA + angVelB.length() * m_boundingRadiusB;
|
||||
b3Vector3 relLinVel = (linVelB-linVelA);
|
||||
b3Vector3 relLinVel = (linVelB - linVelA);
|
||||
b3Scalar relLinVelocLength = relLinVel.dot(m_separatingNormal);
|
||||
if (relLinVelocLength<0.f)
|
||||
if (relLinVelocLength < 0.f)
|
||||
{
|
||||
relLinVelocLength = 0.f;
|
||||
}
|
||||
|
||||
b3Scalar projectedMotion = maxAngularProjectedVelocity +relLinVelocLength;
|
||||
|
||||
b3Scalar projectedMotion = maxAngularProjectedVelocity + relLinVelocLength;
|
||||
m_separatingDistance -= projectedMotion;
|
||||
}
|
||||
|
||||
|
||||
m_posA = toPosA;
|
||||
m_posB = toPosB;
|
||||
m_ornA = toOrnA;
|
||||
m_ornB = toOrnB;
|
||||
}
|
||||
|
||||
void initSeparatingDistance(const b3Vector3& separatingVector,b3Scalar separatingDistance,const b3Transform& transA,const b3Transform& transB)
|
||||
void initSeparatingDistance(const b3Vector3& separatingVector, b3Scalar separatingDistance, const b3Transform& transA, const b3Transform& transB)
|
||||
{
|
||||
m_separatingDistance = separatingDistance;
|
||||
|
||||
if (m_separatingDistance>0.f)
|
||||
if (m_separatingDistance > 0.f)
|
||||
{
|
||||
m_separatingNormal = separatingVector;
|
||||
|
||||
|
||||
const b3Vector3& toPosA = transA.getOrigin();
|
||||
const b3Vector3& toPosB = transB.getOrigin();
|
||||
b3Quaternion toOrnA = transA.getRotation();
|
||||
@@ -220,9 +205,6 @@ public:
|
||||
m_ornB = toOrnB;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //B3_TRANSFORM_UTIL_H
|
||||
|
||||
#endif //B3_TRANSFORM_UTIL_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -4,94 +4,87 @@
|
||||
#include "Bullet3Common/shared/b3PlatformDefinitions.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include "Bullet3Common/b3Vector3.h"
|
||||
#define b3Float4 b3Vector3
|
||||
#define b3Float4ConstArg const b3Vector3&
|
||||
#define b3Dot3F4 b3Dot
|
||||
#define b3Cross3 b3Cross
|
||||
#define b3MakeFloat4 b3MakeVector3
|
||||
inline b3Vector3 b3Normalized(const b3Vector3& vec)
|
||||
{
|
||||
return vec.normalized();
|
||||
}
|
||||
|
||||
inline b3Float4 b3FastNormalized3(b3Float4ConstArg v)
|
||||
{
|
||||
return v.normalized();
|
||||
}
|
||||
|
||||
inline b3Float4 b3MaxFloat4 (const b3Float4& a, const b3Float4& b)
|
||||
{
|
||||
b3Float4 tmp = a;
|
||||
tmp.setMax(b);
|
||||
return tmp;
|
||||
}
|
||||
inline b3Float4 b3MinFloat4 (const b3Float4& a, const b3Float4& b)
|
||||
{
|
||||
b3Float4 tmp = a;
|
||||
tmp.setMin(b);
|
||||
return tmp;
|
||||
}
|
||||
#include "Bullet3Common/b3Vector3.h"
|
||||
#define b3Float4 b3Vector3
|
||||
#define b3Float4ConstArg const b3Vector3&
|
||||
#define b3Dot3F4 b3Dot
|
||||
#define b3Cross3 b3Cross
|
||||
#define b3MakeFloat4 b3MakeVector3
|
||||
inline b3Vector3 b3Normalized(const b3Vector3& vec)
|
||||
{
|
||||
return vec.normalized();
|
||||
}
|
||||
|
||||
inline b3Float4 b3FastNormalized3(b3Float4ConstArg v)
|
||||
{
|
||||
return v.normalized();
|
||||
}
|
||||
|
||||
inline b3Float4 b3MaxFloat4(const b3Float4& a, const b3Float4& b)
|
||||
{
|
||||
b3Float4 tmp = a;
|
||||
tmp.setMax(b);
|
||||
return tmp;
|
||||
}
|
||||
inline b3Float4 b3MinFloat4(const b3Float4& a, const b3Float4& b)
|
||||
{
|
||||
b3Float4 tmp = a;
|
||||
tmp.setMin(b);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
#else
|
||||
typedef float4 b3Float4;
|
||||
#define b3Float4ConstArg const b3Float4
|
||||
#define b3MakeFloat4 (float4)
|
||||
float b3Dot3F4(b3Float4ConstArg v0,b3Float4ConstArg v1)
|
||||
{
|
||||
float4 a1 = b3MakeFloat4(v0.xyz,0.f);
|
||||
float4 b1 = b3MakeFloat4(v1.xyz,0.f);
|
||||
return dot(a1, b1);
|
||||
}
|
||||
b3Float4 b3Cross3(b3Float4ConstArg v0,b3Float4ConstArg v1)
|
||||
{
|
||||
float4 a1 = b3MakeFloat4(v0.xyz,0.f);
|
||||
float4 b1 = b3MakeFloat4(v1.xyz,0.f);
|
||||
return cross(a1, b1);
|
||||
}
|
||||
#define b3MinFloat4 min
|
||||
#define b3MaxFloat4 max
|
||||
typedef float4 b3Float4;
|
||||
#define b3Float4ConstArg const b3Float4
|
||||
#define b3MakeFloat4 (float4)
|
||||
float b3Dot3F4(b3Float4ConstArg v0, b3Float4ConstArg v1)
|
||||
{
|
||||
float4 a1 = b3MakeFloat4(v0.xyz, 0.f);
|
||||
float4 b1 = b3MakeFloat4(v1.xyz, 0.f);
|
||||
return dot(a1, b1);
|
||||
}
|
||||
b3Float4 b3Cross3(b3Float4ConstArg v0, b3Float4ConstArg v1)
|
||||
{
|
||||
float4 a1 = b3MakeFloat4(v0.xyz, 0.f);
|
||||
float4 b1 = b3MakeFloat4(v1.xyz, 0.f);
|
||||
return cross(a1, b1);
|
||||
}
|
||||
#define b3MinFloat4 min
|
||||
#define b3MaxFloat4 max
|
||||
|
||||
#define b3Normalized(a) normalize(a)
|
||||
#define b3Normalized(a) normalize(a)
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
inline bool b3IsAlmostZero(b3Float4ConstArg v)
|
||||
{
|
||||
if(b3Fabs(v.x)>1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6)
|
||||
if (b3Fabs(v.x) > 1e-6 || b3Fabs(v.y) > 1e-6 || b3Fabs(v.z) > 1e-6)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )
|
||||
inline int b3MaxDot(b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut)
|
||||
{
|
||||
float maxDot = -B3_INFINITY;
|
||||
int i = 0;
|
||||
int ptIndex = -1;
|
||||
for( i = 0; i < vecLen; i++ )
|
||||
{
|
||||
float dot = b3Dot3F4(vecArray[i],vec);
|
||||
|
||||
if( dot > maxDot )
|
||||
{
|
||||
maxDot = dot;
|
||||
ptIndex = i;
|
||||
}
|
||||
}
|
||||
b3Assert(ptIndex>=0);
|
||||
if (ptIndex<0)
|
||||
float maxDot = -B3_INFINITY;
|
||||
int i = 0;
|
||||
int ptIndex = -1;
|
||||
for (i = 0; i < vecLen; i++)
|
||||
{
|
||||
float dot = b3Dot3F4(vecArray[i], vec);
|
||||
|
||||
if (dot > maxDot)
|
||||
{
|
||||
maxDot = dot;
|
||||
ptIndex = i;
|
||||
}
|
||||
}
|
||||
b3Assert(ptIndex >= 0);
|
||||
if (ptIndex < 0)
|
||||
{
|
||||
ptIndex = 0;
|
||||
}
|
||||
*dotOut = maxDot;
|
||||
return ptIndex;
|
||||
*dotOut = maxDot;
|
||||
return ptIndex;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif //B3_FLOAT4_H
|
||||
#endif //B3_FLOAT4_H
|
||||
|
||||
@@ -20,11 +20,10 @@ subject to the following restrictions:
|
||||
|
||||
struct b3UnsignedInt2
|
||||
{
|
||||
union
|
||||
{
|
||||
union {
|
||||
struct
|
||||
{
|
||||
unsigned int x,y;
|
||||
unsigned int x, y;
|
||||
};
|
||||
struct
|
||||
{
|
||||
@@ -35,11 +34,10 @@ struct b3UnsignedInt2
|
||||
|
||||
struct b3Int2
|
||||
{
|
||||
union
|
||||
{
|
||||
union {
|
||||
struct
|
||||
{
|
||||
int x,y;
|
||||
int x, y;
|
||||
};
|
||||
struct
|
||||
{
|
||||
@@ -51,7 +49,8 @@ struct b3Int2
|
||||
inline b3Int2 b3MakeInt2(int x, int y)
|
||||
{
|
||||
b3Int2 v;
|
||||
v.s[0] = x; v.s[1] = y;
|
||||
v.s[0] = x;
|
||||
v.s[1] = y;
|
||||
return v;
|
||||
}
|
||||
#else
|
||||
@@ -60,5 +59,5 @@ inline b3Int2 b3MakeInt2(int x, int y)
|
||||
#define b3Int2 int2
|
||||
#define b3MakeInt2 (int2)
|
||||
|
||||
#endif //__cplusplus
|
||||
#endif //__cplusplus
|
||||
#endif
|
||||
@@ -5,16 +5,15 @@
|
||||
|
||||
#include "Bullet3Common/b3Scalar.h"
|
||||
|
||||
|
||||
B3_ATTRIBUTE_ALIGNED16(struct) b3UnsignedInt4
|
||||
B3_ATTRIBUTE_ALIGNED16(struct)
|
||||
b3UnsignedInt4
|
||||
{
|
||||
B3_DECLARE_ALIGNED_ALLOCATOR();
|
||||
|
||||
union
|
||||
{
|
||||
union {
|
||||
struct
|
||||
{
|
||||
unsigned int x,y,z,w;
|
||||
unsigned int x, y, z, w;
|
||||
};
|
||||
struct
|
||||
{
|
||||
@@ -23,15 +22,15 @@ B3_ATTRIBUTE_ALIGNED16(struct) b3UnsignedInt4
|
||||
};
|
||||
};
|
||||
|
||||
B3_ATTRIBUTE_ALIGNED16(struct) b3Int4
|
||||
B3_ATTRIBUTE_ALIGNED16(struct)
|
||||
b3Int4
|
||||
{
|
||||
B3_DECLARE_ALIGNED_ALLOCATOR();
|
||||
|
||||
union
|
||||
{
|
||||
union {
|
||||
struct
|
||||
{
|
||||
int x,y,z,w;
|
||||
int x, y, z, w;
|
||||
};
|
||||
struct
|
||||
{
|
||||
@@ -43,26 +42,30 @@ B3_ATTRIBUTE_ALIGNED16(struct) b3Int4
|
||||
B3_FORCE_INLINE b3Int4 b3MakeInt4(int x, int y, int z, int w = 0)
|
||||
{
|
||||
b3Int4 v;
|
||||
v.s[0] = x; v.s[1] = y; v.s[2] = z; v.s[3] = w;
|
||||
v.s[0] = x;
|
||||
v.s[1] = y;
|
||||
v.s[2] = z;
|
||||
v.s[3] = w;
|
||||
return v;
|
||||
}
|
||||
|
||||
B3_FORCE_INLINE b3UnsignedInt4 b3MakeUnsignedInt4(unsigned int x, unsigned int y, unsigned int z, unsigned int w = 0)
|
||||
{
|
||||
b3UnsignedInt4 v;
|
||||
v.s[0] = x; v.s[1] = y; v.s[2] = z; v.s[3] = w;
|
||||
v.s[0] = x;
|
||||
v.s[1] = y;
|
||||
v.s[2] = z;
|
||||
v.s[3] = w;
|
||||
return v;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
|
||||
#define b3UnsignedInt4 uint4
|
||||
#define b3Int4 int4
|
||||
#define b3MakeInt4 (int4)
|
||||
#define b3MakeUnsignedInt4 (uint4)
|
||||
|
||||
#endif //__cplusplus
|
||||
|
||||
#endif //__cplusplus
|
||||
|
||||
#endif //B3_INT4_H
|
||||
#endif //B3_INT4_H
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
#include "Bullet3Common/shared/b3Quat.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "Bullet3Common/b3Matrix3x3.h"
|
||||
@@ -22,43 +21,41 @@ inline b3Mat3x3 b3AbsoluteMat3x3(b3Mat3x3ConstArg mat)
|
||||
return mat.absolute();
|
||||
}
|
||||
|
||||
#define b3GetRow(m,row) m.getRow(row)
|
||||
#define b3GetRow(m, row) m.getRow(row)
|
||||
|
||||
__inline
|
||||
b3Float4 mtMul3(b3Float4ConstArg a, b3Mat3x3ConstArg b)
|
||||
__inline b3Float4 mtMul3(b3Float4ConstArg a, b3Mat3x3ConstArg b)
|
||||
{
|
||||
return b*a;
|
||||
return b * a;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
typedef struct
|
||||
{
|
||||
b3Float4 m_row[3];
|
||||
}b3Mat3x3;
|
||||
} b3Mat3x3;
|
||||
|
||||
#define b3Mat3x3ConstArg const b3Mat3x3
|
||||
#define b3GetRow(m,row) (m.m_row[row])
|
||||
#define b3GetRow(m, row) (m.m_row[row])
|
||||
|
||||
inline b3Mat3x3 b3QuatGetRotationMatrix(b3Quat quat)
|
||||
{
|
||||
b3Float4 quat2 = (b3Float4)(quat.x*quat.x, quat.y*quat.y, quat.z*quat.z, 0.f);
|
||||
b3Float4 quat2 = (b3Float4)(quat.x * quat.x, quat.y * quat.y, quat.z * quat.z, 0.f);
|
||||
b3Mat3x3 out;
|
||||
|
||||
out.m_row[0].x=1-2*quat2.y-2*quat2.z;
|
||||
out.m_row[0].y=2*quat.x*quat.y-2*quat.w*quat.z;
|
||||
out.m_row[0].z=2*quat.x*quat.z+2*quat.w*quat.y;
|
||||
out.m_row[0].x = 1 - 2 * quat2.y - 2 * quat2.z;
|
||||
out.m_row[0].y = 2 * quat.x * quat.y - 2 * quat.w * quat.z;
|
||||
out.m_row[0].z = 2 * quat.x * quat.z + 2 * quat.w * quat.y;
|
||||
out.m_row[0].w = 0.f;
|
||||
|
||||
out.m_row[1].x=2*quat.x*quat.y+2*quat.w*quat.z;
|
||||
out.m_row[1].y=1-2*quat2.x-2*quat2.z;
|
||||
out.m_row[1].z=2*quat.y*quat.z-2*quat.w*quat.x;
|
||||
out.m_row[1].x = 2 * quat.x * quat.y + 2 * quat.w * quat.z;
|
||||
out.m_row[1].y = 1 - 2 * quat2.x - 2 * quat2.z;
|
||||
out.m_row[1].z = 2 * quat.y * quat.z - 2 * quat.w * quat.x;
|
||||
out.m_row[1].w = 0.f;
|
||||
|
||||
out.m_row[2].x=2*quat.x*quat.z-2*quat.w*quat.y;
|
||||
out.m_row[2].y=2*quat.y*quat.z+2*quat.w*quat.x;
|
||||
out.m_row[2].z=1-2*quat2.x-2*quat2.y;
|
||||
out.m_row[2].x = 2 * quat.x * quat.z - 2 * quat.w * quat.y;
|
||||
out.m_row[2].y = 2 * quat.y * quat.z + 2 * quat.w * quat.x;
|
||||
out.m_row[2].z = 1 - 2 * quat2.x - 2 * quat2.y;
|
||||
out.m_row[2].w = 0.f;
|
||||
|
||||
return out;
|
||||
@@ -73,27 +70,19 @@ inline b3Mat3x3 b3AbsoluteMat3x3(b3Mat3x3ConstArg matIn)
|
||||
return out;
|
||||
}
|
||||
|
||||
__inline b3Mat3x3 mtZero();
|
||||
|
||||
__inline
|
||||
b3Mat3x3 mtZero();
|
||||
__inline b3Mat3x3 mtIdentity();
|
||||
|
||||
__inline
|
||||
b3Mat3x3 mtIdentity();
|
||||
__inline b3Mat3x3 mtTranspose(b3Mat3x3 m);
|
||||
|
||||
__inline
|
||||
b3Mat3x3 mtTranspose(b3Mat3x3 m);
|
||||
__inline b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b);
|
||||
|
||||
__inline
|
||||
b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b);
|
||||
__inline b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b);
|
||||
|
||||
__inline
|
||||
b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b);
|
||||
__inline b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b);
|
||||
|
||||
__inline
|
||||
b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b);
|
||||
|
||||
__inline
|
||||
b3Mat3x3 mtZero()
|
||||
__inline b3Mat3x3 mtZero()
|
||||
{
|
||||
b3Mat3x3 m;
|
||||
m.m_row[0] = (b3Float4)(0.f);
|
||||
@@ -102,18 +91,16 @@ b3Mat3x3 mtZero()
|
||||
return m;
|
||||
}
|
||||
|
||||
__inline
|
||||
b3Mat3x3 mtIdentity()
|
||||
__inline b3Mat3x3 mtIdentity()
|
||||
{
|
||||
b3Mat3x3 m;
|
||||
m.m_row[0] = (b3Float4)(1,0,0,0);
|
||||
m.m_row[1] = (b3Float4)(0,1,0,0);
|
||||
m.m_row[2] = (b3Float4)(0,0,1,0);
|
||||
m.m_row[0] = (b3Float4)(1, 0, 0, 0);
|
||||
m.m_row[1] = (b3Float4)(0, 1, 0, 0);
|
||||
m.m_row[2] = (b3Float4)(0, 0, 1, 0);
|
||||
return m;
|
||||
}
|
||||
|
||||
__inline
|
||||
b3Mat3x3 mtTranspose(b3Mat3x3 m)
|
||||
__inline b3Mat3x3 mtTranspose(b3Mat3x3 m)
|
||||
{
|
||||
b3Mat3x3 out;
|
||||
out.m_row[0] = (b3Float4)(m.m_row[0].x, m.m_row[1].x, m.m_row[2].x, 0.f);
|
||||
@@ -122,58 +109,49 @@ b3Mat3x3 mtTranspose(b3Mat3x3 m)
|
||||
return out;
|
||||
}
|
||||
|
||||
__inline
|
||||
b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b)
|
||||
__inline b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b)
|
||||
{
|
||||
b3Mat3x3 transB;
|
||||
transB = mtTranspose( b );
|
||||
transB = mtTranspose(b);
|
||||
b3Mat3x3 ans;
|
||||
// why this doesn't run when 0ing in the for{}
|
||||
a.m_row[0].w = 0.f;
|
||||
a.m_row[1].w = 0.f;
|
||||
a.m_row[2].w = 0.f;
|
||||
for(int i=0; i<3; i++)
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
// a.m_row[i].w = 0.f;
|
||||
ans.m_row[i].x = b3Dot3F4(a.m_row[i],transB.m_row[0]);
|
||||
ans.m_row[i].y = b3Dot3F4(a.m_row[i],transB.m_row[1]);
|
||||
ans.m_row[i].z = b3Dot3F4(a.m_row[i],transB.m_row[2]);
|
||||
// a.m_row[i].w = 0.f;
|
||||
ans.m_row[i].x = b3Dot3F4(a.m_row[i], transB.m_row[0]);
|
||||
ans.m_row[i].y = b3Dot3F4(a.m_row[i], transB.m_row[1]);
|
||||
ans.m_row[i].z = b3Dot3F4(a.m_row[i], transB.m_row[2]);
|
||||
ans.m_row[i].w = 0.f;
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
__inline
|
||||
b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b)
|
||||
__inline b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b)
|
||||
{
|
||||
b3Float4 ans;
|
||||
ans.x = b3Dot3F4( a.m_row[0], b );
|
||||
ans.y = b3Dot3F4( a.m_row[1], b );
|
||||
ans.z = b3Dot3F4( a.m_row[2], b );
|
||||
ans.x = b3Dot3F4(a.m_row[0], b);
|
||||
ans.y = b3Dot3F4(a.m_row[1], b);
|
||||
ans.z = b3Dot3F4(a.m_row[2], b);
|
||||
ans.w = 0.f;
|
||||
return ans;
|
||||
}
|
||||
|
||||
__inline
|
||||
b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b)
|
||||
__inline b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b)
|
||||
{
|
||||
b3Float4 colx = b3MakeFloat4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);
|
||||
b3Float4 coly = b3MakeFloat4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);
|
||||
b3Float4 colz = b3MakeFloat4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);
|
||||
|
||||
b3Float4 ans;
|
||||
ans.x = b3Dot3F4( a, colx );
|
||||
ans.y = b3Dot3F4( a, coly );
|
||||
ans.z = b3Dot3F4( a, colz );
|
||||
ans.x = b3Dot3F4(a, colx);
|
||||
ans.y = b3Dot3F4(a, coly);
|
||||
ans.z = b3Dot3F4(a, colz);
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif //B3_MAT3x3_H
|
||||
#endif //B3_MAT3x3_H
|
||||
|
||||
@@ -8,18 +8,18 @@ struct MyTest
|
||||
|
||||
#ifdef __cplusplus
|
||||
//#define b3ConstArray(a) const b3AlignedObjectArray<a>&
|
||||
#define b3ConstArray(a) const a*
|
||||
#define b3ConstArray(a) const a *
|
||||
#define b3AtomicInc(a) ((*a)++)
|
||||
|
||||
inline int b3AtomicAdd (volatile int *p, int val)
|
||||
inline int b3AtomicAdd(volatile int *p, int val)
|
||||
{
|
||||
int oldValue = *p;
|
||||
int newValue = oldValue+val;
|
||||
int newValue = oldValue + val;
|
||||
*p = newValue;
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
#define __global
|
||||
#define __global
|
||||
|
||||
#define B3_STATIC static
|
||||
#else
|
||||
@@ -27,7 +27,7 @@ inline int b3AtomicAdd (volatile int *p, int val)
|
||||
#define B3_LARGE_FLOAT 1e18f
|
||||
#define B3_INFINITY 1e18f
|
||||
#define b3Assert(a)
|
||||
#define b3ConstArray(a) __global const a*
|
||||
#define b3ConstArray(a) __global const a *
|
||||
#define b3AtomicInc atomic_inc
|
||||
#define b3AtomicAdd atomic_add
|
||||
#define b3Fabs fabs
|
||||
|
||||
@@ -5,35 +5,34 @@
|
||||
#include "Bullet3Common/shared/b3Float4.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include "Bullet3Common/b3Quaternion.h"
|
||||
#include "Bullet3Common/b3Transform.h"
|
||||
#include "Bullet3Common/b3Quaternion.h"
|
||||
#include "Bullet3Common/b3Transform.h"
|
||||
|
||||
#define b3Quat b3Quaternion
|
||||
#define b3QuatConstArg const b3Quaternion&
|
||||
inline b3Quat b3QuatInverse(b3QuatConstArg orn)
|
||||
{
|
||||
return orn.inverse();
|
||||
}
|
||||
#define b3Quat b3Quaternion
|
||||
#define b3QuatConstArg const b3Quaternion&
|
||||
inline b3Quat b3QuatInverse(b3QuatConstArg orn)
|
||||
{
|
||||
return orn.inverse();
|
||||
}
|
||||
|
||||
inline b3Float4 b3TransformPoint(b3Float4ConstArg point, b3Float4ConstArg translation, b3QuatConstArg orientation)
|
||||
{
|
||||
b3Transform tr;
|
||||
tr.setOrigin(translation);
|
||||
tr.setRotation(orientation);
|
||||
return tr(point);
|
||||
}
|
||||
inline b3Float4 b3TransformPoint(b3Float4ConstArg point, b3Float4ConstArg translation, b3QuatConstArg orientation)
|
||||
{
|
||||
b3Transform tr;
|
||||
tr.setOrigin(translation);
|
||||
tr.setRotation(orientation);
|
||||
return tr(point);
|
||||
}
|
||||
|
||||
#else
|
||||
typedef float4 b3Quat;
|
||||
#define b3QuatConstArg const b3Quat
|
||||
|
||||
|
||||
typedef float4 b3Quat;
|
||||
#define b3QuatConstArg const b3Quat
|
||||
|
||||
inline float4 b3FastNormalize4(float4 v)
|
||||
{
|
||||
v = (float4)(v.xyz,0.f);
|
||||
v = (float4)(v.xyz, 0.f);
|
||||
return fast_normalize(v);
|
||||
}
|
||||
|
||||
|
||||
inline b3Quat b3QuatMul(b3Quat a, b3Quat b);
|
||||
inline b3Quat b3QuatNormalized(b3QuatConstArg in);
|
||||
inline b3Quat b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec);
|
||||
@@ -43,20 +42,20 @@ inline b3Quat b3QuatInverse(b3QuatConstArg q);
|
||||
inline b3Quat b3QuatMul(b3QuatConstArg a, b3QuatConstArg b)
|
||||
{
|
||||
b3Quat ans;
|
||||
ans = b3Cross3( a, b );
|
||||
ans += a.w*b+b.w*a;
|
||||
// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);
|
||||
ans.w = a.w*b.w - b3Dot3F4(a, b);
|
||||
ans = b3Cross3(a, b);
|
||||
ans += a.w * b + b.w * a;
|
||||
// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);
|
||||
ans.w = a.w * b.w - b3Dot3F4(a, b);
|
||||
return ans;
|
||||
}
|
||||
|
||||
inline b3Quat b3QuatNormalized(b3QuatConstArg in)
|
||||
{
|
||||
b3Quat q;
|
||||
q=in;
|
||||
q = in;
|
||||
//return b3FastNormalize4(in);
|
||||
float len = native_sqrt(dot(q, q));
|
||||
if(len > 0.f)
|
||||
if (len > 0.f)
|
||||
{
|
||||
q *= 1.f / len;
|
||||
}
|
||||
@@ -69,15 +68,13 @@ inline b3Quat b3QuatNormalized(b3QuatConstArg in)
|
||||
}
|
||||
inline float4 b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec)
|
||||
{
|
||||
b3Quat qInv = b3QuatInvert( q );
|
||||
b3Quat qInv = b3QuatInvert(q);
|
||||
float4 vcpy = vec;
|
||||
vcpy.w = 0.f;
|
||||
float4 out = b3QuatMul(b3QuatMul(q,vcpy),qInv);
|
||||
float4 out = b3QuatMul(b3QuatMul(q, vcpy), qInv);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline b3Quat b3QuatInverse(b3QuatConstArg q)
|
||||
{
|
||||
return (b3Quat)(-q.xyz, q.w);
|
||||
@@ -90,14 +87,14 @@ inline b3Quat b3QuatInvert(b3QuatConstArg q)
|
||||
|
||||
inline float4 b3QuatInvRotate(b3QuatConstArg q, b3QuatConstArg vec)
|
||||
{
|
||||
return b3QuatRotate( b3QuatInvert( q ), vec );
|
||||
return b3QuatRotate(b3QuatInvert(q), vec);
|
||||
}
|
||||
|
||||
inline b3Float4 b3TransformPoint(b3Float4ConstArg point, b3Float4ConstArg translation, b3QuatConstArg orientation)
|
||||
inline b3Float4 b3TransformPoint(b3Float4ConstArg point, b3Float4ConstArg translation, b3QuatConstArg orientation)
|
||||
{
|
||||
return b3QuatRotate( orientation, point ) + (translation);
|
||||
return b3QuatRotate(orientation, point) + (translation);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif //B3_QUAT_H
|
||||
#endif
|
||||
|
||||
#endif //B3_QUAT_H
|
||||
|
||||
Reference in New Issue
Block a user