* Adjustment: Initial CMake reworking.

This commit is contained in:
Robert MacGregor 2022-05-13 23:42:41 -04:00
parent 516163fd5d
commit d7cdf54661
5394 changed files with 2615532 additions and 8711 deletions

View file

@ -0,0 +1,248 @@
#include "b3Clock.h"
template <class T>
const T& b3ClockMin(const T& a, const T& b)
{
return a < b ? a : b ;
}
#ifdef __CELLOS_LV2__
#include <sys/sys_time.h>
#include <sys/time_util.h>
#include <stdio.h>
#endif
#if defined (SUNOS) || defined (__SUNOS__)
#include <stdio.h>
#endif
#if defined(WIN32) || defined(_WIN32)
#define B3_USE_WINDOWS_TIMERS
#define WIN32_LEAN_AND_MEAN
#define NOWINRES
#define NOMCX
#define NOIME
#ifdef _XBOX
#include <Xtl.h>
#else //_XBOX
#include <windows.h>
#endif //_XBOX
#include <time.h>
#else //_WIN32
#include <sys/time.h>
#include <unistd.h>
#endif //_WIN32
struct b3ClockData
{
#ifdef B3_USE_WINDOWS_TIMERS
LARGE_INTEGER mClockFrequency;
DWORD mStartTick;
LONGLONG mPrevElapsedTime;
LARGE_INTEGER mStartTime;
#else
#ifdef __CELLOS_LV2__
uint64_t mStartTime;
#else
struct timeval mStartTime;
#endif
#endif //__CELLOS_LV2__
};
///The b3Clock is a portable basic clock that measures accurate time in seconds, use for profiling.
b3Clock::b3Clock()
{
m_data = new b3ClockData;
#ifdef B3_USE_WINDOWS_TIMERS
QueryPerformanceFrequency(&m_data->mClockFrequency);
#endif
reset();
}
b3Clock::~b3Clock()
{
delete m_data;
}
b3Clock::b3Clock(const b3Clock& other)
{
m_data = new b3ClockData;
*m_data = *other.m_data;
}
b3Clock& b3Clock::operator=(const b3Clock& other)
{
*m_data = *other.m_data;
return *this;
}
/// Resets the initial reference time.
void b3Clock::reset()
{
#ifdef B3_USE_WINDOWS_TIMERS
QueryPerformanceCounter(&m_data->mStartTime);
m_data->mStartTick = GetTickCount();
m_data->mPrevElapsedTime = 0;
#else
#ifdef __CELLOS_LV2__
typedef uint64_t ClockSize;
ClockSize newTime;
//__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
SYS_TIMEBASE_GET( newTime );
m_data->mStartTime = newTime;
#else
gettimeofday(&m_data->mStartTime, 0);
#endif
#endif
}
/// Returns the time in ms since the last call to reset or since
/// the b3Clock was created.
unsigned long int b3Clock::getTimeMilliseconds()
{
#ifdef B3_USE_WINDOWS_TIMERS
LARGE_INTEGER currentTime;
QueryPerformanceCounter(&currentTime);
LONGLONG elapsedTime = currentTime.QuadPart -
m_data->mStartTime.QuadPart;
// Compute the number of millisecond ticks elapsed.
unsigned long msecTicks = (unsigned long)(1000 * elapsedTime /
m_data->mClockFrequency.QuadPart);
// Check for unexpected leaps in the Win32 performance counter.
// (This is caused by unexpected data across the PCI to ISA
// bridge, aka south bridge. See Microsoft KB274323.)
unsigned long elapsedTicks = GetTickCount() - m_data->mStartTick;
signed long msecOff = (signed long)(msecTicks - elapsedTicks);
if (msecOff < -100 || msecOff > 100)
{
// Adjust the starting time forwards.
LONGLONG msecAdjustment = b3ClockMin(msecOff *
m_data->mClockFrequency.QuadPart / 1000, elapsedTime -
m_data->mPrevElapsedTime);
m_data->mStartTime.QuadPart += msecAdjustment;
elapsedTime -= msecAdjustment;
// Recompute the number of millisecond ticks elapsed.
msecTicks = (unsigned long)(1000 * elapsedTime /
m_data->mClockFrequency.QuadPart);
}
// Store the current elapsed time for adjustments next time.
m_data->mPrevElapsedTime = elapsedTime;
return msecTicks;
#else
#ifdef __CELLOS_LV2__
uint64_t freq=sys_time_get_timebase_frequency();
double dFreq=((double) freq) / 1000.0;
typedef uint64_t ClockSize;
ClockSize newTime;
SYS_TIMEBASE_GET( newTime );
//__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
return (unsigned long int)((double(newTime-m_data->mStartTime)) / dFreq);
#else
struct timeval currentTime;
gettimeofday(&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.
unsigned long long int b3Clock::getTimeMicroseconds()
{
#ifdef B3_USE_WINDOWS_TIMERS
LARGE_INTEGER currentTime;
QueryPerformanceCounter(&currentTime);
LONGLONG elapsedTime = currentTime.QuadPart -
m_data->mStartTime.QuadPart;
// Compute the number of millisecond ticks elapsed.
unsigned long long msecTicks = (unsigned long long)(1000 * elapsedTime /
m_data->mClockFrequency.QuadPart);
// Check for unexpected leaps in the Win32 performance counter.
// (This is caused by unexpected data across the PCI to ISA
// bridge, aka south bridge. See Microsoft KB274323.)
unsigned long long elapsedTicks = GetTickCount() - m_data->mStartTick;
signed long long msecOff = (signed long)(msecTicks - elapsedTicks);
if (msecOff < -100 || msecOff > 100)
{
// Adjust the starting time forwards.
LONGLONG msecAdjustment = b3ClockMin(msecOff *
m_data->mClockFrequency.QuadPart / 1000, elapsedTime -
m_data->mPrevElapsedTime);
m_data->mStartTime.QuadPart += msecAdjustment;
elapsedTime -= msecAdjustment;
}
// Store the current elapsed time for adjustments next time.
m_data->mPrevElapsedTime = elapsedTime;
// Convert to microseconds.
unsigned long long usecTicks = (unsigned long)(1000000 * elapsedTime /
m_data->mClockFrequency.QuadPart);
return usecTicks;
#else
#ifdef __CELLOS_LV2__
uint64_t freq=sys_time_get_timebase_frequency();
double dFreq=((double) freq)/ 1000000.0;
typedef uint64_t ClockSize;
ClockSize newTime;
//__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
SYS_TIMEBASE_GET( newTime );
return (unsigned long int)((double(newTime-m_data->mStartTime)) / dFreq);
#else
struct timeval currentTime;
gettimeofday(&currentTime, 0);
return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1000000 +
(currentTime.tv_usec - m_data->mStartTime.tv_usec);
#endif//__CELLOS_LV2__
#endif
}
double b3Clock::getTimeInSeconds()
{
return double(getTimeMicroseconds()/1.e6);
}
void b3Clock::usleep(int microSeconds)
{
#ifdef _WIN32
int millis = microSeconds/1000;
if (millis < 1)
{
millis = 1;
}
Sleep(millis);
#else
::usleep(microSeconds);
//struct timeval tv;
//tv.tv_sec = microSeconds/1000000L;
//tv.tv_usec = microSeconds%1000000L;
//return select(0, 0, 0, 0, &tv);
#endif
}

View file

@ -0,0 +1,40 @@
#ifndef B3_CLOCK_H
#define B3_CLOCK_H
///The b3Clock is a portable basic clock that measures accurate time in seconds, use for profiling.
class b3Clock
{
public:
b3Clock();
b3Clock(const b3Clock& other);
b3Clock& operator=(const b3Clock& other);
~b3Clock();
/// Resets the initial reference time.
void reset();
/// Returns the time in ms since the last call to reset or since
/// the b3Clock was created.
unsigned long int getTimeMilliseconds();
/// Returns the time in us since the last call to reset or since
/// the Clock was created.
unsigned long long int getTimeMicroseconds();
/// Returns the time in seconds since the last call to reset or since
/// the Clock was created.
double getTimeInSeconds();
///Sleep for 'microSeconds', to yield to other threads and not waste 100% CPU cycles.
///Note that some operating systems may sleep a longer time.
static void usleep(int microSeconds);
private:
struct b3ClockData* m_data;
};
#endif //B3_CLOCK_H

View file

@ -0,0 +1,430 @@
/*
Copyright (c) 2003-2013 Erwin Coumans http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/*
***************************************************************************************************
**
** profile.cpp
**
** Real-Time Hierarchical Profiling for Game Programming Gems 3
**
** by Greg Hjelstrom & Byon Garrabrant
**
***************************************************************************************************/
// Credits: The Clock class was inspired by the Timer classes in
// Ogre (www.ogre3d.org).
#include "Bullet3Common/b3MinMax.h"
#include "b3Quickprof.h"
#ifndef B3_NO_PROFILE
static b3Clock b3s_profileClock;
inline void b3Profile_Get_Ticks(unsigned long int * ticks)
{
*ticks = b3s_profileClock.getTimeMicroseconds();
}
inline float b3Profile_Get_Tick_Rate(void)
{
// return 1000000.f;
return 1000.f;
}
/***************************************************************************************************
**
** b3ProfileNode
**
***************************************************************************************************/
/***********************************************************************************************
* INPUT: *
* name - pointer to a static string which is the name of this profile node *
* parent - parent pointer *
* *
* WARNINGS: *
* The name is assumed to be a static pointer, only the pointer is stored and compared for *
* efficiency reasons. *
*=============================================================================================*/
b3ProfileNode::b3ProfileNode( const char * name, b3ProfileNode * parent ) :
Name( name ),
TotalCalls( 0 ),
TotalTime( 0 ),
StartTime( 0 ),
RecursionCounter( 0 ),
Parent( parent ),
Child( NULL ),
Sibling( NULL ),
m_userPtr(0)
{
Reset();
}
void b3ProfileNode::CleanupMemory()
{
delete ( Child);
Child = NULL;
delete ( Sibling);
Sibling = NULL;
}
b3ProfileNode::~b3ProfileNode( void )
{
delete ( Child);
delete ( Sibling);
}
/***********************************************************************************************
* INPUT: *
* name - static string pointer to the name of the node we are searching for *
* *
* WARNINGS: *
* All profile names are assumed to be static strings so this function uses pointer compares *
* to find the named node. *
*=============================================================================================*/
b3ProfileNode * b3ProfileNode::Get_Sub_Node( const char * name )
{
// Try to find this sub node
b3ProfileNode * child = Child;
while ( child ) {
if ( child->Name == name ) {
return child;
}
child = child->Sibling;
}
// We didn't find it, so add it
b3ProfileNode * node = new b3ProfileNode( name, this );
node->Sibling = Child;
Child = node;
return node;
}
void b3ProfileNode::Reset( void )
{
TotalCalls = 0;
TotalTime = 0.0f;
if ( Child ) {
Child->Reset();
}
if ( Sibling ) {
Sibling->Reset();
}
}
void b3ProfileNode::Call( void )
{
TotalCalls++;
if (RecursionCounter++ == 0) {
b3Profile_Get_Ticks(&StartTime);
}
}
bool b3ProfileNode::Return( void )
{
if ( --RecursionCounter == 0 && TotalCalls != 0 ) {
unsigned long int time;
b3Profile_Get_Ticks(&time);
time-=StartTime;
TotalTime += (float)time / b3Profile_Get_Tick_Rate();
}
return ( RecursionCounter == 0 );
}
/***************************************************************************************************
**
** b3ProfileIterator
**
***************************************************************************************************/
b3ProfileIterator::b3ProfileIterator( b3ProfileNode * start )
{
CurrentParent = start;
CurrentChild = CurrentParent->Get_Child();
}
void b3ProfileIterator::First(void)
{
CurrentChild = CurrentParent->Get_Child();
}
void b3ProfileIterator::Next(void)
{
CurrentChild = CurrentChild->Get_Sibling();
}
bool b3ProfileIterator::Is_Done(void)
{
return CurrentChild == NULL;
}
void b3ProfileIterator::Enter_Child( int index )
{
CurrentChild = CurrentParent->Get_Child();
while ( (CurrentChild != NULL) && (index != 0) ) {
index--;
CurrentChild = CurrentChild->Get_Sibling();
}
if ( CurrentChild != NULL ) {
CurrentParent = CurrentChild;
CurrentChild = CurrentParent->Get_Child();
}
}
void b3ProfileIterator::Enter_Parent( void )
{
if ( CurrentParent->Get_Parent() != NULL ) {
CurrentParent = CurrentParent->Get_Parent();
}
CurrentChild = CurrentParent->Get_Child();
}
/***************************************************************************************************
**
** b3ProfileManager
**
***************************************************************************************************/
b3ProfileNode b3ProfileManager::Root( "Root", NULL );
b3ProfileNode * b3ProfileManager::CurrentNode = &b3ProfileManager::Root;
int b3ProfileManager::FrameCounter = 0;
unsigned long int b3ProfileManager::ResetTime = 0;
/***********************************************************************************************
* b3ProfileManager::Start_Profile -- Begin a named profile *
* *
* Steps one level deeper into the tree, if a child already exists with the specified name *
* then it accumulates the profiling; otherwise a new child node is added to the profile tree. *
* *
* INPUT: *
* name - name of this profiling record *
* *
* WARNINGS: *
* The string used is assumed to be a static string; pointer compares are used throughout *
* the profiling code for efficiency. *
*=============================================================================================*/
void b3ProfileManager::Start_Profile( const char * name )
{
if (name != CurrentNode->Get_Name()) {
CurrentNode = CurrentNode->Get_Sub_Node( name );
}
CurrentNode->Call();
}
/***********************************************************************************************
* b3ProfileManager::Stop_Profile -- Stop timing and record the results. *
*=============================================================================================*/
void b3ProfileManager::Stop_Profile( void )
{
// Return will indicate whether we should back up to our parent (we may
// be profiling a recursive function)
if (CurrentNode->Return()) {
CurrentNode = CurrentNode->Get_Parent();
}
}
/***********************************************************************************************
* b3ProfileManager::Reset -- Reset the contents of the profiling system *
* *
* This resets everything except for the tree structure. All of the timing data is reset. *
*=============================================================================================*/
void b3ProfileManager::Reset( void )
{
b3s_profileClock.reset();
Root.Reset();
Root.Call();
FrameCounter = 0;
b3Profile_Get_Ticks(&ResetTime);
}
/***********************************************************************************************
* b3ProfileManager::Increment_Frame_Counter -- Increment the frame counter *
*=============================================================================================*/
void b3ProfileManager::Increment_Frame_Counter( void )
{
FrameCounter++;
}
/***********************************************************************************************
* b3ProfileManager::Get_Time_Since_Reset -- returns the elapsed time since last reset *
*=============================================================================================*/
float b3ProfileManager::Get_Time_Since_Reset( void )
{
unsigned long int time;
b3Profile_Get_Ticks(&time);
time -= ResetTime;
return (float)time / b3Profile_Get_Tick_Rate();
}
#include <stdio.h>
void b3ProfileManager::dumpRecursive(b3ProfileIterator* profileIterator, int spacing)
{
profileIterator->First();
if (profileIterator->Is_Done())
return;
float accumulated_time=0,parent_time = profileIterator->Is_Root() ? b3ProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time();
int i;
int frames_since_reset = b3ProfileManager::Get_Frame_Count_Since_Reset();
for (i=0;i<spacing;i++) b3Printf(".");
b3Printf("----------------------------------\n");
for (i=0;i<spacing;i++) b3Printf(".");
b3Printf("Profiling: %s (total running time: %.3f ms) ---\n", profileIterator->Get_Current_Parent_Name(), parent_time );
float totalTime = 0.f;
int numChildren = 0;
for (i = 0; !profileIterator->Is_Done(); i++,profileIterator->Next())
{
numChildren++;
float current_total_time = profileIterator->Get_Current_Total_Time();
accumulated_time += current_total_time;
float fraction = parent_time > B3_EPSILON ? (current_total_time / parent_time) * 100 : 0.f;
{
int i; for (i=0;i<spacing;i++) b3Printf(".");
}
b3Printf("%d -- %s (%.2f %%) :: %.3f ms / frame (%d calls)\n",i, profileIterator->Get_Current_Name(), fraction,(current_total_time / (double)frames_since_reset),profileIterator->Get_Current_Total_Calls());
totalTime += current_total_time;
//recurse into children
}
if (parent_time < accumulated_time)
{
b3Printf("what's wrong\n");
}
for (i=0;i<spacing;i++) b3Printf(".");
b3Printf("%s (%.3f %%) :: %.3f ms\n", "Unaccounted:",parent_time > B3_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time);
for (i=0;i<numChildren;i++)
{
profileIterator->Enter_Child(i);
dumpRecursive(profileIterator,spacing+3);
profileIterator->Enter_Parent();
}
}
void b3ProfileManager::dumpAll()
{
b3ProfileIterator* profileIterator = 0;
profileIterator = b3ProfileManager::Get_Iterator();
dumpRecursive(profileIterator,0);
b3ProfileManager::Release_Iterator(profileIterator);
}
void b3ProfileManager::dumpRecursive(FILE* f, b3ProfileIterator* profileIterator, int spacing)
{
profileIterator->First();
if (profileIterator->Is_Done())
return;
float accumulated_time=0,parent_time = profileIterator->Is_Root() ? b3ProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time();
int i;
int frames_since_reset = b3ProfileManager::Get_Frame_Count_Since_Reset();
for (i=0;i<spacing;i++) fprintf(f,".");
fprintf(f,"----------------------------------\n");
for (i=0;i<spacing;i++) fprintf(f,".");
fprintf(f,"Profiling: %s (total running time: %.3f ms) ---\n", profileIterator->Get_Current_Parent_Name(), parent_time );
float totalTime = 0.f;
int numChildren = 0;
for (i = 0; !profileIterator->Is_Done(); i++,profileIterator->Next())
{
numChildren++;
float current_total_time = profileIterator->Get_Current_Total_Time();
accumulated_time += current_total_time;
float fraction = parent_time > B3_EPSILON ? (current_total_time / parent_time) * 100 : 0.f;
{
int i; for (i=0;i<spacing;i++) fprintf(f,".");
}
fprintf(f,"%d -- %s (%.2f %%) :: %.3f ms / frame (%d calls)\n",i, profileIterator->Get_Current_Name(), fraction,(current_total_time / (double)frames_since_reset),profileIterator->Get_Current_Total_Calls());
totalTime += current_total_time;
//recurse into children
}
if (parent_time < accumulated_time)
{
fprintf(f,"what's wrong\n");
}
for (i=0;i<spacing;i++)
fprintf(f,".");
fprintf(f,"%s (%.3f %%) :: %.3f ms\n", "Unaccounted:",parent_time > B3_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time);
for (i=0;i<numChildren;i++)
{
profileIterator->Enter_Child(i);
dumpRecursive(f,profileIterator,spacing+3);
profileIterator->Enter_Parent();
}
}
void b3ProfileManager::dumpAll(FILE* f)
{
b3ProfileIterator* profileIterator = 0;
profileIterator = b3ProfileManager::Get_Iterator();
dumpRecursive(f, profileIterator,0);
b3ProfileManager::Release_Iterator(profileIterator);
}
#endif //B3_NO_PROFILE

View file

@ -0,0 +1,173 @@
/*
Copyright (c) 2003-2013 Erwin Coumans http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/***************************************************************************************************
**
** Real-Time Hierarchical Profiling for Game Programming Gems 3
**
** by Greg Hjelstrom & Byon Garrabrant
**
***************************************************************************************************/
// Credits: The Clock class was inspired by the Timer classes in
// Ogre (www.ogre3d.org).
#ifndef B3_QUICK_PROF_H
#define B3_QUICK_PROF_H
//To disable built-in profiling, please comment out next line
//#define B3_NO_PROFILE 1
#ifndef B3_NO_PROFILE
#include <stdio.h>//@todo remove this, backwards compatibility
#include "Bullet3Common/b3Scalar.h"
#include "Bullet3Common/b3AlignedAllocator.h"
#include <new>
#include "b3Clock.h"
///A node in the Profile Hierarchy Tree
class b3ProfileNode {
public:
b3ProfileNode( const char * name, b3ProfileNode * parent );
~b3ProfileNode( void );
b3ProfileNode * Get_Sub_Node( const char * name );
b3ProfileNode * Get_Parent( void ) { return Parent; }
b3ProfileNode * Get_Sibling( void ) { return Sibling; }
b3ProfileNode * Get_Child( void ) { return Child; }
void CleanupMemory();
void Reset( void );
void Call( void );
bool Return( void );
const char * Get_Name( void ) { return Name; }
int Get_Total_Calls( void ) { return TotalCalls; }
float Get_Total_Time( void ) { return TotalTime; }
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;
b3ProfileNode * Parent;
b3ProfileNode * Child;
b3ProfileNode * Sibling;
void* m_userPtr;
};
///An iterator to navigate through the tree
class b3ProfileIterator
{
public:
// Access all the children of the current parent
void First(void);
void Next(void);
bool Is_Done(void);
bool Is_Root(void) { return (CurrentParent->Get_Parent() == 0); }
void Enter_Child( int index ); // Make the given child the new parent
void Enter_Largest_Child( void ); // Make the largest child the new parent
void Enter_Parent( void ); // Make the current parent's parent the new parent
// Access the current child
const char * Get_Current_Name( void ) { return CurrentChild->Get_Name(); }
int Get_Current_Total_Calls( void ) { return CurrentChild->Get_Total_Calls(); }
float Get_Current_Total_Time( void ) { return CurrentChild->Get_Total_Time(); }
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(); }
protected:
b3ProfileNode * CurrentParent;
b3ProfileNode * CurrentChild;
b3ProfileIterator( b3ProfileNode * start );
friend class b3ProfileManager;
};
///The Manager for the Profile system
class b3ProfileManager {
public:
static void Start_Profile( const char * name );
static void Stop_Profile( void );
static void CleanupMemory(void)
{
Root.CleanupMemory();
}
static void Reset( void );
static void Increment_Frame_Counter( void );
static int Get_Frame_Count_Since_Reset( void ) { return FrameCounter; }
static float Get_Time_Since_Reset( void );
static b3ProfileIterator * Get_Iterator( void )
{
return new b3ProfileIterator( &Root );
}
static void Release_Iterator( b3ProfileIterator * iterator ) { delete ( iterator); }
static void dumpRecursive(b3ProfileIterator* profileIterator, int spacing);
static void dumpAll();
static void dumpRecursive(FILE* f, b3ProfileIterator* profileIterator, int spacing);
static void dumpAll(FILE* f);
private:
static b3ProfileNode Root;
static b3ProfileNode * CurrentNode;
static int FrameCounter;
static unsigned long int ResetTime;
};
#else
#endif //#ifndef B3_NO_PROFILE
#endif //B3_QUICK_PROF_H

View file

@ -0,0 +1,99 @@
#include "b3ResourcePath.h"
#include "Bullet3Common/b3Logging.h"
#ifdef __APPLE__
#include <mach-o/dyld.h> /* _NSGetExecutablePath */
#else
#ifdef _WIN32
#include <windows.h>
#else
//not Mac, not Windows, let's cross the fingers it is Linux :-)
#include <unistd.h>
#endif
#endif
#include "Bullet3Common/b3FileUtils.h"
#define B3_MAX_EXE_PATH_LEN 4096
int b3ResourcePath::getExePath(char* path, int maxPathLenInBytes)
{
int numBytes = 0;
#if __APPLE__
uint32_t bufsize = uint32_t(maxPathLenInBytes);
if (_NSGetExecutablePath(path, &bufsize)!=0)
{
b3Warning("Cannot find executable path\n");
return false;
} else
{
numBytes = strlen(path);
}
#else
#ifdef _WIN32
//https://msdn.microsoft.com/en-us/library/windows/desktop/ms683197(v=vs.85).aspx
HMODULE hModule = GetModuleHandle(NULL);
numBytes = GetModuleFileNameA(hModule, path, maxPathLenInBytes);
#else
///http://stackoverflow.com/questions/933850/how-to-find-the-location-of-the-executable-in-c
numBytes = (int)readlink("/proc/self/exe", path, maxPathLenInBytes-1);
if (numBytes > 0)
{
path[numBytes] = 0;
} else
{
b3Warning("Cannot find executable path\n");
}
#endif //_WIN32
#endif //__APPLE__
return numBytes;
}
int b3ResourcePath::findResourcePath(const char* resourceName, char* resourcePath, int resourcePathMaxNumBytes)
{
//first find in a resource/<exeName> location, then in various folders within 'data' using b3FileUtils
char exePath[B3_MAX_EXE_PATH_LEN];
int l = b3ResourcePath::getExePath(exePath, B3_MAX_EXE_PATH_LEN);
if (l)
{
char pathToExe[B3_MAX_EXE_PATH_LEN];
int exeNamePos = b3FileUtils::extractPath(exePath,pathToExe,B3_MAX_EXE_PATH_LEN);
if (exeNamePos)
{
sprintf(resourcePath,"%s../data/%s",pathToExe,resourceName);
//printf("try resource at %s\n", resourcePath);
if (b3FileUtils::findFile(resourcePath, resourcePath, resourcePathMaxNumBytes))
{
return strlen(resourcePath);
}
sprintf(resourcePath,"%s../resources/%s/%s",pathToExe,&exePath[exeNamePos],resourceName);
//printf("try resource at %s\n", resourcePath);
if (b3FileUtils::findFile(resourcePath, resourcePath, resourcePathMaxNumBytes))
{
return strlen(resourcePath);
}
sprintf(resourcePath,"%s.runfiles/google3/third_party/bullet/data/%s",exePath,resourceName);
//printf("try resource at %s\n", resourcePath);
if (b3FileUtils::findFile(resourcePath, resourcePath, resourcePathMaxNumBytes))
{
return strlen(resourcePath);
}
}
}
bool res = b3FileUtils::findFile(resourceName, resourcePath, resourcePathMaxNumBytes);
if (res)
{
return strlen(resourcePath);
}
return 0;
}

View file

@ -0,0 +1,13 @@
#ifndef _B3_RESOURCE_PATH_H
#define _B3_RESOURCE_PATH_H
#include <string>
class b3ResourcePath
{
public:
static int getExePath(char* path, int maxPathLenInBytes);
static int findResourcePath(const char* sourceName, char* resourcePath, int maxResourcePathLenInBytes);
};
#endif