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:
erwincoumans
2018-09-23 14:17:31 -07:00
parent b73b05e9fb
commit ab8f16961e
1773 changed files with 1081087 additions and 474249 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -16,55 +16,49 @@ subject to the following restrictions:
#ifndef BT_THREAD_SUPPORT_INTERFACE_H
#define BT_THREAD_SUPPORT_INTERFACE_H
class btCriticalSection
{
public:
btCriticalSection() {}
virtual ~btCriticalSection() {}
btCriticalSection() {}
virtual ~btCriticalSection() {}
virtual void lock() = 0;
virtual void unlock() = 0;
virtual void lock() = 0;
virtual void unlock() = 0;
};
class btThreadSupportInterface
{
public:
virtual ~btThreadSupportInterface() {}
virtual ~btThreadSupportInterface() {}
virtual int getNumWorkerThreads() const = 0; // number of worker threads (total number of logical processors - 1)
virtual int getCacheFriendlyNumThreads() const = 0; // the number of logical processors sharing a single L3 cache
virtual int getLogicalToPhysicalCoreRatio() const = 0; // the number of logical processors per physical processor (usually 1 or 2)
virtual void runTask(int threadIndex, void* userData) = 0;
virtual void waitForAllTasks() = 0;
virtual int getNumWorkerThreads() const = 0; // number of worker threads (total number of logical processors - 1)
virtual int getCacheFriendlyNumThreads() const = 0; // the number of logical processors sharing a single L3 cache
virtual int getLogicalToPhysicalCoreRatio() const = 0; // the number of logical processors per physical processor (usually 1 or 2)
virtual void runTask( int threadIndex, void* userData ) = 0;
virtual void waitForAllTasks() = 0;
virtual btCriticalSection* createCriticalSection() = 0;
virtual void deleteCriticalSection(btCriticalSection* criticalSection) = 0;
virtual btCriticalSection* createCriticalSection() = 0;
virtual void deleteCriticalSection( btCriticalSection* criticalSection ) = 0;
typedef void (*ThreadFunc)(void* userPtr);
typedef void( *ThreadFunc )( void* userPtr );
struct ConstructionInfo
{
ConstructionInfo(const char* uniqueName,
ThreadFunc userThreadFunc,
int threadStackSize = 65535)
: m_uniqueName(uniqueName),
m_userThreadFunc(userThreadFunc),
m_threadStackSize(threadStackSize)
{
}
struct ConstructionInfo
{
ConstructionInfo( const char* uniqueName,
ThreadFunc userThreadFunc,
int threadStackSize = 65535
)
:m_uniqueName( uniqueName ),
m_userThreadFunc( userThreadFunc ),
m_threadStackSize( threadStackSize )
{
}
const char* m_uniqueName;
ThreadFunc m_userThreadFunc;
int m_threadStackSize;
};
const char* m_uniqueName;
ThreadFunc m_userThreadFunc;
int m_threadStackSize;
};
static btThreadSupportInterface* create( const ConstructionInfo& info );
static btThreadSupportInterface* create(const ConstructionInfo& info);
};
#endif //BT_THREAD_SUPPORT_INTERFACE_H
#endif //BT_THREAD_SUPPORT_INTERFACE_H

View File

@@ -13,9 +13,7 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#if BT_THREADSAFE && !defined( _WIN32 )
#if BT_THREADSAFE && !defined(_WIN32)
#include "LinearMath/btScalar.h"
#include "LinearMath/btAlignedObjectArray.h"
@@ -27,14 +25,12 @@ subject to the following restrictions:
#include <errno.h>
#include <unistd.h>
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 600 //for definition of pthread_barrier_t, see http://pages.cs.wisc.edu/~travitch/pthreads_primer.html
#endif //_XOPEN_SOURCE
#define _XOPEN_SOURCE 600 //for definition of pthread_barrier_t, see http://pages.cs.wisc.edu/~travitch/pthreads_primer.html
#endif //_XOPEN_SOURCE
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h> //for sysconf
#include <unistd.h> //for sysconf
///
/// getNumHardwareThreads()
@@ -48,318 +44,309 @@ subject to the following restrictions:
int btGetNumHardwareThreads()
{
return btMin<int>(BT_MAX_THREAD_COUNT, std::thread::hardware_concurrency());
return btMin<int>(BT_MAX_THREAD_COUNT, std::thread::hardware_concurrency());
}
#else
int btGetNumHardwareThreads()
{
return btMin<int>(BT_MAX_THREAD_COUNT, sysconf( _SC_NPROCESSORS_ONLN ));
return btMin<int>(BT_MAX_THREAD_COUNT, sysconf(_SC_NPROCESSORS_ONLN));
}
#endif
// btThreadSupportPosix helps to initialize/shutdown libspe2, start/stop SPU tasks and communication
class btThreadSupportPosix : public btThreadSupportInterface
{
public:
struct btThreadStatus
{
int m_taskId;
int m_commandId;
int m_status;
struct btThreadStatus
{
int m_taskId;
int m_commandId;
int m_status;
ThreadFunc m_userThreadFunc;
void* m_userPtr; //for taskDesc etc
ThreadFunc m_userThreadFunc;
void* m_userPtr; //for taskDesc etc
pthread_t thread;
//each tread will wait until this signal to start its work
sem_t* startSemaphore;
pthread_t thread;
//each tread will wait until this signal to start its work
sem_t* startSemaphore;
// this is a copy of m_mainSemaphore,
//each tread will signal once it is finished with its work
sem_t* m_mainSemaphore;
unsigned long threadUsed;
};
// this is a copy of m_mainSemaphore,
//each tread will signal once it is finished with its work
sem_t* m_mainSemaphore;
unsigned long threadUsed;
};
private:
typedef unsigned long long UINT64;
typedef unsigned long long UINT64;
btAlignedObjectArray<btThreadStatus> m_activeThreadStatus;
// m_mainSemaphoresemaphore will signal, if and how many threads are finished with their work
sem_t* m_mainSemaphore;
int m_numThreads;
UINT64 m_startedThreadsMask;
void startThreads( const ConstructionInfo& threadInfo );
void stopThreads();
int waitForResponse();
btAlignedObjectArray<btThreadStatus> m_activeThreadStatus;
// m_mainSemaphoresemaphore will signal, if and how many threads are finished with their work
sem_t* m_mainSemaphore;
int m_numThreads;
UINT64 m_startedThreadsMask;
void startThreads(const ConstructionInfo& threadInfo);
void stopThreads();
int waitForResponse();
public:
btThreadSupportPosix( const ConstructionInfo& threadConstructionInfo );
virtual ~btThreadSupportPosix();
btThreadSupportPosix(const ConstructionInfo& threadConstructionInfo);
virtual ~btThreadSupportPosix();
virtual int getNumWorkerThreads() const BT_OVERRIDE { return m_numThreads; }
// TODO: return the number of logical processors sharing the first L3 cache
virtual int getCacheFriendlyNumThreads() const BT_OVERRIDE { return m_numThreads + 1; }
// TODO: detect if CPU has hyperthreading enabled
virtual int getLogicalToPhysicalCoreRatio() const BT_OVERRIDE { return 1; }
virtual int getNumWorkerThreads() const BT_OVERRIDE { return m_numThreads; }
// TODO: return the number of logical processors sharing the first L3 cache
virtual int getCacheFriendlyNumThreads() const BT_OVERRIDE { return m_numThreads + 1; }
// TODO: detect if CPU has hyperthreading enabled
virtual int getLogicalToPhysicalCoreRatio() const BT_OVERRIDE { return 1; }
virtual void runTask( int threadIndex, void* userData ) BT_OVERRIDE;
virtual void waitForAllTasks() BT_OVERRIDE;
virtual void runTask(int threadIndex, void* userData) BT_OVERRIDE;
virtual void waitForAllTasks() BT_OVERRIDE;
virtual btCriticalSection* createCriticalSection() BT_OVERRIDE;
virtual void deleteCriticalSection( btCriticalSection* criticalSection ) BT_OVERRIDE;
virtual btCriticalSection* createCriticalSection() BT_OVERRIDE;
virtual void deleteCriticalSection(btCriticalSection* criticalSection) BT_OVERRIDE;
};
#define checkPThreadFunction(returnValue) \
if(0 != returnValue) { \
printf("PThread problem at line %i in file %s: %i %d\n", __LINE__, __FILE__, returnValue, errno); \
}
#define checkPThreadFunction(returnValue) \
if (0 != returnValue) \
{ \
printf("PThread problem at line %i in file %s: %i %d\n", __LINE__, __FILE__, returnValue, errno); \
}
// The number of threads should be equal to the number of available cores
// Todo: each worker should be linked to a single core, using SetThreadIdealProcessor.
btThreadSupportPosix::btThreadSupportPosix( const ConstructionInfo& threadConstructionInfo )
btThreadSupportPosix::btThreadSupportPosix(const ConstructionInfo& threadConstructionInfo)
{
startThreads( threadConstructionInfo );
startThreads(threadConstructionInfo);
}
// cleanup/shutdown Libspe2
btThreadSupportPosix::~btThreadSupportPosix()
{
stopThreads();
stopThreads();
}
#if (defined (__APPLE__))
#if (defined(__APPLE__))
#define NAMED_SEMAPHORES
#endif
static sem_t* createSem( const char* baseName )
static sem_t* createSem(const char* baseName)
{
static int semCount = 0;
static int semCount = 0;
#ifdef NAMED_SEMAPHORES
/// Named semaphore begin
char name[ 32 ];
snprintf( name, 32, "/%8.s-%4.d-%4.4d", baseName, getpid(), semCount++ );
sem_t* tempSem = sem_open( name, O_CREAT, 0600, 0 );
/// Named semaphore begin
char name[32];
snprintf(name, 32, "/%8.s-%4.d-%4.4d", baseName, getpid(), semCount++);
sem_t* tempSem = sem_open(name, O_CREAT, 0600, 0);
if ( tempSem != reinterpret_cast<sem_t *>( SEM_FAILED ) )
{
// printf("Created \"%s\" Semaphore %p\n", name, tempSem);
}
else
{
//printf("Error creating Semaphore %d\n", errno);
exit( -1 );
}
/// Named semaphore end
if (tempSem != reinterpret_cast<sem_t*>(SEM_FAILED))
{
// printf("Created \"%s\" Semaphore %p\n", name, tempSem);
}
else
{
//printf("Error creating Semaphore %d\n", errno);
exit(-1);
}
/// Named semaphore end
#else
sem_t* tempSem = new sem_t;
checkPThreadFunction( sem_init( tempSem, 0, 0 ) );
sem_t* tempSem = new sem_t;
checkPThreadFunction(sem_init(tempSem, 0, 0));
#endif
return tempSem;
return tempSem;
}
static void destroySem( sem_t* semaphore )
static void destroySem(sem_t* semaphore)
{
#ifdef NAMED_SEMAPHORES
checkPThreadFunction( sem_close( semaphore ) );
checkPThreadFunction(sem_close(semaphore));
#else
checkPThreadFunction( sem_destroy( semaphore ) );
delete semaphore;
checkPThreadFunction(sem_destroy(semaphore));
delete semaphore;
#endif
}
static void *threadFunction( void *argument )
static void* threadFunction(void* argument)
{
btThreadSupportPosix::btThreadStatus* status = ( btThreadSupportPosix::btThreadStatus* )argument;
btThreadSupportPosix::btThreadStatus* status = (btThreadSupportPosix::btThreadStatus*)argument;
while ( 1 )
{
checkPThreadFunction( sem_wait( status->startSemaphore ) );
void* userPtr = status->m_userPtr;
while (1)
{
checkPThreadFunction(sem_wait(status->startSemaphore));
void* userPtr = status->m_userPtr;
if ( userPtr )
{
btAssert( status->m_status );
status->m_userThreadFunc( userPtr );
status->m_status = 2;
checkPThreadFunction( sem_post( status->m_mainSemaphore ) );
status->threadUsed++;
}
else
{
//exit Thread
status->m_status = 3;
checkPThreadFunction( sem_post( status->m_mainSemaphore ) );
printf( "Thread with taskId %i exiting\n", status->m_taskId );
break;
}
}
if (userPtr)
{
btAssert(status->m_status);
status->m_userThreadFunc(userPtr);
status->m_status = 2;
checkPThreadFunction(sem_post(status->m_mainSemaphore));
status->threadUsed++;
}
else
{
//exit Thread
status->m_status = 3;
checkPThreadFunction(sem_post(status->m_mainSemaphore));
printf("Thread with taskId %i exiting\n", status->m_taskId);
break;
}
}
printf( "Thread TERMINATED\n" );
return 0;
printf("Thread TERMINATED\n");
return 0;
}
///send messages to SPUs
void btThreadSupportPosix::runTask( int threadIndex, void* userData )
void btThreadSupportPosix::runTask(int threadIndex, void* userData)
{
///we should spawn an SPU task here, and in 'waitForResponse' it should wait for response of the (one of) the first tasks that finished
btThreadStatus& threadStatus = m_activeThreadStatus[ threadIndex ];
btAssert( threadIndex >= 0 );
btAssert( threadIndex < m_activeThreadStatus.size() );
///we should spawn an SPU task here, and in 'waitForResponse' it should wait for response of the (one of) the first tasks that finished
btThreadStatus& threadStatus = m_activeThreadStatus[threadIndex];
btAssert(threadIndex >= 0);
btAssert(threadIndex < m_activeThreadStatus.size());
threadStatus.m_commandId = 1;
threadStatus.m_status = 1;
threadStatus.m_userPtr = userData;
m_startedThreadsMask |= UINT64( 1 ) << threadIndex;
threadStatus.m_commandId = 1;
threadStatus.m_status = 1;
threadStatus.m_userPtr = userData;
m_startedThreadsMask |= UINT64(1) << threadIndex;
// fire event to start new task
checkPThreadFunction( sem_post( threadStatus.startSemaphore ) );
// fire event to start new task
checkPThreadFunction(sem_post(threadStatus.startSemaphore));
}
///check for messages from SPUs
int btThreadSupportPosix::waitForResponse()
{
///We should wait for (one of) the first tasks to finish (or other SPU messages), and report its response
///A possible response can be 'yes, SPU handled it', or 'no, please do a PPU fallback'
///We should wait for (one of) the first tasks to finish (or other SPU messages), and report its response
///A possible response can be 'yes, SPU handled it', or 'no, please do a PPU fallback'
btAssert( m_activeThreadStatus.size() );
btAssert(m_activeThreadStatus.size());
// wait for any of the threads to finish
checkPThreadFunction( sem_wait( m_mainSemaphore ) );
// get at least one thread which has finished
size_t last = -1;
// wait for any of the threads to finish
checkPThreadFunction(sem_wait(m_mainSemaphore));
// get at least one thread which has finished
size_t last = -1;
for ( size_t t = 0; t < size_t( m_activeThreadStatus.size() ); ++t )
{
if ( 2 == m_activeThreadStatus[ t ].m_status )
{
last = t;
break;
}
}
for (size_t t = 0; t < size_t(m_activeThreadStatus.size()); ++t)
{
if (2 == m_activeThreadStatus[t].m_status)
{
last = t;
break;
}
}
btThreadStatus& threadStatus = m_activeThreadStatus[ last ];
btThreadStatus& threadStatus = m_activeThreadStatus[last];
btAssert( threadStatus.m_status > 1 );
threadStatus.m_status = 0;
btAssert(threadStatus.m_status > 1);
threadStatus.m_status = 0;
// need to find an active spu
btAssert( last >= 0 );
m_startedThreadsMask &= ~( UINT64( 1 ) << last );
// need to find an active spu
btAssert(last >= 0);
m_startedThreadsMask &= ~(UINT64(1) << last);
return last;
return last;
}
void btThreadSupportPosix::waitForAllTasks()
{
while ( m_startedThreadsMask )
{
waitForResponse();
}
while (m_startedThreadsMask)
{
waitForResponse();
}
}
void btThreadSupportPosix::startThreads( const ConstructionInfo& threadConstructionInfo )
void btThreadSupportPosix::startThreads(const ConstructionInfo& threadConstructionInfo)
{
m_numThreads = btGetNumHardwareThreads() - 1; // main thread exists already
printf( "%s creating %i threads.\n", __FUNCTION__, m_numThreads );
m_activeThreadStatus.resize( m_numThreads );
m_startedThreadsMask = 0;
m_numThreads = btGetNumHardwareThreads() - 1; // main thread exists already
printf("%s creating %i threads.\n", __FUNCTION__, m_numThreads);
m_activeThreadStatus.resize(m_numThreads);
m_startedThreadsMask = 0;
m_mainSemaphore = createSem( "main" );
//checkPThreadFunction(sem_wait(mainSemaphore));
m_mainSemaphore = createSem("main");
//checkPThreadFunction(sem_wait(mainSemaphore));
for ( int i = 0; i < m_numThreads; i++ )
{
printf( "starting thread %d\n", i );
btThreadStatus& threadStatus = m_activeThreadStatus[ i ];
threadStatus.startSemaphore = createSem( "threadLocal" );
checkPThreadFunction( pthread_create( &threadStatus.thread, NULL, &threadFunction, (void*) &threadStatus ) );
for (int i = 0; i < m_numThreads; i++)
{
printf("starting thread %d\n", i);
btThreadStatus& threadStatus = m_activeThreadStatus[i];
threadStatus.startSemaphore = createSem("threadLocal");
checkPThreadFunction(pthread_create(&threadStatus.thread, NULL, &threadFunction, (void*)&threadStatus));
threadStatus.m_userPtr = 0;
threadStatus.m_taskId = i;
threadStatus.m_commandId = 0;
threadStatus.m_status = 0;
threadStatus.m_mainSemaphore = m_mainSemaphore;
threadStatus.m_userThreadFunc = threadConstructionInfo.m_userThreadFunc;
threadStatus.threadUsed = 0;
threadStatus.m_userPtr = 0;
threadStatus.m_taskId = i;
threadStatus.m_commandId = 0;
threadStatus.m_status = 0;
threadStatus.m_mainSemaphore = m_mainSemaphore;
threadStatus.m_userThreadFunc = threadConstructionInfo.m_userThreadFunc;
threadStatus.threadUsed = 0;
printf( "started thread %d \n", i );
}
printf("started thread %d \n", i);
}
}
///tell the task scheduler we are done with the SPU tasks
void btThreadSupportPosix::stopThreads()
{
for ( size_t t = 0; t < size_t( m_activeThreadStatus.size() ); ++t )
{
btThreadStatus& threadStatus = m_activeThreadStatus[ t ];
printf( "%s: Thread %i used: %ld\n", __FUNCTION__, int( t ), threadStatus.threadUsed );
for (size_t t = 0; t < size_t(m_activeThreadStatus.size()); ++t)
{
btThreadStatus& threadStatus = m_activeThreadStatus[t];
printf("%s: Thread %i used: %ld\n", __FUNCTION__, int(t), threadStatus.threadUsed);
threadStatus.m_userPtr = 0;
checkPThreadFunction( sem_post( threadStatus.startSemaphore ) );
checkPThreadFunction( sem_wait( m_mainSemaphore ) );
threadStatus.m_userPtr = 0;
checkPThreadFunction(sem_post(threadStatus.startSemaphore));
checkPThreadFunction(sem_wait(m_mainSemaphore));
printf( "destroy semaphore\n" );
destroySem( threadStatus.startSemaphore );
printf( "semaphore destroyed\n" );
checkPThreadFunction( pthread_join( threadStatus.thread, 0 ) );
}
printf( "destroy main semaphore\n" );
destroySem( m_mainSemaphore );
printf( "main semaphore destroyed\n" );
m_activeThreadStatus.clear();
printf("destroy semaphore\n");
destroySem(threadStatus.startSemaphore);
printf("semaphore destroyed\n");
checkPThreadFunction(pthread_join(threadStatus.thread, 0));
}
printf("destroy main semaphore\n");
destroySem(m_mainSemaphore);
printf("main semaphore destroyed\n");
m_activeThreadStatus.clear();
}
class btCriticalSectionPosix : public btCriticalSection
{
pthread_mutex_t m_mutex;
pthread_mutex_t m_mutex;
public:
btCriticalSectionPosix()
{
pthread_mutex_init( &m_mutex, NULL );
}
virtual ~btCriticalSectionPosix()
{
pthread_mutex_destroy( &m_mutex );
}
btCriticalSectionPosix()
{
pthread_mutex_init(&m_mutex, NULL);
}
virtual ~btCriticalSectionPosix()
{
pthread_mutex_destroy(&m_mutex);
}
virtual void lock()
{
pthread_mutex_lock( &m_mutex );
}
virtual void unlock()
{
pthread_mutex_unlock( &m_mutex );
}
virtual void lock()
{
pthread_mutex_lock(&m_mutex);
}
virtual void unlock()
{
pthread_mutex_unlock(&m_mutex);
}
};
btCriticalSection* btThreadSupportPosix::createCriticalSection()
{
return new btCriticalSectionPosix();
return new btCriticalSectionPosix();
}
void btThreadSupportPosix::deleteCriticalSection( btCriticalSection* cs )
void btThreadSupportPosix::deleteCriticalSection(btCriticalSection* cs)
{
delete cs;
delete cs;
}
btThreadSupportInterface* btThreadSupportInterface::create( const ConstructionInfo& info )
btThreadSupportInterface* btThreadSupportInterface::create(const ConstructionInfo& info)
{
return new btThreadSupportPosix( info );
return new btThreadSupportPosix(info);
}
#endif // BT_THREADSAFE && !defined( _WIN32 )
#endif // BT_THREADSAFE && !defined( _WIN32 )

View File

@@ -13,7 +13,7 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#if defined( _WIN32 ) && BT_THREADSAFE
#if defined(_WIN32) && BT_THREADSAFE
#include "LinearMath/btScalar.h"
#include "LinearMath/btMinMax.h"
@@ -23,450 +23,430 @@ subject to the following restrictions:
#include <windows.h>
#include <stdio.h>
struct btProcessorInfo
{
int numLogicalProcessors;
int numCores;
int numNumaNodes;
int numL1Cache;
int numL2Cache;
int numL3Cache;
int numPhysicalPackages;
static const int maxNumTeamMasks = 32;
int numTeamMasks;
UINT64 processorTeamMasks[ maxNumTeamMasks ];
int numLogicalProcessors;
int numCores;
int numNumaNodes;
int numL1Cache;
int numL2Cache;
int numL3Cache;
int numPhysicalPackages;
static const int maxNumTeamMasks = 32;
int numTeamMasks;
UINT64 processorTeamMasks[maxNumTeamMasks];
};
UINT64 getProcessorTeamMask( const btProcessorInfo& procInfo, int procId )
UINT64 getProcessorTeamMask(const btProcessorInfo& procInfo, int procId)
{
UINT64 procMask = UINT64( 1 ) << procId;
for ( int i = 0; i < procInfo.numTeamMasks; ++i )
{
if ( procMask & procInfo.processorTeamMasks[ i ] )
{
return procInfo.processorTeamMasks[ i ];
}
}
return 0;
UINT64 procMask = UINT64(1) << procId;
for (int i = 0; i < procInfo.numTeamMasks; ++i)
{
if (procMask & procInfo.processorTeamMasks[i])
{
return procInfo.processorTeamMasks[i];
}
}
return 0;
}
int getProcessorTeamIndex( const btProcessorInfo& procInfo, int procId )
int getProcessorTeamIndex(const btProcessorInfo& procInfo, int procId)
{
UINT64 procMask = UINT64( 1 ) << procId;
for ( int i = 0; i < procInfo.numTeamMasks; ++i )
{
if ( procMask & procInfo.processorTeamMasks[ i ] )
{
return i;
}
}
return -1;
UINT64 procMask = UINT64(1) << procId;
for (int i = 0; i < procInfo.numTeamMasks; ++i)
{
if (procMask & procInfo.processorTeamMasks[i])
{
return i;
}
}
return -1;
}
int countSetBits( ULONG64 bits )
int countSetBits(ULONG64 bits)
{
int count = 0;
while ( bits )
{
if ( bits & 1 )
{
count++;
}
bits >>= 1;
}
return count;
int count = 0;
while (bits)
{
if (bits & 1)
{
count++;
}
bits >>= 1;
}
return count;
}
typedef BOOL(WINAPI* Pfn_GetLogicalProcessorInformation)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD);
typedef BOOL( WINAPI *Pfn_GetLogicalProcessorInformation )( PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD );
void getProcessorInformation( btProcessorInfo* procInfo )
void getProcessorInformation(btProcessorInfo* procInfo)
{
memset( procInfo, 0, sizeof( *procInfo ) );
Pfn_GetLogicalProcessorInformation getLogicalProcInfo =
(Pfn_GetLogicalProcessorInformation) GetProcAddress( GetModuleHandle( TEXT( "kernel32" ) ), "GetLogicalProcessorInformation" );
if ( getLogicalProcInfo == NULL )
{
// no info
return;
}
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buf = NULL;
DWORD bufSize = 0;
while ( true )
{
if ( getLogicalProcInfo( buf, &bufSize ) )
{
break;
}
else
{
if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER )
{
if ( buf )
{
free( buf );
}
buf = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION) malloc( bufSize );
}
}
}
memset(procInfo, 0, sizeof(*procInfo));
Pfn_GetLogicalProcessorInformation getLogicalProcInfo =
(Pfn_GetLogicalProcessorInformation)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "GetLogicalProcessorInformation");
if (getLogicalProcInfo == NULL)
{
// no info
return;
}
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buf = NULL;
DWORD bufSize = 0;
while (true)
{
if (getLogicalProcInfo(buf, &bufSize))
{
break;
}
else
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
if (buf)
{
free(buf);
}
buf = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)malloc(bufSize);
}
}
}
int len = bufSize / sizeof( *buf );
for ( int i = 0; i < len; ++i )
{
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION info = buf + i;
switch ( info->Relationship )
{
case RelationNumaNode:
procInfo->numNumaNodes++;
break;
int len = bufSize / sizeof(*buf);
for (int i = 0; i < len; ++i)
{
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION info = buf + i;
switch (info->Relationship)
{
case RelationNumaNode:
procInfo->numNumaNodes++;
break;
case RelationProcessorCore:
procInfo->numCores++;
procInfo->numLogicalProcessors += countSetBits( info->ProcessorMask );
break;
case RelationProcessorCore:
procInfo->numCores++;
procInfo->numLogicalProcessors += countSetBits(info->ProcessorMask);
break;
case RelationCache:
if ( info->Cache.Level == 1 )
{
procInfo->numL1Cache++;
}
else if ( info->Cache.Level == 2 )
{
procInfo->numL2Cache++;
}
else if ( info->Cache.Level == 3 )
{
procInfo->numL3Cache++;
// processors that share L3 cache are considered to be on the same team
// because they can more easily work together on the same data.
// Large performance penalties will occur if 2 or more threads from different
// teams attempt to frequently read and modify the same cache lines.
//
// On the AMD Ryzen 7 CPU for example, the 8 cores on the CPU are split into
// 2 CCX units of 4 cores each. Each CCX has a separate L3 cache, so if both
// CCXs are operating on the same data, many cycles will be spent keeping the
// two caches coherent.
if ( procInfo->numTeamMasks < btProcessorInfo::maxNumTeamMasks )
{
procInfo->processorTeamMasks[ procInfo->numTeamMasks ] = info->ProcessorMask;
procInfo->numTeamMasks++;
}
}
break;
case RelationCache:
if (info->Cache.Level == 1)
{
procInfo->numL1Cache++;
}
else if (info->Cache.Level == 2)
{
procInfo->numL2Cache++;
}
else if (info->Cache.Level == 3)
{
procInfo->numL3Cache++;
// processors that share L3 cache are considered to be on the same team
// because they can more easily work together on the same data.
// Large performance penalties will occur if 2 or more threads from different
// teams attempt to frequently read and modify the same cache lines.
//
// On the AMD Ryzen 7 CPU for example, the 8 cores on the CPU are split into
// 2 CCX units of 4 cores each. Each CCX has a separate L3 cache, so if both
// CCXs are operating on the same data, many cycles will be spent keeping the
// two caches coherent.
if (procInfo->numTeamMasks < btProcessorInfo::maxNumTeamMasks)
{
procInfo->processorTeamMasks[procInfo->numTeamMasks] = info->ProcessorMask;
procInfo->numTeamMasks++;
}
}
break;
case RelationProcessorPackage:
procInfo->numPhysicalPackages++;
break;
}
}
free( buf );
case RelationProcessorPackage:
procInfo->numPhysicalPackages++;
break;
}
}
free(buf);
}
///btThreadSupportWin32 helps to initialize/shutdown libspe2, start/stop SPU tasks and communication
class btThreadSupportWin32 : public btThreadSupportInterface
{
public:
struct btThreadStatus
{
int m_taskId;
int m_commandId;
int m_status;
struct btThreadStatus
{
int m_taskId;
int m_commandId;
int m_status;
ThreadFunc m_userThreadFunc;
void* m_userPtr; //for taskDesc etc
ThreadFunc m_userThreadFunc;
void* m_userPtr; //for taskDesc etc
void* m_threadHandle; //this one is calling 'Win32ThreadFunc'
void* m_threadHandle; //this one is calling 'Win32ThreadFunc'
void* m_eventStartHandle;
char m_eventStartHandleName[ 32 ];
void* m_eventStartHandle;
char m_eventStartHandleName[32];
void* m_eventCompleteHandle;
char m_eventCompleteHandleName[ 32 ];
};
void* m_eventCompleteHandle;
char m_eventCompleteHandleName[32];
};
private:
btAlignedObjectArray<btThreadStatus> m_activeThreadStatus;
btAlignedObjectArray<void*> m_completeHandles;
int m_numThreads;
DWORD_PTR m_startedThreadMask;
btProcessorInfo m_processorInfo;
btAlignedObjectArray<btThreadStatus> m_activeThreadStatus;
btAlignedObjectArray<void*> m_completeHandles;
int m_numThreads;
DWORD_PTR m_startedThreadMask;
btProcessorInfo m_processorInfo;
void startThreads( const ConstructionInfo& threadInfo );
void stopThreads();
int waitForResponse();
void startThreads(const ConstructionInfo& threadInfo);
void stopThreads();
int waitForResponse();
public:
btThreadSupportWin32(const ConstructionInfo& threadConstructionInfo);
virtual ~btThreadSupportWin32();
btThreadSupportWin32( const ConstructionInfo& threadConstructionInfo );
virtual ~btThreadSupportWin32();
virtual int getNumWorkerThreads() const BT_OVERRIDE { return m_numThreads; }
virtual int getCacheFriendlyNumThreads() const BT_OVERRIDE { return countSetBits(m_processorInfo.processorTeamMasks[0]); }
virtual int getLogicalToPhysicalCoreRatio() const BT_OVERRIDE { return m_processorInfo.numLogicalProcessors / m_processorInfo.numCores; }
virtual int getNumWorkerThreads() const BT_OVERRIDE { return m_numThreads; }
virtual int getCacheFriendlyNumThreads() const BT_OVERRIDE { return countSetBits(m_processorInfo.processorTeamMasks[0]); }
virtual int getLogicalToPhysicalCoreRatio() const BT_OVERRIDE { return m_processorInfo.numLogicalProcessors / m_processorInfo.numCores; }
virtual void runTask(int threadIndex, void* userData) BT_OVERRIDE;
virtual void waitForAllTasks() BT_OVERRIDE;
virtual void runTask( int threadIndex, void* userData ) BT_OVERRIDE;
virtual void waitForAllTasks() BT_OVERRIDE;
virtual btCriticalSection* createCriticalSection() BT_OVERRIDE;
virtual void deleteCriticalSection( btCriticalSection* criticalSection ) BT_OVERRIDE;
virtual btCriticalSection* createCriticalSection() BT_OVERRIDE;
virtual void deleteCriticalSection(btCriticalSection* criticalSection) BT_OVERRIDE;
};
btThreadSupportWin32::btThreadSupportWin32( const ConstructionInfo & threadConstructionInfo )
btThreadSupportWin32::btThreadSupportWin32(const ConstructionInfo& threadConstructionInfo)
{
startThreads( threadConstructionInfo );
startThreads(threadConstructionInfo);
}
btThreadSupportWin32::~btThreadSupportWin32()
{
stopThreads();
stopThreads();
}
DWORD WINAPI win32threadStartFunc( LPVOID lpParam )
DWORD WINAPI win32threadStartFunc(LPVOID lpParam)
{
btThreadSupportWin32::btThreadStatus* status = ( btThreadSupportWin32::btThreadStatus* )lpParam;
btThreadSupportWin32::btThreadStatus* status = (btThreadSupportWin32::btThreadStatus*)lpParam;
while ( 1 )
{
WaitForSingleObject( status->m_eventStartHandle, INFINITE );
void* userPtr = status->m_userPtr;
while (1)
{
WaitForSingleObject(status->m_eventStartHandle, INFINITE);
void* userPtr = status->m_userPtr;
if ( userPtr )
{
btAssert( status->m_status );
status->m_userThreadFunc( userPtr );
status->m_status = 2;
SetEvent( status->m_eventCompleteHandle );
}
else
{
//exit Thread
status->m_status = 3;
printf( "Thread with taskId %i with handle %p exiting\n", status->m_taskId, status->m_threadHandle );
SetEvent( status->m_eventCompleteHandle );
break;
}
}
printf( "Thread TERMINATED\n" );
return 0;
if (userPtr)
{
btAssert(status->m_status);
status->m_userThreadFunc(userPtr);
status->m_status = 2;
SetEvent(status->m_eventCompleteHandle);
}
else
{
//exit Thread
status->m_status = 3;
printf("Thread with taskId %i with handle %p exiting\n", status->m_taskId, status->m_threadHandle);
SetEvent(status->m_eventCompleteHandle);
break;
}
}
printf("Thread TERMINATED\n");
return 0;
}
void btThreadSupportWin32::runTask( int threadIndex, void* userData )
void btThreadSupportWin32::runTask(int threadIndex, void* userData)
{
btThreadStatus& threadStatus = m_activeThreadStatus[ threadIndex ];
btAssert( threadIndex >= 0 );
btAssert( int( threadIndex ) < m_activeThreadStatus.size() );
btThreadStatus& threadStatus = m_activeThreadStatus[threadIndex];
btAssert(threadIndex >= 0);
btAssert(int(threadIndex) < m_activeThreadStatus.size());
threadStatus.m_commandId = 1;
threadStatus.m_status = 1;
threadStatus.m_userPtr = userData;
m_startedThreadMask |= DWORD_PTR( 1 ) << threadIndex;
threadStatus.m_commandId = 1;
threadStatus.m_status = 1;
threadStatus.m_userPtr = userData;
m_startedThreadMask |= DWORD_PTR(1) << threadIndex;
///fire event to start new task
SetEvent( threadStatus.m_eventStartHandle );
///fire event to start new task
SetEvent(threadStatus.m_eventStartHandle);
}
int btThreadSupportWin32::waitForResponse()
{
btAssert( m_activeThreadStatus.size() );
btAssert(m_activeThreadStatus.size());
int last = -1;
DWORD res = WaitForMultipleObjects( m_completeHandles.size(), &m_completeHandles[ 0 ], FALSE, INFINITE );
btAssert( res != WAIT_FAILED );
last = res - WAIT_OBJECT_0;
int last = -1;
DWORD res = WaitForMultipleObjects(m_completeHandles.size(), &m_completeHandles[0], FALSE, INFINITE);
btAssert(res != WAIT_FAILED);
last = res - WAIT_OBJECT_0;
btThreadStatus& threadStatus = m_activeThreadStatus[ last ];
btAssert( threadStatus.m_threadHandle );
btAssert( threadStatus.m_eventCompleteHandle );
btThreadStatus& threadStatus = m_activeThreadStatus[last];
btAssert(threadStatus.m_threadHandle);
btAssert(threadStatus.m_eventCompleteHandle);
//WaitForSingleObject(threadStatus.m_eventCompleteHandle, INFINITE);
btAssert( threadStatus.m_status > 1 );
threadStatus.m_status = 0;
//WaitForSingleObject(threadStatus.m_eventCompleteHandle, INFINITE);
btAssert(threadStatus.m_status > 1);
threadStatus.m_status = 0;
///need to find an active spu
btAssert( last >= 0 );
m_startedThreadMask &= ~( DWORD_PTR( 1 ) << last );
///need to find an active spu
btAssert(last >= 0);
m_startedThreadMask &= ~(DWORD_PTR(1) << last);
return last;
return last;
}
void btThreadSupportWin32::waitForAllTasks()
{
while ( m_startedThreadMask )
{
waitForResponse();
}
while (m_startedThreadMask)
{
waitForResponse();
}
}
void btThreadSupportWin32::startThreads( const ConstructionInfo& threadConstructionInfo )
void btThreadSupportWin32::startThreads(const ConstructionInfo& threadConstructionInfo)
{
static int uniqueId = 0;
uniqueId++;
btProcessorInfo& procInfo = m_processorInfo;
getProcessorInformation( &procInfo );
DWORD_PTR dwProcessAffinityMask = 0;
DWORD_PTR dwSystemAffinityMask = 0;
if ( !GetProcessAffinityMask( GetCurrentProcess(), &dwProcessAffinityMask, &dwSystemAffinityMask ) )
{
dwProcessAffinityMask = 0;
}
///The number of threads should be equal to the number of available cores - 1
m_numThreads = btMin(procInfo.numLogicalProcessors, int(BT_MAX_THREAD_COUNT)) - 1; // cap to max thread count (-1 because main thread already exists)
static int uniqueId = 0;
uniqueId++;
btProcessorInfo& procInfo = m_processorInfo;
getProcessorInformation(&procInfo);
DWORD_PTR dwProcessAffinityMask = 0;
DWORD_PTR dwSystemAffinityMask = 0;
if (!GetProcessAffinityMask(GetCurrentProcess(), &dwProcessAffinityMask, &dwSystemAffinityMask))
{
dwProcessAffinityMask = 0;
}
///The number of threads should be equal to the number of available cores - 1
m_numThreads = btMin(procInfo.numLogicalProcessors, int(BT_MAX_THREAD_COUNT)) - 1; // cap to max thread count (-1 because main thread already exists)
m_activeThreadStatus.resize( m_numThreads );
m_completeHandles.resize( m_numThreads );
m_startedThreadMask = 0;
m_activeThreadStatus.resize(m_numThreads);
m_completeHandles.resize(m_numThreads);
m_startedThreadMask = 0;
// set main thread affinity
if ( DWORD_PTR mask = dwProcessAffinityMask & getProcessorTeamMask( procInfo, 0 ))
{
SetThreadAffinityMask( GetCurrentThread(), mask );
SetThreadIdealProcessor( GetCurrentThread(), 0 );
}
// set main thread affinity
if (DWORD_PTR mask = dwProcessAffinityMask & getProcessorTeamMask(procInfo, 0))
{
SetThreadAffinityMask(GetCurrentThread(), mask);
SetThreadIdealProcessor(GetCurrentThread(), 0);
}
for ( int i = 0; i < m_numThreads; i++ )
{
printf( "starting thread %d\n", i );
for (int i = 0; i < m_numThreads; i++)
{
printf("starting thread %d\n", i);
btThreadStatus& threadStatus = m_activeThreadStatus[ i ];
btThreadStatus& threadStatus = m_activeThreadStatus[i];
LPSECURITY_ATTRIBUTES lpThreadAttributes = NULL;
SIZE_T dwStackSize = threadConstructionInfo.m_threadStackSize;
LPTHREAD_START_ROUTINE lpStartAddress = &win32threadStartFunc;
LPVOID lpParameter = &threadStatus;
DWORD dwCreationFlags = 0;
LPDWORD lpThreadId = 0;
LPSECURITY_ATTRIBUTES lpThreadAttributes = NULL;
SIZE_T dwStackSize = threadConstructionInfo.m_threadStackSize;
LPTHREAD_START_ROUTINE lpStartAddress = &win32threadStartFunc;
LPVOID lpParameter = &threadStatus;
DWORD dwCreationFlags = 0;
LPDWORD lpThreadId = 0;
threadStatus.m_userPtr = 0;
threadStatus.m_userPtr = 0;
sprintf( threadStatus.m_eventStartHandleName, "es%.8s%d%d", threadConstructionInfo.m_uniqueName, uniqueId, i );
threadStatus.m_eventStartHandle = CreateEventA( 0, false, false, threadStatus.m_eventStartHandleName );
sprintf(threadStatus.m_eventStartHandleName, "es%.8s%d%d", threadConstructionInfo.m_uniqueName, uniqueId, i);
threadStatus.m_eventStartHandle = CreateEventA(0, false, false, threadStatus.m_eventStartHandleName);
sprintf( threadStatus.m_eventCompleteHandleName, "ec%.8s%d%d", threadConstructionInfo.m_uniqueName, uniqueId, i );
threadStatus.m_eventCompleteHandle = CreateEventA( 0, false, false, threadStatus.m_eventCompleteHandleName );
sprintf(threadStatus.m_eventCompleteHandleName, "ec%.8s%d%d", threadConstructionInfo.m_uniqueName, uniqueId, i);
threadStatus.m_eventCompleteHandle = CreateEventA(0, false, false, threadStatus.m_eventCompleteHandleName);
m_completeHandles[ i ] = threadStatus.m_eventCompleteHandle;
m_completeHandles[i] = threadStatus.m_eventCompleteHandle;
HANDLE handle = CreateThread( lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags, lpThreadId );
//SetThreadPriority( handle, THREAD_PRIORITY_HIGHEST );
// highest priority -- can cause erratic performance when numThreads > numCores
// we don't want worker threads to be higher priority than the main thread or the main thread could get
// totally shut out and unable to tell the workers to stop
//SetThreadPriority( handle, THREAD_PRIORITY_BELOW_NORMAL );
HANDLE handle = CreateThread(lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags, lpThreadId);
//SetThreadPriority( handle, THREAD_PRIORITY_HIGHEST );
// highest priority -- can cause erratic performance when numThreads > numCores
// we don't want worker threads to be higher priority than the main thread or the main thread could get
// totally shut out and unable to tell the workers to stop
//SetThreadPriority( handle, THREAD_PRIORITY_BELOW_NORMAL );
{
int processorId = i + 1; // leave processor 0 for main thread
DWORD_PTR teamMask = getProcessorTeamMask( procInfo, processorId );
if ( teamMask )
{
// bind each thread to only execute on processors of it's assigned team
// - for single-socket Intel x86 CPUs this has no effect (only a single, shared L3 cache so there is only 1 team)
// - for multi-socket Intel this will keep threads from migrating from one socket to another
// - for AMD Ryzen this will keep threads from migrating from one CCX to another
DWORD_PTR mask = teamMask & dwProcessAffinityMask;
if ( mask )
{
SetThreadAffinityMask( handle, mask );
}
}
SetThreadIdealProcessor( handle, processorId );
}
{
int processorId = i + 1; // leave processor 0 for main thread
DWORD_PTR teamMask = getProcessorTeamMask(procInfo, processorId);
if (teamMask)
{
// bind each thread to only execute on processors of it's assigned team
// - for single-socket Intel x86 CPUs this has no effect (only a single, shared L3 cache so there is only 1 team)
// - for multi-socket Intel this will keep threads from migrating from one socket to another
// - for AMD Ryzen this will keep threads from migrating from one CCX to another
DWORD_PTR mask = teamMask & dwProcessAffinityMask;
if (mask)
{
SetThreadAffinityMask(handle, mask);
}
}
SetThreadIdealProcessor(handle, processorId);
}
threadStatus.m_taskId = i;
threadStatus.m_commandId = 0;
threadStatus.m_status = 0;
threadStatus.m_threadHandle = handle;
threadStatus.m_userThreadFunc = threadConstructionInfo.m_userThreadFunc;
threadStatus.m_taskId = i;
threadStatus.m_commandId = 0;
threadStatus.m_status = 0;
threadStatus.m_threadHandle = handle;
threadStatus.m_userThreadFunc = threadConstructionInfo.m_userThreadFunc;
printf( "started %s thread %d with threadHandle %p\n", threadConstructionInfo.m_uniqueName, i, handle );
}
printf("started %s thread %d with threadHandle %p\n", threadConstructionInfo.m_uniqueName, i, handle);
}
}
///tell the task scheduler we are done with the SPU tasks
void btThreadSupportWin32::stopThreads()
{
for ( int i = 0; i < m_activeThreadStatus.size(); i++ )
{
btThreadStatus& threadStatus = m_activeThreadStatus[ i ];
if ( threadStatus.m_status > 0 )
{
WaitForSingleObject( threadStatus.m_eventCompleteHandle, INFINITE );
}
for (int i = 0; i < m_activeThreadStatus.size(); i++)
{
btThreadStatus& threadStatus = m_activeThreadStatus[i];
if (threadStatus.m_status > 0)
{
WaitForSingleObject(threadStatus.m_eventCompleteHandle, INFINITE);
}
threadStatus.m_userPtr = NULL;
SetEvent( threadStatus.m_eventStartHandle );
WaitForSingleObject( threadStatus.m_eventCompleteHandle, INFINITE );
threadStatus.m_userPtr = NULL;
SetEvent(threadStatus.m_eventStartHandle);
WaitForSingleObject(threadStatus.m_eventCompleteHandle, INFINITE);
CloseHandle( threadStatus.m_eventCompleteHandle );
CloseHandle( threadStatus.m_eventStartHandle );
CloseHandle( threadStatus.m_threadHandle );
CloseHandle(threadStatus.m_eventCompleteHandle);
CloseHandle(threadStatus.m_eventStartHandle);
CloseHandle(threadStatus.m_threadHandle);
}
}
m_activeThreadStatus.clear();
m_completeHandles.clear();
m_activeThreadStatus.clear();
m_completeHandles.clear();
}
class btWin32CriticalSection : public btCriticalSection
{
private:
CRITICAL_SECTION mCriticalSection;
CRITICAL_SECTION mCriticalSection;
public:
btWin32CriticalSection()
{
InitializeCriticalSection( &mCriticalSection );
}
btWin32CriticalSection()
{
InitializeCriticalSection(&mCriticalSection);
}
~btWin32CriticalSection()
{
DeleteCriticalSection( &mCriticalSection );
}
~btWin32CriticalSection()
{
DeleteCriticalSection(&mCriticalSection);
}
void lock()
{
EnterCriticalSection( &mCriticalSection );
}
void lock()
{
EnterCriticalSection(&mCriticalSection);
}
void unlock()
{
LeaveCriticalSection( &mCriticalSection );
}
void unlock()
{
LeaveCriticalSection(&mCriticalSection);
}
};
btCriticalSection* btThreadSupportWin32::createCriticalSection()
{
unsigned char* mem = (unsigned char*) btAlignedAlloc( sizeof( btWin32CriticalSection ), 16 );
btWin32CriticalSection* cs = new( mem ) btWin32CriticalSection();
return cs;
unsigned char* mem = (unsigned char*)btAlignedAlloc(sizeof(btWin32CriticalSection), 16);
btWin32CriticalSection* cs = new (mem) btWin32CriticalSection();
return cs;
}
void btThreadSupportWin32::deleteCriticalSection( btCriticalSection* criticalSection )
void btThreadSupportWin32::deleteCriticalSection(btCriticalSection* criticalSection)
{
criticalSection->~btCriticalSection();
btAlignedFree( criticalSection );
criticalSection->~btCriticalSection();
btAlignedFree(criticalSection);
}
btThreadSupportInterface* btThreadSupportInterface::create( const ConstructionInfo& info )
btThreadSupportInterface* btThreadSupportInterface::create(const ConstructionInfo& info)
{
return new btThreadSupportWin32( info );
return new btThreadSupportWin32(info);
}
#endif //defined(_WIN32) && BT_THREADSAFE
#endif //defined(_WIN32) && BT_THREADSAFE

View File

@@ -12,8 +12,6 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BT_AABB_UTIL2
#define BT_AABB_UTIL2
@@ -21,20 +19,18 @@ subject to the following restrictions:
#include "btVector3.h"
#include "btMinMax.h"
SIMD_FORCE_INLINE void AabbExpand (btVector3& aabbMin,
btVector3& aabbMax,
const btVector3& expansionMin,
const btVector3& expansionMax)
SIMD_FORCE_INLINE void AabbExpand(btVector3& aabbMin,
btVector3& aabbMax,
const btVector3& expansionMin,
const btVector3& expansionMax)
{
aabbMin = aabbMin + expansionMin;
aabbMax = aabbMax + expansionMax;
}
/// conservative test for overlap between two aabbs
SIMD_FORCE_INLINE bool TestPointAgainstAabb2(const btVector3 &aabbMin1, const btVector3 &aabbMax1,
const btVector3 &point)
SIMD_FORCE_INLINE bool TestPointAgainstAabb2(const btVector3& aabbMin1, const btVector3& aabbMax1,
const btVector3& point)
{
bool overlap = true;
overlap = (aabbMin1.getX() > point.getX() || aabbMax1.getX() < point.getX()) ? false : overlap;
@@ -43,10 +39,9 @@ SIMD_FORCE_INLINE bool TestPointAgainstAabb2(const btVector3 &aabbMin1, const bt
return overlap;
}
/// conservative test for overlap between two aabbs
SIMD_FORCE_INLINE bool TestAabbAgainstAabb2(const btVector3 &aabbMin1, const btVector3 &aabbMax1,
const btVector3 &aabbMin2, const btVector3 &aabbMax2)
SIMD_FORCE_INLINE bool TestAabbAgainstAabb2(const btVector3& aabbMin1, const btVector3& aabbMax1,
const btVector3& aabbMin2, const btVector3& aabbMax2)
{
bool overlap = true;
overlap = (aabbMin1.getX() > aabbMax2.getX() || aabbMax1.getX() < aabbMin2.getX()) ? false : overlap;
@@ -56,37 +51,34 @@ SIMD_FORCE_INLINE bool TestAabbAgainstAabb2(const btVector3 &aabbMin1, const btV
}
/// conservative test for overlap between triangle and aabb
SIMD_FORCE_INLINE bool TestTriangleAgainstAabb2(const btVector3 *vertices,
const btVector3 &aabbMin, const btVector3 &aabbMax)
SIMD_FORCE_INLINE bool TestTriangleAgainstAabb2(const btVector3* vertices,
const btVector3& aabbMin, const btVector3& aabbMax)
{
const btVector3 &p1 = vertices[0];
const btVector3 &p2 = vertices[1];
const btVector3 &p3 = vertices[2];
const btVector3& p1 = vertices[0];
const btVector3& p2 = vertices[1];
const btVector3& p3 = vertices[2];
if (btMin(btMin(p1[0], p2[0]), p3[0]) > aabbMax[0]) return false;
if (btMax(btMax(p1[0], p2[0]), p3[0]) < aabbMin[0]) return false;
if (btMin(btMin(p1[2], p2[2]), p3[2]) > aabbMax[2]) return false;
if (btMax(btMax(p1[2], p2[2]), p3[2]) < aabbMin[2]) return false;
if (btMin(btMin(p1[1], p2[1]), p3[1]) > aabbMax[1]) return false;
if (btMax(btMax(p1[1], p2[1]), p3[1]) < aabbMin[1]) return false;
return true;
}
SIMD_FORCE_INLINE int btOutcode(const btVector3& p,const btVector3& halfExtent)
SIMD_FORCE_INLINE int btOutcode(const btVector3& p, const btVector3& halfExtent)
{
return (p.getX() < -halfExtent.getX() ? 0x01 : 0x0) |
(p.getX() > halfExtent.getX() ? 0x08 : 0x0) |
(p.getY() < -halfExtent.getY() ? 0x02 : 0x0) |
(p.getY() > halfExtent.getY() ? 0x10 : 0x0) |
(p.getZ() < -halfExtent.getZ() ? 0x4 : 0x0) |
(p.getZ() > halfExtent.getZ() ? 0x20 : 0x0);
return (p.getX() < -halfExtent.getX() ? 0x01 : 0x0) |
(p.getX() > halfExtent.getX() ? 0x08 : 0x0) |
(p.getY() < -halfExtent.getY() ? 0x02 : 0x0) |
(p.getY() > halfExtent.getY() ? 0x10 : 0x0) |
(p.getZ() < -halfExtent.getZ() ? 0x4 : 0x0) |
(p.getZ() > halfExtent.getZ() ? 0x20 : 0x0);
}
SIMD_FORCE_INLINE bool btRayAabb2(const btVector3& rayFrom,
const btVector3& rayInvDirection,
const unsigned int raySign[3],
@@ -97,11 +89,11 @@ SIMD_FORCE_INLINE bool btRayAabb2(const btVector3& rayFrom,
{
btScalar tmax, tymin, tymax, tzmin, tzmax;
tmin = (bounds[raySign[0]].getX() - rayFrom.getX()) * rayInvDirection.getX();
tmax = (bounds[1-raySign[0]].getX() - rayFrom.getX()) * rayInvDirection.getX();
tmax = (bounds[1 - raySign[0]].getX() - rayFrom.getX()) * rayInvDirection.getX();
tymin = (bounds[raySign[1]].getY() - rayFrom.getY()) * rayInvDirection.getY();
tymax = (bounds[1-raySign[1]].getY() - rayFrom.getY()) * rayInvDirection.getY();
tymax = (bounds[1 - raySign[1]].getY() - rayFrom.getY()) * rayInvDirection.getY();
if ( (tmin > tymax) || (tymin > tmax) )
if ((tmin > tymax) || (tymin > tmax))
return false;
if (tymin > tmin)
@@ -111,59 +103,59 @@ SIMD_FORCE_INLINE bool btRayAabb2(const btVector3& rayFrom,
tmax = tymax;
tzmin = (bounds[raySign[2]].getZ() - rayFrom.getZ()) * rayInvDirection.getZ();
tzmax = (bounds[1-raySign[2]].getZ() - rayFrom.getZ()) * rayInvDirection.getZ();
tzmax = (bounds[1 - raySign[2]].getZ() - rayFrom.getZ()) * rayInvDirection.getZ();
if ( (tmin > tzmax) || (tzmin > tmax) )
if ((tmin > tzmax) || (tzmin > tmax))
return false;
if (tzmin > tmin)
tmin = tzmin;
if (tzmax < tmax)
tmax = tzmax;
return ( (tmin < lambda_max) && (tmax > lambda_min) );
return ((tmin < lambda_max) && (tmax > lambda_min));
}
SIMD_FORCE_INLINE bool btRayAabb(const btVector3& rayFrom,
const btVector3& rayTo,
const btVector3& aabbMin,
SIMD_FORCE_INLINE bool btRayAabb(const btVector3& rayFrom,
const btVector3& rayTo,
const btVector3& aabbMin,
const btVector3& aabbMax,
btScalar& param, btVector3& normal)
btScalar& param, btVector3& normal)
{
btVector3 aabbHalfExtent = (aabbMax-aabbMin)* btScalar(0.5);
btVector3 aabbCenter = (aabbMax+aabbMin)* btScalar(0.5);
btVector3 source = rayFrom - aabbCenter;
btVector3 target = rayTo - aabbCenter;
int sourceOutcode = btOutcode(source,aabbHalfExtent);
int targetOutcode = btOutcode(target,aabbHalfExtent);
btVector3 aabbHalfExtent = (aabbMax - aabbMin) * btScalar(0.5);
btVector3 aabbCenter = (aabbMax + aabbMin) * btScalar(0.5);
btVector3 source = rayFrom - aabbCenter;
btVector3 target = rayTo - aabbCenter;
int sourceOutcode = btOutcode(source, aabbHalfExtent);
int targetOutcode = btOutcode(target, aabbHalfExtent);
if ((sourceOutcode & targetOutcode) == 0x0)
{
btScalar lambda_enter = btScalar(0.0);
btScalar lambda_exit = param;
btScalar lambda_exit = param;
btVector3 r = target - source;
int i;
btScalar normSign = 1;
btVector3 hitNormal(0,0,0);
int bit=1;
btScalar normSign = 1;
btVector3 hitNormal(0, 0, 0);
int bit = 1;
for (int j=0;j<2;j++)
for (int j = 0; j < 2; j++)
{
for (i = 0; i != 3; ++i)
{
if (sourceOutcode & bit)
{
btScalar lambda = (-source[i] - aabbHalfExtent[i]*normSign) / r[i];
btScalar lambda = (-source[i] - aabbHalfExtent[i] * normSign) / r[i];
if (lambda_enter <= lambda)
{
lambda_enter = lambda;
hitNormal.setValue(0,0,0);
hitNormal.setValue(0, 0, 0);
hitNormal[i] = normSign;
}
}
else if (targetOutcode & bit)
else if (targetOutcode & bit)
{
btScalar lambda = (-source[i] - aabbHalfExtent[i]*normSign) / r[i];
btScalar lambda = (-source[i] - aabbHalfExtent[i] * normSign) / r[i];
btSetMin(lambda_exit, lambda);
}
bit<<=1;
bit <<= 1;
}
normSign = btScalar(-1.);
}
@@ -177,56 +169,49 @@ SIMD_FORCE_INLINE bool btRayAabb(const btVector3& rayFrom,
return false;
}
SIMD_FORCE_INLINE void btTransformAabb(const btVector3& halfExtents, btScalar margin,const btTransform& t,btVector3& aabbMinOut,btVector3& aabbMaxOut)
SIMD_FORCE_INLINE void btTransformAabb(const btVector3& halfExtents, btScalar margin, const btTransform& t, btVector3& aabbMinOut, btVector3& aabbMaxOut)
{
btVector3 halfExtentsWithMargin = halfExtents+btVector3(margin,margin,margin);
btMatrix3x3 abs_b = t.getBasis().absolute();
btVector3 halfExtentsWithMargin = halfExtents + btVector3(margin, margin, margin);
btMatrix3x3 abs_b = t.getBasis().absolute();
btVector3 center = t.getOrigin();
btVector3 extent = halfExtentsWithMargin.dot3( abs_b[0], abs_b[1], abs_b[2] );
btVector3 extent = halfExtentsWithMargin.dot3(abs_b[0], abs_b[1], abs_b[2]);
aabbMinOut = center - extent;
aabbMaxOut = center + extent;
}
SIMD_FORCE_INLINE void btTransformAabb(const btVector3& localAabbMin,const btVector3& localAabbMax, btScalar margin,const btTransform& trans,btVector3& aabbMinOut,btVector3& aabbMaxOut)
SIMD_FORCE_INLINE void btTransformAabb(const btVector3& localAabbMin, const btVector3& localAabbMax, btScalar margin, const btTransform& trans, btVector3& aabbMinOut, btVector3& aabbMaxOut)
{
btAssert(localAabbMin.getX() <= localAabbMax.getX());
btAssert(localAabbMin.getY() <= localAabbMax.getY());
btAssert(localAabbMin.getZ() <= localAabbMax.getZ());
btVector3 localHalfExtents = btScalar(0.5)*(localAabbMax-localAabbMin);
localHalfExtents+=btVector3(margin,margin,margin);
btAssert(localAabbMin.getX() <= localAabbMax.getX());
btAssert(localAabbMin.getY() <= localAabbMax.getY());
btAssert(localAabbMin.getZ() <= localAabbMax.getZ());
btVector3 localHalfExtents = btScalar(0.5) * (localAabbMax - localAabbMin);
localHalfExtents += btVector3(margin, margin, margin);
btVector3 localCenter = btScalar(0.5)*(localAabbMax+localAabbMin);
btMatrix3x3 abs_b = trans.getBasis().absolute();
btVector3 center = trans(localCenter);
btVector3 extent = localHalfExtents.dot3( abs_b[0], abs_b[1], abs_b[2] );
aabbMinOut = center-extent;
aabbMaxOut = center+extent;
btVector3 localCenter = btScalar(0.5) * (localAabbMax + localAabbMin);
btMatrix3x3 abs_b = trans.getBasis().absolute();
btVector3 center = trans(localCenter);
btVector3 extent = localHalfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]);
aabbMinOut = center - extent;
aabbMaxOut = center + extent;
}
#define USE_BANCHLESS 1
#ifdef USE_BANCHLESS
//This block replaces the block below and uses no branches, and replaces the 8 bit return with a 32 bit return for improved performance (~3x on XBox 360)
SIMD_FORCE_INLINE unsigned testQuantizedAabbAgainstQuantizedAabb(const unsigned short int* aabbMin1,const unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2)
{
return static_cast<unsigned int>(btSelect((unsigned)((aabbMin1[0] <= aabbMax2[0]) & (aabbMax1[0] >= aabbMin2[0])
& (aabbMin1[2] <= aabbMax2[2]) & (aabbMax1[2] >= aabbMin2[2])
& (aabbMin1[1] <= aabbMax2[1]) & (aabbMax1[1] >= aabbMin2[1])),
1, 0));
}
//This block replaces the block below and uses no branches, and replaces the 8 bit return with a 32 bit return for improved performance (~3x on XBox 360)
SIMD_FORCE_INLINE unsigned testQuantizedAabbAgainstQuantizedAabb(const unsigned short int* aabbMin1, const unsigned short int* aabbMax1, const unsigned short int* aabbMin2, const unsigned short int* aabbMax2)
{
return static_cast<unsigned int>(btSelect((unsigned)((aabbMin1[0] <= aabbMax2[0]) & (aabbMax1[0] >= aabbMin2[0]) & (aabbMin1[2] <= aabbMax2[2]) & (aabbMax1[2] >= aabbMin2[2]) & (aabbMin1[1] <= aabbMax2[1]) & (aabbMax1[1] >= aabbMin2[1])),
1, 0));
}
#else
SIMD_FORCE_INLINE bool testQuantizedAabbAgainstQuantizedAabb(const unsigned short int* aabbMin1,const unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2)
{
bool overlap = true;
overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap;
overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap;
overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap;
return overlap;
}
#endif //USE_BANCHLESS
#endif //BT_AABB_UTIL2
SIMD_FORCE_INLINE bool testQuantizedAabbAgainstQuantizedAabb(const unsigned short int* aabbMin1, const unsigned short int* aabbMax1, const unsigned short int* aabbMin2, const unsigned short int* aabbMax2)
{
bool overlap = true;
overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap;
overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap;
overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap;
return overlap;
}
#endif //USE_BANCHLESS
#endif //BT_AABB_UTIL2

View File

@@ -18,8 +18,8 @@ subject to the following restrictions:
#ifdef BT_DEBUG_MEMORY_ALLOCATIONS
int gNumAlignedAllocs = 0;
int gNumAlignedFree = 0;
int gTotalBytesAlignedAllocs = 0;//detect memory leaks
#endif //BT_DEBUG_MEMORY_ALLOCATIONST_DEBUG_ALLOCATIONS
int gTotalBytesAlignedAllocs = 0; //detect memory leaks
#endif //BT_DEBUG_MEMORY_ALLOCATIONST_DEBUG_ALLOCATIONS
static void *btAllocDefault(size_t size)
{
@@ -34,9 +34,7 @@ static void btFreeDefault(void *ptr)
static btAllocFunc *sAllocFunc = btAllocDefault;
static btFreeFunc *sFreeFunc = btFreeDefault;
#if defined (BT_HAS_ALIGNED_ALLOCATOR)
#if defined(BT_HAS_ALIGNED_ALLOCATOR)
#include <malloc.h>
static void *btAlignedAllocDefault(size_t size, int alignment)
{
@@ -61,49 +59,48 @@ static inline void btAlignedFreeDefault(void *ptr)
}
#else
static inline void *btAlignedAllocDefault(size_t size, int alignment)
{
void *ret;
char *real;
real = (char *)sAllocFunc(size + sizeof(void *) + (alignment-1));
if (real) {
ret = btAlignPointer(real + sizeof(void *),alignment);
*((void **)(ret)-1) = (void *)(real);
} else {
ret = (void *)(real);
}
return (ret);
void *ret;
char *real;
real = (char *)sAllocFunc(size + sizeof(void *) + (alignment - 1));
if (real)
{
ret = btAlignPointer(real + sizeof(void *), alignment);
*((void **)(ret)-1) = (void *)(real);
}
else
{
ret = (void *)(real);
}
return (ret);
}
static inline void btAlignedFreeDefault(void *ptr)
{
void* real;
void *real;
if (ptr) {
real = *((void **)(ptr)-1);
sFreeFunc(real);
}
if (ptr)
{
real = *((void **)(ptr)-1);
sFreeFunc(real);
}
}
#endif
static btAlignedAllocFunc *sAlignedAllocFunc = btAlignedAllocDefault;
static btAlignedFreeFunc *sAlignedFreeFunc = btAlignedFreeDefault;
void btAlignedAllocSetCustomAligned(btAlignedAllocFunc *allocFunc, btAlignedFreeFunc *freeFunc)
{
sAlignedAllocFunc = allocFunc ? allocFunc : btAlignedAllocDefault;
sAlignedFreeFunc = freeFunc ? freeFunc : btAlignedFreeDefault;
sAlignedAllocFunc = allocFunc ? allocFunc : btAlignedAllocDefault;
sAlignedFreeFunc = freeFunc ? freeFunc : btAlignedFreeDefault;
}
void btAlignedAllocSetCustom(btAllocFunc *allocFunc, btFreeFunc *freeFunc)
{
sAllocFunc = allocFunc ? allocFunc : btAllocDefault;
sFreeFunc = freeFunc ? freeFunc : btFreeDefault;
sAllocFunc = allocFunc ? allocFunc : btAllocDefault;
sFreeFunc = freeFunc ? freeFunc : btFreeDefault;
}
#ifdef BT_DEBUG_MEMORY_ALLOCATIONS
@@ -116,15 +113,15 @@ static int mynumallocs = 0;
int btDumpMemoryLeaks()
{
int totalLeak = 0;
for (int i=0;i<mynumallocs;i++)
for (int i = 0; i < mynumallocs; i++)
{
printf("Error: leaked memory of allocation #%d (%d bytes)\n", allocations_id[i], allocations_bytes[i]);
totalLeak+=allocations_bytes[i];
totalLeak += allocations_bytes[i];
}
if (totalLeak)
{
printf("Error: memory leaks: %d allocations were not freed and leaked together %d bytes\n",mynumallocs,totalLeak);
printf("Error: memory leaks: %d allocations were not freed and leaked together %d bytes\n", mynumallocs, totalLeak);
}
return totalLeak;
}
@@ -133,137 +130,134 @@ int btDumpMemoryLeaks()
struct btDebugPtrMagic
{
union
{
void** vptrptr;
void* vptr;
int* iptr;
char* cptr;
union {
void **vptrptr;
void *vptr;
int *iptr;
char *cptr;
};
};
void* btAlignedAllocInternal (size_t size, int alignment,int line,char* filename)
void *btAlignedAllocInternal(size_t size, int alignment, int line, char *filename)
{
if (size==0)
if (size == 0)
{
printf("Whaat? size==0");
return 0;
}
static int allocId = 0;
void *ret;
char *real;
// to find some particular memory leak, you could do something like this:
// if (allocId==172)
// {
// printf("catch me!\n");
// }
// if (size>1024*1024)
// {
// printf("big alloc!%d\n", size);
// }
void *ret;
char *real;
gTotalBytesAlignedAllocs += size;
gNumAlignedAllocs++;
// to find some particular memory leak, you could do something like this:
// if (allocId==172)
// {
// printf("catch me!\n");
// }
// if (size>1024*1024)
// {
// printf("big alloc!%d\n", size);
// }
int sz4prt = 4*sizeof(void *);
real = (char *)sAllocFunc(size + sz4prt + (alignment-1));
if (real) {
ret = (void*) btAlignPointer(real + sz4prt, alignment);
btDebugPtrMagic p;
p.vptr = ret;
p.cptr-=sizeof(void*);
*p.vptrptr = (void*)real;
p.cptr-=sizeof(void*);
*p.iptr = size;
p.cptr-=sizeof(void*);
*p.iptr = allocId;
allocations_id[mynumallocs] = allocId;
allocations_bytes[mynumallocs] = size;
mynumallocs++;
gTotalBytesAlignedAllocs += size;
gNumAlignedAllocs++;
} else {
ret = (void *)(real);//??
}
int sz4prt = 4 * sizeof(void *);
printf("allocation %d at address %x, from %s,line %d, size %d (total allocated = %d)\n",allocId,real, filename,line,size,gTotalBytesAlignedAllocs);
real = (char *)sAllocFunc(size + sz4prt + (alignment - 1));
if (real)
{
ret = (void *)btAlignPointer(real + sz4prt, alignment);
btDebugPtrMagic p;
p.vptr = ret;
p.cptr -= sizeof(void *);
*p.vptrptr = (void *)real;
p.cptr -= sizeof(void *);
*p.iptr = size;
p.cptr -= sizeof(void *);
*p.iptr = allocId;
allocations_id[mynumallocs] = allocId;
allocations_bytes[mynumallocs] = size;
mynumallocs++;
}
else
{
ret = (void *)(real); //??
}
printf("allocation %d at address %x, from %s,line %d, size %d (total allocated = %d)\n", allocId, real, filename, line, size, gTotalBytesAlignedAllocs);
allocId++;
int* ptr = (int*)ret;
*ptr = 12;
return (ret);
int *ptr = (int *)ret;
*ptr = 12;
return (ret);
}
void btAlignedFreeInternal (void* ptr,int line,char* filename)
void btAlignedFreeInternal(void *ptr, int line, char *filename)
{
void *real;
void* real;
if (ptr)
{
gNumAlignedFree++;
if (ptr) {
gNumAlignedFree++;
btDebugPtrMagic p;
p.vptr = ptr;
p.cptr -= sizeof(void *);
real = *p.vptrptr;
p.cptr -= sizeof(void *);
int size = *p.iptr;
p.cptr -= sizeof(void *);
int allocId = *p.iptr;
btDebugPtrMagic p;
p.vptr = ptr;
p.cptr-=sizeof(void*);
real = *p.vptrptr;
p.cptr-=sizeof(void*);
int size = *p.iptr;
p.cptr-=sizeof(void*);
int allocId = *p.iptr;
bool found = false;
bool found = false;
for (int i=0;i<mynumallocs;i++)
{
if ( allocations_id[i] == allocId)
{
allocations_id[i] = allocations_id[mynumallocs-1];
allocations_bytes[i] = allocations_bytes[mynumallocs-1];
mynumallocs--;
found = true;
break;
}
}
gTotalBytesAlignedAllocs -= size;
for (int i = 0; i < mynumallocs; i++)
{
if (allocations_id[i] == allocId)
{
allocations_id[i] = allocations_id[mynumallocs - 1];
allocations_bytes[i] = allocations_bytes[mynumallocs - 1];
mynumallocs--;
found = true;
break;
}
}
int diff = gNumAlignedAllocs-gNumAlignedFree;
printf("free %d at address %x, from %s,line %d, size %d (total remain = %d in %d non-freed allocations)\n",allocId,real, filename,line,size, gTotalBytesAlignedAllocs, diff);
gTotalBytesAlignedAllocs -= size;
sFreeFunc(real);
} else
{
//printf("deleting a NULL ptr, no effect\n");
}
int diff = gNumAlignedAllocs - gNumAlignedFree;
printf("free %d at address %x, from %s,line %d, size %d (total remain = %d in %d non-freed allocations)\n", allocId, real, filename, line, size, gTotalBytesAlignedAllocs, diff);
sFreeFunc(real);
}
else
{
//printf("deleting a NULL ptr, no effect\n");
}
}
#else //BT_DEBUG_MEMORY_ALLOCATIONS
#else //BT_DEBUG_MEMORY_ALLOCATIONS
void* btAlignedAllocInternal (size_t size, int alignment)
void *btAlignedAllocInternal(size_t size, int alignment)
{
void* ptr;
void *ptr;
ptr = sAlignedAllocFunc(size, alignment);
// printf("btAlignedAllocInternal %d, %x\n",size,ptr);
// printf("btAlignedAllocInternal %d, %x\n",size,ptr);
return ptr;
}
void btAlignedFreeInternal (void* ptr)
void btAlignedFreeInternal(void *ptr)
{
if (!ptr)
{
return;
}
// printf("btAlignedFreeInternal %x\n",ptr);
// printf("btAlignedFreeInternal %x\n",ptr);
sAlignedFreeFunc(ptr);
}
#endif //BT_DEBUG_MEMORY_ALLOCATIONS
#endif //BT_DEBUG_MEMORY_ALLOCATIONS

View File

@@ -22,7 +22,6 @@ subject to the following restrictions:
#include "btScalar.h"
///BT_DEBUG_MEMORY_ALLOCATIONS preprocessor can be set in build system
///for regression tests to detect memory leaks
///#define BT_DEBUG_MEMORY_ALLOCATIONS 1
@@ -30,84 +29,87 @@ subject to the following restrictions:
int btDumpMemoryLeaks();
#define btAlignedAlloc(a,b) \
btAlignedAllocInternal(a,b,__LINE__,__FILE__)
#define btAlignedAlloc(a, b) \
btAlignedAllocInternal(a, b, __LINE__, __FILE__)
#define btAlignedFree(ptr) \
btAlignedFreeInternal(ptr,__LINE__,__FILE__)
btAlignedFreeInternal(ptr, __LINE__, __FILE__)
void* btAlignedAllocInternal (size_t size, int alignment,int line,char* filename);
void* btAlignedAllocInternal(size_t size, int alignment, int line, char* filename);
void btAlignedFreeInternal (void* ptr,int line,char* filename);
void btAlignedFreeInternal(void* ptr, int line, char* filename);
#else
void* btAlignedAllocInternal (size_t size, int alignment);
void btAlignedFreeInternal (void* ptr);
void* btAlignedAllocInternal(size_t size, int alignment);
void btAlignedFreeInternal(void* ptr);
#define btAlignedAlloc(size,alignment) btAlignedAllocInternal(size,alignment)
#define btAlignedFree(ptr) btAlignedFreeInternal(ptr)
#define btAlignedAlloc(size, alignment) btAlignedAllocInternal(size, alignment)
#define btAlignedFree(ptr) btAlignedFreeInternal(ptr)
#endif
typedef int size_type;
typedef int size_type;
typedef void *(btAlignedAllocFunc)(size_t size, int alignment);
typedef void (btAlignedFreeFunc)(void *memblock);
typedef void *(btAllocFunc)(size_t size);
typedef void (btFreeFunc)(void *memblock);
typedef void*(btAlignedAllocFunc)(size_t size, int alignment);
typedef void(btAlignedFreeFunc)(void* memblock);
typedef void*(btAllocFunc)(size_t size);
typedef void(btFreeFunc)(void* memblock);
///The developer can let all Bullet memory allocations go through a custom memory allocator, using btAlignedAllocSetCustom
void btAlignedAllocSetCustom(btAllocFunc *allocFunc, btFreeFunc *freeFunc);
void btAlignedAllocSetCustom(btAllocFunc* allocFunc, btFreeFunc* freeFunc);
///If the developer has already an custom aligned allocator, then btAlignedAllocSetCustomAligned can be used. The default aligned allocator pre-allocates extra memory using the non-aligned allocator, and instruments it.
void btAlignedAllocSetCustomAligned(btAlignedAllocFunc *allocFunc, btAlignedFreeFunc *freeFunc);
void btAlignedAllocSetCustomAligned(btAlignedAllocFunc* allocFunc, btAlignedFreeFunc* freeFunc);
///The btAlignedAllocator is a portable class for aligned memory allocations.
///Default implementations for unaligned and aligned allocations can be overridden by a custom allocator using btAlignedAllocSetCustom and btAlignedAllocSetCustomAligned.
template < typename T , unsigned Alignment >
class btAlignedAllocator {
typedef btAlignedAllocator< T , Alignment > self_type;
public:
template <typename T, unsigned Alignment>
class btAlignedAllocator
{
typedef btAlignedAllocator<T, Alignment> self_type;
public:
//just going down a list:
btAlignedAllocator() {}
/*
btAlignedAllocator( const self_type & ) {}
*/
template < typename Other >
btAlignedAllocator( const btAlignedAllocator< Other , Alignment > & ) {}
template <typename Other>
btAlignedAllocator(const btAlignedAllocator<Other, Alignment>&)
{
}
typedef const T* const_pointer;
typedef const T& const_reference;
typedef T* pointer;
typedef T& reference;
typedef T value_type;
typedef const T* const_pointer;
typedef const T& const_reference;
typedef T* pointer;
typedef T& reference;
typedef T value_type;
pointer address ( reference ref ) const { return &ref; }
const_pointer address ( const_reference ref ) const { return &ref; }
pointer allocate ( size_type n , const_pointer * hint = 0 ) {
pointer address(reference ref) const { return &ref; }
const_pointer address(const_reference ref) const { return &ref; }
pointer allocate(size_type n, const_pointer* hint = 0)
{
(void)hint;
return reinterpret_cast< pointer >(btAlignedAlloc( sizeof(value_type) * n , Alignment ));
return reinterpret_cast<pointer>(btAlignedAlloc(sizeof(value_type) * n, Alignment));
}
void construct ( pointer ptr , const value_type & value ) { new (ptr) value_type( value ); }
void deallocate( pointer ptr ) {
btAlignedFree( reinterpret_cast< void * >( ptr ) );
void construct(pointer ptr, const value_type& value) { new (ptr) value_type(value); }
void deallocate(pointer ptr)
{
btAlignedFree(reinterpret_cast<void*>(ptr));
}
void destroy ( pointer ptr ) { ptr->~value_type(); }
void destroy(pointer ptr) { ptr->~value_type(); }
template < typename O > struct rebind {
typedef btAlignedAllocator< O , Alignment > other;
template <typename O>
struct rebind
{
typedef btAlignedAllocator<O, Alignment> other;
};
template < typename O >
self_type & operator=( const btAlignedAllocator< O , Alignment > & ) { return *this; }
template <typename O>
self_type& operator=(const btAlignedAllocator<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 //BT_ALIGNED_ALLOCATOR
#endif //BT_ALIGNED_ALLOCATOR

View File

@@ -13,11 +13,10 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BT_OBJECT_ARRAY__
#define BT_OBJECT_ARRAY__
#include "btScalar.h" // has definitions like SIMD_FORCE_INLINE
#include "btScalar.h" // has definitions like SIMD_FORCE_INLINE
#include "btAlignedAllocator.h"
///If the platform doesn't support placement new, you can disable BT_USE_PLACEMENT_NEW
@@ -28,16 +27,16 @@ subject to the following restrictions:
#define BT_USE_PLACEMENT_NEW 1
//#define BT_USE_MEMCPY 1 //disable, because it is cumbersome to find out for each platform where memcpy is defined. It can be in <memory.h> or <string.h> or otherwise...
#define BT_ALLOW_ARRAY_COPY_OPERATOR // enabling this can accidently perform deep copies of data if you are not careful
#define BT_ALLOW_ARRAY_COPY_OPERATOR // enabling this can accidently perform deep copies of data if you are not careful
#ifdef BT_USE_MEMCPY
#include <memory.h>
#include <string.h>
#endif //BT_USE_MEMCPY
#endif //BT_USE_MEMCPY
#ifdef BT_USE_PLACEMENT_NEW
#include <new> //for placement new
#endif //BT_USE_PLACEMENT_NEW
#include <new> //for placement new
#endif //BT_USE_PLACEMENT_NEW
// The register keyword is deprecated in C++11 so don't use it.
#if __cplusplus > 199711L
@@ -48,374 +47,358 @@ subject to the following restrictions:
///The btAlignedObjectArray template class uses a subset of the stl::vector interface for its methods
///It is developed to replace stl::vector to avoid portability issues, including STL alignment issues to add SIMD/SSE data
template <typename T>
//template <class T>
template <typename T>
//template <class T>
class btAlignedObjectArray
{
btAlignedAllocator<T , 16> m_allocator;
btAlignedAllocator<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 BT_ALLOW_ARRAY_COPY_OPERATOR
public:
SIMD_FORCE_INLINE btAlignedObjectArray<T>& operator=(const btAlignedObjectArray<T> &other)
SIMD_FORCE_INLINE btAlignedObjectArray<T>& operator=(const btAlignedObjectArray<T>& other)
{
copyFromArray(other);
return *this;
}
#else//BT_ALLOW_ARRAY_COPY_OPERATOR
#else //BT_ALLOW_ARRAY_COPY_OPERATOR
private:
SIMD_FORCE_INLINE btAlignedObjectArray<T>& operator=(const btAlignedObjectArray<T> &other);
#endif//BT_ALLOW_ARRAY_COPY_OPERATOR
SIMD_FORCE_INLINE btAlignedObjectArray<T>& operator=(const btAlignedObjectArray<T>& other);
#endif //BT_ALLOW_ARRAY_COPY_OPERATOR
protected:
SIMD_FORCE_INLINE int allocSize(int size)
{
return (size ? size*2 : 1);
}
SIMD_FORCE_INLINE void copy(int start,int end, T* dest) const
{
int i;
for (i=start;i<end;++i)
SIMD_FORCE_INLINE int allocSize(int size)
{
return (size ? size * 2 : 1);
}
SIMD_FORCE_INLINE void copy(int start, int end, T* dest) const
{
int i;
for (i = start; i < end; ++i)
#ifdef BT_USE_PLACEMENT_NEW
new (&dest[i]) T(m_data[i]);
new (&dest[i]) T(m_data[i]);
#else
dest[i] = m_data[i];
#endif //BT_USE_PLACEMENT_NEW
}
dest[i] = m_data[i];
#endif //BT_USE_PLACEMENT_NEW
}
SIMD_FORCE_INLINE void init()
SIMD_FORCE_INLINE void init()
{
//PCK: added this line
m_ownsMemory = true;
m_data = 0;
m_size = 0;
m_capacity = 0;
}
SIMD_FORCE_INLINE void destroy(int first, int last)
{
int i;
for (i = first; i < last; i++)
{
//PCK: added this line
m_ownsMemory = true;
m_data = 0;
m_size = 0;
m_capacity = 0;
m_data[i].~T();
}
SIMD_FORCE_INLINE void destroy(int first,int last)
}
SIMD_FORCE_INLINE void* allocate(int size)
{
if (size)
return m_allocator.allocate(size);
return 0;
}
SIMD_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:
btAlignedObjectArray()
{
init();
}
~btAlignedObjectArray()
{
clear();
}
///Generally it is best to avoid using the copy constructor of an btAlignedObjectArray, and use a (const) reference to the array instead.
btAlignedObjectArray(const btAlignedObjectArray& otherArray)
{
init();
int otherSize = otherArray.size();
resize(otherSize);
otherArray.copy(0, otherSize, m_data);
}
/// return the number of elements in the array
SIMD_FORCE_INLINE int size() const
{
return m_size;
}
SIMD_FORCE_INLINE const T& at(int n) const
{
btAssert(n >= 0);
btAssert(n < size());
return m_data[n];
}
SIMD_FORCE_INLINE T& at(int n)
{
btAssert(n >= 0);
btAssert(n < size());
return m_data[n];
}
SIMD_FORCE_INLINE const T& operator[](int n) const
{
btAssert(n >= 0);
btAssert(n < size());
return m_data[n];
}
SIMD_FORCE_INLINE T& operator[](int n)
{
btAssert(n >= 0);
btAssert(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.
SIMD_FORCE_INLINE void clear()
{
destroy(0, size());
deallocate();
init();
}
SIMD_FORCE_INLINE void pop_back()
{
btAssert(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.
SIMD_FORCE_INLINE void resizeNoInitialize(int newsize)
{
if (newsize > size())
{
reserve(newsize);
}
m_size = newsize;
}
SIMD_FORCE_INLINE void resize(int newsize, const T& fillData = T())
{
const BT_REGISTER int curSize = size();
if (newsize < curSize)
{
for (int i = newsize; i < curSize; i++)
{
m_data[i].~T();
}
}
SIMD_FORCE_INLINE void* allocate(int size)
else
{
if (size)
return m_allocator.allocate(size);
return 0;
}
SIMD_FORCE_INLINE void deallocate()
{
if(m_data) {
//PCK: enclosed the deallocation in this block
if (m_ownsMemory)
{
m_allocator.deallocate(m_data);
}
m_data = 0;
}
}
public:
btAlignedObjectArray()
{
init();
}
~btAlignedObjectArray()
{
clear();
}
///Generally it is best to avoid using the copy constructor of an btAlignedObjectArray, and use a (const) reference to the array instead.
btAlignedObjectArray(const btAlignedObjectArray& otherArray)
{
init();
int otherSize = otherArray.size();
resize (otherSize);
otherArray.copy(0, otherSize, m_data);
}
/// return the number of elements in the array
SIMD_FORCE_INLINE int size() const
{
return m_size;
}
SIMD_FORCE_INLINE const T& at(int n) const
{
btAssert(n>=0);
btAssert(n<size());
return m_data[n];
}
SIMD_FORCE_INLINE T& at(int n)
{
btAssert(n>=0);
btAssert(n<size());
return m_data[n];
}
SIMD_FORCE_INLINE const T& operator[](int n) const
{
btAssert(n>=0);
btAssert(n<size());
return m_data[n];
}
SIMD_FORCE_INLINE T& operator[](int n)
{
btAssert(n>=0);
btAssert(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.
SIMD_FORCE_INLINE void clear()
{
destroy(0,size());
deallocate();
init();
}
SIMD_FORCE_INLINE void pop_back()
{
btAssert(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.
SIMD_FORCE_INLINE void resizeNoInitialize(int newsize)
{
if (newsize > size())
if (newsize > curSize)
{
reserve(newsize);
}
m_size = newsize;
#ifdef BT_USE_PLACEMENT_NEW
for (int i = curSize; i < newsize; i++)
{
new (&m_data[i]) T(fillData);
}
#endif //BT_USE_PLACEMENT_NEW
}
SIMD_FORCE_INLINE void resize(int newsize, const T& fillData=T())
m_size = newsize;
}
SIMD_FORCE_INLINE T& expandNonInitializing()
{
const BT_REGISTER int sz = size();
if (sz == capacity())
{
const BT_REGISTER int curSize = size();
if (newsize < curSize)
{
for(int i = newsize; i < curSize; i++)
{
m_data[i].~T();
}
} else
{
if (newsize > curSize)
{
reserve(newsize);
}
#ifdef BT_USE_PLACEMENT_NEW
for (int i=curSize;i<newsize;i++)
{
new ( &m_data[i]) T(fillData);
}
#endif //BT_USE_PLACEMENT_NEW
}
m_size = newsize;
reserve(allocSize(size()));
}
SIMD_FORCE_INLINE T& expandNonInitializing( )
{
const BT_REGISTER int sz = size();
if( sz == capacity() )
{
reserve( allocSize(size()) );
}
m_size++;
m_size++;
return m_data[sz];
return m_data[sz];
}
SIMD_FORCE_INLINE T& expand(const T& fillValue = T())
{
const BT_REGISTER int sz = size();
if (sz == capacity())
{
reserve(allocSize(size()));
}
SIMD_FORCE_INLINE T& expand( const T& fillValue=T())
{
const BT_REGISTER int sz = size();
if( sz == capacity() )
{
reserve( allocSize(size()) );
}
m_size++;
m_size++;
#ifdef BT_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];
}
SIMD_FORCE_INLINE void push_back(const T& _Val)
{
const BT_REGISTER int sz = size();
if (sz == capacity())
{
reserve(allocSize(size()));
}
SIMD_FORCE_INLINE void push_back(const T& _Val)
{
const BT_REGISTER int sz = size();
if( sz == capacity() )
{
reserve( allocSize(size()) );
}
#ifdef BT_USE_PLACEMENT_NEW
new ( &m_data[m_size] ) T(_Val);
new (&m_data[m_size]) T(_Val);
#else
m_data[size()] = _Val;
#endif //BT_USE_PLACEMENT_NEW
m_data[size()] = _Val;
#endif //BT_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()
SIMD_FORCE_INLINE int capacity() const
{
return m_capacity;
}
SIMD_FORCE_INLINE void reserve(int _Count)
{ // determine new minimum length of allocated storage
if (capacity() < _Count)
{ // not enough room, reallocate
T* s = (T*)allocate(_Count);
copy(0, size(), s);
destroy(0, size());
deallocate();
//PCK: added this line
m_ownsMemory = true;
m_data = s;
m_capacity = _Count;
}
}
/// return the pre-allocated (reserved) elements, this is at least as large as the total number of elements,see size() and reserve()
SIMD_FORCE_INLINE int capacity() const
{
return m_capacity;
}
SIMD_FORCE_INLINE void reserve(int _Count)
{ // determine new minimum length of allocated storage
if (capacity() < _Count)
{ // not enough room, reallocate
T* s = (T*)allocate(_Count);
copy(0, size(), s);
destroy(0,size());
deallocate();
//PCK: added this line
m_ownsMemory = true;
m_data = s;
m_capacity = _Count;
}
}
class less
class less
{
public:
bool operator()(const T& a, const T& b) const
{
public:
return (a < b);
}
};
bool operator() ( const T& a, const T& b ) const
{
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 BT_USE_MEMCPY
char temp[sizeof(T)];
memcpy(temp,&m_data[index0],sizeof(T));
memcpy(&m_data[index0],&m_data[index1],sizeof(T));
memcpy(&m_data[index1],temp,sizeof(T));
char temp[sizeof(T)];
memcpy(temp, &m_data[index0], sizeof(T));
memcpy(&m_data[index0], &m_data[index1], sizeof(T));
memcpy(&m_data[index1], temp, sizeof(T));
#else
T temp = m_data[index0];
m_data[index0] = m_data[index1];
m_data[index1] = temp;
#endif //BT_USE_PLACEMENT_NEW
}
T temp = m_data[index0];
m_data[index0] = m_data[index1];
m_data[index1] = temp;
#endif //BT_USE_PLACEMENT_NEW
}
template <typename L>
void heapSort(const L& CompareFunc)
@@ -423,49 +406,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)
{
@@ -475,41 +457,41 @@ protected:
}
return index;
}
// If the key is not in the array, return -1 instead of 0,
// since 0 also means the first element in the array.
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 removeAtIndex(int index)
{
if (index<size())
{
swap( index,size()-1);
pop_back();
}
}
void remove(const T& key)
// If the key is not in the array, return -1 instead of 0,
// since 0 also means the first element in the array.
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 removeAtIndex(int index)
{
if (index < size())
{
swap(index, size() - 1);
pop_back();
}
}
void remove(const T& key)
{
int findIndex = findLinearSearch(key);
removeAtIndex(findIndex);
removeAtIndex(findIndex);
}
//PCK: whole function
void initializeFromBuffer(void *buffer, int size, int capacity)
void initializeFromBuffer(void* buffer, int size, int capacity)
{
clear();
m_ownsMemory = false;
@@ -521,10 +503,9 @@ protected:
void copyFromArray(const btAlignedObjectArray& otherArray)
{
int otherSize = otherArray.size();
resize (otherSize);
resize(otherSize);
otherArray.copy(0, otherSize, m_data);
}
};
#endif //BT_OBJECT_ARRAY__
#endif //BT_OBJECT_ARRAY__

File diff suppressed because it is too large Load Diff

View File

@@ -34,106 +34,102 @@ public:
mNumFaces = 0;
mNumIndices = 0;
}
bool mPolygons; // true if indices represents polygons, false indices are triangles
unsigned int mNumOutputVertices; // number of vertices in the output hull
btAlignedObjectArray<btVector3> m_OutputVertices; // array of vertices
unsigned int mNumFaces; // the number of faces produced
unsigned int mNumIndices; // the total number of indices
btAlignedObjectArray<unsigned int> m_Indices; // pointer to indices.
bool mPolygons; // true if indices represents polygons, false indices are triangles
unsigned int mNumOutputVertices; // number of vertices in the output hull
btAlignedObjectArray<btVector3> m_OutputVertices; // array of vertices
unsigned int mNumFaces; // the number of faces produced
unsigned int mNumIndices; // the total number of indices
btAlignedObjectArray<unsigned int> m_Indices; // pointer to indices.
// If triangles, then indices are array indexes into the vertex list.
// If polygons, indices are in the form (number of points in face) (p1, p2, p3, ..) etc..
// If triangles, then indices are array indexes into the vertex list.
// If polygons, indices are in the form (number of points in face) (p1, p2, p3, ..) etc..
};
enum HullFlag
{
QF_TRIANGLES = (1<<0), // report results as triangles, not polygons.
QF_REVERSE_ORDER = (1<<1), // reverse order of the triangle indices.
QF_DEFAULT = QF_TRIANGLES
QF_TRIANGLES = (1 << 0), // report results as triangles, not polygons.
QF_REVERSE_ORDER = (1 << 1), // reverse order of the triangle indices.
QF_DEFAULT = QF_TRIANGLES
};
class HullDesc
{
public:
HullDesc(void)
{
mFlags = QF_DEFAULT;
mVcount = 0;
mVertices = 0;
mVertexStride = sizeof(btVector3);
mNormalEpsilon = 0.001f;
mMaxVertices = 4096; // maximum number of points to be considered for a convex hull.
mMaxFaces = 4096;
mFlags = QF_DEFAULT;
mVcount = 0;
mVertices = 0;
mVertexStride = sizeof(btVector3);
mNormalEpsilon = 0.001f;
mMaxVertices = 4096; // maximum number of points to be considered for a convex hull.
mMaxFaces = 4096;
};
HullDesc(HullFlag flag,
unsigned int vcount,
const btVector3 *vertices,
unsigned int stride = sizeof(btVector3))
unsigned int vcount,
const btVector3* vertices,
unsigned int stride = sizeof(btVector3))
{
mFlags = flag;
mVcount = vcount;
mVertices = vertices;
mVertexStride = stride;
mNormalEpsilon = btScalar(0.001);
mMaxVertices = 4096;
mFlags = flag;
mVcount = vcount;
mVertices = vertices;
mVertexStride = stride;
mNormalEpsilon = btScalar(0.001);
mMaxVertices = 4096;
}
bool HasHullFlag(HullFlag flag) const
{
if ( mFlags & flag ) return true;
if (mFlags & flag) return true;
return false;
}
void SetHullFlag(HullFlag flag)
{
mFlags|=flag;
mFlags |= flag;
}
void ClearHullFlag(HullFlag flag)
{
mFlags&=~flag;
mFlags &= ~flag;
}
unsigned int mFlags; // flags to use when generating the convex hull.
unsigned int mVcount; // number of vertices in the input point cloud
const btVector3 *mVertices; // the array of vertices.
unsigned int mVertexStride; // the stride of each vertex, in bytes.
btScalar mNormalEpsilon; // the epsilon for removing duplicates. This is a normalized value, if normalized bit is on.
unsigned int mMaxVertices; // maximum number of vertices to be considered for the hull!
unsigned int mMaxFaces;
unsigned int mFlags; // flags to use when generating the convex hull.
unsigned int mVcount; // number of vertices in the input point cloud
const btVector3* mVertices; // the array of vertices.
unsigned int mVertexStride; // the stride of each vertex, in bytes.
btScalar mNormalEpsilon; // the epsilon for removing duplicates. This is a normalized value, if normalized bit is on.
unsigned int mMaxVertices; // maximum number of vertices to be considered for the hull!
unsigned int mMaxFaces;
};
enum HullError
{
QE_OK, // success!
QE_FAIL // failed.
QE_OK, // success!
QE_FAIL // failed.
};
class btPlane
{
public:
btVector3 normal;
btScalar dist; // distance below origin - the D from plane equasion Ax+By+Cz+D=0
btPlane(const btVector3 &n,btScalar d):normal(n),dist(d){}
btPlane():normal(),dist(0){}
public:
btVector3 normal;
btScalar dist; // distance below origin - the D from plane equasion Ax+By+Cz+D=0
btPlane(const btVector3& n, btScalar d) : normal(n), dist(d) {}
btPlane() : normal(), dist(0) {}
};
class ConvexH
class ConvexH
{
public:
public:
class HalfEdge
{
public:
public:
short ea; // the other half of the edge (index into edges list)
unsigned char v; // the vertex at the start of this edge (index into vertices list)
unsigned char p; // the facet on which this edge lies (index into facets list)
HalfEdge(){}
HalfEdge(short _ea,unsigned char _v, unsigned char _p):ea(_ea),v(_v),p(_p){}
HalfEdge() {}
HalfEdge(short _ea, unsigned char _v, unsigned char _p) : ea(_ea), v(_v), p(_p) {}
};
ConvexH()
{
@@ -143,25 +139,29 @@ class ConvexH
}
btAlignedObjectArray<btVector3> vertices;
btAlignedObjectArray<HalfEdge> edges;
btAlignedObjectArray<btPlane> facets;
ConvexH(int vertices_size,int edges_size,int facets_size);
btAlignedObjectArray<btPlane> facets;
ConvexH(int vertices_size, int edges_size, int facets_size);
};
class int4
{
public:
int x,y,z,w;
int x, y, z, w;
int4(){};
int4(int _x,int _y, int _z,int _w){x=_x;y=_y;z=_z;w=_w;}
const int& operator[](int i) const {return (&x)[i];}
int& operator[](int i) {return (&x)[i];}
int4(int _x, int _y, int _z, int _w)
{
x = _x;
y = _y;
z = _z;
w = _w;
}
const int& operator[](int i) const { return (&x)[i]; }
int& operator[](int i) { return (&x)[i]; }
};
class PHullResult
{
public:
PHullResult(void)
{
mVcount = 0;
@@ -173,69 +173,61 @@ public:
unsigned int mVcount;
unsigned int mIndexCount;
unsigned int mFaceCount;
btVector3* mVertices;
btVector3* mVertices;
TUIntArray m_Indices;
};
///The HullLibrary class can create a convex hull from a collection of vertices, using the ComputeHull method.
///The btShapeHull class uses this HullLibrary to create a approximate convex mesh given a general (non-polyhedral) convex shape.
class HullLibrary
{
btAlignedObjectArray<class btHullTriangle*> m_tris;
public:
btAlignedObjectArray<int> m_vertexIndexMapping;
HullError CreateConvexHull(const HullDesc& desc, // describes the input request
HullResult& result); // contains the resulst
HullError ReleaseResult(HullResult &result); // release memory allocated for this result, we are done with it.
HullError CreateConvexHull(const HullDesc& desc, // describes the input request
HullResult& result); // contains the resulst
HullError ReleaseResult(HullResult& result); // release memory allocated for this result, we are done with it.
private:
bool ComputeHull(unsigned int vcount, const btVector3* vertices, PHullResult& result, unsigned int vlimit);
bool ComputeHull(unsigned int vcount,const btVector3 *vertices,PHullResult &result,unsigned int vlimit);
class btHullTriangle* allocateTriangle(int a, int b, int c);
void deAllocateTriangle(btHullTriangle*);
void b2bfix(btHullTriangle* s, btHullTriangle* t);
class btHullTriangle* allocateTriangle(int a,int b,int c);
void deAllocateTriangle(btHullTriangle*);
void b2bfix(btHullTriangle* s,btHullTriangle*t);
void removeb2b(btHullTriangle* s, btHullTriangle* t);
void removeb2b(btHullTriangle* s,btHullTriangle*t);
void checkit(btHullTriangle *t);
void checkit(btHullTriangle* t);
btHullTriangle* extrudable(btScalar epsilon);
int calchull(btVector3 *verts,int verts_count, TUIntArray& tris_out, int &tris_count,int vlimit);
int calchull(btVector3* verts, int verts_count, TUIntArray& tris_out, int& tris_count, int vlimit);
int calchullgen(btVector3 *verts,int verts_count, int vlimit);
int calchullgen(btVector3* verts, int verts_count, int vlimit);
int4 FindSimplex(btVector3 *verts,int verts_count,btAlignedObjectArray<int> &allow);
int4 FindSimplex(btVector3* verts, int verts_count, btAlignedObjectArray<int>& allow);
class ConvexH* ConvexHCrop(ConvexH& convex,const btPlane& slice);
class ConvexH* ConvexHCrop(ConvexH& convex, const btPlane& slice);
void extrude(class btHullTriangle* t0,int v);
void extrude(class btHullTriangle* t0, int v);
ConvexH* test_cube();
//BringOutYourDead (John Ratcliff): When you create a convex hull you hand it a large input set of vertices forming a 'point cloud'.
//BringOutYourDead (John Ratcliff): When you create a convex hull you hand it a large input set of vertices forming a 'point cloud'.
//After the hull is generated it give you back a set of polygon faces which index the *original* point cloud.
//The thing is, often times, there are many 'dead vertices' in the point cloud that are on longer referenced by the hull.
//The routine 'BringOutYourDead' find only the referenced vertices, copies them to an new buffer, and re-indexes the hull so that it is a minimal representation.
void BringOutYourDead(const btVector3* verts,unsigned int vcount, btVector3* overts,unsigned int &ocount,unsigned int* indices,unsigned indexcount);
void BringOutYourDead(const btVector3* verts, unsigned int vcount, btVector3* overts, unsigned int& ocount, unsigned int* indices, unsigned indexcount);
bool CleanupVertices(unsigned int svcount,
const btVector3* svertices,
unsigned int stride,
unsigned int &vcount, // output number of vertices
btVector3* vertices, // location to store the results.
btScalar normalepsilon,
btVector3& scale);
const btVector3* svertices,
unsigned int stride,
unsigned int& vcount, // output number of vertices
btVector3* vertices, // location to store the results.
btScalar normalepsilon,
btVector3& scale);
};
#endif //BT_CD_HULL_H
#endif //BT_CD_HULL_H

File diff suppressed because it is too large Load Diff

View File

@@ -23,58 +23,56 @@ subject to the following restrictions:
/// Ole Kniemeyer, MAXON Computer GmbH
class btConvexHullComputer
{
private:
btScalar compute(const void* coords, bool doubleCoords, int stride, int count, btScalar shrink, btScalar shrinkClamp);
public:
class Edge
{
private:
btScalar compute(const void* coords, bool doubleCoords, int stride, int count, btScalar shrink, btScalar shrinkClamp);
int next;
int reverse;
int targetVertex;
friend class btConvexHullComputer;
public:
class Edge
int getSourceVertex() const
{
private:
int next;
int reverse;
int targetVertex;
return (this + reverse)->targetVertex;
}
friend class btConvexHullComputer;
int getTargetVertex() const
{
return targetVertex;
}
public:
int getSourceVertex() const
{
return (this + reverse)->targetVertex;
}
const Edge* getNextEdgeOfVertex() const // clockwise list of all edges of a vertex
{
return this + next;
}
int getTargetVertex() const
{
return targetVertex;
}
const Edge* getNextEdgeOfFace() const // counter-clockwise list of all edges of a face
{
return (this + reverse)->getNextEdgeOfVertex();
}
const Edge* getNextEdgeOfVertex() const // clockwise list of all edges of a vertex
{
return this + next;
}
const Edge* getReverseEdge() const
{
return this + reverse;
}
};
const Edge* getNextEdgeOfFace() const // counter-clockwise list of all edges of a face
{
return (this + reverse)->getNextEdgeOfVertex();
}
// Vertices of the output hull
btAlignedObjectArray<btVector3> vertices;
const Edge* getReverseEdge() const
{
return this + reverse;
}
};
// Edges of the output hull
btAlignedObjectArray<Edge> edges;
// Faces of the convex hull. Each entry is an index into the "edges" array pointing to an edge of the face. Faces are planar n-gons
btAlignedObjectArray<int> faces;
// Vertices of the output hull
btAlignedObjectArray<btVector3> vertices;
// Edges of the output hull
btAlignedObjectArray<Edge> edges;
// Faces of the convex hull. Each entry is an index into the "edges" array pointing to an edge of the face. Faces are planar n-gons
btAlignedObjectArray<int> faces;
/*
/*
Compute convex hull of "count" vertices stored in "coords". "stride" is the difference in bytes
between the addresses of consecutive vertices. If "shrink" is positive, the convex hull is shrunken
by that amount (each face is moved by "shrink" length units towards the center along its normal).
@@ -86,18 +84,16 @@ class btConvexHullComputer
The output convex hull can be found in the member variables "vertices", "edges", "faces".
*/
btScalar compute(const float* coords, int stride, int count, btScalar shrink, btScalar shrinkClamp)
{
return compute(coords, false, stride, count, shrink, shrinkClamp);
}
btScalar compute(const float* coords, int stride, int count, btScalar shrink, btScalar shrinkClamp)
{
return compute(coords, false, stride, count, shrink, shrinkClamp);
}
// same as above, but double precision
btScalar compute(const double* coords, int stride, int count, btScalar shrink, btScalar shrinkClamp)
{
return compute(coords, true, stride, count, shrink, shrinkClamp);
}
// same as above, but double precision
btScalar compute(const double* coords, int stride, int count, btScalar shrink, btScalar shrinkClamp)
{
return compute(coords, true, stride, count, shrink, shrinkClamp);
}
};
#endif //BT_CONVEX_HULL_COMPUTER_H
#endif //BT_CONVEX_HULL_COMPUTER_H

View File

@@ -4,20 +4,20 @@
#include "LinearMath/btScalar.h"
#include <string.h>//memset
#ifdef USE_SIMD
#include <string.h> //memset
#ifdef USE_SIMD
#include <emmintrin.h>
#ifdef BT_ALLOW_SSE4
#include <intrin.h>
#endif //BT_ALLOW_SSE4
#endif //USE_SIMD
#endif //BT_ALLOW_SSE4
#endif //USE_SIMD
#if defined BT_USE_NEON
#define ARM_NEON_GCC_COMPATIBILITY 1
#define ARM_NEON_GCC_COMPATIBILITY 1
#include <arm_neon.h>
#include <sys/types.h>
#include <sys/sysctl.h> //for sysctlbyname
#endif //BT_USE_NEON
#include <sys/sysctl.h> //for sysctlbyname
#endif //BT_USE_NEON
///Rudimentary btCpuFeatureUtility for CPU features: only report the features that Bullet actually uses (SSE4/FMA3, NEON_HPFP)
///We assume SSE2 in case BT_USE_SSE2 is defined in LinearMath/btScalar.h
@@ -26,14 +26,13 @@ class btCpuFeatureUtility
public:
enum btCpuFeature
{
CPU_FEATURE_FMA3=1,
CPU_FEATURE_SSE4_1=2,
CPU_FEATURE_NEON_HPFP=4
CPU_FEATURE_FMA3 = 1,
CPU_FEATURE_SSE4_1 = 2,
CPU_FEATURE_NEON_HPFP = 4
};
static int getCpuFeatures()
{
static int capabilities = 0;
static bool testedCapabilities = false;
if (0 != testedCapabilities)
@@ -49,15 +48,15 @@ public:
if (0 == err && hasFeature)
capabilities |= CPU_FEATURE_NEON_HPFP;
}
#endif //BT_USE_NEON
#endif //BT_USE_NEON
#ifdef BT_ALLOW_SSE4
#ifdef BT_ALLOW_SSE4
{
int cpuInfo[4];
int cpuInfo[4];
memset(cpuInfo, 0, sizeof(cpuInfo));
unsigned long long sseExt = 0;
unsigned long long sseExt = 0;
__cpuid(cpuInfo, 1);
bool osUsesXSAVE_XRSTORE = cpuInfo[2] & (1 << 27) || false;
bool cpuAVXSuport = cpuInfo[2] & (1 << 28) || false;
@@ -79,14 +78,11 @@ public:
capabilities |= btCpuFeatureUtility::CPU_FEATURE_SSE4_1;
}
}
#endif//BT_ALLOW_SSE4
#endif //BT_ALLOW_SSE4
testedCapabilities = true;
return capabilities;
}
};
#endif //BT_CPU_UTILITY_H
#endif //BT_CPU_UTILITY_H

View File

@@ -4,39 +4,37 @@
#include "btMotionState.h"
///The btDefaultMotionState provides a common implementation to synchronize world transforms with offsets.
ATTRIBUTE_ALIGNED16(struct) btDefaultMotionState : public btMotionState
ATTRIBUTE_ALIGNED16(struct)
btDefaultMotionState : public btMotionState
{
btTransform m_graphicsWorldTrans;
btTransform m_centerOfMassOffset;
btTransform m_centerOfMassOffset;
btTransform m_startWorldTrans;
void* m_userPointer;
void* m_userPointer;
BT_DECLARE_ALIGNED_ALLOCATOR();
btDefaultMotionState(const btTransform& startTrans = btTransform::getIdentity(),const btTransform& centerOfMassOffset = btTransform::getIdentity())
btDefaultMotionState(const btTransform& startTrans = btTransform::getIdentity(), const btTransform& centerOfMassOffset = btTransform::getIdentity())
: m_graphicsWorldTrans(startTrans),
m_centerOfMassOffset(centerOfMassOffset),
m_startWorldTrans(startTrans),
m_userPointer(0)
m_centerOfMassOffset(centerOfMassOffset),
m_startWorldTrans(startTrans),
m_userPointer(0)
{
}
///synchronizes world transform from user to physics
virtual void getWorldTransform(btTransform& centerOfMassWorldTrans ) const
virtual void getWorldTransform(btTransform & centerOfMassWorldTrans) const
{
centerOfMassWorldTrans = m_graphicsWorldTrans * m_centerOfMassOffset.inverse() ;
centerOfMassWorldTrans = m_graphicsWorldTrans * m_centerOfMassOffset.inverse();
}
///synchronizes world transform from physics to user
///Bullet only calls the update of worldtransform for active objects
virtual void setWorldTransform(const btTransform& centerOfMassWorldTrans)
virtual void setWorldTransform(const btTransform& centerOfMassWorldTrans)
{
m_graphicsWorldTrans = centerOfMassWorldTrans * m_centerOfMassOffset;
m_graphicsWorldTrans = centerOfMassWorldTrans * m_centerOfMassOffset;
}
};
#endif //BT_DEFAULT_MOTION_STATE_H
#endif //BT_DEFAULT_MOTION_STATE_H

View File

@@ -12,49 +12,43 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#include "btGeometryUtil.h"
/*
Make sure this dummy function never changes so that it
can be used by probes that are checking whether the
library is actually installed.
*/
extern "C"
{
void btBulletMathProbe ();
{
void btBulletMathProbe();
void btBulletMathProbe () {}
void btBulletMathProbe() {}
}
bool btGeometryUtil::isPointInsidePlanes(const btAlignedObjectArray<btVector3>& planeEquations, const btVector3& point, btScalar margin)
bool btGeometryUtil::isPointInsidePlanes(const btAlignedObjectArray<btVector3>& planeEquations, const btVector3& point, btScalar margin)
{
int numbrushes = planeEquations.size();
for (int i=0;i<numbrushes;i++)
for (int i = 0; i < numbrushes; i++)
{
const btVector3& N1 = planeEquations[i];
btScalar dist = btScalar(N1.dot(point))+btScalar(N1[3])-margin;
if (dist>btScalar(0.))
btScalar dist = btScalar(N1.dot(point)) + btScalar(N1[3]) - margin;
if (dist > btScalar(0.))
{
return false;
}
}
return true;
}
bool btGeometryUtil::areVerticesBehindPlane(const btVector3& planeNormal, const btAlignedObjectArray<btVector3>& vertices, btScalar margin)
bool btGeometryUtil::areVerticesBehindPlane(const btVector3& planeNormal, const btAlignedObjectArray<btVector3>& vertices, btScalar margin)
{
int numvertices = vertices.size();
for (int i=0;i<numvertices;i++)
for (int i = 0; i < numvertices; i++)
{
const btVector3& N1 = vertices[i];
btScalar dist = btScalar(planeNormal.dot(N1))+btScalar(planeNormal[3])-margin;
if (dist>btScalar(0.))
btScalar dist = btScalar(planeNormal.dot(N1)) + btScalar(planeNormal[3]) - margin;
if (dist > btScalar(0.))
{
return false;
}
@@ -62,102 +56,98 @@ bool btGeometryUtil::areVerticesBehindPlane(const btVector3& planeNormal, const
return true;
}
bool notExist(const btVector3& planeEquation,const btAlignedObjectArray<btVector3>& planeEquations);
bool notExist(const btVector3& planeEquation, const btAlignedObjectArray<btVector3>& planeEquations);
bool notExist(const btVector3& planeEquation,const btAlignedObjectArray<btVector3>& planeEquations)
bool notExist(const btVector3& planeEquation, const btAlignedObjectArray<btVector3>& planeEquations)
{
int numbrushes = planeEquations.size();
for (int i=0;i<numbrushes;i++)
for (int i = 0; i < numbrushes; i++)
{
const btVector3& N1 = planeEquations[i];
if (planeEquation.dot(N1) > btScalar(0.999))
{
return false;
}
}
}
return true;
}
void btGeometryUtil::getPlaneEquationsFromVertices(btAlignedObjectArray<btVector3>& vertices, btAlignedObjectArray<btVector3>& planeEquationsOut )
void btGeometryUtil::getPlaneEquationsFromVertices(btAlignedObjectArray<btVector3>& vertices, btAlignedObjectArray<btVector3>& planeEquationsOut)
{
const int numvertices = vertices.size();
const int numvertices = vertices.size();
// brute force:
for (int i=0;i<numvertices;i++)
for (int i = 0; i < numvertices; i++)
{
const btVector3& N1 = vertices[i];
for (int j=i+1;j<numvertices;j++)
for (int j = i + 1; j < numvertices; j++)
{
const btVector3& N2 = vertices[j];
for (int k=j+1;k<numvertices;k++)
{
for (int k = j + 1; k < numvertices; k++)
{
const btVector3& N3 = vertices[k];
btVector3 planeEquation,edge0,edge1;
edge0 = N2-N1;
edge1 = N3-N1;
btVector3 planeEquation, edge0, edge1;
edge0 = N2 - N1;
edge1 = N3 - N1;
btScalar normalSign = btScalar(1.);
for (int ww=0;ww<2;ww++)
for (int ww = 0; ww < 2; ww++)
{
planeEquation = normalSign * edge0.cross(edge1);
if (planeEquation.length2() > btScalar(0.0001))
{
planeEquation.normalize();
if (notExist(planeEquation,planeEquationsOut))
if (notExist(planeEquation, planeEquationsOut))
{
planeEquation[3] = -planeEquation.dot(N1);
//check if inside, and replace supportingVertexOut if needed
if (areVerticesBehindPlane(planeEquation,vertices,btScalar(0.01)))
{
planeEquationsOut.push_back(planeEquation);
}
//check if inside, and replace supportingVertexOut if needed
if (areVerticesBehindPlane(planeEquation, vertices, btScalar(0.01)))
{
planeEquationsOut.push_back(planeEquation);
}
}
}
normalSign = btScalar(-1.);
}
}
}
}
}
void btGeometryUtil::getVerticesFromPlaneEquations(const btAlignedObjectArray<btVector3>& planeEquations , btAlignedObjectArray<btVector3>& verticesOut )
void btGeometryUtil::getVerticesFromPlaneEquations(const btAlignedObjectArray<btVector3>& planeEquations, btAlignedObjectArray<btVector3>& verticesOut)
{
const int numbrushes = planeEquations.size();
// brute force:
for (int i=0;i<numbrushes;i++)
for (int i = 0; i < numbrushes; i++)
{
const btVector3& N1 = planeEquations[i];
for (int j=i+1;j<numbrushes;j++)
for (int j = i + 1; j < numbrushes; j++)
{
const btVector3& N2 = planeEquations[j];
for (int k=j+1;k<numbrushes;k++)
{
for (int k = j + 1; k < numbrushes; k++)
{
const btVector3& N3 = planeEquations[k];
btVector3 n2n3; n2n3 = N2.cross(N3);
btVector3 n3n1; n3n1 = N3.cross(N1);
btVector3 n1n2; n1n2 = N1.cross(N2);
if ( ( n2n3.length2() > btScalar(0.0001) ) &&
( n3n1.length2() > btScalar(0.0001) ) &&
( n1n2.length2() > btScalar(0.0001) ) )
btVector3 n2n3;
n2n3 = N2.cross(N3);
btVector3 n3n1;
n3n1 = N3.cross(N1);
btVector3 n1n2;
n1n2 = N1.cross(N2);
if ((n2n3.length2() > btScalar(0.0001)) &&
(n3n1.length2() > btScalar(0.0001)) &&
(n1n2.length2() > btScalar(0.0001)))
{
//point P out of 3 plane equations:
// d1 ( N2 * N3 ) + d2 ( N3 * N1 ) + d3 ( N1 * N2 )
//P = -------------------------------------------------------------------------
// N1 . ( N2 * N3 )
// d1 ( N2 * N3 ) + d2 ( N3 * N1 ) + d3 ( N1 * N2 )
//P = -------------------------------------------------------------------------
// N1 . ( N2 * N3 )
btScalar quotient = (N1.dot(n2n3));
if (btFabs(quotient) > btScalar(0.000001))
@@ -172,7 +162,7 @@ void btGeometryUtil::getVerticesFromPlaneEquations(const btAlignedObjectArray<bt
potentialVertex *= quotient;
//check if inside, and replace supportingVertexOut if needed
if (isPointInsidePlanes(planeEquations,potentialVertex,btScalar(0.01)))
if (isPointInsidePlanes(planeEquations, potentialVertex, btScalar(0.01)))
{
verticesOut.push_back(potentialVertex);
}
@@ -182,4 +172,3 @@ void btGeometryUtil::getVerticesFromPlaneEquations(const btAlignedObjectArray<bt
}
}
}

View File

@@ -12,7 +12,6 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BT_GEOMETRY_UTIL_H
#define BT_GEOMETRY_UTIL_H
@@ -22,21 +21,16 @@ subject to the following restrictions:
///The btGeometryUtil helper class provides a few methods to convert between plane equations and vertices.
class btGeometryUtil
{
public:
static void getPlaneEquationsFromVertices(btAlignedObjectArray<btVector3>& vertices, btAlignedObjectArray<btVector3>& planeEquationsOut );
public:
static void getPlaneEquationsFromVertices(btAlignedObjectArray<btVector3>& vertices, btAlignedObjectArray<btVector3>& planeEquationsOut);
static void getVerticesFromPlaneEquations(const btAlignedObjectArray<btVector3>& planeEquations , btAlignedObjectArray<btVector3>& verticesOut );
static bool isInside(const btAlignedObjectArray<btVector3>& vertices, const btVector3& planeNormal, btScalar margin);
static bool isPointInsidePlanes(const btAlignedObjectArray<btVector3>& planeEquations, const btVector3& point, btScalar margin);
static void getVerticesFromPlaneEquations(const btAlignedObjectArray<btVector3>& planeEquations, btAlignedObjectArray<btVector3>& verticesOut);
static bool areVerticesBehindPlane(const btVector3& planeNormal, const btAlignedObjectArray<btVector3>& vertices, btScalar margin);
static bool isInside(const btAlignedObjectArray<btVector3>& vertices, const btVector3& planeNormal, btScalar margin);
static bool isPointInsidePlanes(const btAlignedObjectArray<btVector3>& planeEquations, const btVector3& point, btScalar margin);
static bool areVerticesBehindPlane(const btVector3& planeNormal, const btAlignedObjectArray<btVector3>& vertices, btScalar margin);
};
#endif //BT_GEOMETRY_UTIL_H
#endif //BT_GEOMETRY_UTIL_H

View File

@@ -13,41 +13,40 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef GRAHAM_SCAN_2D_CONVEX_HULL_H
#define GRAHAM_SCAN_2D_CONVEX_HULL_H
#include "btVector3.h"
#include "btAlignedObjectArray.h"
struct GrahamVector3 : public btVector3
{
GrahamVector3(const btVector3& org, int orgIndex)
:btVector3(org),
m_orgIndex(orgIndex)
: btVector3(org),
m_orgIndex(orgIndex)
{
}
btScalar m_angle;
btScalar m_angle;
int m_orgIndex;
};
struct btAngleCompareFunc {
struct btAngleCompareFunc
{
btVector3 m_anchor;
btAngleCompareFunc(const btVector3& anchor)
: m_anchor(anchor)
: m_anchor(anchor)
{
}
bool operator()(const GrahamVector3& a, const GrahamVector3& b) const {
bool operator()(const GrahamVector3& a, const GrahamVector3& b) const
{
if (a.m_angle != b.m_angle)
return a.m_angle < b.m_angle;
else
{
btScalar al = (a-m_anchor).length2();
btScalar bl = (b-m_anchor).length2();
btScalar al = (a - m_anchor).length2();
btScalar bl = (b - m_anchor).length2();
if (al != bl)
return al < bl;
return al < bl;
else
{
return a.m_orgIndex < b.m_orgIndex;
@@ -58,73 +57,73 @@ struct btAngleCompareFunc {
inline void GrahamScanConvexHull2D(btAlignedObjectArray<GrahamVector3>& originalPoints, btAlignedObjectArray<GrahamVector3>& hull, const btVector3& normalAxis)
{
btVector3 axis0,axis1;
btPlaneSpace1(normalAxis,axis0,axis1);
btVector3 axis0, axis1;
btPlaneSpace1(normalAxis, axis0, axis1);
if (originalPoints.size()<=1)
if (originalPoints.size() <= 1)
{
for (int i=0;i<originalPoints.size();i++)
for (int i = 0; i < originalPoints.size(); i++)
hull.push_back(originalPoints[0]);
return;
}
//step1 : find anchor point with smallest projection on axis0 and move it to first location
for (int i=0;i<originalPoints.size();i++)
for (int i = 0; i < originalPoints.size(); i++)
{
// const btVector3& left = originalPoints[i];
// const btVector3& right = originalPoints[0];
// const btVector3& left = originalPoints[i];
// const btVector3& right = originalPoints[0];
btScalar projL = originalPoints[i].dot(axis0);
btScalar projR = originalPoints[0].dot(axis0);
if (projL < projR)
{
originalPoints.swap(0,i);
originalPoints.swap(0, i);
}
}
//also precompute angles
originalPoints[0].m_angle = -1e30f;
for (int i=1;i<originalPoints.size();i++)
for (int i = 1; i < originalPoints.size(); i++)
{
btVector3 ar = originalPoints[i]-originalPoints[0];
btScalar ar1 = axis1.dot(ar);
btScalar ar0 = axis0.dot(ar);
if( ar1*ar1+ar0*ar0 < FLT_EPSILON )
{
originalPoints[i].m_angle = 0.0f;
}
else
{
originalPoints[i].m_angle = btAtan2Fast(ar1, ar0);
}
btVector3 ar = originalPoints[i] - originalPoints[0];
btScalar ar1 = axis1.dot(ar);
btScalar ar0 = axis0.dot(ar);
if (ar1 * ar1 + ar0 * ar0 < FLT_EPSILON)
{
originalPoints[i].m_angle = 0.0f;
}
else
{
originalPoints[i].m_angle = btAtan2Fast(ar1, ar0);
}
}
//step 2: sort all points, based on 'angle' with this anchor
btAngleCompareFunc comp(originalPoints[0]);
originalPoints.quickSortInternal(comp,1,originalPoints.size()-1);
originalPoints.quickSortInternal(comp, 1, originalPoints.size() - 1);
int i;
for (i = 0; i<2; i++)
for (i = 0; i < 2; i++)
hull.push_back(originalPoints[i]);
//step 3: keep all 'convex' points and discard concave points (using back tracking)
for (; i != originalPoints.size(); i++)
for (; i != originalPoints.size(); i++)
{
bool isConvex = false;
while (!isConvex&& hull.size()>1) {
btVector3& a = hull[hull.size()-2];
btVector3& b = hull[hull.size()-1];
isConvex = btCross(a-b,a-originalPoints[i]).dot(normalAxis)> 0;
while (!isConvex && hull.size() > 1)
{
btVector3& a = hull[hull.size() - 2];
btVector3& b = hull[hull.size() - 1];
isConvex = btCross(a - b, a - originalPoints[i]).dot(normalAxis) > 0;
if (!isConvex)
hull.pop_back();
else
else
hull.push_back(originalPoints[i]);
}
if( hull.size() == 1 )
{
hull.push_back( originalPoints[i] );
}
if (hull.size() == 1)
{
hull.push_back(originalPoints[i]);
}
}
}
#endif //GRAHAM_SCAN_2D_CONVEX_HULL_H
#endif //GRAHAM_SCAN_2D_CONVEX_HULL_H

View File

@@ -13,7 +13,6 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BT_HASH_MAP_H
#define BT_HASH_MAP_H
@@ -24,32 +23,32 @@ subject to the following restrictions:
struct btHashString
{
std::string m_string1;
unsigned int m_hash;
unsigned int m_hash;
SIMD_FORCE_INLINE unsigned int getHash()const
SIMD_FORCE_INLINE unsigned int getHash() const
{
return m_hash;
}
btHashString()
{
m_string1="";
m_hash=0;
m_string1 = "";
m_hash = 0;
}
btHashString(const char* name)
:m_string1(name)
: m_string1(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;
for(int i = 0; m_string1.c_str()[i]; i++)
for (int i = 0; m_string1.c_str()[i]; i++)
{
hash = hash ^ (m_string1.c_str()[i]); /* xor the low 8 bits */
hash = hash * FNVMultiple; /* multiply by the magic number */
hash = hash ^ (m_string1.c_str()[i]); /* xor the low 8 bits */
hash = hash * FNVMultiple; /* multiply by the magic number */
}
m_hash = hash;
}
@@ -60,28 +59,27 @@ struct btHashString
}
};
const int BT_HASH_NULL=0xffffffff;
const int BT_HASH_NULL = 0xffffffff;
class btHashInt
{
int m_uid;
public:
int m_uid;
public:
btHashInt()
{
}
btHashInt(int uid) :m_uid(uid)
btHashInt(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;
}
@@ -91,35 +89,35 @@ public:
return getUid1() == other.getUid1();
}
//to our success
SIMD_FORCE_INLINE unsigned int getHash()const
SIMD_FORCE_INLINE unsigned int getHash() const
{
unsigned 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 btHashPtr
{
union
{
const void* m_pointer;
unsigned int m_hashValues[2];
union {
const void* m_pointer;
unsigned int m_hashValues[2];
};
public:
btHashPtr(const void* ptr)
:m_pointer(ptr)
: m_pointer(ptr)
{
}
const void* getPointer() const
const void* getPointer() const
{
return m_pointer;
}
@@ -130,64 +128,68 @@ public:
}
//to our success
SIMD_FORCE_INLINE unsigned int getHash()const
SIMD_FORCE_INLINE unsigned int getHash() const
{
const bool VOID_IS_8 = ((sizeof(void*)==8));
unsigned int key = VOID_IS_8? m_hashValues[0]+m_hashValues[1] : m_hashValues[0];
const bool VOID_IS_8 = ((sizeof(void*) == 8));
unsigned 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 btHashKeyPtr
{
int m_uid;
int m_uid;
public:
btHashKeyPtr(int uid) : m_uid(uid)
{
}
btHashKeyPtr(int uid) :m_uid(uid)
{
}
int getUid1() const
{
return m_uid;
}
int getUid1() const
{
return m_uid;
}
bool equals(const btHashKeyPtr<Value>& other) const
{
return getUid1() == other.getUid1();
}
bool equals(const btHashKeyPtr<Value>& other) const
{
return getUid1() == other.getUid1();
}
//to our success
SIMD_FORCE_INLINE unsigned int getHash()const
{
unsigned 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
SIMD_FORCE_INLINE unsigned int getHash() const
{
unsigned int key = m_uid;
// Thomas Wang's hash
key += ~(key << 15);
key ^= (key >> 10);
key += (key << 3);
key ^= (key >> 6);
key += ~(key << 11);
key ^= (key >> 16);
return key;
}
};
template <class Value>
class btHashKey
{
int m_uid;
public:
int m_uid;
btHashKey(int uid) :m_uid(uid)
public:
btHashKey(int uid) : m_uid(uid)
{
}
int getUid1() const
int getUid1() const
{
return m_uid;
}
@@ -197,30 +199,33 @@ public:
return getUid1() == other.getUid1();
}
//to our success
SIMD_FORCE_INLINE unsigned int getHash()const
SIMD_FORCE_INLINE unsigned int getHash() const
{
unsigned 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 btHashMap template class implements a generic and lightweight hashmap.
///A basic sample of how to use btHashMap is located in Demos\BasicDemo\main.cpp
template <class Key, class Value>
class btHashMap
{
protected:
btAlignedObjectArray<int> m_hashTable;
btAlignedObjectArray<int> m_next;
btAlignedObjectArray<Value> m_valueArray;
btAlignedObjectArray<Key> m_keyArray;
btAlignedObjectArray<int> m_hashTable;
btAlignedObjectArray<int> m_next;
void growTables(const Key& /*key*/)
btAlignedObjectArray<Value> m_valueArray;
btAlignedObjectArray<Key> m_keyArray;
void growTables(const Key& /*key*/)
{
int newCapacity = m_valueArray.capacity();
@@ -234,7 +239,7 @@ protected:
int i;
for (i= 0; i < newCapacity; ++i)
for (i = 0; i < newCapacity; ++i)
{
m_hashTable[i] = BT_HASH_NULL;
}
@@ -243,30 +248,28 @@ protected:
m_next[i] = BT_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 != BT_HASH_NULL)
{
m_valueArray[index]=value;
m_valueArray[index] = value;
return;
}
@@ -280,19 +283,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 ==BT_HASH_NULL)
if (pairIndex == BT_HASH_NULL)
{
return;
}
@@ -333,7 +336,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];
btAssert(index != BT_HASH_NULL);
@@ -365,10 +368,8 @@ protected:
m_valueArray.pop_back();
m_keyArray.pop_back();
}
int size() const
{
return m_valueArray.size();
@@ -377,8 +378,8 @@ protected:
const Value* getAtIndex(int index) const
{
btAssert(index < m_valueArray.size());
btAssert(index>=0);
if (index>=0 && index < m_valueArray.size())
btAssert(index >= 0);
if (index >= 0 && index < m_valueArray.size())
{
return &m_valueArray[index];
}
@@ -388,38 +389,39 @@ protected:
Value* getAtIndex(int index)
{
btAssert(index < m_valueArray.size());
btAssert(index>=0);
if (index>=0 && index < m_valueArray.size())
btAssert(index >= 0);
if (index >= 0 && index < m_valueArray.size())
{
return &m_valueArray[index];
}
return 0;
}
Key getKeyAtIndex(int index)
{
btAssert(index < m_keyArray.size());
btAssert(index>=0);
Key getKeyAtIndex(int index)
{
btAssert(index < m_keyArray.size());
btAssert(index >= 0);
return m_keyArray[index];
}
const Key getKeyAtIndex(int index) const
{
btAssert(index < m_keyArray.size());
btAssert(index>=0);
}
const Key getKeyAtIndex(int index) const
{
btAssert(index < m_keyArray.size());
btAssert(index >= 0);
return m_keyArray[index];
}
}
Value* operator[](const Key& key) {
Value* operator[](const Key& key)
{
return find(key);
}
const Value* operator[](const Key& key) const {
const Value* operator[](const Key& key) const
{
return find(key);
}
const Value* find(const Key& key) const
const Value* find(const Key& key) const
{
int index = findIndex(key);
if (index == BT_HASH_NULL)
@@ -429,7 +431,7 @@ protected:
return &m_valueArray[index];
}
Value* find(const Key& key)
Value* find(const Key& key)
{
int index = findIndex(key);
if (index == BT_HASH_NULL)
@@ -439,10 +441,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())
{
@@ -457,14 +458,13 @@ protected:
return index;
}
void clear()
void clear()
{
m_hashTable.clear();
m_next.clear();
m_valueArray.clear();
m_keyArray.clear();
}
};
#endif //BT_HASH_MAP_H
#endif //BT_HASH_MAP_H

View File

@@ -13,86 +13,84 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BT_IDEBUG_DRAW__H
#define BT_IDEBUG_DRAW__H
#include "btVector3.h"
#include "btTransform.h"
///The btIDebugDraw interface class allows hooking up a debug renderer to visually debug simulations.
///Typical use case: create a debug drawer object, and assign it to a btCollisionWorld or btDynamicsWorld using setDebugDrawer and call debugDrawWorld.
///A class that implements the btIDebugDraw interface has to implement the drawLine method at a minimum.
///For color arguments the X,Y,Z components refer to Red, Green and Blue each in the range [0..1]
class btIDebugDraw
class btIDebugDraw
{
public:
ATTRIBUTE_ALIGNED16(struct) DefaultColors
public:
ATTRIBUTE_ALIGNED16(struct)
DefaultColors
{
btVector3 m_activeObject;
btVector3 m_deactivatedObject;
btVector3 m_wantsDeactivationObject;
btVector3 m_disabledDeactivationObject;
btVector3 m_disabledSimulationObject;
btVector3 m_aabb;
btVector3 m_activeObject;
btVector3 m_deactivatedObject;
btVector3 m_wantsDeactivationObject;
btVector3 m_disabledDeactivationObject;
btVector3 m_disabledSimulationObject;
btVector3 m_aabb;
btVector3 m_contactPoint;
DefaultColors()
: m_activeObject(1,1,1),
m_deactivatedObject(0,1,0),
m_wantsDeactivationObject(0,1,1),
m_disabledDeactivationObject(1,0,0),
m_disabledSimulationObject(1,1,0),
m_aabb(1,0,0),
m_contactPoint(1,1,0)
: m_activeObject(1, 1, 1),
m_deactivatedObject(0, 1, 0),
m_wantsDeactivationObject(0, 1, 1),
m_disabledDeactivationObject(1, 0, 0),
m_disabledSimulationObject(1, 1, 0),
m_aabb(1, 0, 0),
m_contactPoint(1, 1, 0)
{
}
};
enum DebugDrawModes
enum DebugDrawModes
{
DBG_NoDebug=0,
DBG_NoDebug = 0,
DBG_DrawWireframe = 1,
DBG_DrawAabb=2,
DBG_DrawFeaturesText=4,
DBG_DrawContactPoints=8,
DBG_NoDeactivation=16,
DBG_DrawAabb = 2,
DBG_DrawFeaturesText = 4,
DBG_DrawContactPoints = 8,
DBG_NoDeactivation = 16,
DBG_NoHelpText = 32,
DBG_DrawText=64,
DBG_DrawText = 64,
DBG_ProfileTimings = 128,
DBG_EnableSatComparison = 256,
DBG_DisableBulletLCP = 512,
DBG_EnableCCD = 1024,
DBG_DrawConstraints = (1 << 11),
DBG_DrawConstraintLimits = (1 << 12),
DBG_FastWireframe = (1<<13),
DBG_DrawNormals = (1<<14),
DBG_DrawFrames = (1<<15),
DBG_FastWireframe = (1 << 13),
DBG_DrawNormals = (1 << 14),
DBG_DrawFrames = (1 << 15),
DBG_MAX_DEBUG_DRAW_MODE
};
virtual ~btIDebugDraw() {};
virtual ~btIDebugDraw(){};
virtual DefaultColors getDefaultColors() const { DefaultColors colors; return colors; }
virtual DefaultColors getDefaultColors() const
{
DefaultColors colors;
return colors;
}
///the default implementation for setDefaultColors has no effect. A derived class can implement it and store the colors.
virtual void setDefaultColors(const DefaultColors& /*colors*/) {}
virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& color)=0;
virtual void drawLine(const btVector3& from,const btVector3& to, const btVector3& fromColor, const btVector3& toColor)
virtual void drawLine(const btVector3& from, const btVector3& to, const btVector3& color) = 0;
virtual void drawLine(const btVector3& from, const btVector3& to, const btVector3& fromColor, const btVector3& toColor)
{
(void) toColor;
drawLine (from, to, fromColor);
(void)toColor;
drawLine(from, to, fromColor);
}
virtual void drawSphere(btScalar radius, const btTransform& transform, const btVector3& color)
virtual void drawSphere(btScalar radius, const btTransform& transform, const btVector3& color)
{
btVector3 center = transform.getOrigin();
btVector3 up = transform.getBasis().getColumn(1);
btVector3 axis = transform.getBasis().getColumn(0);
@@ -101,103 +99,102 @@ class btIDebugDraw
btScalar minPs = -SIMD_HALF_PI;
btScalar maxPs = SIMD_HALF_PI;
btScalar stepDegrees = 30.f;
drawSpherePatch(center, up, axis, radius,minTh, maxTh, minPs, maxPs, color, stepDegrees ,false);
drawSpherePatch(center, up, -axis, radius,minTh, maxTh, minPs, maxPs, color, stepDegrees,false );
drawSpherePatch(center, up, axis, radius, minTh, maxTh, minPs, maxPs, color, stepDegrees, false);
drawSpherePatch(center, up, -axis, radius, minTh, maxTh, minPs, maxPs, color, stepDegrees, false);
}
virtual void drawSphere (const btVector3& p, btScalar radius, const btVector3& color)
virtual void drawSphere(const btVector3& p, btScalar radius, const btVector3& color)
{
btTransform tr;
tr.setIdentity();
tr.setOrigin(p);
drawSphere(radius,tr,color);
}
virtual void drawTriangle(const btVector3& v0,const btVector3& v1,const btVector3& v2,const btVector3& /*n0*/,const btVector3& /*n1*/,const btVector3& /*n2*/,const btVector3& color, btScalar alpha)
{
drawTriangle(v0,v1,v2,color,alpha);
}
virtual void drawTriangle(const btVector3& v0,const btVector3& v1,const btVector3& v2,const btVector3& color, btScalar /*alpha*/)
{
drawLine(v0,v1,color);
drawLine(v1,v2,color);
drawLine(v2,v0,color);
drawSphere(radius, tr, color);
}
virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color)=0;
virtual void reportErrorWarning(const char* warningString) = 0;
virtual void draw3dText(const btVector3& location,const char* textString) = 0;
virtual void setDebugMode(int debugMode) =0;
virtual int getDebugMode() const = 0;
virtual void drawAabb(const btVector3& from,const btVector3& to,const btVector3& color)
virtual void drawTriangle(const btVector3& v0, const btVector3& v1, const btVector3& v2, const btVector3& /*n0*/, const btVector3& /*n1*/, const btVector3& /*n2*/, const btVector3& color, btScalar alpha)
{
drawTriangle(v0, v1, v2, color, alpha);
}
virtual void drawTriangle(const btVector3& v0, const btVector3& v1, const btVector3& v2, const btVector3& color, btScalar /*alpha*/)
{
drawLine(v0, v1, color);
drawLine(v1, v2, color);
drawLine(v2, v0, color);
}
btVector3 halfExtents = (to-from)* 0.5f;
btVector3 center = (to+from) *0.5f;
int i,j;
virtual void drawContactPoint(const btVector3& PointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color) = 0;
btVector3 edgecoord(1.f,1.f,1.f),pa,pb;
for (i=0;i<4;i++)
virtual void reportErrorWarning(const char* warningString) = 0;
virtual void draw3dText(const btVector3& location, const char* textString) = 0;
virtual void setDebugMode(int debugMode) = 0;
virtual int getDebugMode() const = 0;
virtual void drawAabb(const btVector3& from, const btVector3& to, const btVector3& color)
{
btVector3 halfExtents = (to - from) * 0.5f;
btVector3 center = (to + from) * 0.5f;
int i, j;
btVector3 edgecoord(1.f, 1.f, 1.f), pa, pb;
for (i = 0; i < 4; i++)
{
for (j=0;j<3;j++)
for (j = 0; j < 3; j++)
{
pa = btVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1],
edgecoord[2]*halfExtents[2]);
pa+=center;
pa = btVector3(edgecoord[0] * halfExtents[0], edgecoord[1] * halfExtents[1],
edgecoord[2] * halfExtents[2]);
pa += center;
int othercoord = j%3;
edgecoord[othercoord]*=-1.f;
pb = btVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1],
edgecoord[2]*halfExtents[2]);
pb+=center;
int othercoord = j % 3;
edgecoord[othercoord] *= -1.f;
pb = btVector3(edgecoord[0] * halfExtents[0], edgecoord[1] * halfExtents[1],
edgecoord[2] * halfExtents[2]);
pb += center;
drawLine(pa,pb,color);
drawLine(pa, pb, color);
}
edgecoord = btVector3(-1.f,-1.f,-1.f);
if (i<3)
edgecoord[i]*=-1.f;
edgecoord = btVector3(-1.f, -1.f, -1.f);
if (i < 3)
edgecoord[i] *= -1.f;
}
}
virtual void drawTransform(const btTransform& transform, btScalar orthoLen)
{
btVector3 start = transform.getOrigin();
drawLine(start, start+transform.getBasis() * btVector3(orthoLen, 0, 0), btVector3(btScalar(1.), btScalar(0.3), btScalar(0.3)));
drawLine(start, start+transform.getBasis() * btVector3(0, orthoLen, 0), btVector3(btScalar(0.3), btScalar(1.), btScalar(0.3)));
drawLine(start, start+transform.getBasis() * btVector3(0, 0, orthoLen), btVector3(btScalar(0.3), btScalar(0.3), btScalar(1.)));
drawLine(start, start + transform.getBasis() * btVector3(orthoLen, 0, 0), btVector3(btScalar(1.), btScalar(0.3), btScalar(0.3)));
drawLine(start, start + transform.getBasis() * btVector3(0, orthoLen, 0), btVector3(btScalar(0.3), btScalar(1.), btScalar(0.3)));
drawLine(start, start + transform.getBasis() * btVector3(0, 0, orthoLen), btVector3(btScalar(0.3), btScalar(0.3), btScalar(1.)));
}
virtual void drawArc(const btVector3& center, const btVector3& normal, const btVector3& axis, btScalar radiusA, btScalar radiusB, btScalar minAngle, btScalar maxAngle,
const btVector3& color, bool drawSect, btScalar stepDegrees = btScalar(10.f))
virtual void drawArc(const btVector3& center, const btVector3& normal, const btVector3& axis, btScalar radiusA, btScalar radiusB, btScalar minAngle, btScalar maxAngle,
const btVector3& color, bool drawSect, btScalar stepDegrees = btScalar(10.f))
{
const btVector3& vx = axis;
btVector3 vy = normal.cross(axis);
btScalar step = stepDegrees * SIMD_RADS_PER_DEG;
int nSteps = (int)btFabs((maxAngle - minAngle) / step);
if(!nSteps) nSteps = 1;
if (!nSteps) nSteps = 1;
btVector3 prev = center + radiusA * vx * btCos(minAngle) + radiusB * vy * btSin(minAngle);
if(drawSect)
if (drawSect)
{
drawLine(center, prev, color);
}
for(int i = 1; i <= nSteps; i++)
for (int i = 1; i <= nSteps; i++)
{
btScalar angle = minAngle + (maxAngle - minAngle) * btScalar(i) / btScalar(nSteps);
btVector3 next = center + radiusA * vx * btCos(angle) + radiusB * vy * btSin(angle);
drawLine(prev, next, color);
prev = next;
}
if(drawSect)
if (drawSect)
{
drawLine(center, prev, color);
}
}
virtual void drawSpherePatch(const btVector3& center, const btVector3& up, const btVector3& axis, btScalar radius,
btScalar minTh, btScalar maxTh, btScalar minPs, btScalar maxPs, const btVector3& color, btScalar stepDegrees = btScalar(10.f),bool drawCenter = true)
virtual void drawSpherePatch(const btVector3& center, const btVector3& up, const btVector3& axis, btScalar radius,
btScalar minTh, btScalar maxTh, btScalar minPs, btScalar maxPs, const btVector3& color, btScalar stepDegrees = btScalar(10.f), bool drawCenter = true)
{
btVector3 vA[74];
btVector3 vB[74];
@@ -211,33 +208,33 @@ class btIDebugDraw
btVector3 jv = kv.cross(iv);
bool drawN = false;
bool drawS = false;
if(minTh <= -SIMD_HALF_PI)
if (minTh <= -SIMD_HALF_PI)
{
minTh = -SIMD_HALF_PI + step;
drawN = true;
}
if(maxTh >= SIMD_HALF_PI)
if (maxTh >= SIMD_HALF_PI)
{
maxTh = SIMD_HALF_PI - step;
drawS = true;
}
if(minTh > maxTh)
if (minTh > maxTh)
{
minTh = -SIMD_HALF_PI + step;
maxTh = SIMD_HALF_PI - step;
maxTh = SIMD_HALF_PI - step;
drawN = drawS = true;
}
int n_hor = (int)((maxTh - minTh) / step) + 1;
if(n_hor < 2) n_hor = 2;
if (n_hor < 2) n_hor = 2;
btScalar step_h = (maxTh - minTh) / btScalar(n_hor - 1);
bool isClosed = false;
if(minPs > maxPs)
if (minPs > maxPs)
{
minPs = -SIMD_PI + step;
maxPs = SIMD_PI;
maxPs = SIMD_PI;
isClosed = true;
}
else if((maxPs - minPs) >= SIMD_PI * btScalar(2.f))
else if ((maxPs - minPs) >= SIMD_PI * btScalar(2.f))
{
isClosed = true;
}
@@ -246,63 +243,64 @@ class btIDebugDraw
isClosed = false;
}
int n_vert = (int)((maxPs - minPs) / step) + 1;
if(n_vert < 2) n_vert = 2;
if (n_vert < 2) n_vert = 2;
btScalar step_v = (maxPs - minPs) / btScalar(n_vert - 1);
for(int i = 0; i < n_hor; i++)
for (int i = 0; i < n_hor; i++)
{
btScalar th = minTh + btScalar(i) * step_h;
btScalar sth = radius * btSin(th);
btScalar cth = radius * btCos(th);
for(int j = 0; j < n_vert; j++)
for (int j = 0; j < n_vert; j++)
{
btScalar psi = minPs + btScalar(j) * step_v;
btScalar sps = btSin(psi);
btScalar cps = btCos(psi);
pvB[j] = center + cth * cps * iv + cth * sps * jv + sth * kv;
if(i)
if (i)
{
drawLine(pvA[j], pvB[j], color);
}
else if(drawS)
else if (drawS)
{
drawLine(spole, pvB[j], color);
}
if(j)
if (j)
{
drawLine(pvB[j-1], pvB[j], color);
drawLine(pvB[j - 1], pvB[j], color);
}
else
{
arcStart = pvB[j];
}
if((i == (n_hor - 1)) && drawN)
if ((i == (n_hor - 1)) && drawN)
{
drawLine(npole, pvB[j], color);
}
if (drawCenter)
{
if(isClosed)
if (isClosed)
{
if(j == (n_vert-1))
if (j == (n_vert - 1))
{
drawLine(arcStart, pvB[j], color);
}
}
else
{
if(((!i) || (i == (n_hor-1))) && ((!j) || (j == (n_vert-1))))
if (((!i) || (i == (n_hor - 1))) && ((!j) || (j == (n_vert - 1))))
{
drawLine(center, pvB[j], color);
}
}
}
}
pT = pvA; pvA = pvB; pvB = pT;
pT = pvA;
pvA = pvB;
pvB = pT;
}
}
virtual void drawBox(const btVector3& bbMin, const btVector3& bbMax, const btVector3& color)
{
drawLine(btVector3(bbMin[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMin[1], bbMin[2]), color);
@@ -338,31 +336,27 @@ class btIDebugDraw
{
int stepDegrees = 30;
btVector3 capStart(0.f,0.f,0.f);
btVector3 capStart(0.f, 0.f, 0.f);
capStart[upAxis] = -halfHeight;
btVector3 capEnd(0.f,0.f,0.f);
btVector3 capEnd(0.f, 0.f, 0.f);
capEnd[upAxis] = halfHeight;
// Draw the ends
{
btTransform childTransform = transform;
childTransform.getOrigin() = transform * capStart;
{
btVector3 center = childTransform.getOrigin();
btVector3 up = childTransform.getBasis().getColumn((upAxis+1)%3);
btVector3 up = childTransform.getBasis().getColumn((upAxis + 1) % 3);
btVector3 axis = -childTransform.getBasis().getColumn(upAxis);
btScalar minTh = -SIMD_HALF_PI;
btScalar maxTh = SIMD_HALF_PI;
btScalar minPs = -SIMD_HALF_PI;
btScalar maxPs = SIMD_HALF_PI;
drawSpherePatch(center, up, axis, radius,minTh, maxTh, minPs, maxPs, color, btScalar(stepDegrees) ,false);
drawSpherePatch(center, up, axis, radius, minTh, maxTh, minPs, maxPs, color, btScalar(stepDegrees), false);
}
}
{
@@ -370,52 +364,51 @@ class btIDebugDraw
childTransform.getOrigin() = transform * capEnd;
{
btVector3 center = childTransform.getOrigin();
btVector3 up = childTransform.getBasis().getColumn((upAxis+1)%3);
btVector3 up = childTransform.getBasis().getColumn((upAxis + 1) % 3);
btVector3 axis = childTransform.getBasis().getColumn(upAxis);
btScalar minTh = -SIMD_HALF_PI;
btScalar maxTh = SIMD_HALF_PI;
btScalar minPs = -SIMD_HALF_PI;
btScalar maxPs = SIMD_HALF_PI;
drawSpherePatch(center, up, axis, radius,minTh, maxTh, minPs, maxPs, color, btScalar(stepDegrees) ,false);
drawSpherePatch(center, up, axis, radius, minTh, maxTh, minPs, maxPs, color, btScalar(stepDegrees), false);
}
}
// Draw some additional lines
btVector3 start = transform.getOrigin();
for (int i=0;i<360;i+=stepDegrees)
for (int i = 0; i < 360; i += stepDegrees)
{
capEnd[(upAxis+1)%3] = capStart[(upAxis+1)%3] = btSin(btScalar(i)*SIMD_RADS_PER_DEG)*radius;
capEnd[(upAxis+2)%3] = capStart[(upAxis+2)%3] = btCos(btScalar(i)*SIMD_RADS_PER_DEG)*radius;
drawLine(start+transform.getBasis() * capStart,start+transform.getBasis() * capEnd, color);
capEnd[(upAxis + 1) % 3] = capStart[(upAxis + 1) % 3] = btSin(btScalar(i) * SIMD_RADS_PER_DEG) * radius;
capEnd[(upAxis + 2) % 3] = capStart[(upAxis + 2) % 3] = btCos(btScalar(i) * SIMD_RADS_PER_DEG) * radius;
drawLine(start + transform.getBasis() * capStart, start + transform.getBasis() * capEnd, color);
}
}
virtual void drawCylinder(btScalar radius, btScalar halfHeight, int upAxis, const btTransform& transform, const btVector3& color)
{
btVector3 start = transform.getOrigin();
btVector3 offsetHeight(0,0,0);
btVector3 offsetHeight(0, 0, 0);
offsetHeight[upAxis] = halfHeight;
int stepDegrees=30;
btVector3 capStart(0.f,0.f,0.f);
int stepDegrees = 30;
btVector3 capStart(0.f, 0.f, 0.f);
capStart[upAxis] = -halfHeight;
btVector3 capEnd(0.f,0.f,0.f);
btVector3 capEnd(0.f, 0.f, 0.f);
capEnd[upAxis] = halfHeight;
for (int i=0;i<360;i+=stepDegrees)
for (int i = 0; i < 360; i += stepDegrees)
{
capEnd[(upAxis+1)%3] = capStart[(upAxis+1)%3] = btSin(btScalar(i)*SIMD_RADS_PER_DEG)*radius;
capEnd[(upAxis+2)%3] = capStart[(upAxis+2)%3] = btCos(btScalar(i)*SIMD_RADS_PER_DEG)*radius;
drawLine(start+transform.getBasis() * capStart,start+transform.getBasis() * capEnd, color);
capEnd[(upAxis + 1) % 3] = capStart[(upAxis + 1) % 3] = btSin(btScalar(i) * SIMD_RADS_PER_DEG) * radius;
capEnd[(upAxis + 2) % 3] = capStart[(upAxis + 2) % 3] = btCos(btScalar(i) * SIMD_RADS_PER_DEG) * radius;
drawLine(start + transform.getBasis() * capStart, start + transform.getBasis() * capEnd, color);
}
// Drawing top and bottom caps of the cylinder
btVector3 yaxis(0,0,0);
btVector3 yaxis(0, 0, 0);
yaxis[upAxis] = btScalar(1.0);
btVector3 xaxis(0,0,0);
xaxis[(upAxis+1)%3] = btScalar(1.0);
drawArc(start-transform.getBasis()*(offsetHeight),transform.getBasis()*yaxis,transform.getBasis()*xaxis,radius,radius,0,SIMD_2_PI,color,false,btScalar(10.0));
drawArc(start+transform.getBasis()*(offsetHeight),transform.getBasis()*yaxis,transform.getBasis()*xaxis,radius,radius,0,SIMD_2_PI,color,false,btScalar(10.0));
btVector3 xaxis(0, 0, 0);
xaxis[(upAxis + 1) % 3] = btScalar(1.0);
drawArc(start - transform.getBasis() * (offsetHeight), transform.getBasis() * yaxis, transform.getBasis() * xaxis, radius, radius, 0, SIMD_2_PI, color, false, btScalar(10.0));
drawArc(start + transform.getBasis() * (offsetHeight), transform.getBasis() * yaxis, transform.getBasis() * xaxis, radius, radius, 0, SIMD_2_PI, color, false, btScalar(10.0));
}
virtual void drawCone(btScalar radius, btScalar height, int upAxis, const btTransform& transform, const btVector3& color)
@@ -423,50 +416,49 @@ class btIDebugDraw
int stepDegrees = 30;
btVector3 start = transform.getOrigin();
btVector3 offsetHeight(0,0,0);
btVector3 offsetHeight(0, 0, 0);
btScalar halfHeight = height * btScalar(0.5);
offsetHeight[upAxis] = halfHeight;
btVector3 offsetRadius(0,0,0);
offsetRadius[(upAxis+1)%3] = radius;
btVector3 offset2Radius(0,0,0);
offset2Radius[(upAxis+2)%3] = radius;
btVector3 offsetRadius(0, 0, 0);
offsetRadius[(upAxis + 1) % 3] = radius;
btVector3 offset2Radius(0, 0, 0);
offset2Radius[(upAxis + 2) % 3] = radius;
btVector3 capEnd(0.f,0.f,0.f);
btVector3 capEnd(0.f, 0.f, 0.f);
capEnd[upAxis] = -halfHeight;
for (int i=0;i<360;i+=stepDegrees)
for (int i = 0; i < 360; i += stepDegrees)
{
capEnd[(upAxis+1)%3] = btSin(btScalar(i)*SIMD_RADS_PER_DEG)*radius;
capEnd[(upAxis+2)%3] = btCos(btScalar(i)*SIMD_RADS_PER_DEG)*radius;
drawLine(start+transform.getBasis() * (offsetHeight),start+transform.getBasis() * capEnd, color);
capEnd[(upAxis + 1) % 3] = btSin(btScalar(i) * SIMD_RADS_PER_DEG) * radius;
capEnd[(upAxis + 2) % 3] = btCos(btScalar(i) * SIMD_RADS_PER_DEG) * radius;
drawLine(start + transform.getBasis() * (offsetHeight), start + transform.getBasis() * capEnd, color);
}
drawLine(start+transform.getBasis() * (offsetHeight),start+transform.getBasis() * (-offsetHeight+offsetRadius),color);
drawLine(start+transform.getBasis() * (offsetHeight),start+transform.getBasis() * (-offsetHeight-offsetRadius),color);
drawLine(start+transform.getBasis() * (offsetHeight),start+transform.getBasis() * (-offsetHeight+offset2Radius),color);
drawLine(start+transform.getBasis() * (offsetHeight),start+transform.getBasis() * (-offsetHeight-offset2Radius),color);
drawLine(start + transform.getBasis() * (offsetHeight), start + transform.getBasis() * (-offsetHeight + offsetRadius), color);
drawLine(start + transform.getBasis() * (offsetHeight), start + transform.getBasis() * (-offsetHeight - offsetRadius), color);
drawLine(start + transform.getBasis() * (offsetHeight), start + transform.getBasis() * (-offsetHeight + offset2Radius), color);
drawLine(start + transform.getBasis() * (offsetHeight), start + transform.getBasis() * (-offsetHeight - offset2Radius), color);
// Drawing the base of the cone
btVector3 yaxis(0,0,0);
btVector3 yaxis(0, 0, 0);
yaxis[upAxis] = btScalar(1.0);
btVector3 xaxis(0,0,0);
xaxis[(upAxis+1)%3] = btScalar(1.0);
drawArc(start-transform.getBasis()*(offsetHeight),transform.getBasis()*yaxis,transform.getBasis()*xaxis,radius,radius,0,SIMD_2_PI,color,false,10.0);
btVector3 xaxis(0, 0, 0);
xaxis[(upAxis + 1) % 3] = btScalar(1.0);
drawArc(start - transform.getBasis() * (offsetHeight), transform.getBasis() * yaxis, transform.getBasis() * xaxis, radius, radius, 0, SIMD_2_PI, color, false, 10.0);
}
virtual void drawPlane(const btVector3& planeNormal, btScalar planeConst, const btTransform& transform, const btVector3& color)
{
btVector3 planeOrigin = planeNormal * planeConst;
btVector3 vec0,vec1;
btPlaneSpace1(planeNormal,vec0,vec1);
btVector3 vec0, vec1;
btPlaneSpace1(planeNormal, vec0, vec1);
btScalar vecLen = 100.f;
btVector3 pt0 = planeOrigin + vec0*vecLen;
btVector3 pt1 = planeOrigin - vec0*vecLen;
btVector3 pt2 = planeOrigin + vec1*vecLen;
btVector3 pt3 = planeOrigin - vec1*vecLen;
drawLine(transform*pt0,transform*pt1,color);
drawLine(transform*pt2,transform*pt3,color);
btVector3 pt0 = planeOrigin + vec0 * vecLen;
btVector3 pt1 = planeOrigin - vec0 * vecLen;
btVector3 pt2 = planeOrigin + vec1 * vecLen;
btVector3 pt3 = planeOrigin - vec1 * vecLen;
drawLine(transform * pt0, transform * pt1, color);
drawLine(transform * pt2, transform * pt3, color);
}
virtual void clearLines()
@@ -478,6 +470,4 @@ class btIDebugDraw
}
};
#endif //BT_IDEBUG_DRAW__H
#endif //BT_IDEBUG_DRAW__H

View File

@@ -12,62 +12,62 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BT_GEN_LIST_H
#define BT_GEN_LIST_H
class btGEN_Link {
class btGEN_Link
{
public:
btGEN_Link() : m_next(0), m_prev(0) {}
btGEN_Link(btGEN_Link *next, btGEN_Link *prev) : m_next(next), m_prev(prev) {}
btGEN_Link *getNext() const { return m_next; }
btGEN_Link *getPrev() const { return m_prev; }
btGEN_Link() : m_next(0), m_prev(0) {}
btGEN_Link(btGEN_Link *next, btGEN_Link *prev) : m_next(next), m_prev(prev) {}
bool isHead() const { return m_prev == 0; }
bool isTail() const { return m_next == 0; }
btGEN_Link *getNext() const { return m_next; }
btGEN_Link *getPrev() const { return m_prev; }
void insertBefore(btGEN_Link *link) {
m_next = link;
m_prev = link->m_prev;
m_next->m_prev = this;
m_prev->m_next = this;
}
bool isHead() const { return m_prev == 0; }
bool isTail() const { return m_next == 0; }
void insertAfter(btGEN_Link *link) {
m_next = link->m_next;
m_prev = link;
m_next->m_prev = this;
m_prev->m_next = this;
}
void insertBefore(btGEN_Link *link)
{
m_next = link;
m_prev = link->m_prev;
m_next->m_prev = this;
m_prev->m_next = this;
}
void remove() {
m_next->m_prev = m_prev;
m_prev->m_next = m_next;
}
void insertAfter(btGEN_Link *link)
{
m_next = link->m_next;
m_prev = link;
m_next->m_prev = this;
m_prev->m_next = this;
}
private:
btGEN_Link *m_next;
btGEN_Link *m_prev;
};
void remove()
{
m_next->m_prev = m_prev;
m_prev->m_next = m_next;
}
class btGEN_List {
public:
btGEN_List() : m_head(&m_tail, 0), m_tail(0, &m_head) {}
btGEN_Link *getHead() const { return m_head.getNext(); }
btGEN_Link *getTail() const { return m_tail.getPrev(); }
void addHead(btGEN_Link *link) { link->insertAfter(&m_head); }
void addTail(btGEN_Link *link) { link->insertBefore(&m_tail); }
private:
btGEN_Link m_head;
btGEN_Link m_tail;
btGEN_Link *m_next;
btGEN_Link *m_prev;
};
#endif //BT_GEN_LIST_H
class btGEN_List
{
public:
btGEN_List() : m_head(&m_tail, 0), m_tail(0, &m_head) {}
btGEN_Link *getHead() const { return m_head.getNext(); }
btGEN_Link *getTail() const { return m_tail.getPrev(); }
void addHead(btGEN_Link *link) { link->insertAfter(&m_head); }
void addTail(btGEN_Link *link) { link->insertBefore(&m_tail); }
private:
btGEN_Link m_head;
btGEN_Link m_tail;
};
#endif //BT_GEN_LIST_H

File diff suppressed because it is too large Load Diff

View File

@@ -24,24 +24,23 @@ subject to the following restrictions:
//#define BT_DEBUG_OSTREAM
#ifdef BT_DEBUG_OSTREAM
#include <iostream>
#include <iomanip> // std::setw
#endif //BT_DEBUG_OSTREAM
#include <iomanip> // std::setw
#endif //BT_DEBUG_OSTREAM
class btIntSortPredicate
{
public:
bool operator() ( const int& a, const int& b ) const
{
return a < b;
}
public:
bool operator()(const int& a, const int& b) const
{
return a < b;
}
};
template <typename T>
struct btVectorX
{
btAlignedObjectArray<T> m_storage;
btAlignedObjectArray<T> m_storage;
btVectorX()
{
}
@@ -49,7 +48,7 @@ struct btVectorX
{
m_storage.resize(numRows);
}
void resize(int rows)
{
m_storage.resize(rows);
@@ -66,13 +65,13 @@ struct btVectorX
{
return rows();
}
T nrm2() const
{
T norm = T(0);
int nn = rows();
{
if (nn == 1)
{
@@ -82,11 +81,11 @@ struct btVectorX
{
T scale = 0.0;
T ssq = 1.0;
/* The following loop is equivalent to this call to the LAPACK
auxiliary routine: CALL SLASSQ( N, X, INCX, SCALE, SSQ ) */
for (int ix=0;ix<nn;ix++)
for (int ix = 0; ix < nn; ix++)
{
if ((*this)[ix] != 0.0)
{
@@ -110,38 +109,36 @@ struct btVectorX
}
}
return norm;
}
void setZero()
void setZero()
{
if (m_storage.size())
{
// for (int i=0;i<m_storage.size();i++)
// m_storage[i]=0;
//memset(&m_storage[0],0,sizeof(T)*m_storage.size());
btSetZero(&m_storage[0],m_storage.size());
btSetZero(&m_storage[0], m_storage.size());
}
}
const T& operator[] (int index) const
const T& operator[](int index) const
{
return m_storage[index];
}
T& operator[] (int index)
T& operator[](int index)
{
return m_storage[index];
}
T* getBufferPointerWritable()
{
return m_storage.size() ? &m_storage[0] : 0;
}
const T* getBufferPointer() const
{
return m_storage.size() ? &m_storage[0] : 0;
}
};
/*
template <typename T>
@@ -151,8 +148,7 @@ struct btVectorX
}
*/
template <typename T>
template <typename T>
struct btMatrixX
{
int m_rows;
@@ -161,10 +157,10 @@ struct btMatrixX
int m_resizeOperations;
int m_setElemOperations;
btAlignedObjectArray<T> m_storage;
mutable btAlignedObjectArray< btAlignedObjectArray<int> > m_rowNonZeroElements1;
btAlignedObjectArray<T> m_storage;
mutable btAlignedObjectArray<btAlignedObjectArray<int> > m_rowNonZeroElements1;
T* getBufferPointerWritable()
T* getBufferPointerWritable()
{
return m_storage.size() ? &m_storage[0] : 0;
}
@@ -174,21 +170,21 @@ struct btMatrixX
return m_storage.size() ? &m_storage[0] : 0;
}
btMatrixX()
:m_rows(0),
m_cols(0),
m_operations(0),
m_resizeOperations(0),
m_setElemOperations(0)
: m_rows(0),
m_cols(0),
m_operations(0),
m_resizeOperations(0),
m_setElemOperations(0)
{
}
btMatrixX(int rows,int cols)
:m_rows(rows),
m_cols(cols),
m_operations(0),
m_resizeOperations(0),
m_setElemOperations(0)
btMatrixX(int rows, int cols)
: m_rows(rows),
m_cols(cols),
m_operations(0),
m_resizeOperations(0),
m_setElemOperations(0)
{
resize(rows,cols);
resize(rows, cols);
}
void resize(int rows, int cols)
{
@@ -197,7 +193,7 @@ struct btMatrixX
m_cols = cols;
{
BT_PROFILE("m_storage.resize");
m_storage.resize(rows*cols);
m_storage.resize(rows * cols);
}
}
int cols() const
@@ -215,108 +211,99 @@ struct btMatrixX
}
*/
void addElem(int row,int col, T val)
void addElem(int row, int col, T val)
{
if (val)
{
if (m_storage[col+row*m_cols]==0.f)
if (m_storage[col + row * m_cols] == 0.f)
{
setElem(row,col,val);
} else
setElem(row, col, val);
}
else
{
m_storage[row*m_cols+col] += val;
m_storage[row * m_cols + col] += val;
}
}
}
void setElem(int row,int col, T val)
void setElem(int row, int col, T val)
{
m_setElemOperations++;
m_storage[row*m_cols+col] = val;
m_storage[row * m_cols + col] = val;
}
void mulElem(int row,int col, T val)
void mulElem(int row, int col, T val)
{
m_setElemOperations++;
//mul doesn't change sparsity info
m_storage[row*m_cols+col] *= val;
m_storage[row * m_cols + col] *= val;
}
void copyLowerToUpperTriangle()
{
int count=0;
for (int row=0;row<rows();row++)
int count = 0;
for (int row = 0; row < rows(); row++)
{
for (int col=0;col<row;col++)
for (int col = 0; col < row; col++)
{
setElem(col,row, (*this)(row,col));
setElem(col, row, (*this)(row, col));
count++;
}
}
//printf("copyLowerToUpperTriangle copied %d elements out of %dx%d=%d\n", count,rows(),cols(),cols()*rows());
}
const T& operator() (int row,int col) const
{
return m_storage[col+row*m_cols];
}
const T& operator()(int row, int col) const
{
return m_storage[col + row * m_cols];
}
void setZero()
{
{
BT_PROFILE("storage=0");
btSetZero(&m_storage[0],m_storage.size());
btSetZero(&m_storage[0], m_storage.size());
//memset(&m_storage[0],0,sizeof(T)*m_storage.size());
//for (int i=0;i<m_storage.size();i++)
// m_storage[i]=0;
// m_storage[i]=0;
}
}
void setIdentity()
{
btAssert(rows() == cols());
setZero();
for (int row=0;row<rows();row++)
for (int row = 0; row < rows(); row++)
{
setElem(row,row,1);
setElem(row, row, 1);
}
}
void printMatrix(const char* msg)
void printMatrix(const char* msg)
{
printf("%s ---------------------\n",msg);
for (int i=0;i<rows();i++)
printf("%s ---------------------\n", msg);
for (int i = 0; i < rows(); i++)
{
printf("\n");
for (int j=0;j<cols();j++)
for (int j = 0; j < cols(); j++)
{
printf("%2.1f\t",(*this)(i,j));
printf("%2.1f\t", (*this)(i, j));
}
}
printf("\n---------------------\n");
}
void rowComputeNonZeroElements() const
{
m_rowNonZeroElements1.resize(rows());
for (int i=0;i<rows();i++)
for (int i = 0; i < rows(); i++)
{
m_rowNonZeroElements1[i].resize(0);
for (int j=0;j<cols();j++)
for (int j = 0; j < cols(); j++)
{
if ((*this)(i,j)!=0.f)
if ((*this)(i, j) != 0.f)
{
m_rowNonZeroElements1[i].push_back(j);
}
@@ -326,54 +313,52 @@ struct btMatrixX
btMatrixX transpose() const
{
//transpose is optimized for sparse matrices
btMatrixX tr(m_cols,m_rows);
btMatrixX tr(m_cols, m_rows);
tr.setZero();
for (int i=0;i<m_cols;i++)
for (int j=0;j<m_rows;j++)
for (int i = 0; i < m_cols; i++)
for (int j = 0; j < m_rows; j++)
{
T v = (*this)(j,i);
T v = (*this)(j, i);
if (v)
{
tr.setElem(i,j,v);
tr.setElem(i, j, v);
}
}
return tr;
}
btMatrixX operator*(const btMatrixX& other)
{
//btMatrixX*btMatrixX implementation, brute force
btAssert(cols() == other.rows());
btMatrixX res(rows(),other.cols());
btMatrixX res(rows(), other.cols());
res.setZero();
// BT_PROFILE("btMatrixX mul");
for (int j=0; j < res.cols(); ++j)
// BT_PROFILE("btMatrixX mul");
for (int j = 0; j < res.cols(); ++j)
{
{
for (int i=0; i < res.rows(); ++i)
for (int i = 0; i < res.rows(); ++i)
{
T dotProd=0;
// T dotProd2=0;
T dotProd = 0;
// T dotProd2=0;
//int waste=0,waste2=0;
{
// bool useOtherCol = true;
// bool useOtherCol = true;
{
for (int v=0;v<rows();v++)
for (int v = 0; v < rows(); v++)
{
T w = (*this)(i,v);
if (other(v,j)!=0.f)
T w = (*this)(i, v);
if (other(v, j) != 0.f)
{
dotProd+=w*other(v,j);
dotProd += w * other(v, j);
}
}
}
}
if (dotProd)
res.setElem(i,j,dotProd);
res.setElem(i, j, dotProd);
}
}
}
@@ -381,174 +366,166 @@ struct btMatrixX
}
// this assumes the 4th and 8th rows of B and C are zero.
void multiplyAdd2_p8r (const btScalar *B, const btScalar *C, int numRows, int numRowsOther ,int row, int col)
void multiplyAdd2_p8r(const btScalar* B, const btScalar* C, int numRows, int numRowsOther, int row, int col)
{
const btScalar *bb = B;
for ( int i = 0;i<numRows;i++)
const btScalar* bb = B;
for (int i = 0; i < numRows; i++)
{
const btScalar *cc = C;
for ( int j = 0;j<numRowsOther;j++)
const btScalar* cc = C;
for (int j = 0; j < numRowsOther; j++)
{
btScalar sum;
sum = bb[0]*cc[0];
sum += bb[1]*cc[1];
sum += bb[2]*cc[2];
sum += bb[4]*cc[4];
sum += bb[5]*cc[5];
sum += bb[6]*cc[6];
addElem(row+i,col+j,sum);
sum = bb[0] * cc[0];
sum += bb[1] * cc[1];
sum += bb[2] * cc[2];
sum += bb[4] * cc[4];
sum += bb[5] * cc[5];
sum += bb[6] * cc[6];
addElem(row + i, col + j, sum);
cc += 8;
}
bb += 8;
}
}
void multiply2_p8r (const btScalar *B, const btScalar *C, int numRows, int numRowsOther, int row, int col)
void multiply2_p8r(const btScalar* B, const btScalar* C, int numRows, int numRowsOther, int row, int col)
{
btAssert (numRows>0 && numRowsOther>0 && B && C);
const btScalar *bb = B;
for ( int i = 0;i<numRows;i++)
btAssert(numRows > 0 && numRowsOther > 0 && B && C);
const btScalar* bb = B;
for (int i = 0; i < numRows; i++)
{
const btScalar *cc = C;
for ( int j = 0;j<numRowsOther;j++)
const btScalar* cc = C;
for (int j = 0; j < numRowsOther; j++)
{
btScalar sum;
sum = bb[0]*cc[0];
sum += bb[1]*cc[1];
sum += bb[2]*cc[2];
sum += bb[4]*cc[4];
sum += bb[5]*cc[5];
sum += bb[6]*cc[6];
setElem(row+i,col+j,sum);
sum = bb[0] * cc[0];
sum += bb[1] * cc[1];
sum += bb[2] * cc[2];
sum += bb[4] * cc[4];
sum += bb[5] * cc[5];
sum += bb[6] * cc[6];
setElem(row + i, col + j, sum);
cc += 8;
}
bb += 8;
}
}
void setSubMatrix(int rowstart,int colstart,int rowend,int colend,const T value)
void setSubMatrix(int rowstart, int colstart, int rowend, int colend, const T value)
{
int numRows = rowend+1-rowstart;
int numCols = colend+1-colstart;
for (int row=0;row<numRows;row++)
int numRows = rowend + 1 - rowstart;
int numCols = colend + 1 - colstart;
for (int row = 0; row < numRows; row++)
{
for (int col=0;col<numCols;col++)
for (int col = 0; col < numCols; col++)
{
setElem(rowstart+row,colstart+col,value);
setElem(rowstart + row, colstart + col, value);
}
}
}
void setSubMatrix(int rowstart,int colstart,int rowend,int colend,const btMatrixX& block)
void setSubMatrix(int rowstart, int colstart, int rowend, int colend, const btMatrixX& block)
{
btAssert(rowend+1-rowstart == block.rows());
btAssert(colend+1-colstart == block.cols());
for (int row=0;row<block.rows();row++)
btAssert(rowend + 1 - rowstart == block.rows());
btAssert(colend + 1 - colstart == block.cols());
for (int row = 0; row < block.rows(); row++)
{
for (int col=0;col<block.cols();col++)
for (int col = 0; col < block.cols(); col++)
{
setElem(rowstart+row,colstart+col,block(row,col));
setElem(rowstart + row, colstart + col, block(row, col));
}
}
}
void setSubMatrix(int rowstart,int colstart,int rowend,int colend,const btVectorX<T>& block)
void setSubMatrix(int rowstart, int colstart, int rowend, int colend, const btVectorX<T>& block)
{
btAssert(rowend+1-rowstart == block.rows());
btAssert(colend+1-colstart == block.cols());
for (int row=0;row<block.rows();row++)
btAssert(rowend + 1 - rowstart == block.rows());
btAssert(colend + 1 - colstart == block.cols());
for (int row = 0; row < block.rows(); row++)
{
for (int col=0;col<block.cols();col++)
for (int col = 0; col < block.cols(); col++)
{
setElem(rowstart+row,colstart+col,block[row]);
setElem(rowstart + row, colstart + col, block[row]);
}
}
}
btMatrixX negative()
{
btMatrixX neg(rows(),cols());
for (int i=0;i<rows();i++)
for (int j=0;j<cols();j++)
btMatrixX neg(rows(), cols());
for (int i = 0; i < rows(); i++)
for (int j = 0; j < cols(); j++)
{
T v = (*this)(i,j);
neg.setElem(i,j,-v);
T v = (*this)(i, j);
neg.setElem(i, j, -v);
}
return neg;
}
};
typedef btMatrixX<float> btMatrixXf;
typedef btVectorX<float> btVectorXf;
typedef btMatrixX<double> btMatrixXd;
typedef btVectorX<double> btVectorXd;
#ifdef BT_DEBUG_OSTREAM
template <typename T>
std::ostream& operator<< (std::ostream& os, const btMatrixX<T>& mat)
template <typename T>
std::ostream& operator<<(std::ostream& os, const btMatrixX<T>& mat)
{
os << " [";
//printf("%s ---------------------\n",msg);
for (int i = 0; i < mat.rows(); i++)
{
os << " [";
//printf("%s ---------------------\n",msg);
for (int i=0;i<mat.rows();i++)
for (int j = 0; j < mat.cols(); j++)
{
for (int j=0;j<mat.cols();j++)
{
os << std::setw(12) << mat(i,j);
}
if (i!=mat.rows()-1)
os << std::endl << " ";
os << std::setw(12) << mat(i, j);
}
os << " ]";
//printf("\n---------------------\n");
return os;
if (i != mat.rows() - 1)
os << std::endl
<< " ";
}
template <typename T>
std::ostream& operator<< (std::ostream& os, const btVectorX<T>& mat)
os << " ]";
//printf("\n---------------------\n");
return os;
}
template <typename T>
std::ostream& operator<<(std::ostream& os, const btVectorX<T>& mat)
{
os << " [";
//printf("%s ---------------------\n",msg);
for (int i = 0; i < mat.rows(); i++)
{
os << " [";
//printf("%s ---------------------\n",msg);
for (int i=0;i<mat.rows();i++)
{
os << std::setw(12) << mat[i];
if (i!=mat.rows()-1)
os << std::endl << " ";
}
os << " ]";
//printf("\n---------------------\n");
return os;
os << std::setw(12) << mat[i];
if (i != mat.rows() - 1)
os << std::endl
<< " ";
}
os << " ]";
//printf("\n---------------------\n");
#endif //BT_DEBUG_OSTREAM
return os;
}
#endif //BT_DEBUG_OSTREAM
inline void setElem(btMatrixXd& mat, int row, int col, double val)
{
mat.setElem(row,col,val);
mat.setElem(row, col, val);
}
inline void setElem(btMatrixXf& mat, int row, int col, float val)
{
mat.setElem(row,col,val);
mat.setElem(row, col, val);
}
#ifdef BT_USE_DOUBLE_PRECISION
#define btVectorXu btVectorXd
#define btMatrixXu btMatrixXd
#define btVectorXu btVectorXd
#define btMatrixXu btMatrixXd
#else
#define btVectorXu btVectorXf
#define btMatrixXu btMatrixXf
#endif //BT_USE_DOUBLE_PRECISION
#define btVectorXu btVectorXf
#define btMatrixXu btMatrixXf
#endif //BT_USE_DOUBLE_PRECISION
#endif//BT_MATRIX_H_H
#endif //BT_MATRIX_H_H

View File

@@ -12,60 +12,58 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BT_GEN_MINMAX_H
#define BT_GEN_MINMAX_H
#include "btScalar.h"
template <class T>
SIMD_FORCE_INLINE const T& btMin(const T& a, const T& b)
SIMD_FORCE_INLINE const T& btMin(const T& a, const T& b)
{
return a < b ? a : b ;
return a < b ? a : b;
}
template <class T>
SIMD_FORCE_INLINE const T& btMax(const T& a, const T& b)
SIMD_FORCE_INLINE const T& btMax(const T& a, const T& b)
{
return a > b ? a : b;
return a > b ? a : b;
}
template <class T>
SIMD_FORCE_INLINE const T& btClamped(const T& a, const T& lb, const T& ub)
SIMD_FORCE_INLINE const T& btClamped(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>
SIMD_FORCE_INLINE void btSetMin(T& a, const T& b)
SIMD_FORCE_INLINE void btSetMin(T& a, const T& b)
{
if (b < a)
if (b < a)
{
a = b;
}
}
template <class T>
SIMD_FORCE_INLINE void btSetMax(T& a, const T& b)
SIMD_FORCE_INLINE void btSetMax(T& a, const T& b)
{
if (a < b)
if (a < b)
{
a = b;
}
}
template <class T>
SIMD_FORCE_INLINE void btClamp(T& a, const T& lb, const T& ub)
SIMD_FORCE_INLINE void btClamp(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 //BT_GEN_MINMAX_H
#endif //BT_GEN_MINMAX_H

View File

@@ -20,21 +20,17 @@ subject to the following restrictions:
///The btMotionState interface class allows the dynamics world to synchronize and interpolate the updated world transforms with graphics
///For optimizations, potentially only moving objects get synchronized (using setWorldPosition/setWorldOrientation)
class btMotionState
class btMotionState
{
public:
virtual ~btMotionState()
{
}
virtual void getWorldTransform(btTransform& worldTrans ) const =0;
public:
virtual ~btMotionState()
{
}
//Bullet only calls the update of worldtransform for active objects
virtual void setWorldTransform(const btTransform& worldTrans)=0;
virtual void getWorldTransform(btTransform& worldTrans) const = 0;
//Bullet only calls the update of worldtransform for active objects
virtual void setWorldTransform(const btTransform& worldTrans) = 0;
};
#endif //BT_MOTIONSTATE_H
#endif //BT_MOTIONSTATE_H

View File

@@ -3,96 +3,92 @@
namespace
{
btScalar abs_column_sum(const btMatrix3x3& a, int i)
{
return btFabs(a[0][i]) + btFabs(a[1][i]) + btFabs(a[2][i]);
}
btScalar abs_row_sum(const btMatrix3x3& a, int i)
{
return btFabs(a[i][0]) + btFabs(a[i][1]) + btFabs(a[i][2]);
}
btScalar p1_norm(const btMatrix3x3& a)
{
const btScalar sum0 = abs_column_sum(a,0);
const btScalar sum1 = abs_column_sum(a,1);
const btScalar sum2 = abs_column_sum(a,2);
return btMax(btMax(sum0, sum1), sum2);
}
btScalar pinf_norm(const btMatrix3x3& a)
{
const btScalar sum0 = abs_row_sum(a,0);
const btScalar sum1 = abs_row_sum(a,1);
const btScalar sum2 = abs_row_sum(a,2);
return btMax(btMax(sum0, sum1), sum2);
}
btScalar abs_column_sum(const btMatrix3x3& a, int i)
{
return btFabs(a[0][i]) + btFabs(a[1][i]) + btFabs(a[2][i]);
}
btScalar abs_row_sum(const btMatrix3x3& a, int i)
{
return btFabs(a[i][0]) + btFabs(a[i][1]) + btFabs(a[i][2]);
}
btScalar p1_norm(const btMatrix3x3& a)
{
const btScalar sum0 = abs_column_sum(a, 0);
const btScalar sum1 = abs_column_sum(a, 1);
const btScalar sum2 = abs_column_sum(a, 2);
return btMax(btMax(sum0, sum1), sum2);
}
btScalar pinf_norm(const btMatrix3x3& a)
{
const btScalar sum0 = abs_row_sum(a, 0);
const btScalar sum1 = abs_row_sum(a, 1);
const btScalar sum2 = abs_row_sum(a, 2);
return btMax(btMax(sum0, sum1), sum2);
}
} // namespace
btPolarDecomposition::btPolarDecomposition(btScalar tolerance, unsigned int maxIterations)
: m_tolerance(tolerance)
, m_maxIterations(maxIterations)
: m_tolerance(tolerance), m_maxIterations(maxIterations)
{
}
unsigned int btPolarDecomposition::decompose(const btMatrix3x3& a, btMatrix3x3& u, btMatrix3x3& h) const
{
// Use the 'u' and 'h' matrices for intermediate calculations
u = a;
h = a.inverse();
// Use the 'u' and 'h' matrices for intermediate calculations
u = a;
h = a.inverse();
for (unsigned int i = 0; i < m_maxIterations; ++i)
{
const btScalar h_1 = p1_norm(h);
const btScalar h_inf = pinf_norm(h);
const btScalar u_1 = p1_norm(u);
const btScalar u_inf = pinf_norm(u);
for (unsigned int i = 0; i < m_maxIterations; ++i)
{
const btScalar h_1 = p1_norm(h);
const btScalar h_inf = pinf_norm(h);
const btScalar u_1 = p1_norm(u);
const btScalar u_inf = pinf_norm(u);
const btScalar h_norm = h_1 * h_inf;
const btScalar u_norm = u_1 * u_inf;
const btScalar h_norm = h_1 * h_inf;
const btScalar u_norm = u_1 * u_inf;
// The matrix is effectively singular so we cannot invert it
if (btFuzzyZero(h_norm) || btFuzzyZero(u_norm))
break;
// The matrix is effectively singular so we cannot invert it
if (btFuzzyZero(h_norm) || btFuzzyZero(u_norm))
break;
const btScalar gamma = btPow(h_norm / u_norm, 0.25f);
const btScalar inv_gamma = btScalar(1.0) / gamma;
const btScalar gamma = btPow(h_norm / u_norm, 0.25f);
const btScalar inv_gamma = btScalar(1.0) / gamma;
// Determine the delta to 'u'
const btMatrix3x3 delta = (u * (gamma - btScalar(2.0)) + h.transpose() * inv_gamma) * btScalar(0.5);
// Determine the delta to 'u'
const btMatrix3x3 delta = (u * (gamma - btScalar(2.0)) + h.transpose() * inv_gamma) * btScalar(0.5);
// Update the matrices
u += delta;
h = u.inverse();
// Update the matrices
u += delta;
h = u.inverse();
// Check for convergence
if (p1_norm(delta) <= m_tolerance * u_1)
{
h = u.transpose() * a;
h = (h + h.transpose()) * 0.5;
return i;
}
}
// Check for convergence
if (p1_norm(delta) <= m_tolerance * u_1)
{
h = u.transpose() * a;
h = (h + h.transpose()) * 0.5;
return i;
}
}
// The algorithm has failed to converge to the specified tolerance, but we
// want to make sure that the matrices returned are in the right form.
h = u.transpose() * a;
h = (h + h.transpose()) * 0.5;
// The algorithm has failed to converge to the specified tolerance, but we
// want to make sure that the matrices returned are in the right form.
h = u.transpose() * a;
h = (h + h.transpose()) * 0.5;
return m_maxIterations;
return m_maxIterations;
}
unsigned int btPolarDecomposition::maxIterations() const
{
return m_maxIterations;
return m_maxIterations;
}
unsigned int polarDecompose(const btMatrix3x3& a, btMatrix3x3& u, btMatrix3x3& h)
{
static btPolarDecomposition polar;
return polar.decompose(a, u, h);
static btPolarDecomposition polar;
return polar.decompose(a, u, h);
}

View File

@@ -13,10 +13,8 @@
*/
class btPolarDecomposition
{
public:
/**
public:
/**
* Creates an instance with optional parameters.
*
* @param tolerance - the tolerance used to determine convergence of the
@@ -24,10 +22,10 @@ class btPolarDecomposition
* @param maxIterations - the maximum number of iterations used to achieve
* convergence
*/
btPolarDecomposition(btScalar tolerance = btScalar(0.0001),
unsigned int maxIterations = 16);
btPolarDecomposition(btScalar tolerance = btScalar(0.0001),
unsigned int maxIterations = 16);
/**
/**
* Decomposes a matrix into orthogonal and symmetric, positive-definite
* parts. If the number of iterations returned by this function is equal to
* the maximum number of iterations, the algorithm has failed to converge.
@@ -38,19 +36,19 @@ class btPolarDecomposition
*
* @return the number of iterations performed by the algorithm.
*/
unsigned int decompose(const btMatrix3x3& a, btMatrix3x3& u, btMatrix3x3& h) const;
unsigned int decompose(const btMatrix3x3& a, btMatrix3x3& u, btMatrix3x3& h) const;
/**
/**
* Returns the maximum number of iterations that this algorithm will perform
* to achieve convergence.
*
* @return maximum number of iterations
*/
unsigned int maxIterations() const;
unsigned int maxIterations() const;
private:
btScalar m_tolerance;
unsigned int m_maxIterations;
private:
btScalar m_tolerance;
unsigned int m_maxIterations;
};
/**
@@ -66,7 +64,6 @@ class btPolarDecomposition
*
* @return the number of iterations performed by the algorithm.
*/
unsigned int polarDecompose(const btMatrix3x3& a, btMatrix3x3& u, btMatrix3x3& h);
#endif // POLARDECOMPOSITION_H
unsigned int polarDecompose(const btMatrix3x3& a, btMatrix3x3& u, btMatrix3x3& h);
#endif // POLARDECOMPOSITION_H

View File

@@ -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
@@ -23,38 +22,38 @@ subject to the following restrictions:
///The btPoolAllocator class allows to efficiently allocate a large pool of objects, instead of dynamically allocating them separately.
class btPoolAllocator
{
int m_elemSize;
int m_maxElements;
int m_freeCount;
void* m_firstFree;
unsigned char* m_pool;
btSpinMutex m_mutex; // only used if BT_THREADSAFE
int m_elemSize;
int m_maxElements;
int m_freeCount;
void* m_firstFree;
unsigned char* m_pool;
btSpinMutex m_mutex; // only used if BT_THREADSAFE
public:
btPoolAllocator(int elemSize, int maxElements)
:m_elemSize(elemSize),
m_maxElements(maxElements)
: m_elemSize(elemSize),
m_maxElements(maxElements)
{
m_pool = (unsigned char*) btAlignedAlloc( static_cast<unsigned int>(m_elemSize*m_maxElements),16);
m_pool = (unsigned char*)btAlignedAlloc(static_cast<unsigned int>(m_elemSize * m_maxElements), 16);
unsigned char* p = m_pool;
m_firstFree = p;
m_freeCount = m_maxElements;
int count = m_maxElements;
while (--count) {
*(void**)p = (p + m_elemSize);
p += m_elemSize;
}
*(void**)p = 0;
}
m_firstFree = p;
m_freeCount = m_maxElements;
int count = m_maxElements;
while (--count)
{
*(void**)p = (p + m_elemSize);
p += m_elemSize;
}
*(void**)p = 0;
}
~btPoolAllocator()
{
btAlignedFree( m_pool);
btAlignedFree(m_pool);
}
int getFreeCount() const
int getFreeCount() const
{
return m_freeCount;
}
@@ -69,26 +68,27 @@ public:
return m_maxElements;
}
void* allocate(int size)
void* allocate(int size)
{
// release mode fix
(void)size;
btMutexLock(&m_mutex);
btAssert(!size || size<=m_elemSize);
btMutexLock(&m_mutex);
btAssert(!size || size <= m_elemSize);
//btAssert(m_freeCount>0); // should return null if all full
void* result = m_firstFree;
if (NULL != m_firstFree)
{
m_firstFree = *(void**)m_firstFree;
--m_freeCount;
}
btMutexUnlock(&m_mutex);
return result;
void* result = m_firstFree;
if (NULL != m_firstFree)
{
m_firstFree = *(void**)m_firstFree;
--m_freeCount;
}
btMutexUnlock(&m_mutex);
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;
@@ -97,34 +97,34 @@ public:
return false;
}
void freeMemory(void* ptr)
void freeMemory(void* ptr)
{
if (ptr) {
btAssert((unsigned char*)ptr >= m_pool && (unsigned char*)ptr < m_pool + m_maxElements * m_elemSize);
if (ptr)
{
btAssert((unsigned char*)ptr >= m_pool && (unsigned char*)ptr < m_pool + m_maxElements * m_elemSize);
btMutexLock(&m_mutex);
*(void**)ptr = m_firstFree;
m_firstFree = ptr;
++m_freeCount;
btMutexUnlock(&m_mutex);
}
btMutexLock(&m_mutex);
*(void**)ptr = m_firstFree;
m_firstFree = ptr;
++m_freeCount;
btMutexUnlock(&m_mutex);
}
}
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

View File

@@ -12,18 +12,13 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BT_SIMD_QUADWORD_H
#define BT_SIMD_QUADWORD_H
#include "btScalar.h"
#include "btMinMax.h"
#if defined (__CELLOS_LV2) && defined (__SPU__)
#if defined(__CELLOS_LV2) && defined(__SPU__)
#include <altivec.h>
#endif
@@ -31,51 +26,53 @@ 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
ATTRIBUTE_ALIGNED16(class) btQuadWord
ATTRIBUTE_ALIGNED16(class)
btQuadWord
#else
class btQuadWord
#endif
{
protected:
#if defined (__SPU__) && defined (__CELLOS_LV2__)
#if defined(__SPU__) && defined(__CELLOS_LV2__)
union {
vec_float4 mVec128;
btScalar m_floats[4];
btScalar m_floats[4];
};
public:
vec_float4 get128() const
vec_float4 get128() const
{
return mVec128;
}
protected:
#else //__CELLOS_LV2__ __SPU__
#if defined(BT_USE_SSE) || defined(BT_USE_NEON)
protected:
#else //__CELLOS_LV2__ __SPU__
#if defined(BT_USE_SSE) || defined(BT_USE_NEON)
union {
btSimdFloat4 mVec128;
btScalar m_floats[4];
btScalar m_floats[4];
};
public:
SIMD_FORCE_INLINE btSimdFloat4 get128() const
SIMD_FORCE_INLINE btSimdFloat4 get128() const
{
return mVec128;
}
SIMD_FORCE_INLINE void set128(btSimdFloat4 v128)
SIMD_FORCE_INLINE void set128(btSimdFloat4 v128)
{
mVec128 = v128;
}
#else
btScalar m_floats[4];
#endif // BT_USE_SSE
btScalar m_floats[4];
#endif // BT_USE_SSE
#endif //__CELLOS_LV2__ __SPU__
#endif //__CELLOS_LV2__ __SPU__
public:
public:
#if (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) || defined(BT_USE_NEON)
// Set Vector
// Set Vector
SIMD_FORCE_INLINE btQuadWord(const btSimdFloat4 vec)
{
mVec128 = vec;
@@ -88,157 +85,154 @@ public:
}
// Assignment Operator
SIMD_FORCE_INLINE btQuadWord&
operator=(const btQuadWord& v)
SIMD_FORCE_INLINE btQuadWord&
operator=(const btQuadWord& v)
{
mVec128 = v.mVec128;
return *this;
}
#endif
/**@brief Return the x value */
SIMD_FORCE_INLINE const btScalar& getX() const { return m_floats[0]; }
/**@brief Return the y value */
SIMD_FORCE_INLINE const btScalar& getY() const { return m_floats[1]; }
/**@brief Return the z value */
SIMD_FORCE_INLINE const btScalar& getZ() const { return m_floats[2]; }
/**@brief Set the x value */
SIMD_FORCE_INLINE void setX(btScalar _x) { m_floats[0] = _x;};
/**@brief Set the y value */
SIMD_FORCE_INLINE void setY(btScalar _y) { m_floats[1] = _y;};
/**@brief Set the z value */
SIMD_FORCE_INLINE void setZ(btScalar _z) { m_floats[2] = _z;};
/**@brief Set the w value */
SIMD_FORCE_INLINE void setW(btScalar _w) { m_floats[3] = _w;};
/**@brief Return the x value */
SIMD_FORCE_INLINE const btScalar& x() const { return m_floats[0]; }
/**@brief Return the y value */
SIMD_FORCE_INLINE const btScalar& y() const { return m_floats[1]; }
/**@brief Return the z value */
SIMD_FORCE_INLINE const btScalar& z() const { return m_floats[2]; }
/**@brief Return the w value */
SIMD_FORCE_INLINE const btScalar& w() const { return m_floats[3]; }
/**@brief Return the x value */
SIMD_FORCE_INLINE const btScalar& getX() const { return m_floats[0]; }
/**@brief Return the y value */
SIMD_FORCE_INLINE const btScalar& getY() const { return m_floats[1]; }
/**@brief Return the z value */
SIMD_FORCE_INLINE const btScalar& getZ() const { return m_floats[2]; }
/**@brief Set the x value */
SIMD_FORCE_INLINE void setX(btScalar _x) { m_floats[0] = _x; };
/**@brief Set the y value */
SIMD_FORCE_INLINE void setY(btScalar _y) { m_floats[1] = _y; };
/**@brief Set the z value */
SIMD_FORCE_INLINE void setZ(btScalar _z) { m_floats[2] = _z; };
/**@brief Set the w value */
SIMD_FORCE_INLINE void setW(btScalar _w) { m_floats[3] = _w; };
/**@brief Return the x value */
SIMD_FORCE_INLINE const btScalar& x() const { return m_floats[0]; }
/**@brief Return the y value */
SIMD_FORCE_INLINE const btScalar& y() const { return m_floats[1]; }
/**@brief Return the z value */
SIMD_FORCE_INLINE const btScalar& z() const { return m_floats[2]; }
/**@brief Return the w value */
SIMD_FORCE_INLINE const btScalar& w() const { return m_floats[3]; }
//SIMD_FORCE_INLINE btScalar& operator[](int i) { return (&m_floats[0])[i]; }
//SIMD_FORCE_INLINE btScalar& operator[](int i) { return (&m_floats[0])[i]; }
//SIMD_FORCE_INLINE const btScalar& operator[](int i) const { return (&m_floats[0])[i]; }
///operator btScalar*() replaces operator[], using implicit conversion. We added operator != and operator == to avoid pointer comparisons.
SIMD_FORCE_INLINE operator btScalar *() { return &m_floats[0]; }
SIMD_FORCE_INLINE operator const btScalar *() const { return &m_floats[0]; }
SIMD_FORCE_INLINE operator btScalar*() { return &m_floats[0]; }
SIMD_FORCE_INLINE operator const btScalar*() const { return &m_floats[0]; }
SIMD_FORCE_INLINE bool operator==(const btQuadWord& other) const
SIMD_FORCE_INLINE bool operator==(const btQuadWord& other) const
{
#ifdef BT_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
}
SIMD_FORCE_INLINE bool operator!=(const btQuadWord& other) const
SIMD_FORCE_INLINE bool operator!=(const btQuadWord& 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
*/
SIMD_FORCE_INLINE void setValue(const btScalar& _x, const btScalar& _y, const btScalar& _z)
{
m_floats[0]=_x;
m_floats[1]=_y;
m_floats[2]=_z;
m_floats[3] = 0.f;
}
SIMD_FORCE_INLINE void setValue(const btScalar& _x, const btScalar& _y, const btScalar& _z)
{
m_floats[0] = _x;
m_floats[1] = _y;
m_floats[2] = _z;
m_floats[3] = 0.f;
}
/* void getValue(btScalar *m) const
/* void getValue(btScalar *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
*/
SIMD_FORCE_INLINE void setValue(const btScalar& _x, const btScalar& _y, const btScalar& _z,const btScalar& _w)
{
m_floats[0]=_x;
m_floats[1]=_y;
m_floats[2]=_z;
m_floats[3]=_w;
}
/**@brief No initialization constructor */
SIMD_FORCE_INLINE btQuadWord()
// :m_floats[0](btScalar(0.)),m_floats[1](btScalar(0.)),m_floats[2](btScalar(0.)),m_floats[3](btScalar(0.))
{
}
/**@brief Three argument constructor (zeros w)
SIMD_FORCE_INLINE void setValue(const btScalar& _x, const btScalar& _y, const btScalar& _z, const btScalar& _w)
{
m_floats[0] = _x;
m_floats[1] = _y;
m_floats[2] = _z;
m_floats[3] = _w;
}
/**@brief No initialization constructor */
SIMD_FORCE_INLINE btQuadWord()
// :m_floats[0](btScalar(0.)),m_floats[1](btScalar(0.)),m_floats[2](btScalar(0.)),m_floats[3](btScalar(0.))
{
}
/**@brief Three argument constructor (zeros w)
* @param x Value of x
* @param y Value of y
* @param z Value of z
*/
SIMD_FORCE_INLINE btQuadWord(const btScalar& _x, const btScalar& _y, const btScalar& _z)
{
m_floats[0] = _x, m_floats[1] = _y, m_floats[2] = _z, m_floats[3] = 0.0f;
}
SIMD_FORCE_INLINE btQuadWord(const btScalar& _x, const btScalar& _y, const btScalar& _z)
{
m_floats[0] = _x, m_floats[1] = _y, m_floats[2] = _z, m_floats[3] = 0.0f;
}
/**@brief Initializing constructor
/**@brief Initializing constructor
* @param x Value of x
* @param y Value of y
* @param z Value of z
* @param w Value of w
*/
SIMD_FORCE_INLINE btQuadWord(const btScalar& _x, const btScalar& _y, const btScalar& _z,const btScalar& _w)
{
m_floats[0] = _x, m_floats[1] = _y, m_floats[2] = _z, m_floats[3] = _w;
}
SIMD_FORCE_INLINE btQuadWord(const btScalar& _x, const btScalar& _y, const btScalar& _z, const btScalar& _w)
{
m_floats[0] = _x, m_floats[1] = _y, m_floats[2] = _z, m_floats[3] = _w;
}
/**@brief Set each element to the max of the current values and the values of another btQuadWord
/**@brief Set each element to the max of the current values and the values of another btQuadWord
* @param other The other btQuadWord to compare with
*/
SIMD_FORCE_INLINE void setMax(const btQuadWord& other)
{
#ifdef BT_USE_SSE
mVec128 = _mm_max_ps(mVec128, other.mVec128);
#elif defined(BT_USE_NEON)
mVec128 = vmaxq_f32(mVec128, other.mVec128);
#else
btSetMax(m_floats[0], other.m_floats[0]);
btSetMax(m_floats[1], other.m_floats[1]);
btSetMax(m_floats[2], other.m_floats[2]);
btSetMax(m_floats[3], other.m_floats[3]);
#endif
}
/**@brief Set each element to the min of the current values and the values of another btQuadWord
SIMD_FORCE_INLINE void setMax(const btQuadWord& other)
{
#ifdef BT_USE_SSE
mVec128 = _mm_max_ps(mVec128, other.mVec128);
#elif defined(BT_USE_NEON)
mVec128 = vmaxq_f32(mVec128, other.mVec128);
#else
btSetMax(m_floats[0], other.m_floats[0]);
btSetMax(m_floats[1], other.m_floats[1]);
btSetMax(m_floats[2], other.m_floats[2]);
btSetMax(m_floats[3], other.m_floats[3]);
#endif
}
/**@brief Set each element to the min of the current values and the values of another btQuadWord
* @param other The other btQuadWord to compare with
*/
SIMD_FORCE_INLINE void setMin(const btQuadWord& other)
{
#ifdef BT_USE_SSE
mVec128 = _mm_min_ps(mVec128, other.mVec128);
#elif defined(BT_USE_NEON)
mVec128 = vminq_f32(mVec128, other.mVec128);
#else
btSetMin(m_floats[0], other.m_floats[0]);
btSetMin(m_floats[1], other.m_floats[1]);
btSetMin(m_floats[2], other.m_floats[2]);
btSetMin(m_floats[3], other.m_floats[3]);
#endif
}
SIMD_FORCE_INLINE void setMin(const btQuadWord& other)
{
#ifdef BT_USE_SSE
mVec128 = _mm_min_ps(mVec128, other.mVec128);
#elif defined(BT_USE_NEON)
mVec128 = vminq_f32(mVec128, other.mVec128);
#else
btSetMin(m_floats[0], other.m_floats[0]);
btSetMin(m_floats[1], other.m_floats[1]);
btSetMin(m_floats[2], other.m_floats[2]);
btSetMin(m_floats[3], other.m_floats[3]);
#endif
}
};
#endif //BT_SIMD_QUADWORD_H
#endif //BT_SIMD_QUADWORD_H

File diff suppressed because it is too large Load Diff

View File

@@ -16,16 +16,13 @@
#include "btQuickprof.h"
#include "btThreads.h"
#ifdef __CELLOS_LV2__
#include <sys/sys_time.h>
#include <sys/time_util.h>
#include <stdio.h>
#endif
#if defined (SUNOS) || defined (__SUNOS__)
#if defined(SUNOS) || defined(__SUNOS__)
#include <stdio.h>
#endif
#ifdef __APPLE__
@@ -42,49 +39,46 @@
#define NOIME
#ifdef _XBOX
#include <Xtl.h>
#else //_XBOX
#include <windows.h>
#include <Xtl.h>
#else //_XBOX
#include <windows.h>
#if WINVER <0x0602
#if WINVER < 0x0602
#define GetTickCount64 GetTickCount
#endif
#endif //_XBOX
#endif //_XBOX
#include <time.h>
#else //_WIN32
#else //_WIN32
#include <sys/time.h>
#ifdef BT_LINUX_REALTIME
//required linking against rt (librt)
#include <time.h>
#endif //BT_LINUX_REALTIME
#endif //BT_LINUX_REALTIME
#endif //_WIN32
#endif //_WIN32
#define mymin(a,b) (a > b ? a : b)
#define mymin(a, b) (a > b ? a : b)
struct btClockData
{
#ifdef BT_USE_WINDOWS_TIMERS
LARGE_INTEGER mClockFrequency;
LONGLONG mStartTick;
LARGE_INTEGER mStartTime;
#else
#ifdef __CELLOS_LV2__
uint64_t mStartTime;
uint64_t mStartTime;
#else
#ifdef __APPLE__
uint64_t mStartTimeNano;
uint64_t mStartTimeNano;
#endif
struct timeval mStartTime;
#endif
#endif //__CELLOS_LV2__
#endif //__CELLOS_LV2__
};
///The btClock is a portable basic clock that measures accurate time in seconds, use for profiling.
@@ -114,8 +108,7 @@ btClock& btClock::operator=(const btClock& other)
return *this;
}
/// Resets the initial reference time.
/// Resets the initial reference time.
void btClock::reset()
{
#ifdef BT_USE_WINDOWS_TIMERS
@@ -124,14 +117,14 @@ void btClock::reset()
#else
#ifdef __CELLOS_LV2__
typedef uint64_t ClockSize;
typedef uint64_t ClockSize;
ClockSize newTime;
//__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
SYS_TIMEBASE_GET( newTime );
SYS_TIMEBASE_GET(newTime);
m_data->mStartTime = newTime;
#else
#ifdef __APPLE__
m_data->mStartTimeNano = mach_absolute_time();
m_data->mStartTimeNano = mach_absolute_time();
#endif
gettimeofday(&m_data->mStartTime, 0);
#endif
@@ -146,66 +139,66 @@ unsigned long long int btClock::getTimeMilliseconds()
LARGE_INTEGER currentTime;
QueryPerformanceCounter(&currentTime);
LONGLONG elapsedTime = currentTime.QuadPart -
m_data->mStartTime.QuadPart;
// Compute the number of millisecond ticks elapsed.
m_data->mStartTime.QuadPart;
// Compute the number of millisecond ticks elapsed.
unsigned long msecTicks = (unsigned long)(1000 * elapsedTime /
m_data->mClockFrequency.QuadPart);
m_data->mClockFrequency.QuadPart);
return msecTicks;
return msecTicks;
#else
#ifdef __CELLOS_LV2__
uint64_t freq=sys_time_get_timebase_frequency();
double dFreq=((double) freq) / 1000.0;
typedef uint64_t ClockSize;
ClockSize newTime;
SYS_TIMEBASE_GET( newTime );
//__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
uint64_t freq = sys_time_get_timebase_frequency();
double dFreq = ((double)freq) / 1000.0;
typedef uint64_t ClockSize;
ClockSize newTime;
SYS_TIMEBASE_GET(newTime);
//__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
return (unsigned long int)((double(newTime-m_data->mStartTime)) / dFreq);
return (unsigned long int)((double(newTime - m_data->mStartTime)) / dFreq);
#else
struct timeval currentTime;
gettimeofday(&currentTime, 0);
return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1000 +
(currentTime.tv_usec - m_data->mStartTime.tv_usec) / 1000;
#endif //__CELLOS_LV2__
struct timeval currentTime;
gettimeofday(&currentTime, 0);
return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1000 +
(currentTime.tv_usec - m_data->mStartTime.tv_usec) / 1000;
#endif //__CELLOS_LV2__
#endif
}
/// Returns the time in us since the last call to reset or since
/// the Clock was created.
/// Returns the time in us since the last call to reset or since
/// the Clock was created.
unsigned long long int btClock::getTimeMicroseconds()
{
#ifdef BT_USE_WINDOWS_TIMERS
//see https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx
LARGE_INTEGER currentTime, elapsedTime;
QueryPerformanceCounter(&currentTime);
elapsedTime.QuadPart = currentTime.QuadPart -
m_data->mStartTime.QuadPart;
elapsedTime.QuadPart *= 1000000;
elapsedTime.QuadPart /= m_data->mClockFrequency.QuadPart;
//see https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx
LARGE_INTEGER currentTime, elapsedTime;
return (unsigned long long) elapsedTime.QuadPart;
QueryPerformanceCounter(&currentTime);
elapsedTime.QuadPart = currentTime.QuadPart -
m_data->mStartTime.QuadPart;
elapsedTime.QuadPart *= 1000000;
elapsedTime.QuadPart /= m_data->mClockFrequency.QuadPart;
return (unsigned long long)elapsedTime.QuadPart;
#else
#ifdef __CELLOS_LV2__
uint64_t freq=sys_time_get_timebase_frequency();
double dFreq=((double) freq)/ 1000000.0;
typedef uint64_t ClockSize;
ClockSize newTime;
//__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
SYS_TIMEBASE_GET( newTime );
uint64_t freq = sys_time_get_timebase_frequency();
double dFreq = ((double)freq) / 1000000.0;
typedef uint64_t ClockSize;
ClockSize newTime;
//__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
SYS_TIMEBASE_GET(newTime);
return (unsigned long int)((double(newTime-m_data->mStartTime)) / dFreq);
return (unsigned long int)((double(newTime - m_data->mStartTime)) / dFreq);
#else
struct timeval currentTime;
gettimeofday(&currentTime, 0);
return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1000000 +
(currentTime.tv_usec - m_data->mStartTime.tv_usec);
#endif//__CELLOS_LV2__
struct timeval currentTime;
gettimeofday(&currentTime, 0);
return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1000000 +
(currentTime.tv_usec - m_data->mStartTime.tv_usec);
#endif //__CELLOS_LV2__
#endif
}
@@ -213,65 +206,63 @@ unsigned long long int btClock::getTimeNanoseconds()
{
#ifdef BT_USE_WINDOWS_TIMERS
//see https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx
LARGE_INTEGER currentTime, elapsedTime;
QueryPerformanceCounter(&currentTime);
elapsedTime.QuadPart = currentTime.QuadPart -
m_data->mStartTime.QuadPart;
elapsedTime.QuadPart *= 1000000000;
elapsedTime.QuadPart /= m_data->mClockFrequency.QuadPart;
LARGE_INTEGER currentTime, elapsedTime;
return (unsigned long long) elapsedTime.QuadPart;
QueryPerformanceCounter(&currentTime);
elapsedTime.QuadPart = currentTime.QuadPart -
m_data->mStartTime.QuadPart;
elapsedTime.QuadPart *= 1000000000;
elapsedTime.QuadPart /= m_data->mClockFrequency.QuadPart;
return (unsigned long long)elapsedTime.QuadPart;
#else
#ifdef __CELLOS_LV2__
uint64_t freq=sys_time_get_timebase_frequency();
double dFreq=((double) freq)/ 1e9;
typedef uint64_t ClockSize;
ClockSize newTime;
//__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
SYS_TIMEBASE_GET( newTime );
uint64_t freq = sys_time_get_timebase_frequency();
double dFreq = ((double)freq) / 1e9;
typedef uint64_t ClockSize;
ClockSize newTime;
//__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
SYS_TIMEBASE_GET(newTime);
return (unsigned long int)((double(newTime-m_data->mStartTime)) / dFreq);
return (unsigned long int)((double(newTime - m_data->mStartTime)) / dFreq);
#else
#ifdef __APPLE__
uint64_t ticks = mach_absolute_time() - m_data->mStartTimeNano;
static long double conversion = 0.0L;
if( 0.0L == conversion )
{
// attempt to get conversion to nanoseconds
mach_timebase_info_data_t info;
int err = mach_timebase_info( &info );
if( err )
{
btAssert(0);
conversion = 1.;
}
conversion = info.numer / info.denom;
}
return (ticks * conversion);
uint64_t ticks = mach_absolute_time() - m_data->mStartTimeNano;
static long double conversion = 0.0L;
if (0.0L == conversion)
{
// attempt to get conversion to nanoseconds
mach_timebase_info_data_t info;
int err = mach_timebase_info(&info);
if (err)
{
btAssert(0);
conversion = 1.;
}
conversion = info.numer / info.denom;
}
return (ticks * conversion);
#else //__APPLE__
#else//__APPLE__
#ifdef BT_LINUX_REALTIME
timespec ts;
clock_gettime(CLOCK_REALTIME,&ts);
return 1000000000*ts.tv_sec + ts.tv_nsec;
timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
return 1000000000 * ts.tv_sec + ts.tv_nsec;
#else
struct timeval currentTime;
gettimeofday(&currentTime, 0);
return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1e9 +
(currentTime.tv_usec - m_data->mStartTime.tv_usec)*1000;
#endif //BT_LINUX_REALTIME
struct timeval currentTime;
gettimeofday(&currentTime, 0);
return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1e9 +
(currentTime.tv_usec - m_data->mStartTime.tv_usec) * 1000;
#endif //BT_LINUX_REALTIME
#endif//__APPLE__
#endif//__CELLOS_LV2__
#endif
#endif //__APPLE__
#endif //__CELLOS_LV2__
#endif
}
/// Returns the time in s since the last call to reset or since
/// Returns the time in s since the last call to reset or since
/// the Clock was created.
btScalar btClock::getTimeSeconds()
{
@@ -281,23 +272,19 @@ btScalar btClock::getTimeSeconds()
#ifndef BT_NO_PROFILE
static btClock gProfileClock;
inline void Profile_Get_Ticks(unsigned long int * ticks)
inline void Profile_Get_Ticks(unsigned long int* ticks)
{
*ticks = (unsigned long int)gProfileClock.getTimeMicroseconds();
}
inline float Profile_Get_Tick_Rate(void)
{
// return 1000000.f;
// return 1000000.f;
return 1000.f;
}
/***************************************************************************************************
**
** CProfileNode
@@ -313,35 +300,32 @@ inline float Profile_Get_Tick_Rate(void)
* The name is assumed to be a static pointer, only the pointer is stored and compared for *
* efficiency reasons. *
*=============================================================================================*/
CProfileNode::CProfileNode( const char * name, CProfileNode * parent ) :
Name( name ),
TotalCalls( 0 ),
TotalTime( 0 ),
StartTime( 0 ),
RecursionCounter( 0 ),
Parent( parent ),
Child( NULL ),
Sibling( NULL ),
m_userPtr(0)
CProfileNode::CProfileNode(const char* name, CProfileNode* parent) : Name(name),
TotalCalls(0),
TotalTime(0),
StartTime(0),
RecursionCounter(0),
Parent(parent),
Child(NULL),
Sibling(NULL),
m_userPtr(0)
{
Reset();
}
void CProfileNode::CleanupMemory()
void CProfileNode::CleanupMemory()
{
delete ( Child);
delete (Child);
Child = NULL;
delete ( Sibling);
delete (Sibling);
Sibling = NULL;
}
CProfileNode::~CProfileNode( void )
CProfileNode::~CProfileNode(void)
{
CleanupMemory();
}
/***********************************************************************************************
* INPUT: *
* name - static string pointer to the name of the node we are searching for *
@@ -350,12 +334,14 @@ CProfileNode::~CProfileNode( void )
* All profile names are assumed to be static strings so this function uses pointer compares *
* to find the named node. *
*=============================================================================================*/
CProfileNode * CProfileNode::Get_Sub_Node( const char * name )
CProfileNode* CProfileNode::Get_Sub_Node(const char* name)
{
// Try to find this sub node
CProfileNode * child = Child;
while ( child ) {
if ( child->Name == name ) {
CProfileNode* child = Child;
while (child)
{
if (child->Name == name)
{
return child;
}
child = child->Sibling;
@@ -363,176 +349,212 @@ CProfileNode * CProfileNode::Get_Sub_Node( const char * name )
// We didn't find it, so add it
CProfileNode * node = new CProfileNode( name, this );
CProfileNode* node = new CProfileNode(name, this);
node->Sibling = Child;
Child = node;
return node;
}
void CProfileNode::Reset( void )
void CProfileNode::Reset(void)
{
TotalCalls = 0;
TotalTime = 0.0f;
if ( Child ) {
if (Child)
{
Child->Reset();
}
if ( Sibling ) {
if (Sibling)
{
Sibling->Reset();
}
}
void CProfileNode::Call( void )
void CProfileNode::Call(void)
{
TotalCalls++;
if (RecursionCounter++ == 0) {
if (RecursionCounter++ == 0)
{
Profile_Get_Ticks(&StartTime);
}
}
bool CProfileNode::Return( void )
bool CProfileNode::Return(void)
{
if ( --RecursionCounter == 0 && TotalCalls != 0 ) {
if (--RecursionCounter == 0 && TotalCalls != 0)
{
unsigned long int time;
Profile_Get_Ticks(&time);
time-=StartTime;
time -= StartTime;
TotalTime += (float)time / Profile_Get_Tick_Rate();
}
return ( RecursionCounter == 0 );
return (RecursionCounter == 0);
}
/***************************************************************************************************
**
** CProfileIterator
**
***************************************************************************************************/
CProfileIterator::CProfileIterator( CProfileNode * start )
CProfileIterator::CProfileIterator(CProfileNode* start)
{
CurrentParent = start;
CurrentChild = CurrentParent->Get_Child();
}
void CProfileIterator::First(void)
void CProfileIterator::First(void)
{
CurrentChild = CurrentParent->Get_Child();
}
void CProfileIterator::Next(void)
void CProfileIterator::Next(void)
{
CurrentChild = CurrentChild->Get_Sibling();
}
bool CProfileIterator::Is_Done(void)
bool CProfileIterator::Is_Done(void)
{
return CurrentChild == NULL;
}
void CProfileIterator::Enter_Child( int index )
void CProfileIterator::Enter_Child(int index)
{
CurrentChild = CurrentParent->Get_Child();
while ( (CurrentChild != NULL) && (index != 0) ) {
while ((CurrentChild != NULL) && (index != 0))
{
index--;
CurrentChild = CurrentChild->Get_Sibling();
}
if ( CurrentChild != NULL ) {
if (CurrentChild != NULL)
{
CurrentParent = CurrentChild;
CurrentChild = CurrentParent->Get_Child();
}
}
void CProfileIterator::Enter_Parent( void )
void CProfileIterator::Enter_Parent(void)
{
if ( CurrentParent->Get_Parent() != NULL ) {
if (CurrentParent->Get_Parent() != NULL)
{
CurrentParent = CurrentParent->Get_Parent();
}
CurrentChild = CurrentParent->Get_Child();
}
/***************************************************************************************************
**
** CProfileManager
**
***************************************************************************************************/
CProfileNode gRoots[BT_QUICKPROF_MAX_THREAD_COUNT] = {
CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL),
CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL),
CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL),
CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL),
CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL),
CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL),
CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL),
CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL),
CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL),
CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL),
CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL),
CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL),
CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL),
CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL),
CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL),
CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL)};
CProfileNode gRoots[BT_QUICKPROF_MAX_THREAD_COUNT]={
CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),
CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),
CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),
CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),
CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),
CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),
CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),
CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),
CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),
CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),
CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),
CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),
CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),
CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),
CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),
CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL)
CProfileNode* gCurrentNodes[BT_QUICKPROF_MAX_THREAD_COUNT] =
{
&gRoots[0],
&gRoots[1],
&gRoots[2],
&gRoots[3],
&gRoots[4],
&gRoots[5],
&gRoots[6],
&gRoots[7],
&gRoots[8],
&gRoots[9],
&gRoots[10],
&gRoots[11],
&gRoots[12],
&gRoots[13],
&gRoots[14],
&gRoots[15],
&gRoots[16],
&gRoots[17],
&gRoots[18],
&gRoots[19],
&gRoots[20],
&gRoots[21],
&gRoots[22],
&gRoots[23],
&gRoots[24],
&gRoots[25],
&gRoots[26],
&gRoots[27],
&gRoots[28],
&gRoots[29],
&gRoots[30],
&gRoots[31],
&gRoots[32],
&gRoots[33],
&gRoots[34],
&gRoots[35],
&gRoots[36],
&gRoots[37],
&gRoots[38],
&gRoots[39],
&gRoots[40],
&gRoots[41],
&gRoots[42],
&gRoots[43],
&gRoots[44],
&gRoots[45],
&gRoots[46],
&gRoots[47],
&gRoots[48],
&gRoots[49],
&gRoots[50],
&gRoots[51],
&gRoots[52],
&gRoots[53],
&gRoots[54],
&gRoots[55],
&gRoots[56],
&gRoots[57],
&gRoots[58],
&gRoots[59],
&gRoots[60],
&gRoots[61],
&gRoots[62],
&gRoots[63],
};
int CProfileManager::FrameCounter = 0;
unsigned long int CProfileManager::ResetTime = 0;
CProfileNode* gCurrentNodes[BT_QUICKPROF_MAX_THREAD_COUNT]=
CProfileIterator* CProfileManager::Get_Iterator(void)
{
&gRoots[ 0], &gRoots[ 1], &gRoots[ 2], &gRoots[ 3],
&gRoots[ 4], &gRoots[ 5], &gRoots[ 6], &gRoots[ 7],
&gRoots[ 8], &gRoots[ 9], &gRoots[10], &gRoots[11],
&gRoots[12], &gRoots[13], &gRoots[14], &gRoots[15],
&gRoots[16], &gRoots[17], &gRoots[18], &gRoots[19],
&gRoots[20], &gRoots[21], &gRoots[22], &gRoots[23],
&gRoots[24], &gRoots[25], &gRoots[26], &gRoots[27],
&gRoots[28], &gRoots[29], &gRoots[30], &gRoots[31],
&gRoots[32], &gRoots[33], &gRoots[34], &gRoots[35],
&gRoots[36], &gRoots[37], &gRoots[38], &gRoots[39],
&gRoots[40], &gRoots[41], &gRoots[42], &gRoots[43],
&gRoots[44], &gRoots[45], &gRoots[46], &gRoots[47],
&gRoots[48], &gRoots[49], &gRoots[50], &gRoots[51],
&gRoots[52], &gRoots[53], &gRoots[54], &gRoots[55],
&gRoots[56], &gRoots[57], &gRoots[58], &gRoots[59],
&gRoots[60], &gRoots[61], &gRoots[62], &gRoots[63],
};
int threadIndex = btQuickprofGetCurrentThreadIndex2();
if ((threadIndex < 0) || threadIndex >= BT_QUICKPROF_MAX_THREAD_COUNT)
return 0;
int CProfileManager::FrameCounter = 0;
unsigned long int CProfileManager::ResetTime = 0;
CProfileIterator * CProfileManager::Get_Iterator( void )
{
int threadIndex = btQuickprofGetCurrentThreadIndex2();
if ((threadIndex<0) || threadIndex >= BT_QUICKPROF_MAX_THREAD_COUNT)
return 0;
return new CProfileIterator( &gRoots[threadIndex]);
return new CProfileIterator(&gRoots[threadIndex]);
}
void CProfileManager::CleanupMemory(void)
void CProfileManager::CleanupMemory(void)
{
for (int i=0;i<BT_QUICKPROF_MAX_THREAD_COUNT;i++)
for (int i = 0; i < BT_QUICKPROF_MAX_THREAD_COUNT; i++)
{
gRoots[i].CleanupMemory();
}
}
/***********************************************************************************************
* CProfileManager::Start_Profile -- Begin a named profile *
* *
@@ -546,51 +568,47 @@ void CProfileManager::CleanupMemory(void)
* The string used is assumed to be a static string; pointer compares are used throughout *
* the profiling code for efficiency. *
*=============================================================================================*/
void CProfileManager::Start_Profile( const char * name )
void CProfileManager::Start_Profile(const char* name)
{
int threadIndex = btQuickprofGetCurrentThreadIndex2();
if ((threadIndex<0) || threadIndex >= BT_QUICKPROF_MAX_THREAD_COUNT)
if ((threadIndex < 0) || threadIndex >= BT_QUICKPROF_MAX_THREAD_COUNT)
return;
if (name != gCurrentNodes[threadIndex]->Get_Name()) {
gCurrentNodes[threadIndex] = gCurrentNodes[threadIndex]->Get_Sub_Node( name );
if (name != gCurrentNodes[threadIndex]->Get_Name())
{
gCurrentNodes[threadIndex] = gCurrentNodes[threadIndex]->Get_Sub_Node(name);
}
gCurrentNodes[threadIndex]->Call();
}
/***********************************************************************************************
* CProfileManager::Stop_Profile -- Stop timing and record the results. *
*=============================================================================================*/
void CProfileManager::Stop_Profile( void )
void CProfileManager::Stop_Profile(void)
{
int threadIndex = btQuickprofGetCurrentThreadIndex2();
if ((threadIndex<0) || threadIndex >= BT_QUICKPROF_MAX_THREAD_COUNT)
if ((threadIndex < 0) || threadIndex >= BT_QUICKPROF_MAX_THREAD_COUNT)
return;
// Return will indicate whether we should back up to our parent (we may
// be profiling a recursive function)
if (gCurrentNodes[threadIndex]->Return()) {
if (gCurrentNodes[threadIndex]->Return())
{
gCurrentNodes[threadIndex] = gCurrentNodes[threadIndex]->Get_Parent();
}
}
/***********************************************************************************************
* CProfileManager::Reset -- Reset the contents of the profiling system *
* *
* This resets everything except for the tree structure. All of the timing data is reset. *
*=============================================================================================*/
void CProfileManager::Reset( void )
void CProfileManager::Reset(void)
{
gProfileClock.reset();
int threadIndex = btQuickprofGetCurrentThreadIndex2();
if ((threadIndex<0) || threadIndex >= BT_QUICKPROF_MAX_THREAD_COUNT)
if ((threadIndex < 0) || threadIndex >= BT_QUICKPROF_MAX_THREAD_COUNT)
return;
gRoots[threadIndex].Reset();
gRoots[threadIndex].Call();
@@ -598,20 +616,18 @@ void CProfileManager::Reset( void )
Profile_Get_Ticks(&ResetTime);
}
/***********************************************************************************************
* CProfileManager::Increment_Frame_Counter -- Increment the frame counter *
*=============================================================================================*/
void CProfileManager::Increment_Frame_Counter( void )
void CProfileManager::Increment_Frame_Counter(void)
{
FrameCounter++;
}
/***********************************************************************************************
* CProfileManager::Get_Time_Since_Reset -- returns the elapsed time since last reset *
*=============================================================================================*/
float CProfileManager::Get_Time_Since_Reset( void )
float CProfileManager::Get_Time_Since_Reset(void)
{
unsigned long int time;
Profile_Get_Ticks(&time);
@@ -621,34 +637,34 @@ float CProfileManager::Get_Time_Since_Reset( void )
#include <stdio.h>
void CProfileManager::dumpRecursive(CProfileIterator* profileIterator, int spacing)
void CProfileManager::dumpRecursive(CProfileIterator* profileIterator, int spacing)
{
profileIterator->First();
if (profileIterator->Is_Done())
return;
float accumulated_time=0,parent_time = profileIterator->Is_Root() ? CProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time();
float accumulated_time = 0, parent_time = profileIterator->Is_Root() ? CProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time();
int i;
int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset();
for (i=0;i<spacing;i++) printf(".");
for (i = 0; i < spacing; i++) printf(".");
printf("----------------------------------\n");
for (i=0;i<spacing;i++) printf(".");
printf("Profiling: %s (total running time: %.3f ms) ---\n", profileIterator->Get_Current_Parent_Name(), parent_time );
for (i = 0; i < spacing; i++) printf(".");
printf("Profiling: %s (total running time: %.3f ms) ---\n", profileIterator->Get_Current_Parent_Name(), parent_time);
float totalTime = 0.f;
int numChildren = 0;
for (i = 0; !profileIterator->Is_Done(); i++,profileIterator->Next())
for (i = 0; !profileIterator->Is_Done(); i++, profileIterator->Next())
{
numChildren++;
float current_total_time = profileIterator->Get_Current_Total_Time();
accumulated_time += current_total_time;
float fraction = parent_time > SIMD_EPSILON ? (current_total_time / parent_time) * 100 : 0.f;
{
int i; for (i=0;i<spacing;i++) printf(".");
int i;
for (i = 0; i < spacing; i++) printf(".");
}
printf("%d -- %s (%.2f %%) :: %.3f ms / frame (%d calls)\n",i, profileIterator->Get_Current_Name(), fraction,(current_total_time / (double)frames_since_reset),profileIterator->Get_Current_Total_Calls());
printf("%d -- %s (%.2f %%) :: %.3f ms / frame (%d calls)\n", i, profileIterator->Get_Current_Name(), fraction, (current_total_time / (double)frames_since_reset), profileIterator->Get_Current_Total_Calls());
totalTime += current_total_time;
//recurse into children
}
@@ -657,25 +673,23 @@ void CProfileManager::dumpRecursive(CProfileIterator* profileIterator, int spaci
{
//printf("what's wrong\n");
}
for (i=0;i<spacing;i++) printf(".");
printf("%s (%.3f %%) :: %.3f ms\n", "Unaccounted:",parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time);
for (i = 0; i < spacing; i++) printf(".");
printf("%s (%.3f %%) :: %.3f ms\n", "Unaccounted:", parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time);
for (i=0;i<numChildren;i++)
for (i = 0; i < numChildren; i++)
{
profileIterator->Enter_Child(i);
dumpRecursive(profileIterator,spacing+3);
dumpRecursive(profileIterator, spacing + 3);
profileIterator->Enter_Parent();
}
}
void CProfileManager::dumpAll()
void CProfileManager::dumpAll()
{
CProfileIterator* profileIterator = 0;
profileIterator = CProfileManager::Get_Iterator();
dumpRecursive(profileIterator,0);
dumpRecursive(profileIterator, 0);
CProfileManager::Release_Iterator(profileIterator);
}
@@ -703,50 +717,47 @@ void CProfileManager::dumpAll()
#endif // defined(__ANDROID__) && defined(__clang__)
// clang-format on
unsigned int btQuickprofGetCurrentThreadIndex2() {
const unsigned int kNullIndex = ~0U;
unsigned int btQuickprofGetCurrentThreadIndex2()
{
const unsigned int kNullIndex = ~0U;
#if BT_THREADSAFE
return btGetCurrentThreadIndex();
return btGetCurrentThreadIndex();
#else
#if defined(BT_HAVE_TLS)
static __thread unsigned int sThreadIndex = kNullIndex;
static __thread unsigned int sThreadIndex = kNullIndex;
#elif defined(_WIN32)
__declspec(thread) static unsigned int sThreadIndex = kNullIndex;
__declspec(thread) static unsigned int sThreadIndex = kNullIndex;
#else
unsigned int sThreadIndex = 0;
return -1;
unsigned int sThreadIndex = 0;
return -1;
#endif
static int gThreadCounter = 0;
static int gThreadCounter = 0;
if (sThreadIndex == kNullIndex) {
sThreadIndex = gThreadCounter++;
}
return sThreadIndex;
#endif //BT_THREADSAFE
if (sThreadIndex == kNullIndex)
{
sThreadIndex = gThreadCounter++;
}
return sThreadIndex;
#endif //BT_THREADSAFE
}
void btEnterProfileZoneDefault(const char* name)
void btEnterProfileZoneDefault(const char* name)
{
}
void btLeaveProfileZoneDefault()
void btLeaveProfileZoneDefault()
{
}
#else
void btEnterProfileZoneDefault(const char* name)
void btEnterProfileZoneDefault(const char* name)
{
}
void btLeaveProfileZoneDefault()
void btLeaveProfileZoneDefault()
{
}
#endif //BT_NO_PROFILE
#endif //BT_NO_PROFILE
static btEnterProfileZoneFunc* bts_enterFunc = btEnterProfileZoneDefault;
static btLeaveProfileZoneFunc* bts_leaveFunc = btLeaveProfileZoneDefault;
@@ -762,14 +773,13 @@ void btLeaveProfileZone()
btEnterProfileZoneFunc* btGetCurrentEnterProfileZoneFunc()
{
return bts_enterFunc ;
return bts_enterFunc;
}
btLeaveProfileZoneFunc* btGetCurrentLeaveProfileZoneFunc()
{
return bts_leaveFunc;
}
void btSetCustomEnterProfileZoneFunc(btEnterProfileZoneFunc* enterFunc)
{
bts_enterFunc = enterFunc;
@@ -779,13 +789,12 @@ void btSetCustomLeaveProfileZoneFunc(btLeaveProfileZoneFunc* leaveFunc)
bts_leaveFunc = leaveFunc;
}
CProfileSample::CProfileSample( const char * name )
{
CProfileSample::CProfileSample(const char* name)
{
btEnterProfileZone(name);
}
CProfileSample::~CProfileSample( void )
{
CProfileSample::~CProfileSample(void)
{
btLeaveProfileZone();
}

View File

@@ -7,11 +7,9 @@
**
***************************************************************************************************/
// Credits: The Clock class was inspired by the Timer classes in
// Credits: The Clock class was inspired by the Timer classes in
// Ogre (www.ogre3d.org).
#ifndef BT_QUICK_PROF_H
#define BT_QUICK_PROF_H
@@ -34,97 +32,87 @@ public:
/// Resets the initial reference time.
void reset();
/// Returns the time in ms since the last call to reset or since
/// Returns the time in ms since the last call to reset or since
/// the btClock was created.
unsigned long long int getTimeMilliseconds();
/// Returns the time in us since the last call to reset or since
/// Returns the time in us since the last call to reset or since
/// the Clock was created.
unsigned long long int getTimeMicroseconds();
unsigned long long int getTimeNanoseconds();
/// Returns the time in s since the last call to reset or since
/// Returns the time in s since the last call to reset or since
/// the Clock was created.
btScalar getTimeSeconds();
private:
struct btClockData* m_data;
};
#endif //USE_BT_CLOCK
#endif //USE_BT_CLOCK
typedef void (btEnterProfileZoneFunc)(const char* msg);
typedef void (btLeaveProfileZoneFunc)();
typedef void(btEnterProfileZoneFunc)(const char* msg);
typedef void(btLeaveProfileZoneFunc)();
btEnterProfileZoneFunc* btGetCurrentEnterProfileZoneFunc();
btLeaveProfileZoneFunc* btGetCurrentLeaveProfileZoneFunc();
void btSetCustomEnterProfileZoneFunc(btEnterProfileZoneFunc* enterFunc);
void btSetCustomLeaveProfileZoneFunc(btLeaveProfileZoneFunc* leaveFunc);
#ifndef BT_NO_PROFILE // FIX redefinition
#ifndef BT_NO_PROFILE // FIX redefinition
//To disable built-in profiling, please comment out next line
//#define BT_NO_PROFILE 1
#endif //BT_NO_PROFILE
#endif //BT_NO_PROFILE
const unsigned int BT_QUICKPROF_MAX_THREAD_COUNT = 64;
#ifndef BT_NO_PROFILE
//btQuickprofGetCurrentThreadIndex will return -1 if thread index cannot be determined,
//btQuickprofGetCurrentThreadIndex will return -1 if thread index cannot be determined,
//otherwise returns thread index in range [0..maxThreads]
unsigned int btQuickprofGetCurrentThreadIndex2();
#include <stdio.h>//@todo remove this, backwards compatibility
#include <stdio.h> //@todo remove this, backwards compatibility
#include "btAlignedAllocator.h"
#include <new>
///A node in the Profile Hierarchy Tree
class CProfileNode {
class CProfileNode
{
public:
CProfileNode( const char * name, CProfileNode * parent );
~CProfileNode( void );
CProfileNode(const char* name, CProfileNode* parent);
~CProfileNode(void);
CProfileNode * Get_Sub_Node( const char * name );
CProfileNode* Get_Sub_Node(const char* name);
CProfileNode * Get_Parent( void ) { return Parent; }
CProfileNode * Get_Sibling( void ) { return Sibling; }
CProfileNode * Get_Child( void ) { return Child; }
CProfileNode* Get_Parent(void) { return Parent; }
CProfileNode* Get_Sibling(void) { return Sibling; }
CProfileNode* Get_Child(void) { return Child; }
void CleanupMemory();
void Reset( void );
void Call( void );
bool Return( void );
void CleanupMemory();
void Reset(void);
void Call(void);
bool Return(void);
const char* Get_Name(void) { return Name; }
int Get_Total_Calls(void) { return TotalCalls; }
float Get_Total_Time(void) { return TotalTime; }
void* GetUserPointer() const { return m_userPtr; }
void SetUserPointer(void* ptr) { m_userPtr = ptr; }
const char * Get_Name( void ) { return Name; }
int Get_Total_Calls( void ) { return TotalCalls; }
float Get_Total_Time( void ) { return TotalTime; }
void* GetUserPointer() const {return m_userPtr;}
void SetUserPointer(void* ptr) { m_userPtr = ptr;}
protected:
const char* Name;
int TotalCalls;
float TotalTime;
unsigned long int StartTime;
int RecursionCounter;
const char * Name;
int TotalCalls;
float TotalTime;
unsigned long int StartTime;
int RecursionCounter;
CProfileNode * Parent;
CProfileNode * Child;
CProfileNode * Sibling;
void* m_userPtr;
CProfileNode* Parent;
CProfileNode* Child;
CProfileNode* Sibling;
void* m_userPtr;
};
///An iterator to navigate through the tree
@@ -132,91 +120,80 @@ class CProfileIterator
{
public:
// Access all the children of the current parent
void First(void);
void Next(void);
bool Is_Done(void);
bool Is_Root(void) { return (CurrentParent->Get_Parent() == 0); }
void First(void);
void Next(void);
bool Is_Done(void);
bool Is_Root(void) { return (CurrentParent->Get_Parent() == 0); }
void Enter_Child( int index ); // Make the given child the new parent
void Enter_Largest_Child( void ); // Make the largest child the new parent
void Enter_Parent( void ); // Make the current parent's parent the new parent
void Enter_Child(int index); // Make the given child the new parent
void Enter_Largest_Child(void); // Make the largest child the new parent
void Enter_Parent(void); // Make the current parent's parent the new parent
// Access the current child
const char * Get_Current_Name( void ) { return CurrentChild->Get_Name(); }
int Get_Current_Total_Calls( void ) { return CurrentChild->Get_Total_Calls(); }
float Get_Current_Total_Time( void ) { return CurrentChild->Get_Total_Time(); }
const char* Get_Current_Name(void) { return CurrentChild->Get_Name(); }
int Get_Current_Total_Calls(void) { return CurrentChild->Get_Total_Calls(); }
float Get_Current_Total_Time(void) { return CurrentChild->Get_Total_Time(); }
void* Get_Current_UserPointer( void ) { return CurrentChild->GetUserPointer(); }
void Set_Current_UserPointer(void* ptr) {CurrentChild->SetUserPointer(ptr);}
void* Get_Current_UserPointer(void) { return CurrentChild->GetUserPointer(); }
void Set_Current_UserPointer(void* ptr) { CurrentChild->SetUserPointer(ptr); }
// Access the current parent
const char * Get_Current_Parent_Name( void ) { return CurrentParent->Get_Name(); }
int Get_Current_Parent_Total_Calls( void ) { return CurrentParent->Get_Total_Calls(); }
float Get_Current_Parent_Total_Time( void ) { return CurrentParent->Get_Total_Time(); }
const char* Get_Current_Parent_Name(void) { return CurrentParent->Get_Name(); }
int Get_Current_Parent_Total_Calls(void) { return CurrentParent->Get_Total_Calls(); }
float Get_Current_Parent_Total_Time(void) { return CurrentParent->Get_Total_Time(); }
protected:
CProfileNode* CurrentParent;
CProfileNode* CurrentChild;
CProfileNode * CurrentParent;
CProfileNode * CurrentChild;
CProfileIterator( CProfileNode * start );
friend class CProfileManager;
CProfileIterator(CProfileNode* start);
friend class CProfileManager;
};
///The Manager for the Profile system
class CProfileManager {
class CProfileManager
{
public:
static void Start_Profile( const char * name );
static void Stop_Profile( void );
static void Start_Profile(const char* name);
static void Stop_Profile(void);
static void CleanupMemory(void);
// {
// Root.CleanupMemory();
// }
static void CleanupMemory(void);
// {
// Root.CleanupMemory();
// }
static void Reset( void );
static void Increment_Frame_Counter( void );
static int Get_Frame_Count_Since_Reset( void ) { return FrameCounter; }
static float Get_Time_Since_Reset( void );
static void Reset(void);
static void Increment_Frame_Counter(void);
static int Get_Frame_Count_Since_Reset(void) { return FrameCounter; }
static float Get_Time_Since_Reset(void);
static CProfileIterator * Get_Iterator( void );
// {
//
// return new CProfileIterator( &Root );
// }
static void Release_Iterator( CProfileIterator * iterator ) { delete ( iterator); }
static CProfileIterator* Get_Iterator(void);
// {
//
// return new CProfileIterator( &Root );
// }
static void Release_Iterator(CProfileIterator* iterator) { delete (iterator); }
static void dumpRecursive(CProfileIterator* profileIterator, int spacing);
static void dumpRecursive(CProfileIterator* profileIterator, int spacing);
static void dumpAll();
static void dumpAll();
private:
static int FrameCounter;
static unsigned long int ResetTime;
static int FrameCounter;
static unsigned long int ResetTime;
};
#endif //#ifndef BT_NO_PROFILE
#endif //#ifndef BT_NO_PROFILE
///ProfileSampleClass is a simple way to profile a function's scope
///Use the BT_PROFILE macro at the start of scope to time
class CProfileSample {
class CProfileSample
{
public:
CProfileSample( const char * name );
CProfileSample(const char* name);
~CProfileSample( void );
~CProfileSample(void);
};
#define BT_PROFILE( name ) CProfileSample __profile( name )
#endif //BT_QUICK_PROF_H
#define BT_PROFILE(name) CProfileSample __profile(name)
#endif //BT_QUICK_PROF_H

View File

@@ -12,8 +12,6 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BT_GEN_RANDOM_H
#define BT_GEN_RANDOM_H
@@ -24,8 +22,8 @@ subject to the following restrictions:
#define GEN_RAND_MAX UINT_MAX
SIMD_FORCE_INLINE void GEN_srand(unsigned int seed) { init_genrand(seed); }
SIMD_FORCE_INLINE unsigned int GEN_rand() { return genrand_int32(); }
SIMD_FORCE_INLINE void GEN_srand(unsigned int seed) { init_genrand(seed); }
SIMD_FORCE_INLINE unsigned int GEN_rand() { return genrand_int32(); }
#else
@@ -33,10 +31,9 @@ SIMD_FORCE_INLINE unsigned int GEN_rand() { return genrand_int
#define GEN_RAND_MAX RAND_MAX
SIMD_FORCE_INLINE void GEN_srand(unsigned int seed) { srand(seed); }
SIMD_FORCE_INLINE unsigned int GEN_rand() { return rand(); }
SIMD_FORCE_INLINE void GEN_srand(unsigned int seed) { srand(seed); }
SIMD_FORCE_INLINE unsigned int GEN_rand() { return rand(); }
#endif
#endif //BT_GEN_RANDOM_H
#endif //BT_GEN_RANDOM_H

View File

@@ -32,7 +32,6 @@ inline int btGetVersion()
return BT_BULLET_VERSION;
}
// The following macro "BT_NOT_EMPTY_FILE" can be put into a file
// in order suppress the MS Visual C++ Linker warning 4221
//
@@ -44,16 +43,19 @@ inline int btGetVersion()
//
// see more https://stackoverflow.com/questions/1822887/what-is-the-best-way-to-eliminate-ms-visual-c-linker-warning-warning-lnk422
#if defined (_MSC_VER)
#define BT_NOT_EMPTY_FILE_CAT_II(p, res) res
#define BT_NOT_EMPTY_FILE_CAT_I(a, b) BT_NOT_EMPTY_FILE_CAT_II(~, a ## b)
#define BT_NOT_EMPTY_FILE_CAT(a, b) BT_NOT_EMPTY_FILE_CAT_I(a, b)
#define BT_NOT_EMPTY_FILE namespace { char BT_NOT_EMPTY_FILE_CAT(NoEmptyFileDummy, __COUNTER__); }
#if defined(_MSC_VER)
#define BT_NOT_EMPTY_FILE_CAT_II(p, res) res
#define BT_NOT_EMPTY_FILE_CAT_I(a, b) BT_NOT_EMPTY_FILE_CAT_II(~, a##b)
#define BT_NOT_EMPTY_FILE_CAT(a, b) BT_NOT_EMPTY_FILE_CAT_I(a, b)
#define BT_NOT_EMPTY_FILE \
namespace \
{ \
char BT_NOT_EMPTY_FILE_CAT(NoEmptyFileDummy, __COUNTER__); \
}
#else
#define BT_NOT_EMPTY_FILE
#define BT_NOT_EMPTY_FILE
#endif
// clang and most formatting tools don't support indentation of preprocessor guards, so turn it off
// clang-format off
#if defined(DEBUG) || defined (_DEBUG)

View File

@@ -1,3 +1,4 @@
// clang-format off
char sBulletDNAstr[]= {
char(83),char(68),char(78),char(65),char(78),char(65),char(77),char(69),char(-76),char(1),char(0),char(0),char(109),char(95),char(115),char(105),char(122),char(101),char(0),char(109),
char(95),char(99),char(97),char(112),char(97),char(99),char(105),char(116),char(121),char(0),char(42),char(109),char(95),char(100),char(97),char(116),char(97),char(0),char(109),char(95),
@@ -687,3 +688,5 @@ char(97),char(0),char(4),char(0),char(50),char(0),char(-79),char(1),char(96),cha
char(98),char(0),char(4),char(0),char(48),char(0),char(-79),char(1),char(95),char(0),char(-78),char(1),char(4),char(0),char(-77),char(1),char(0),char(0),char(37),char(0),
};
int sBulletDNAlen= sizeof(sBulletDNAstr);
// clang-format on

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,4 @@
// clang-format off
char sBulletDNAstr64[]= {
char(83),char(68),char(78),char(65),char(78),char(65),char(77),char(69),char(-76),char(1),char(0),char(0),char(109),char(95),char(115),char(105),char(122),char(101),char(0),char(109),
char(95),char(99),char(97),char(112),char(97),char(99),char(105),char(116),char(121),char(0),char(42),char(109),char(95),char(100),char(97),char(116),char(97),char(0),char(109),char(95),
@@ -687,3 +688,4 @@ char(97),char(0),char(4),char(0),char(50),char(0),char(-79),char(1),char(96),cha
char(98),char(0),char(4),char(0),char(48),char(0),char(-79),char(1),char(95),char(0),char(-78),char(1),char(4),char(0),char(-77),char(1),char(0),char(0),char(37),char(0),
};
int sBulletDNAlen64= sizeof(sBulletDNAstr64);
// clang-format on

View File

@@ -12,18 +12,17 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
///These spatial algebra classes are used for btMultiBody,
///These spatial algebra classes are used for btMultiBody,
///see BulletDynamics/Featherstone
#ifndef BT_SPATIAL_ALGEBRA_H
#define BT_SPATIAL_ALGEBRA_H
#include "btMatrix3x3.h"
struct btSpatialForceVector
{
btVector3 m_topVec, m_bottomVec;
{
btVector3 m_topVec, m_bottomVec;
//
btSpatialForceVector() { setZero(); }
btSpatialForceVector(const btVector3 &angular, const btVector3 &linear) : m_topVec(linear), m_bottomVec(angular) {}
@@ -32,21 +31,34 @@ struct btSpatialForceVector
setValue(ax, ay, az, lx, ly, lz);
}
//
void setVector(const btVector3 &angular, const btVector3 &linear) { m_topVec = linear; m_bottomVec = angular; }
void setVector(const btVector3 &angular, const btVector3 &linear)
{
m_topVec = linear;
m_bottomVec = angular;
}
void setValue(const btScalar &ax, const btScalar &ay, const btScalar &az, const btScalar &lx, const btScalar &ly, const btScalar &lz)
{
m_bottomVec.setValue(ax, ay, az); m_topVec.setValue(lx, ly, lz);
m_bottomVec.setValue(ax, ay, az);
m_topVec.setValue(lx, ly, lz);
}
//
void addVector(const btVector3 &angular, const btVector3 &linear) { m_topVec += linear; m_bottomVec += angular; }
void addVector(const btVector3 &angular, const btVector3 &linear)
{
m_topVec += linear;
m_bottomVec += angular;
}
void addValue(const btScalar &ax, const btScalar &ay, const btScalar &az, const btScalar &lx, const btScalar &ly, const btScalar &lz)
{
m_bottomVec[0] += ax; m_bottomVec[1] += ay; m_bottomVec[2] += az;
m_topVec[0] += lx; m_topVec[1] += ly; m_topVec[2] += lz;
m_bottomVec[0] += ax;
m_bottomVec[1] += ay;
m_bottomVec[2] += az;
m_topVec[0] += lx;
m_topVec[1] += ly;
m_topVec[2] += lz;
}
//
const btVector3 & getLinear() const { return m_topVec; }
const btVector3 & getAngular() const { return m_bottomVec; }
const btVector3 &getLinear() const { return m_topVec; }
const btVector3 &getAngular() const { return m_bottomVec; }
//
void setLinear(const btVector3 &linear) { m_topVec = linear; }
void setAngular(const btVector3 &angular) { m_bottomVec = angular; }
@@ -54,14 +66,28 @@ struct btSpatialForceVector
void addAngular(const btVector3 &angular) { m_bottomVec += angular; }
void addLinear(const btVector3 &linear) { m_topVec += linear; }
//
void setZero() { m_topVec.setZero(); m_bottomVec.setZero(); }
void setZero()
{
m_topVec.setZero();
m_bottomVec.setZero();
}
//
btSpatialForceVector & operator += (const btSpatialForceVector &vec) { m_topVec += vec.m_topVec; m_bottomVec += vec.m_bottomVec; return *this; }
btSpatialForceVector & operator -= (const btSpatialForceVector &vec) { m_topVec -= vec.m_topVec; m_bottomVec -= vec.m_bottomVec; return *this; }
btSpatialForceVector operator - (const btSpatialForceVector &vec) const { return btSpatialForceVector(m_bottomVec - vec.m_bottomVec, m_topVec - vec.m_topVec); }
btSpatialForceVector operator + (const btSpatialForceVector &vec) const { return btSpatialForceVector(m_bottomVec + vec.m_bottomVec, m_topVec + vec.m_topVec); }
btSpatialForceVector operator - () const { return btSpatialForceVector(-m_bottomVec, -m_topVec); }
btSpatialForceVector operator * (const btScalar &s) const { return btSpatialForceVector(s * m_bottomVec, s * m_topVec); }
btSpatialForceVector &operator+=(const btSpatialForceVector &vec)
{
m_topVec += vec.m_topVec;
m_bottomVec += vec.m_bottomVec;
return *this;
}
btSpatialForceVector &operator-=(const btSpatialForceVector &vec)
{
m_topVec -= vec.m_topVec;
m_bottomVec -= vec.m_bottomVec;
return *this;
}
btSpatialForceVector operator-(const btSpatialForceVector &vec) const { return btSpatialForceVector(m_bottomVec - vec.m_bottomVec, m_topVec - vec.m_topVec); }
btSpatialForceVector operator+(const btSpatialForceVector &vec) const { return btSpatialForceVector(m_bottomVec + vec.m_bottomVec, m_topVec + vec.m_topVec); }
btSpatialForceVector operator-() const { return btSpatialForceVector(-m_bottomVec, -m_topVec); }
btSpatialForceVector operator*(const btScalar &s) const { return btSpatialForceVector(s * m_bottomVec, s * m_topVec); }
//btSpatialForceVector & operator = (const btSpatialForceVector &vec) { m_topVec = vec.m_topVec; m_bottomVec = vec.m_bottomVec; return *this; }
};
@@ -70,23 +96,36 @@ struct btSpatialMotionVector
btVector3 m_topVec, m_bottomVec;
//
btSpatialMotionVector() { setZero(); }
btSpatialMotionVector(const btVector3 &angular, const btVector3 &linear) : m_topVec(angular), m_bottomVec(linear) {}
btSpatialMotionVector(const btVector3 &angular, const btVector3 &linear) : m_topVec(angular), m_bottomVec(linear) {}
//
void setVector(const btVector3 &angular, const btVector3 &linear) { m_topVec = angular; m_bottomVec = linear; }
void setVector(const btVector3 &angular, const btVector3 &linear)
{
m_topVec = angular;
m_bottomVec = linear;
}
void setValue(const btScalar &ax, const btScalar &ay, const btScalar &az, const btScalar &lx, const btScalar &ly, const btScalar &lz)
{
m_topVec.setValue(ax, ay, az); m_bottomVec.setValue(lx, ly, lz);
m_topVec.setValue(ax, ay, az);
m_bottomVec.setValue(lx, ly, lz);
}
//
void addVector(const btVector3 &angular, const btVector3 &linear) { m_topVec += linear; m_bottomVec += angular; }
void addVector(const btVector3 &angular, const btVector3 &linear)
{
m_topVec += linear;
m_bottomVec += angular;
}
void addValue(const btScalar &ax, const btScalar &ay, const btScalar &az, const btScalar &lx, const btScalar &ly, const btScalar &lz)
{
m_topVec[0] += ax; m_topVec[1] += ay; m_topVec[2] += az;
m_bottomVec[0] += lx; m_bottomVec[1] += ly; m_bottomVec[2] += lz;
m_topVec[0] += ax;
m_topVec[1] += ay;
m_topVec[2] += az;
m_bottomVec[0] += lx;
m_bottomVec[1] += ly;
m_bottomVec[2] += lz;
}
//
const btVector3 & getAngular() const { return m_topVec; }
const btVector3 & getLinear() const { return m_bottomVec; }
//
const btVector3 &getAngular() const { return m_topVec; }
const btVector3 &getLinear() const { return m_bottomVec; }
//
void setAngular(const btVector3 &angular) { m_topVec = angular; }
void setLinear(const btVector3 &linear) { m_bottomVec = linear; }
@@ -94,20 +133,24 @@ struct btSpatialMotionVector
void addAngular(const btVector3 &angular) { m_topVec += angular; }
void addLinear(const btVector3 &linear) { m_bottomVec += linear; }
//
void setZero() { m_topVec.setZero(); m_bottomVec.setZero(); }
void setZero()
{
m_topVec.setZero();
m_bottomVec.setZero();
}
//
btScalar dot(const btSpatialForceVector &b) const
{
return m_bottomVec.dot(b.m_topVec) + m_topVec.dot(b.m_bottomVec);
}
//
template<typename SpatialVectorType>
template <typename SpatialVectorType>
void cross(const SpatialVectorType &b, SpatialVectorType &out) const
{
out.m_topVec = m_topVec.cross(b.m_topVec);
out.m_bottomVec = m_bottomVec.cross(b.m_topVec) + m_topVec.cross(b.m_bottomVec);
}
template<typename SpatialVectorType>
template <typename SpatialVectorType>
SpatialVectorType cross(const SpatialVectorType &b) const
{
SpatialVectorType out;
@@ -116,21 +159,36 @@ struct btSpatialMotionVector
return out;
}
//
btSpatialMotionVector & operator += (const btSpatialMotionVector &vec) { m_topVec += vec.m_topVec; m_bottomVec += vec.m_bottomVec; return *this; }
btSpatialMotionVector & operator -= (const btSpatialMotionVector &vec) { m_topVec -= vec.m_topVec; m_bottomVec -= vec.m_bottomVec; return *this; }
btSpatialMotionVector & operator *= (const btScalar &s) { m_topVec *= s; m_bottomVec *= s; return *this; }
btSpatialMotionVector operator - (const btSpatialMotionVector &vec) const { return btSpatialMotionVector(m_topVec - vec.m_topVec, m_bottomVec - vec.m_bottomVec); }
btSpatialMotionVector operator + (const btSpatialMotionVector &vec) const { return btSpatialMotionVector(m_topVec + vec.m_topVec, m_bottomVec + vec.m_bottomVec); }
btSpatialMotionVector operator - () const { return btSpatialMotionVector(-m_topVec, -m_bottomVec); }
btSpatialMotionVector operator * (const btScalar &s) const { return btSpatialMotionVector(s * m_topVec, s * m_bottomVec); }
btSpatialMotionVector &operator+=(const btSpatialMotionVector &vec)
{
m_topVec += vec.m_topVec;
m_bottomVec += vec.m_bottomVec;
return *this;
}
btSpatialMotionVector &operator-=(const btSpatialMotionVector &vec)
{
m_topVec -= vec.m_topVec;
m_bottomVec -= vec.m_bottomVec;
return *this;
}
btSpatialMotionVector &operator*=(const btScalar &s)
{
m_topVec *= s;
m_bottomVec *= s;
return *this;
}
btSpatialMotionVector operator-(const btSpatialMotionVector &vec) const { return btSpatialMotionVector(m_topVec - vec.m_topVec, m_bottomVec - vec.m_bottomVec); }
btSpatialMotionVector operator+(const btSpatialMotionVector &vec) const { return btSpatialMotionVector(m_topVec + vec.m_topVec, m_bottomVec + vec.m_bottomVec); }
btSpatialMotionVector operator-() const { return btSpatialMotionVector(-m_topVec, -m_bottomVec); }
btSpatialMotionVector operator*(const btScalar &s) const { return btSpatialMotionVector(s * m_topVec, s * m_bottomVec); }
};
struct btSymmetricSpatialDyad
{
btMatrix3x3 m_topLeftMat, m_topRightMat, m_bottomLeftMat;
//
//
btSymmetricSpatialDyad() { setIdentity(); }
btSymmetricSpatialDyad(const btMatrix3x3 &topLeftMat, const btMatrix3x3 &topRightMat, const btMatrix3x3 &bottomLeftMat) { setMatrix(topLeftMat, topRightMat, bottomLeftMat); }
btSymmetricSpatialDyad(const btMatrix3x3 &topLeftMat, const btMatrix3x3 &topRightMat, const btMatrix3x3 &bottomLeftMat) { setMatrix(topLeftMat, topRightMat, bottomLeftMat); }
//
void setMatrix(const btMatrix3x3 &topLeftMat, const btMatrix3x3 &topRightMat, const btMatrix3x3 &bottomLeftMat)
{
@@ -146,17 +204,22 @@ struct btSymmetricSpatialDyad
m_bottomLeftMat += bottomLeftMat;
}
//
void setIdentity() { m_topLeftMat.setIdentity(); m_topRightMat.setIdentity(); m_bottomLeftMat.setIdentity(); }
void setIdentity()
{
m_topLeftMat.setIdentity();
m_topRightMat.setIdentity();
m_bottomLeftMat.setIdentity();
}
//
btSymmetricSpatialDyad & operator -= (const btSymmetricSpatialDyad &mat)
btSymmetricSpatialDyad &operator-=(const btSymmetricSpatialDyad &mat)
{
m_topLeftMat -= mat.m_topLeftMat;
m_topRightMat -= mat.m_topRightMat;
m_bottomLeftMat -= mat.m_bottomLeftMat;
return *this;
return *this;
}
//
btSpatialForceVector operator * (const btSpatialMotionVector &vec)
btSpatialForceVector operator*(const btSpatialMotionVector &vec)
{
return btSpatialForceVector(m_bottomLeftMat * vec.m_topVec + m_topLeftMat.transpose() * vec.m_bottomVec, m_topLeftMat * vec.m_topVec + m_topRightMat * vec.m_bottomVec);
}
@@ -164,7 +227,7 @@ struct btSymmetricSpatialDyad
struct btSpatialTransformationMatrix
{
btMatrix3x3 m_rotMat; //btMatrix3x3 m_trnCrossMat;
btMatrix3x3 m_rotMat; //btMatrix3x3 m_trnCrossMat;
btVector3 m_trnVec;
//
enum eOutputOperation
@@ -174,128 +237,124 @@ struct btSpatialTransformationMatrix
Subtract = 2
};
//
template<typename SpatialVectorType>
void transform( const SpatialVectorType &inVec,
SpatialVectorType &outVec,
eOutputOperation outOp = None)
template <typename SpatialVectorType>
void transform(const SpatialVectorType &inVec,
SpatialVectorType &outVec,
eOutputOperation outOp = None)
{
if(outOp == None)
if (outOp == None)
{
outVec.m_topVec = m_rotMat * inVec.m_topVec;
outVec.m_bottomVec = -m_trnVec.cross(outVec.m_topVec) + m_rotMat * inVec.m_bottomVec;
}
else if(outOp == Add)
else if (outOp == Add)
{
outVec.m_topVec += m_rotMat * inVec.m_topVec;
outVec.m_bottomVec += -m_trnVec.cross(outVec.m_topVec) + m_rotMat * inVec.m_bottomVec;
}
else if(outOp == Subtract)
else if (outOp == Subtract)
{
outVec.m_topVec -= m_rotMat * inVec.m_topVec;
outVec.m_bottomVec -= -m_trnVec.cross(outVec.m_topVec) + m_rotMat * inVec.m_bottomVec;
}
}
template<typename SpatialVectorType>
void transformRotationOnly( const SpatialVectorType &inVec,
SpatialVectorType &outVec,
eOutputOperation outOp = None)
template <typename SpatialVectorType>
void transformRotationOnly(const SpatialVectorType &inVec,
SpatialVectorType &outVec,
eOutputOperation outOp = None)
{
if(outOp == None)
if (outOp == None)
{
outVec.m_topVec = m_rotMat * inVec.m_topVec;
outVec.m_bottomVec = m_rotMat * inVec.m_bottomVec;
}
else if(outOp == Add)
else if (outOp == Add)
{
outVec.m_topVec += m_rotMat * inVec.m_topVec;
outVec.m_bottomVec += m_rotMat * inVec.m_bottomVec;
}
else if(outOp == Subtract)
else if (outOp == Subtract)
{
outVec.m_topVec -= m_rotMat * inVec.m_topVec;
outVec.m_bottomVec -= m_rotMat * inVec.m_bottomVec;
}
}
template<typename SpatialVectorType>
void transformInverse( const SpatialVectorType &inVec,
SpatialVectorType &outVec,
eOutputOperation outOp = None)
template <typename SpatialVectorType>
void transformInverse(const SpatialVectorType &inVec,
SpatialVectorType &outVec,
eOutputOperation outOp = None)
{
if(outOp == None)
if (outOp == None)
{
outVec.m_topVec = m_rotMat.transpose() * inVec.m_topVec;
outVec.m_bottomVec = m_rotMat.transpose() * (inVec.m_bottomVec + m_trnVec.cross(inVec.m_topVec));
}
else if(outOp == Add)
else if (outOp == Add)
{
outVec.m_topVec += m_rotMat.transpose() * inVec.m_topVec;
outVec.m_bottomVec += m_rotMat.transpose() * (inVec.m_bottomVec + m_trnVec.cross(inVec.m_topVec));
}
else if(outOp == Subtract)
else if (outOp == Subtract)
{
outVec.m_topVec -= m_rotMat.transpose() * inVec.m_topVec;
outVec.m_bottomVec -= m_rotMat.transpose() * (inVec.m_bottomVec + m_trnVec.cross(inVec.m_topVec));
}
}
}
template<typename SpatialVectorType>
void transformInverseRotationOnly( const SpatialVectorType &inVec,
SpatialVectorType &outVec,
eOutputOperation outOp = None)
template <typename SpatialVectorType>
void transformInverseRotationOnly(const SpatialVectorType &inVec,
SpatialVectorType &outVec,
eOutputOperation outOp = None)
{
if(outOp == None)
if (outOp == None)
{
outVec.m_topVec = m_rotMat.transpose() * inVec.m_topVec;
outVec.m_bottomVec = m_rotMat.transpose() * inVec.m_bottomVec;
}
else if(outOp == Add)
else if (outOp == Add)
{
outVec.m_topVec += m_rotMat.transpose() * inVec.m_topVec;
outVec.m_bottomVec += m_rotMat.transpose() * inVec.m_bottomVec;
}
else if(outOp == Subtract)
else if (outOp == Subtract)
{
outVec.m_topVec -= m_rotMat.transpose() * inVec.m_topVec;
outVec.m_bottomVec -= m_rotMat.transpose() * inVec.m_bottomVec;
}
}
void transformInverse( const btSymmetricSpatialDyad &inMat,
btSymmetricSpatialDyad &outMat,
eOutputOperation outOp = None)
void transformInverse(const btSymmetricSpatialDyad &inMat,
btSymmetricSpatialDyad &outMat,
eOutputOperation outOp = None)
{
const btMatrix3x3 r_cross( 0, -m_trnVec[2], m_trnVec[1],
m_trnVec[2], 0, -m_trnVec[0],
-m_trnVec[1], m_trnVec[0], 0);
const btMatrix3x3 r_cross(0, -m_trnVec[2], m_trnVec[1],
m_trnVec[2], 0, -m_trnVec[0],
-m_trnVec[1], m_trnVec[0], 0);
if(outOp == None)
if (outOp == None)
{
outMat.m_topLeftMat = m_rotMat.transpose() * ( inMat.m_topLeftMat - inMat.m_topRightMat * r_cross ) * m_rotMat;
outMat.m_topLeftMat = m_rotMat.transpose() * (inMat.m_topLeftMat - inMat.m_topRightMat * r_cross) * m_rotMat;
outMat.m_topRightMat = m_rotMat.transpose() * inMat.m_topRightMat * m_rotMat;
outMat.m_bottomLeftMat = m_rotMat.transpose() * (r_cross * (inMat.m_topLeftMat - inMat.m_topRightMat * r_cross) + inMat.m_bottomLeftMat - inMat.m_topLeftMat.transpose() * r_cross) * m_rotMat;
}
else if(outOp == Add)
else if (outOp == Add)
{
outMat.m_topLeftMat += m_rotMat.transpose() * ( inMat.m_topLeftMat - inMat.m_topRightMat * r_cross ) * m_rotMat;
outMat.m_topLeftMat += m_rotMat.transpose() * (inMat.m_topLeftMat - inMat.m_topRightMat * r_cross) * m_rotMat;
outMat.m_topRightMat += m_rotMat.transpose() * inMat.m_topRightMat * m_rotMat;
outMat.m_bottomLeftMat += m_rotMat.transpose() * (r_cross * (inMat.m_topLeftMat - inMat.m_topRightMat * r_cross) + inMat.m_bottomLeftMat - inMat.m_topLeftMat.transpose() * r_cross) * m_rotMat;
}
else if(outOp == Subtract)
else if (outOp == Subtract)
{
outMat.m_topLeftMat -= m_rotMat.transpose() * ( inMat.m_topLeftMat - inMat.m_topRightMat * r_cross ) * m_rotMat;
outMat.m_topLeftMat -= m_rotMat.transpose() * (inMat.m_topLeftMat - inMat.m_topRightMat * r_cross) * m_rotMat;
outMat.m_topRightMat -= m_rotMat.transpose() * inMat.m_topRightMat * m_rotMat;
outMat.m_bottomLeftMat -= m_rotMat.transpose() * (r_cross * (inMat.m_topLeftMat - inMat.m_topRightMat * r_cross) + inMat.m_bottomLeftMat - inMat.m_topLeftMat.transpose() * r_cross) * m_rotMat;
}
}
template<typename SpatialVectorType>
SpatialVectorType operator * (const SpatialVectorType &vec)
template <typename SpatialVectorType>
SpatialVectorType operator*(const SpatialVectorType &vec)
{
SpatialVectorType out;
transform(vec, out);
@@ -303,7 +362,7 @@ struct btSpatialTransformationMatrix
}
};
template<typename SpatialVectorType>
template <typename SpatialVectorType>
void symmetricSpatialOuterProduct(const SpatialVectorType &a, const SpatialVectorType &b, btSymmetricSpatialDyad &out)
{
//output op maybe?
@@ -314,7 +373,7 @@ void symmetricSpatialOuterProduct(const SpatialVectorType &a, const SpatialVecto
//maybe simple a*spatTranspose(a) would be nicer?
}
template<typename SpatialVectorType>
template <typename SpatialVectorType>
btSymmetricSpatialDyad symmetricSpatialOuterProduct(const SpatialVectorType &a, const SpatialVectorType &b)
{
btSymmetricSpatialDyad out;
@@ -327,5 +386,4 @@ btSymmetricSpatialDyad symmetricSpatialOuterProduct(const SpatialVectorType &a,
//maybe simple a*spatTranspose(a) would be nicer?
}
#endif //BT_SPATIAL_ALGEBRA_H
#endif //BT_SPATIAL_ALGEBRA_H

View File

@@ -20,97 +20,99 @@ Nov.2006
#ifndef BT_STACK_ALLOC
#define BT_STACK_ALLOC
#include "btScalar.h" //for btAssert
#include "btScalar.h" //for btAssert
#include "btAlignedAllocator.h"
///The btBlock class is an internal structure for the btStackAlloc memory allocator.
struct btBlock
{
btBlock* previous;
unsigned char* address;
btBlock* previous;
unsigned char* address;
};
///The StackAlloc class provides some fast stack-based memory allocator (LIFO last-in first-out)
class btStackAlloc
{
public:
btStackAlloc(unsigned int size)
{
ctor();
create(size);
}
~btStackAlloc() { destroy(); }
btStackAlloc(unsigned int size) { ctor();create(size); }
~btStackAlloc() { destroy(); }
inline void create(unsigned int size)
inline void create(unsigned int size)
{
destroy();
data = (unsigned char*) btAlignedAlloc(size,16);
totalsize = size;
data = (unsigned char*)btAlignedAlloc(size, 16);
totalsize = size;
}
inline void destroy()
inline void destroy()
{
btAssert(usedsize==0);
btAssert(usedsize == 0);
//Raise(L"StackAlloc is still in use");
if(usedsize==0)
if (usedsize == 0)
{
if(!ischild && data)
if (!ischild && data)
btAlignedFree(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));
}
btAssert(0);
//&& (L"Not enough memory"));
return(0);
return (0);
}
SIMD_FORCE_INLINE btBlock* beginBlock()
SIMD_FORCE_INLINE btBlock* beginBlock()
{
btBlock* pb = (btBlock*)allocate(sizeof(btBlock));
pb->previous = current;
pb->address = data+usedsize;
current = pb;
return(pb);
btBlock* pb = (btBlock*)allocate(sizeof(btBlock));
pb->previous = current;
pb->address = data + usedsize;
current = pb;
return (pb);
}
SIMD_FORCE_INLINE void endBlock(btBlock* block)
SIMD_FORCE_INLINE void endBlock(btBlock* block)
{
btAssert(block==current);
btAssert(block == current);
//Raise(L"Unmatched blocks");
if(block==current)
if (block == current)
{
current = block->previous;
usedsize = (unsigned int)((block->address-data)-sizeof(btBlock));
current = block->previous;
usedsize = (unsigned int)((block->address - data) - sizeof(btBlock));
}
}
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;
btBlock* current;
bool ischild;
unsigned char* data;
unsigned int totalsize;
unsigned int usedsize;
btBlock* current;
bool ischild;
};
#endif //BT_STACK_ALLOC
#endif //BT_STACK_ALLOC

File diff suppressed because it is too large Load Diff

View File

@@ -12,14 +12,12 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BT_THREADS_H
#define BT_THREADS_H
#include "btScalar.h" // has definitions like SIMD_FORCE_INLINE
#include "btScalar.h" // has definitions like SIMD_FORCE_INLINE
#if defined (_MSC_VER) && _MSC_VER >= 1600
#if defined(_MSC_VER) && _MSC_VER >= 1600
// give us a compile error if any signatures of overriden methods is changed
#define BT_OVERRIDE override
#endif
@@ -36,7 +34,7 @@ const unsigned int BT_MAX_THREAD_COUNT = 64; // only if BT_THREADSAFE is 1
bool btIsMainThread();
bool btThreadsAreRunning();
unsigned int btGetCurrentThreadIndex();
void btResetThreadIndexCounter(); // notify that all worker threads have been destroyed
void btResetThreadIndexCounter(); // notify that all worker threads have been destroyed
///
/// btSpinMutex -- lightweight spin-mutex implemented with atomic ops, never puts
@@ -46,19 +44,18 @@ void btResetThreadIndexCounter(); // notify that all worker threads have been de
///
class btSpinMutex
{
int mLock;
int mLock;
public:
btSpinMutex()
{
mLock = 0;
}
void lock();
void unlock();
bool tryLock();
btSpinMutex()
{
mLock = 0;
}
void lock();
void unlock();
bool tryLock();
};
//
// NOTE: btMutex* is for internal Bullet use only
//
@@ -70,43 +67,42 @@ public:
// of bad because if you call any of these functions from external code
// (where BT_THREADSAFE is undefined) you will get unexpected race conditions.
//
SIMD_FORCE_INLINE void btMutexLock( btSpinMutex* mutex )
SIMD_FORCE_INLINE void btMutexLock(btSpinMutex* mutex)
{
#if BT_THREADSAFE
mutex->lock();
mutex->lock();
#else
(void)mutex;
#endif // #if BT_THREADSAFE
(void)mutex;
#endif // #if BT_THREADSAFE
}
SIMD_FORCE_INLINE void btMutexUnlock( btSpinMutex* mutex )
SIMD_FORCE_INLINE void btMutexUnlock(btSpinMutex* mutex)
{
#if BT_THREADSAFE
mutex->unlock();
mutex->unlock();
#else
(void)mutex;
#endif // #if BT_THREADSAFE
(void)mutex;
#endif // #if BT_THREADSAFE
}
SIMD_FORCE_INLINE bool btMutexTryLock( btSpinMutex* mutex )
SIMD_FORCE_INLINE bool btMutexTryLock(btSpinMutex* mutex)
{
#if BT_THREADSAFE
return mutex->tryLock();
return mutex->tryLock();
#else
(void)mutex;
return true;
#endif // #if BT_THREADSAFE
(void)mutex;
return true;
#endif // #if BT_THREADSAFE
}
//
// btIParallelForBody -- subclass this to express work that can be done in parallel
//
class btIParallelForBody
{
public:
virtual ~btIParallelForBody() {}
virtual void forLoop( int iBegin, int iEnd ) const = 0;
virtual ~btIParallelForBody() {}
virtual void forLoop(int iBegin, int iEnd) const = 0;
};
//
@@ -116,8 +112,8 @@ public:
class btIParallelSumBody
{
public:
virtual ~btIParallelSumBody() {}
virtual btScalar sumLoop( int iBegin, int iEnd ) const = 0;
virtual ~btIParallelSumBody() {}
virtual btScalar sumLoop(int iBegin, int iEnd) const = 0;
};
//
@@ -127,30 +123,30 @@ public:
class btITaskScheduler
{
public:
btITaskScheduler( const char* name );
virtual ~btITaskScheduler() {}
const char* getName() const { return m_name; }
btITaskScheduler(const char* name);
virtual ~btITaskScheduler() {}
const char* getName() const { return m_name; }
virtual int getMaxNumThreads() const = 0;
virtual int getNumThreads() const = 0;
virtual void setNumThreads( int numThreads ) = 0;
virtual void parallelFor( int iBegin, int iEnd, int grainSize, const btIParallelForBody& body ) = 0;
virtual btScalar parallelSum( int iBegin, int iEnd, int grainSize, const btIParallelSumBody& body ) = 0;
virtual void sleepWorkerThreadsHint() {} // hint the task scheduler that we may not be using these threads for a little while
virtual int getMaxNumThreads() const = 0;
virtual int getNumThreads() const = 0;
virtual void setNumThreads(int numThreads) = 0;
virtual void parallelFor(int iBegin, int iEnd, int grainSize, const btIParallelForBody& body) = 0;
virtual btScalar parallelSum(int iBegin, int iEnd, int grainSize, const btIParallelSumBody& body) = 0;
virtual void sleepWorkerThreadsHint() {} // hint the task scheduler that we may not be using these threads for a little while
// internal use only
virtual void activate();
virtual void deactivate();
// internal use only
virtual void activate();
virtual void deactivate();
protected:
const char* m_name;
unsigned int m_savedThreadCounter;
bool m_isActive;
const char* m_name;
unsigned int m_savedThreadCounter;
bool m_isActive;
};
// set the task scheduler to use for all calls to btParallelFor()
// NOTE: you must set this prior to using any of the multi-threaded "Mt" classes
void btSetTaskScheduler( btITaskScheduler* ts );
void btSetTaskScheduler(btITaskScheduler* ts);
// get the current task scheduler
btITaskScheduler* btGetTaskScheduler();
@@ -172,11 +168,10 @@ btITaskScheduler* btGetPPLTaskScheduler();
// btParallelFor -- call this to dispatch work like a for-loop
// (iterations may be done out of order, so no dependencies are allowed)
void btParallelFor( int iBegin, int iEnd, int grainSize, const btIParallelForBody& body );
void btParallelFor(int iBegin, int iEnd, int grainSize, const btIParallelForBody& body);
// btParallelSum -- call this to dispatch work like a for-loop, returns the sum of all iterations
// (iterations may be done out of order, so no dependencies are allowed)
btScalar btParallelSum( int iBegin, int iEnd, int grainSize, const btIParallelSumBody& body );
btScalar btParallelSum(int iBegin, int iEnd, int grainSize, const btIParallelSumBody& body);
#endif

View File

@@ -12,12 +12,9 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BT_TRANSFORM_H
#define BT_TRANSFORM_H
#include "btMatrix3x3.h"
#ifdef BT_USE_DOUBLE_PRECISION
@@ -26,46 +23,45 @@ subject to the following restrictions:
#define btTransformData btTransformFloatData
#endif
/**@brief The btTransform class supports rigid transforms with only translation and rotation and no scaling/shear.
*It can be used in combination with btVector3, btQuaternion and btMatrix3x3 linear algebra classes. */
ATTRIBUTE_ALIGNED16(class) btTransform {
///Storage for the rotation
ATTRIBUTE_ALIGNED16(class)
btTransform
{
///Storage for the rotation
btMatrix3x3 m_basis;
///Storage for the translation
btVector3 m_origin;
///Storage for the translation
btVector3 m_origin;
public:
/**@brief No initialization constructor */
/**@brief No initialization constructor */
btTransform() {}
/**@brief Constructor from btQuaternion (optional btVector3 )
/**@brief Constructor from btQuaternion (optional btVector3 )
* @param q Rotation from quaternion
* @param c Translation from Vector (default 0,0,0) */
explicit SIMD_FORCE_INLINE btTransform(const btQuaternion& q,
const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0)))
explicit SIMD_FORCE_INLINE btTransform(const btQuaternion& q,
const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0)))
: m_basis(q),
m_origin(c)
{}
/**@brief Constructor from btMatrix3x3 (optional btVector3)
* @param b Rotation from Matrix
* @param c Translation from Vector default (0,0,0)*/
explicit SIMD_FORCE_INLINE btTransform(const btMatrix3x3& b,
const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0)))
: m_basis(b),
m_origin(c)
{}
/**@brief Copy constructor */
SIMD_FORCE_INLINE btTransform (const btTransform& other)
: m_basis(other.m_basis),
m_origin(other.m_origin)
m_origin(c)
{
}
/**@brief Assignment Operator */
/**@brief Constructor from btMatrix3x3 (optional btVector3)
* @param b Rotation from Matrix
* @param c Translation from Vector default (0,0,0)*/
explicit SIMD_FORCE_INLINE btTransform(const btMatrix3x3& b,
const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0)))
: m_basis(b),
m_origin(c)
{
}
/**@brief Copy constructor */
SIMD_FORCE_INLINE btTransform(const btTransform& other)
: m_basis(other.m_basis),
m_origin(other.m_origin)
{
}
/**@brief Assignment Operator */
SIMD_FORCE_INLINE btTransform& operator=(const btTransform& other)
{
m_basis = other.m_basis;
@@ -73,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 */
SIMD_FORCE_INLINE void mult(const btTransform& t1, const btTransform& t2) {
m_basis = t1.m_basis * t2.m_basis;
m_origin = t1(t2.m_origin);
}
SIMD_FORCE_INLINE void mult(const btTransform& t1, const btTransform& t2)
{
m_basis = t1.m_basis * t2.m_basis;
m_origin = t1(t2.m_origin);
}
/* void multInverseLeft(const btTransform& t1, const btTransform& t2) {
/* void multInverseLeft(const btTransform& t1, const btTransform& t2) {
btVector3 v = t2.m_origin - t1.m_origin;
m_basis = btMultTransposeLeft(t1.m_basis, t2.m_basis);
m_origin = v * t1.m_basis;
}
*/
/**@brief Return the transform of the vector */
/**@brief Return the transform of the vector */
SIMD_FORCE_INLINE btVector3 operator()(const btVector3& 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 */
SIMD_FORCE_INLINE btVector3 operator*(const btVector3& x) const
{
return (*this)(x);
}
/**@brief Return the transform of the btQuaternion */
/**@brief Return the transform of the btQuaternion */
SIMD_FORCE_INLINE btQuaternion operator*(const btQuaternion& q) const
{
return getRotation() * q;
}
/**@brief Return the basis matrix for the rotation */
SIMD_FORCE_INLINE btMatrix3x3& getBasis() { return m_basis; }
/**@brief Return the basis matrix for the rotation */
SIMD_FORCE_INLINE const btMatrix3x3& getBasis() const { return m_basis; }
/**@brief Return the basis matrix for the rotation */
SIMD_FORCE_INLINE btMatrix3x3& getBasis() { return m_basis; }
/**@brief Return the basis matrix for the rotation */
SIMD_FORCE_INLINE const btMatrix3x3& getBasis() const { return m_basis; }
/**@brief Return the origin vector translation */
SIMD_FORCE_INLINE btVector3& getOrigin() { return m_origin; }
/**@brief Return the origin vector translation */
SIMD_FORCE_INLINE const btVector3& getOrigin() const { return m_origin; }
/**@brief Return the origin vector translation */
SIMD_FORCE_INLINE btVector3& getOrigin() { return m_origin; }
/**@brief Return the origin vector translation */
SIMD_FORCE_INLINE const btVector3& getOrigin() const { return m_origin; }
/**@brief Return a quaternion representing the rotation */
btQuaternion getRotation() const {
/**@brief Return a quaternion representing the rotation */
btQuaternion getRotation() const
{
btQuaternion q;
m_basis.getRotation(q);
return q;
}
/**@brief Set from an array
/**@brief Set from an array
* @param m A pointer to a 16 element array (12 rotation(row major padded on the right by 1), and 3 translation */
void setFromOpenGLMatrix(const btScalar *m)
void setFromOpenGLMatrix(const btScalar* 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 16 element array (12 rotation(row major padded on the right by 1), and 3 translation */
void getOpenGLMatrix(btScalar *m) const
void getOpenGLMatrix(btScalar * m) const
{
m_basis.getOpenGLSubMatrix(m);
m[12] = m_origin.x();
@@ -145,80 +141,76 @@ public:
m[15] = btScalar(1.0);
}
/**@brief Set the translational element
/**@brief Set the translational element
* @param origin The vector to set the translation to */
SIMD_FORCE_INLINE void setOrigin(const btVector3& origin)
{
SIMD_FORCE_INLINE void setOrigin(const btVector3& origin)
{
m_origin = origin;
}
SIMD_FORCE_INLINE btVector3 invXform(const btVector3& inVec) const;
/**@brief Set the rotational element by btMatrix3x3 */
/**@brief Set the rotational element by btMatrix3x3 */
SIMD_FORCE_INLINE void setBasis(const btMatrix3x3& basis)
{
{
m_basis = basis;
}
/**@brief Set the rotational element by btQuaternion */
/**@brief Set the rotational element by btQuaternion */
SIMD_FORCE_INLINE void setRotation(const btQuaternion& q)
{
m_basis.setRotation(q);
}
/**@brief Set this transformation to the identity */
/**@brief Set this transformation to the identity */
void setIdentity()
{
m_basis.setIdentity();
m_origin.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
}
/**@brief Multiply this Transform by another(this = this * another)
/**@brief Multiply this Transform by another(this = this * another)
* @param t The other transform */
btTransform& operator*=(const btTransform& t)
btTransform& operator*=(const btTransform& t)
{
m_origin += m_basis * t.m_origin;
m_basis *= t.m_basis;
return *this;
}
/**@brief Return the inverse of this transform */
/**@brief Return the inverse of this transform */
btTransform inverse() const
{
{
btMatrix3x3 inv = m_basis.transpose();
return btTransform(inv, inv * -m_origin);
}
/**@brief Return the inverse of this transform times the other transform
/**@brief Return the inverse of this transform times the other transform
* @param t The other transform
* return this.inverse() * the other */
btTransform inverseTimes(const btTransform& t) const;
btTransform inverseTimes(const btTransform& t) const;
/**@brief Return the product of this transform and the other */
/**@brief Return the product of this transform and the other */
btTransform operator*(const btTransform& t) const;
/**@brief Return an identity transform */
static const btTransform& getIdentity()
/**@brief Return an identity transform */
static const btTransform& getIdentity()
{
static const btTransform identityTransform(btMatrix3x3::getIdentity());
return identityTransform;
}
void serialize(struct btTransformData& dataOut) const;
void serialize(struct btTransformData & dataOut) const;
void serializeFloat(struct btTransformFloatData& dataOut) const;
void serializeFloat(struct btTransformFloatData & dataOut) const;
void deSerialize(const struct btTransformData& dataIn);
void deSerialize(const struct btTransformData& dataIn);
void deSerializeDouble(const struct btTransformDoubleData& dataIn);
void deSerializeFloat(const struct btTransformFloatData& dataIn);
void deSerializeDouble(const struct btTransformDoubleData& dataIn);
void deSerializeFloat(const struct btTransformFloatData& dataIn);
};
SIMD_FORCE_INLINE btVector3
btTransform::invXform(const btVector3& inVec) const
{
@@ -226,80 +218,69 @@ btTransform::invXform(const btVector3& inVec) const
return (m_basis.transpose() * v);
}
SIMD_FORCE_INLINE btTransform
btTransform::inverseTimes(const btTransform& t) const
SIMD_FORCE_INLINE btTransform
btTransform::inverseTimes(const btTransform& t) const
{
btVector3 v = t.getOrigin() - m_origin;
return btTransform(m_basis.transposeTimes(t.m_basis),
v * m_basis);
return btTransform(m_basis.transposeTimes(t.m_basis),
v * m_basis);
}
SIMD_FORCE_INLINE btTransform
btTransform::operator*(const btTransform& t) const
SIMD_FORCE_INLINE btTransform
btTransform::operator*(const btTransform& t) const
{
return btTransform(m_basis * t.m_basis,
(*this)(t.m_origin));
return btTransform(m_basis * t.m_basis,
(*this)(t.m_origin));
}
/**@brief Test if two transforms have all elements equal */
SIMD_FORCE_INLINE bool operator==(const btTransform& t1, const btTransform& t2)
{
return ( t1.getBasis() == t2.getBasis() &&
t1.getOrigin() == t2.getOrigin() );
return (t1.getBasis() == t2.getBasis() &&
t1.getOrigin() == t2.getOrigin());
}
///for serialization
struct btTransformFloatData
struct btTransformFloatData
{
btMatrix3x3FloatData m_basis;
btVector3FloatData m_origin;
btMatrix3x3FloatData m_basis;
btVector3FloatData m_origin;
};
struct btTransformDoubleData
struct btTransformDoubleData
{
btMatrix3x3DoubleData m_basis;
btVector3DoubleData m_origin;
btMatrix3x3DoubleData m_basis;
btVector3DoubleData m_origin;
};
SIMD_FORCE_INLINE void btTransform::serialize(btTransformData& dataOut) const
SIMD_FORCE_INLINE void btTransform::serialize(btTransformData& dataOut) const
{
m_basis.serialize(dataOut.m_basis);
m_origin.serialize(dataOut.m_origin);
}
SIMD_FORCE_INLINE void btTransform::serializeFloat(btTransformFloatData& dataOut) const
SIMD_FORCE_INLINE void btTransform::serializeFloat(btTransformFloatData& dataOut) const
{
m_basis.serializeFloat(dataOut.m_basis);
m_origin.serializeFloat(dataOut.m_origin);
}
SIMD_FORCE_INLINE void btTransform::deSerialize(const btTransformData& dataIn)
SIMD_FORCE_INLINE void btTransform::deSerialize(const btTransformData& dataIn)
{
m_basis.deSerialize(dataIn.m_basis);
m_origin.deSerialize(dataIn.m_origin);
}
SIMD_FORCE_INLINE void btTransform::deSerializeFloat(const btTransformFloatData& dataIn)
SIMD_FORCE_INLINE void btTransform::deSerializeFloat(const btTransformFloatData& dataIn)
{
m_basis.deSerializeFloat(dataIn.m_basis);
m_origin.deSerializeFloat(dataIn.m_origin);
}
SIMD_FORCE_INLINE void btTransform::deSerializeDouble(const btTransformDoubleData& dataIn)
SIMD_FORCE_INLINE void btTransform::deSerializeDouble(const btTransformDoubleData& dataIn)
{
m_basis.deSerializeDouble(dataIn.m_basis);
m_origin.deSerializeDouble(dataIn.m_origin);
}
#endif //BT_TRANSFORM_H
#endif //BT_TRANSFORM_H

View File

@@ -12,77 +12,66 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BT_TRANSFORM_UTIL_H
#define BT_TRANSFORM_UTIL_H
#include "btTransform.h"
#define ANGULAR_MOTION_THRESHOLD btScalar(0.5)*SIMD_HALF_PI
#define ANGULAR_MOTION_THRESHOLD btScalar(0.5) * SIMD_HALF_PI
SIMD_FORCE_INLINE btVector3 btAabbSupport(const btVector3& halfExtents,const btVector3& supportDir)
SIMD_FORCE_INLINE btVector3 btAabbSupport(const btVector3& halfExtents, const btVector3& supportDir)
{
return btVector3(supportDir.x() < btScalar(0.0) ? -halfExtents.x() : halfExtents.x(),
supportDir.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(),
supportDir.z() < btScalar(0.0) ? -halfExtents.z() : halfExtents.z());
supportDir.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(),
supportDir.z() < btScalar(0.0) ? -halfExtents.z() : halfExtents.z());
}
/// Utils related to temporal transforms
class btTransformUtil
{
public:
static void integrateTransform(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep,btTransform& predictedTransform)
static void integrateTransform(const btTransform& curTrans, const btVector3& linvel, const btVector3& angvel, btScalar timeStep, btTransform& predictedTransform)
{
predictedTransform.setOrigin(curTrans.getOrigin() + linvel * timeStep);
// #define QUATERNION_DERIVATIVE
#ifdef QUATERNION_DERIVATIVE
// #define QUATERNION_DERIVATIVE
#ifdef QUATERNION_DERIVATIVE
btQuaternion predictedOrn = curTrans.getRotation();
predictedOrn += (angvel * predictedOrn) * (timeStep * btScalar(0.5));
predictedOrn.safeNormalize();
#else
#else
//Exponential map
//google for "Practical Parameterization of Rotations Using the Exponential Map", F. Sebastian Grassia
btVector3 axis;
btScalar fAngle2 = angvel.length2();
btScalar fAngle = 0;
if (fAngle2>SIMD_EPSILON)
{
fAngle = btSqrt(fAngle2);
}
btScalar fAngle2 = angvel.length2();
btScalar fAngle = 0;
if (fAngle2 > SIMD_EPSILON)
{
fAngle = btSqrt(fAngle2);
}
//limit the angular motion
if (fAngle*timeStep > ANGULAR_MOTION_THRESHOLD)
if (fAngle * timeStep > ANGULAR_MOTION_THRESHOLD)
{
fAngle = ANGULAR_MOTION_THRESHOLD / timeStep;
}
if ( fAngle < btScalar(0.001) )
if (fAngle < btScalar(0.001))
{
// use Taylor's expansions of sync function
axis = angvel*( btScalar(0.5)*timeStep-(timeStep*timeStep*timeStep)*(btScalar(0.020833333333))*fAngle*fAngle );
axis = angvel * (btScalar(0.5) * timeStep - (timeStep * timeStep * timeStep) * (btScalar(0.020833333333)) * fAngle * fAngle);
}
else
{
// sync(fAngle) = sin(c*fAngle)/t
axis = angvel*( btSin(btScalar(0.5)*fAngle*timeStep)/fAngle );
axis = angvel * (btSin(btScalar(0.5) * fAngle * timeStep) / fAngle);
}
btQuaternion dorn (axis.x(),axis.y(),axis.z(),btCos( fAngle*timeStep*btScalar(0.5) ));
btQuaternion dorn(axis.x(), axis.y(), axis.z(), btCos(fAngle * timeStep * btScalar(0.5)));
btQuaternion orn0 = curTrans.getRotation();
btQuaternion predictedOrn = dorn * orn0;
predictedOrn.safeNormalize();
#endif
if (predictedOrn.length2()>SIMD_EPSILON)
#endif
if (predictedOrn.length2() > SIMD_EPSILON)
{
predictedTransform.setRotation(predictedOrn);
}
@@ -92,137 +81,133 @@ public:
}
}
static void calculateVelocityQuaternion(const btVector3& pos0,const btVector3& pos1,const btQuaternion& orn0,const btQuaternion& orn1,btScalar timeStep,btVector3& linVel,btVector3& angVel)
static void calculateVelocityQuaternion(const btVector3& pos0, const btVector3& pos1, const btQuaternion& orn0, const btQuaternion& orn1, btScalar timeStep, btVector3& linVel, btVector3& angVel)
{
linVel = (pos1 - pos0) / timeStep;
btVector3 axis;
btScalar angle;
btScalar 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 btQuaternion& orn0,const btQuaternion& orn1a,btVector3& axis,btScalar& angle)
static void calculateDiffAxisAngleQuaternion(const btQuaternion& orn0, const btQuaternion& orn1a, btVector3& axis, btScalar& angle)
{
btQuaternion orn1 = orn0.nearest(orn1a);
btQuaternion dorn = orn1 * orn0.inverse();
angle = dorn.getAngle();
axis = btVector3(dorn.x(),dorn.y(),dorn.z());
axis = btVector3(dorn.x(), dorn.y(), dorn.z());
axis[3] = btScalar(0.);
//check for axis length
btScalar len = axis.length2();
if (len < SIMD_EPSILON*SIMD_EPSILON)
axis = btVector3(btScalar(1.),btScalar(0.),btScalar(0.));
if (len < SIMD_EPSILON * SIMD_EPSILON)
axis = btVector3(btScalar(1.), btScalar(0.), btScalar(0.));
else
axis /= btSqrt(len);
}
static void calculateVelocity(const btTransform& transform0,const btTransform& transform1,btScalar timeStep,btVector3& linVel,btVector3& angVel)
static void calculateVelocity(const btTransform& transform0, const btTransform& transform1, btScalar timeStep, btVector3& linVel, btVector3& angVel)
{
linVel = (transform1.getOrigin() - transform0.getOrigin()) / timeStep;
btVector3 axis;
btScalar angle;
calculateDiffAxisAngle(transform0,transform1,axis,angle);
btScalar angle;
calculateDiffAxisAngle(transform0, transform1, axis, angle);
angVel = axis * angle / timeStep;
}
static void calculateDiffAxisAngle(const btTransform& transform0,const btTransform& transform1,btVector3& axis,btScalar& angle)
static void calculateDiffAxisAngle(const btTransform& transform0, const btTransform& transform1, btVector3& axis, btScalar& angle)
{
btMatrix3x3 dmat = transform1.getBasis() * transform0.getBasis().inverse();
btQuaternion dorn;
dmat.getRotation(dorn);
///floating point inaccuracy can lead to w component > 1..., which breaks
///floating point inaccuracy can lead to w component > 1..., which breaks
dorn.normalize();
angle = dorn.getAngle();
axis = btVector3(dorn.x(),dorn.y(),dorn.z());
axis = btVector3(dorn.x(), dorn.y(), dorn.z());
axis[3] = btScalar(0.);
//check for axis length
btScalar len = axis.length2();
if (len < SIMD_EPSILON*SIMD_EPSILON)
axis = btVector3(btScalar(1.),btScalar(0.),btScalar(0.));
if (len < SIMD_EPSILON * SIMD_EPSILON)
axis = btVector3(btScalar(1.), btScalar(0.), btScalar(0.));
else
axis /= btSqrt(len);
}
};
///The btConvexSeparatingDistanceUtil can help speed up convex collision detection
///The btConvexSeparatingDistanceUtil can help speed up convex collision detection
///by conservatively updating a cached separating distance/vector instead of re-calculating the closest distance
class btConvexSeparatingDistanceUtil
class btConvexSeparatingDistanceUtil
{
btQuaternion m_ornA;
btQuaternion m_ornB;
btVector3 m_posA;
btVector3 m_posB;
btVector3 m_separatingNormal;
btQuaternion m_ornA;
btQuaternion m_ornB;
btVector3 m_posA;
btVector3 m_posB;
btScalar m_boundingRadiusA;
btScalar m_boundingRadiusB;
btScalar m_separatingDistance;
btVector3 m_separatingNormal;
btScalar m_boundingRadiusA;
btScalar m_boundingRadiusB;
btScalar m_separatingDistance;
public:
btConvexSeparatingDistanceUtil(btScalar boundingRadiusA,btScalar boundingRadiusB)
:m_boundingRadiusA(boundingRadiusA),
m_boundingRadiusB(boundingRadiusB),
m_separatingDistance(0.f)
btConvexSeparatingDistanceUtil(btScalar boundingRadiusA, btScalar boundingRadiusB)
: m_boundingRadiusA(boundingRadiusA),
m_boundingRadiusB(boundingRadiusB),
m_separatingDistance(0.f)
{
}
btScalar getConservativeSeparatingDistance()
btScalar getConservativeSeparatingDistance()
{
return m_separatingDistance;
}
void updateSeparatingDistance(const btTransform& transA,const btTransform& transB)
void updateSeparatingDistance(const btTransform& transA, const btTransform& transB)
{
const btVector3& toPosA = transA.getOrigin();
const btVector3& toPosB = transB.getOrigin();
btQuaternion toOrnA = transA.getRotation();
btQuaternion toOrnB = transB.getRotation();
if (m_separatingDistance>0.f)
if (m_separatingDistance > 0.f)
{
btVector3 linVelA,angVelA,linVelB,angVelB;
btTransformUtil::calculateVelocityQuaternion(m_posA,toPosA,m_ornA,toOrnA,btScalar(1.),linVelA,angVelA);
btTransformUtil::calculateVelocityQuaternion(m_posB,toPosB,m_ornB,toOrnB,btScalar(1.),linVelB,angVelB);
btVector3 linVelA, angVelA, linVelB, angVelB;
btTransformUtil::calculateVelocityQuaternion(m_posA, toPosA, m_ornA, toOrnA, btScalar(1.), linVelA, angVelA);
btTransformUtil::calculateVelocityQuaternion(m_posB, toPosB, m_ornB, toOrnB, btScalar(1.), linVelB, angVelB);
btScalar maxAngularProjectedVelocity = angVelA.length() * m_boundingRadiusA + angVelB.length() * m_boundingRadiusB;
btVector3 relLinVel = (linVelB-linVelA);
btVector3 relLinVel = (linVelB - linVelA);
btScalar relLinVelocLength = relLinVel.dot(m_separatingNormal);
if (relLinVelocLength<0.f)
if (relLinVelocLength < 0.f)
{
relLinVelocLength = 0.f;
}
btScalar projectedMotion = maxAngularProjectedVelocity +relLinVelocLength;
btScalar projectedMotion = maxAngularProjectedVelocity + relLinVelocLength;
m_separatingDistance -= projectedMotion;
}
m_posA = toPosA;
m_posB = toPosB;
m_ornA = toOrnA;
m_ornB = toOrnB;
}
void initSeparatingDistance(const btVector3& separatingVector,btScalar separatingDistance,const btTransform& transA,const btTransform& transB)
void initSeparatingDistance(const btVector3& separatingVector, btScalar separatingDistance, const btTransform& transA, const btTransform& transB)
{
m_separatingDistance = separatingDistance;
if (m_separatingDistance>0.f)
if (m_separatingDistance > 0.f)
{
m_separatingNormal = separatingVector;
const btVector3& toPosA = transA.getOrigin();
const btVector3& toPosB = transB.getOrigin();
btQuaternion toOrnA = transA.getRotation();
@@ -233,9 +218,6 @@ public:
m_ornB = toOrnB;
}
}
};
#endif //BT_TRANSFORM_UTIL_H
#endif //BT_TRANSFORM_UTIL_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff