added hierarchical profiling (needs more cleanup)
avoid dynamic allocations in btRaycastVehicle
This commit is contained in:
@@ -29,6 +29,9 @@
|
||||
#include "GLDebugDrawer.h"
|
||||
|
||||
static GLDebugDrawer gDebugDrawer;
|
||||
#include "LinearMath/btQuickProf.h"
|
||||
|
||||
CProfileIterator * gProfileIterator=0;
|
||||
|
||||
|
||||
namespace
|
||||
@@ -80,6 +83,9 @@ DemoApplication* CreatDemo(btDemoEntry* entry)
|
||||
{
|
||||
demo->getDynamicsWorld()->setDebugDrawer(&gDebugDrawer);
|
||||
}
|
||||
|
||||
CProfileManager::Reset();
|
||||
|
||||
return demo;
|
||||
|
||||
}
|
||||
@@ -107,6 +113,9 @@ void Timer(int)
|
||||
|
||||
void SimulationLoop()
|
||||
{
|
||||
|
||||
|
||||
|
||||
if (gDrawAabb)
|
||||
{
|
||||
demo->setDebugMode(demo->getDebugMode() |btIDebugDraw::DBG_DrawAabb);
|
||||
@@ -146,10 +155,15 @@ void SimulationLoop()
|
||||
|
||||
|
||||
if (!demo->isIdle())
|
||||
{
|
||||
demo->clientMoveAndDisplay();
|
||||
else
|
||||
demo->displayCallback();
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
demo->displayCallback();
|
||||
}
|
||||
if (testSelection != testIndex)
|
||||
{
|
||||
testIndex = testSelection;
|
||||
@@ -166,6 +180,19 @@ void SimulationLoop()
|
||||
void Keyboard(unsigned char key, int x, int y)
|
||||
{
|
||||
|
||||
if (key >= 0x31 && key < 0x37)
|
||||
{
|
||||
int child = key-0x31;
|
||||
gProfileIterator->Enter_Child(child);
|
||||
}
|
||||
if (key==0x30)
|
||||
{
|
||||
gProfileIterator->Enter_Parent();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
switch (key)
|
||||
{
|
||||
case 27:
|
||||
@@ -212,6 +239,9 @@ void MouseMotion(int x, int y)
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
|
||||
gProfileIterator = CProfileManager::Get_Iterator();
|
||||
|
||||
|
||||
int bulletVersion = btGetVersion();
|
||||
printf("Bullet version %d\n",bulletVersion);
|
||||
|
||||
|
||||
@@ -105,9 +105,6 @@ void BasicDemo::displayCallback(void) {
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
if (m_dynamicsWorld)
|
||||
m_dynamicsWorld->updateAabbs();
|
||||
|
||||
renderme();
|
||||
|
||||
glFlush();
|
||||
|
||||
@@ -300,8 +300,6 @@ void CcdPhysicsDemo::displayCallback(void) {
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
m_dynamicsWorld->updateAabbs();
|
||||
|
||||
|
||||
renderme();
|
||||
|
||||
@@ -431,11 +429,13 @@ int maxNumOutstandingTasks = 4;
|
||||
createSolverLocalStoreMemory,
|
||||
maxNumOutstandingTasks));
|
||||
|
||||
m_solver = new btParallelSequentialImpulseSolver(threadSupportSolver,maxNumOutstandingTasks);
|
||||
m_solver = new btParallelSequentialImpulseSolver(m_threadSupportSolver,maxNumOutstandingTasks);
|
||||
#else
|
||||
m_solver = new btSequentialImpulseConstraintSolver;
|
||||
btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver();
|
||||
|
||||
m_solver = solver;
|
||||
//default solverMode is SOLVER_RANDMIZE_ORDER. Warmstarting seems not to improve convergence, see
|
||||
//m_solver->setSolverMode(btSequentialImpulseConstraintSolver::SOLVER_USE_WARMSTARTING | btSequentialImpulseConstraintSolver::SOLVER_RANDMIZE_ORDER);
|
||||
//solver->setSolverMode(0);//btSequentialImpulseConstraintSolver::SOLVER_USE_WARMSTARTING | btSequentialImpulseConstraintSolver::SOLVER_RANDMIZE_ORDER);
|
||||
|
||||
#endif //USE_PARALLEL_SOLVER
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ void ConvexDecompositionDemo::initPhysics(const char* filename)
|
||||
///you can hook it up to your custom task scheduler by deriving from btThreadSupportInterface
|
||||
#endif
|
||||
|
||||
m_dispatcher = new SpuGatheringCollisionDispatcher(threadSupport,maxNumOutstandingTasks,collisionConfiguration);
|
||||
m_dispatcher = new SpuGatheringCollisionDispatcher(threadSupport,maxNumOutstandingTasks,m_collisionConfiguration);
|
||||
#else
|
||||
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
|
||||
#endif//USE_PARALLEL_DISPATCHER
|
||||
|
||||
@@ -29,6 +29,7 @@ subject to the following restrictions:
|
||||
#include "LinearMath/btQuickprof.h"
|
||||
#include "LinearMath/btDefaultMotionState.h"
|
||||
|
||||
|
||||
#include "BMF_Api.h"
|
||||
|
||||
extern bool gDisableDeactivation;
|
||||
@@ -77,6 +78,7 @@ m_shootBoxShape(0),
|
||||
|
||||
DemoApplication::~DemoApplication()
|
||||
{
|
||||
|
||||
if (m_shootBoxShape)
|
||||
delete m_shootBoxShape;
|
||||
|
||||
@@ -756,6 +758,88 @@ void DemoApplication::resetPerspectiveProjection()
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
extern CProfileIterator * gProfileIterator;
|
||||
|
||||
void DemoApplication::displayProfileString(int xOffset,int yStart,char* message)
|
||||
{
|
||||
glRasterPos3f(xOffset,yStart,0);
|
||||
BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),message);
|
||||
}
|
||||
|
||||
|
||||
void DemoApplication::showProfileInfo(float& xOffset,float& yStart, float yIncr)
|
||||
{
|
||||
|
||||
static double time_since_reset = 0.f;
|
||||
if (!m_idle)
|
||||
{
|
||||
time_since_reset = CProfileManager::Get_Time_Since_Reset();
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
//recompute profiling data, and store profile strings
|
||||
|
||||
char blockTime[128];
|
||||
|
||||
double totalTime = 0;
|
||||
|
||||
int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset();
|
||||
|
||||
gProfileIterator->First();
|
||||
|
||||
double parent_time = gProfileIterator->Is_Root() ? time_since_reset : gProfileIterator->Get_Current_Parent_Total_Time();
|
||||
|
||||
{
|
||||
sprintf(blockTime,"--- Profiling: %s (total running time: %.3f m) ---", gProfileIterator->Get_Current_Parent_Name(), parent_time );
|
||||
displayProfileString(xOffset,yStart,blockTime);
|
||||
yStart += yIncr;
|
||||
sprintf(blockTime,"press number (1,2...) to display child timings, or 0 to go up to parent" );
|
||||
displayProfileString(xOffset,yStart,blockTime);
|
||||
yStart += yIncr;
|
||||
|
||||
}
|
||||
|
||||
|
||||
double accumulated_time = 0.f;
|
||||
|
||||
for (int i = 0; !gProfileIterator->Is_Done(); gProfileIterator->Next())
|
||||
{
|
||||
double current_total_time = gProfileIterator->Get_Current_Total_Time();
|
||||
accumulated_time += current_total_time;
|
||||
double fraction = parent_time > SIMD_EPSILON ? (current_total_time / parent_time) * 100 : 0.f;
|
||||
|
||||
sprintf(blockTime,"%d -- %s (%.2f %%) :: %.3f ms / frame (%d calls)",
|
||||
++i, gProfileIterator->Get_Current_Name(), fraction,
|
||||
(current_total_time / (double)frames_since_reset),gProfileIterator->Get_Current_Total_Calls());
|
||||
displayProfileString(xOffset,yStart,blockTime);
|
||||
yStart += yIncr;
|
||||
totalTime += current_total_time;
|
||||
}
|
||||
|
||||
sprintf(blockTime,"%s (%.3f %%) :: %.3f ms", "Unaccounted",
|
||||
// (min(0, time_since_reset - totalTime) / time_since_reset) * 100);
|
||||
parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time);
|
||||
|
||||
displayProfileString(xOffset,yStart,blockTime);
|
||||
yStart += yIncr;
|
||||
|
||||
|
||||
|
||||
sprintf(blockTime,"-------------------------------------------------");
|
||||
displayProfileString(xOffset,yStart,blockTime);
|
||||
yStart += yIncr;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void DemoApplication::renderme()
|
||||
{
|
||||
updateCamera();
|
||||
@@ -823,6 +907,8 @@ void DemoApplication::renderme()
|
||||
{
|
||||
setOrthographicProjection();
|
||||
|
||||
showProfileInfo(xOffset,yStart,yIncr);
|
||||
|
||||
#ifdef USE_QUICKPROF
|
||||
|
||||
|
||||
|
||||
@@ -39,14 +39,19 @@ subject to the following restrictions:
|
||||
#include "LinearMath/btMatrix3x3.h"
|
||||
#include "LinearMath/btTransform.h"
|
||||
#include "LinearMath/btQuickprof.h"
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
|
||||
class btCollisionShape;
|
||||
class btDynamicsWorld;
|
||||
class btRigidBody;
|
||||
class btTypedConstraint;
|
||||
|
||||
|
||||
|
||||
|
||||
class DemoApplication
|
||||
{
|
||||
void displayProfileString(int xOffset,int yStart,char* message);
|
||||
|
||||
protected:
|
||||
|
||||
@@ -83,6 +88,9 @@ class DemoApplication
|
||||
bool m_idle;
|
||||
int m_lastKey;
|
||||
|
||||
void showProfileInfo(float& xOffset,float& yStart, float yIncr);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
DemoApplication();
|
||||
|
||||
@@ -372,9 +372,6 @@ void RagdollDemo::displayCallback()
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
if (m_dynamicsWorld)
|
||||
m_dynamicsWorld->updateAabbs();
|
||||
|
||||
renderme();
|
||||
|
||||
glFlush();
|
||||
|
||||
@@ -449,21 +449,9 @@ void VehicleDemo::clientMoveAndDisplay()
|
||||
|
||||
void VehicleDemo::displayCallback(void)
|
||||
{
|
||||
|
||||
clientMoveAndDisplay();
|
||||
return;
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
|
||||
|
||||
//m_dynamicsWorld->updateAabbs();
|
||||
|
||||
//draw contactpoints
|
||||
//m_physicsEnvironmentPtr->CallbackTriggers();
|
||||
|
||||
|
||||
//renderme();
|
||||
renderme();
|
||||
|
||||
|
||||
glFlush();
|
||||
|
||||
@@ -28,6 +28,7 @@ Written by: Marten Svanfeldt
|
||||
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
|
||||
#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
|
||||
#include "LinearMath/profile.h"
|
||||
|
||||
#include "SpuSolverTask/SpuParallellSolverTask.h"
|
||||
|
||||
@@ -108,6 +109,8 @@ void btParallelSequentialImpulseSolver::prepareSolve(int numBodies, int numManif
|
||||
|
||||
btScalar btParallelSequentialImpulseSolver::solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints, const btContactSolverInfo& info,class btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,btDispatcher* dispatcher)
|
||||
{
|
||||
PROFILE("parallel_solveGroup");
|
||||
|
||||
if (!numManifolds && !numConstraints)
|
||||
return 0;
|
||||
int i;
|
||||
@@ -259,6 +262,8 @@ btAlignedObjectArray<SpuSolverConstraint> solverConstraintPool_persist;
|
||||
|
||||
void btParallelSequentialImpulseSolver::allSolved (const btContactSolverInfo& info,class btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc)
|
||||
{
|
||||
PROFILE("parallel_allSolved");
|
||||
|
||||
if (!m_numberOfContacts && !m_sortedConstraints.size())
|
||||
{
|
||||
m_sortedManifolds.clear();
|
||||
@@ -348,6 +353,8 @@ void btParallelSequentialImpulseSolver::allSolved (const btContactSolverInfo& in
|
||||
|
||||
// Setup all the moving rigid bodies
|
||||
{
|
||||
PROFILE("setup moving rigidbodies");
|
||||
|
||||
int bodiesPerTask = PARALLEL_SOLVER_BODIES_PER_TASK;
|
||||
int bodiesToSchedule = numBodies;
|
||||
int startBody = 0;
|
||||
@@ -409,6 +416,9 @@ void btParallelSequentialImpulseSolver::allSolved (const btContactSolverInfo& in
|
||||
m_taskScheduler.flushTasks();
|
||||
}
|
||||
|
||||
{
|
||||
PROFILE("parallel_solve_iterations");
|
||||
|
||||
btSpinlock::SpinVariable* spinVar = (btSpinlock::SpinVariable*)btAlignedAlloc(sizeof(btSpinlock::SpinVariable), 128);
|
||||
for (int iter = 0; iter < info.m_numIterations; ++iter)
|
||||
{
|
||||
@@ -436,6 +446,7 @@ void btParallelSequentialImpulseSolver::allSolved (const btContactSolverInfo& in
|
||||
m_taskScheduler.flushTasks();
|
||||
}
|
||||
btAlignedFree((void*)spinVar);
|
||||
}
|
||||
|
||||
// Write back velocity
|
||||
{
|
||||
|
||||
@@ -809,6 +809,8 @@ static int getConstraintSize (btTypedConstraintType type)
|
||||
//-- MAIN METHOD
|
||||
void processSolverTask(void* userPtr, void* lsMemory)
|
||||
{
|
||||
// PROFILE("processSolverTask");
|
||||
|
||||
SolverTask_LocalStoreMemory* localMemory = (SolverTask_LocalStoreMemory*)lsMemory;
|
||||
|
||||
SpuSolverTaskDesc* taskDescPtr = (SpuSolverTaskDesc*)userPtr;
|
||||
|
||||
@@ -32,6 +32,7 @@ subject to the following restrictions:
|
||||
#include "LinearMath/btQuickprof.h"
|
||||
#include "LinearMath/btStackAlloc.h"
|
||||
|
||||
|
||||
//When the user doesn't provide dispatcher or broadphase, create basic versions (and delete them in destructor)
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h"
|
||||
@@ -116,30 +117,38 @@ void btCollisionWorld::addCollisionObject(btCollisionObject* collisionObject,sho
|
||||
|
||||
void btCollisionWorld::performDiscreteCollisionDetection()
|
||||
{
|
||||
PROFILE("performDiscreteCollisionDetection");
|
||||
|
||||
btDispatcherInfo& dispatchInfo = getDispatchInfo();
|
||||
|
||||
BEGIN_PROFILE("perform Broadphase Collision Detection");
|
||||
|
||||
|
||||
//update aabb (of all moved objects)
|
||||
|
||||
{
|
||||
PROFILE("setAabb");
|
||||
btVector3 aabbMin,aabbMax;
|
||||
for (int i=0;i<m_collisionObjects.size();i++)
|
||||
{
|
||||
m_collisionObjects[i]->getCollisionShape()->getAabb(m_collisionObjects[i]->getWorldTransform(),aabbMin,aabbMax);
|
||||
m_broadphasePairCache->setAabb(m_collisionObjects[i]->getBroadphaseHandle(),aabbMin,aabbMax,m_dispatcher1);
|
||||
}
|
||||
|
||||
}
|
||||
{
|
||||
PROFILE("calculateOverlappingPairs");
|
||||
m_broadphasePairCache->calculateOverlappingPairs(m_dispatcher1);
|
||||
}
|
||||
|
||||
END_PROFILE("perform Broadphase Collision Detection");
|
||||
|
||||
BEGIN_PROFILE("performDiscreteCollisionDetection");
|
||||
|
||||
btDispatcher* dispatcher = getDispatcher();
|
||||
{
|
||||
PROFILE("dispatchAllCollisionPairs");
|
||||
if (dispatcher)
|
||||
dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache->getOverlappingPairCache(),dispatchInfo,m_dispatcher1);
|
||||
|
||||
}
|
||||
END_PROFILE("performDiscreteCollisionDetection");
|
||||
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ subject to the following restrictions:
|
||||
#include "btSolverBody.h"
|
||||
#include "btSolverConstraint.h"
|
||||
|
||||
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
|
||||
#ifdef USE_PROFILE
|
||||
@@ -415,6 +416,7 @@ void btSequentialImpulseConstraintSolver::addFrictionConstraint(const btVector3&
|
||||
|
||||
btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc)
|
||||
{
|
||||
PROFILE("solveGroupCacheFriendlySetup");
|
||||
(void)stackAlloc;
|
||||
(void)debugDrawer;
|
||||
|
||||
@@ -718,6 +720,7 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
|
||||
|
||||
btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc)
|
||||
{
|
||||
PROFILE("solveGroupCacheFriendlyIterations");
|
||||
BEGIN_PROFILE("solveConstraintsIterations");
|
||||
int numConstraintPool = m_tmpSolverConstraintPool.size();
|
||||
int numFrictionPool = m_tmpSolverFrictionConstraintPool.size();
|
||||
@@ -750,6 +753,7 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyIterations(
|
||||
|
||||
for (j=0;j<numConstraints;j++)
|
||||
{
|
||||
PROFILE("solveConstraint");
|
||||
btTypedConstraint* constraint = constraints[j];
|
||||
///todo: use solver bodies, so we don't need to copy from/to btRigidBody
|
||||
|
||||
@@ -776,9 +780,11 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyIterations(
|
||||
}
|
||||
|
||||
{
|
||||
PROFILE("resolveSingleCollisionCombinedCacheFriendly");
|
||||
int numPoolConstraints = m_tmpSolverConstraintPool.size();
|
||||
for (j=0;j<numPoolConstraints;j++)
|
||||
{
|
||||
|
||||
const btSolverConstraint& solveManifold = m_tmpSolverConstraintPool[m_orderTmpConstraintPool[j]];
|
||||
resolveSingleCollisionCombinedCacheFriendly(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],
|
||||
m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold,infoGlobal);
|
||||
@@ -786,6 +792,7 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyIterations(
|
||||
}
|
||||
|
||||
{
|
||||
PROFILE("resolveSingleFrictionCacheFriendly");
|
||||
int numFrictionPoolConstraints = m_tmpSolverFrictionConstraintPool.size();
|
||||
|
||||
for (j=0;j<numFrictionPoolConstraints;j++)
|
||||
@@ -850,7 +857,7 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendly(btCollisio
|
||||
/// btSequentialImpulseConstraintSolver Sequentially applies impulses
|
||||
btScalar btSequentialImpulseConstraintSolver::solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc,btDispatcher* dispatcher)
|
||||
{
|
||||
|
||||
PROFILE("solveGroup");
|
||||
if (getSolverMode() & SOLVER_CACHE_FRIENDLY)
|
||||
{
|
||||
//you need to provide at least some bodies
|
||||
|
||||
@@ -48,6 +48,7 @@ void btContinuousDynamicsWorld::internalSingleStepSimulation( btScalar timeStep)
|
||||
|
||||
startProfiling(timeStep);
|
||||
|
||||
|
||||
///update aabbs information
|
||||
updateAabbs();
|
||||
//static int frame=0;
|
||||
|
||||
@@ -22,6 +22,7 @@ subject to the following restrictions:
|
||||
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
|
||||
#include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h"
|
||||
#include "LinearMath/btTransformUtil.h"
|
||||
#include "LinearMath/btQuickProf.h"
|
||||
|
||||
//rigidbody & constraints
|
||||
#include "BulletDynamics/Dynamics/btRigidBody.h"
|
||||
@@ -122,14 +123,14 @@ void btDiscreteDynamicsWorld::saveKinematicState(btScalar timeStep)
|
||||
}
|
||||
}
|
||||
|
||||
void btDiscreteDynamicsWorld::synchronizeMotionStates()
|
||||
void btDiscreteDynamicsWorld::debugDrawWorld()
|
||||
{
|
||||
//debug vehicle wheels
|
||||
|
||||
|
||||
if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawWireframe)
|
||||
{
|
||||
int i;
|
||||
|
||||
//todo: iterate over awake simulation islands!
|
||||
for ( int i=0;i<m_collisionObjects.size();i++)
|
||||
for ( i=0;i<m_collisionObjects.size();i++)
|
||||
{
|
||||
btCollisionObject* colObj = m_collisionObjects[i];
|
||||
if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawWireframe)
|
||||
@@ -155,6 +156,47 @@ void btDiscreteDynamicsWorld::synchronizeMotionStates()
|
||||
|
||||
debugDrawObject(colObj->getWorldTransform(),colObj->getCollisionShape(),color);
|
||||
}
|
||||
}
|
||||
|
||||
for ( i=0;i<this->m_vehicles.size();i++)
|
||||
{
|
||||
for (int v=0;v<m_vehicles[i]->getNumWheels();v++)
|
||||
{
|
||||
btVector3 wheelColor(0,255,255);
|
||||
if (m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_isInContact)
|
||||
{
|
||||
wheelColor.setValue(0,0,255);
|
||||
} else
|
||||
{
|
||||
wheelColor.setValue(255,0,255);
|
||||
}
|
||||
|
||||
btVector3 wheelPosWS = m_vehicles[i]->getWheelInfo(v).m_worldTransform.getOrigin();
|
||||
|
||||
btVector3 axle = btVector3(
|
||||
m_vehicles[i]->getWheelInfo(v).m_worldTransform.getBasis()[0][m_vehicles[i]->getRightAxis()],
|
||||
m_vehicles[i]->getWheelInfo(v).m_worldTransform.getBasis()[1][m_vehicles[i]->getRightAxis()],
|
||||
m_vehicles[i]->getWheelInfo(v).m_worldTransform.getBasis()[2][m_vehicles[i]->getRightAxis()]);
|
||||
|
||||
|
||||
//m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_wheelAxleWS
|
||||
//debug wheels (cylinders)
|
||||
m_debugDrawer->drawLine(wheelPosWS,wheelPosWS+axle,wheelColor);
|
||||
m_debugDrawer->drawLine(wheelPosWS,m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_contactPointWS,wheelColor);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void btDiscreteDynamicsWorld::synchronizeMotionStates()
|
||||
{
|
||||
{
|
||||
//todo: iterate over awake simulation islands!
|
||||
for ( int i=0;i<m_collisionObjects.size();i++)
|
||||
{
|
||||
btCollisionObject* colObj = m_collisionObjects[i];
|
||||
|
||||
btRigidBody* body = btRigidBody::upcast(colObj);
|
||||
if (body && body->getMotionState() && !body->isStaticOrKinematicObject())
|
||||
{
|
||||
@@ -178,31 +220,8 @@ void btDiscreteDynamicsWorld::synchronizeMotionStates()
|
||||
{
|
||||
for (int v=0;v<m_vehicles[i]->getNumWheels();v++)
|
||||
{
|
||||
btVector3 wheelColor(0,255,255);
|
||||
if (m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_isInContact)
|
||||
{
|
||||
wheelColor.setValue(0,0,255);
|
||||
} else
|
||||
{
|
||||
wheelColor.setValue(255,0,255);
|
||||
}
|
||||
|
||||
//synchronize the wheels with the (interpolated) chassis worldtransform
|
||||
m_vehicles[i]->updateWheelTransform(v,true);
|
||||
|
||||
btVector3 wheelPosWS = m_vehicles[i]->getWheelInfo(v).m_worldTransform.getOrigin();
|
||||
|
||||
btVector3 axle = btVector3(
|
||||
m_vehicles[i]->getWheelInfo(v).m_worldTransform.getBasis()[0][m_vehicles[i]->getRightAxis()],
|
||||
m_vehicles[i]->getWheelInfo(v).m_worldTransform.getBasis()[1][m_vehicles[i]->getRightAxis()],
|
||||
m_vehicles[i]->getWheelInfo(v).m_worldTransform.getBasis()[2][m_vehicles[i]->getRightAxis()]);
|
||||
|
||||
|
||||
//m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_wheelAxleWS
|
||||
//debug wheels (cylinders)
|
||||
m_debugDrawer->drawLine(wheelPosWS,wheelPosWS+axle,wheelColor);
|
||||
m_debugDrawer->drawLine(wheelPosWS,m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_contactPointWS,wheelColor);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -212,6 +231,10 @@ void btDiscreteDynamicsWorld::synchronizeMotionStates()
|
||||
|
||||
int btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep)
|
||||
{
|
||||
startProfiling(timeStep);
|
||||
|
||||
PROFILE("stepSimulation");
|
||||
|
||||
int numSimulationSubSteps = 0;
|
||||
|
||||
if (maxSubSteps)
|
||||
@@ -262,13 +285,16 @@ int btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps,
|
||||
|
||||
synchronizeMotionStates();
|
||||
|
||||
CProfileManager::Increment_Frame_Counter();
|
||||
|
||||
return numSimulationSubSteps;
|
||||
}
|
||||
|
||||
void btDiscreteDynamicsWorld::internalSingleStepSimulation(btScalar timeStep)
|
||||
{
|
||||
|
||||
startProfiling(timeStep);
|
||||
PROFILE("internalSingleStepSimulation");
|
||||
|
||||
|
||||
///update aabbs information
|
||||
updateAabbs();
|
||||
@@ -306,8 +332,6 @@ void btDiscreteDynamicsWorld::internalSingleStepSimulation(btScalar timeStep)
|
||||
|
||||
updateActivationState( timeStep );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void btDiscreteDynamicsWorld::setGravity(const btVector3& gravity)
|
||||
@@ -363,6 +387,7 @@ void btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body, short group, short
|
||||
|
||||
void btDiscreteDynamicsWorld::updateVehicles(btScalar timeStep)
|
||||
{
|
||||
PROFILE("updateVehicles");
|
||||
BEGIN_PROFILE("updateVehicles");
|
||||
|
||||
for ( int i=0;i<m_vehicles.size();i++)
|
||||
@@ -375,6 +400,7 @@ void btDiscreteDynamicsWorld::updateVehicles(btScalar timeStep)
|
||||
|
||||
void btDiscreteDynamicsWorld::updateActivationState(btScalar timeStep)
|
||||
{
|
||||
PROFILE("updateActivationState");
|
||||
BEGIN_PROFILE("updateActivationState");
|
||||
|
||||
for ( int i=0;i<m_collisionObjects.size();i++)
|
||||
@@ -462,6 +488,7 @@ class btSortConstraintOnIslandPredicate
|
||||
|
||||
void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
|
||||
{
|
||||
PROFILE("solveConstraints");
|
||||
|
||||
struct InplaceSolverIslandCallback : public btSimulationIslandManager::IslandCallback
|
||||
{
|
||||
@@ -569,6 +596,7 @@ void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
|
||||
|
||||
void btDiscreteDynamicsWorld::calculateSimulationIslands()
|
||||
{
|
||||
PROFILE("calculateSimulationIslands");
|
||||
BEGIN_PROFILE("calculateSimulationIslands");
|
||||
|
||||
getSimulationIslandManager()->updateActivationState(getCollisionWorld(),getCollisionWorld()->getDispatcher());
|
||||
@@ -606,7 +634,8 @@ void btDiscreteDynamicsWorld::calculateSimulationIslands()
|
||||
|
||||
void btDiscreteDynamicsWorld::updateAabbs()
|
||||
{
|
||||
BEGIN_PROFILE("updateAabbs");
|
||||
PROFILE("updateAabbs");
|
||||
|
||||
|
||||
btVector3 colorvec(1,0,0);
|
||||
btTransform predictedTrans;
|
||||
@@ -658,6 +687,7 @@ void btDiscreteDynamicsWorld::updateAabbs()
|
||||
|
||||
void btDiscreteDynamicsWorld::integrateTransforms(btScalar timeStep)
|
||||
{
|
||||
PROFILE("integrateTransforms");
|
||||
BEGIN_PROFILE("integrateTransforms");
|
||||
btTransform predictedTrans;
|
||||
for ( int i=0;i<m_collisionObjects.size();i++)
|
||||
@@ -680,6 +710,7 @@ void btDiscreteDynamicsWorld::integrateTransforms(btScalar timeStep)
|
||||
|
||||
void btDiscreteDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
|
||||
{
|
||||
PROFILE("predictUnconstraintMotion");
|
||||
BEGIN_PROFILE("predictUnconstraintMotion");
|
||||
for ( int i=0;i<m_collisionObjects.size();i++)
|
||||
{
|
||||
@@ -705,6 +736,10 @@ void btDiscreteDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
|
||||
void btDiscreteDynamicsWorld::startProfiling(btScalar timeStep)
|
||||
{
|
||||
(void)timeStep;
|
||||
|
||||
CProfileManager::Reset();
|
||||
|
||||
|
||||
#ifdef USE_QUICKPROF
|
||||
|
||||
|
||||
|
||||
@@ -138,6 +138,8 @@ public:
|
||||
|
||||
void debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color);
|
||||
|
||||
void debugDrawWorld();
|
||||
|
||||
virtual void setConstraintSolver(btConstraintSolver* solver);
|
||||
|
||||
virtual btConstraintSolver* getConstraintSolver();
|
||||
|
||||
@@ -526,15 +526,10 @@ void btRaycastVehicle::updateFriction(btScalar timeStep)
|
||||
if (!numWheel)
|
||||
return;
|
||||
|
||||
|
||||
void* mem = btAlignedAlloc(numWheel*sizeof(btVector3),16);
|
||||
btVector3* forwardWS = new (mem)btVector3[numWheel];
|
||||
mem = btAlignedAlloc(numWheel*sizeof(btVector3),16);
|
||||
btVector3* axle = new (mem)btVector3[numWheel];
|
||||
mem = btAlignedAlloc(numWheel*sizeof(btScalar),16);
|
||||
btScalar* forwardImpulse = new (mem)btScalar[numWheel];
|
||||
mem = btAlignedAlloc(numWheel*sizeof(btScalar),16);
|
||||
btScalar* sideImpulse = new(mem) btScalar[numWheel];
|
||||
m_forwardWS.resize(numWheel);
|
||||
m_axle.resize(numWheel);
|
||||
m_forwardImpulse.resize(numWheel);
|
||||
m_sideImpulse.resize(numWheel);
|
||||
|
||||
int numWheelsOnGround = 0;
|
||||
|
||||
@@ -546,8 +541,8 @@ void btRaycastVehicle::updateFriction(btScalar timeStep)
|
||||
class btRigidBody* groundObject = (class btRigidBody*) wheelInfo.m_raycastInfo.m_groundObject;
|
||||
if (groundObject)
|
||||
numWheelsOnGround++;
|
||||
sideImpulse[i] = btScalar(0.);
|
||||
forwardImpulse[i] = btScalar(0.);
|
||||
m_sideImpulse[i] = btScalar(0.);
|
||||
m_forwardImpulse[i] = btScalar(0.);
|
||||
|
||||
}
|
||||
|
||||
@@ -566,25 +561,25 @@ void btRaycastVehicle::updateFriction(btScalar timeStep)
|
||||
const btTransform& wheelTrans = getWheelTransformWS( i );
|
||||
|
||||
btMatrix3x3 wheelBasis0 = wheelTrans.getBasis();
|
||||
axle[i] = btVector3(
|
||||
m_axle[i] = btVector3(
|
||||
wheelBasis0[0][m_indexRightAxis],
|
||||
wheelBasis0[1][m_indexRightAxis],
|
||||
wheelBasis0[2][m_indexRightAxis]);
|
||||
|
||||
const btVector3& surfNormalWS = wheelInfo.m_raycastInfo.m_contactNormalWS;
|
||||
btScalar proj = axle[i].dot(surfNormalWS);
|
||||
axle[i] -= surfNormalWS * proj;
|
||||
axle[i] = axle[i].normalize();
|
||||
btScalar proj = m_axle[i].dot(surfNormalWS);
|
||||
m_axle[i] -= surfNormalWS * proj;
|
||||
m_axle[i] = m_axle[i].normalize();
|
||||
|
||||
forwardWS[i] = surfNormalWS.cross(axle[i]);
|
||||
forwardWS[i].normalize();
|
||||
m_forwardWS[i] = surfNormalWS.cross(m_axle[i]);
|
||||
m_forwardWS[i].normalize();
|
||||
|
||||
|
||||
resolveSingleBilateral(*m_chassisBody, wheelInfo.m_raycastInfo.m_contactPointWS,
|
||||
*groundObject, wheelInfo.m_raycastInfo.m_contactPointWS,
|
||||
btScalar(0.), axle[i],sideImpulse[i],timeStep);
|
||||
btScalar(0.), m_axle[i],m_sideImpulse[i],timeStep);
|
||||
|
||||
sideImpulse[i] *= sideFrictionStiffness2;
|
||||
m_sideImpulse[i] *= sideFrictionStiffness2;
|
||||
|
||||
}
|
||||
|
||||
@@ -613,7 +608,7 @@ void btRaycastVehicle::updateFriction(btScalar timeStep)
|
||||
{
|
||||
btScalar defaultRollingFrictionImpulse = 0.f;
|
||||
btScalar maxImpulse = wheelInfo.m_brake ? wheelInfo.m_brake : defaultRollingFrictionImpulse;
|
||||
btWheelContactPoint contactPt(m_chassisBody,groundObject,wheelInfo.m_raycastInfo.m_contactPointWS,forwardWS[wheel],maxImpulse);
|
||||
btWheelContactPoint contactPt(m_chassisBody,groundObject,wheelInfo.m_raycastInfo.m_contactPointWS,m_forwardWS[wheel],maxImpulse);
|
||||
rollingFriction = calcRollingFriction(contactPt);
|
||||
}
|
||||
}
|
||||
@@ -623,7 +618,7 @@ void btRaycastVehicle::updateFriction(btScalar timeStep)
|
||||
|
||||
|
||||
|
||||
forwardImpulse[wheel] = btScalar(0.);
|
||||
m_forwardImpulse[wheel] = btScalar(0.);
|
||||
m_wheelInfo[wheel].m_skidInfo= btScalar(1.);
|
||||
|
||||
if (groundObject)
|
||||
@@ -636,10 +631,10 @@ void btRaycastVehicle::updateFriction(btScalar timeStep)
|
||||
btScalar maximpSquared = maximp * maximpSide;
|
||||
|
||||
|
||||
forwardImpulse[wheel] = rollingFriction;//wheelInfo.m_engineForce* timeStep;
|
||||
m_forwardImpulse[wheel] = rollingFriction;//wheelInfo.m_engineForce* timeStep;
|
||||
|
||||
btScalar x = (forwardImpulse[wheel] ) * fwdFactor;
|
||||
btScalar y = (sideImpulse[wheel] ) * sideFactor;
|
||||
btScalar x = (m_forwardImpulse[wheel] ) * fwdFactor;
|
||||
btScalar y = (m_sideImpulse[wheel] ) * sideFactor;
|
||||
|
||||
btScalar impulseSquared = (x*x + y*y);
|
||||
|
||||
@@ -663,12 +658,12 @@ void btRaycastVehicle::updateFriction(btScalar timeStep)
|
||||
{
|
||||
for (int wheel = 0;wheel < getNumWheels(); wheel++)
|
||||
{
|
||||
if (sideImpulse[wheel] != btScalar(0.))
|
||||
if (m_sideImpulse[wheel] != btScalar(0.))
|
||||
{
|
||||
if (m_wheelInfo[wheel].m_skidInfo< btScalar(1.))
|
||||
{
|
||||
forwardImpulse[wheel] *= m_wheelInfo[wheel].m_skidInfo;
|
||||
sideImpulse[wheel] *= m_wheelInfo[wheel].m_skidInfo;
|
||||
m_forwardImpulse[wheel] *= m_wheelInfo[wheel].m_skidInfo;
|
||||
m_sideImpulse[wheel] *= m_wheelInfo[wheel].m_skidInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -683,11 +678,11 @@ void btRaycastVehicle::updateFriction(btScalar timeStep)
|
||||
btVector3 rel_pos = wheelInfo.m_raycastInfo.m_contactPointWS -
|
||||
m_chassisBody->getCenterOfMassPosition();
|
||||
|
||||
if (forwardImpulse[wheel] != btScalar(0.))
|
||||
if (m_forwardImpulse[wheel] != btScalar(0.))
|
||||
{
|
||||
m_chassisBody->applyImpulse(forwardWS[wheel]*(forwardImpulse[wheel]),rel_pos);
|
||||
m_chassisBody->applyImpulse(m_forwardWS[wheel]*(m_forwardImpulse[wheel]),rel_pos);
|
||||
}
|
||||
if (sideImpulse[wheel] != btScalar(0.))
|
||||
if (m_sideImpulse[wheel] != btScalar(0.))
|
||||
{
|
||||
class btRigidBody* groundObject = (class btRigidBody*) m_wheelInfo[wheel].m_raycastInfo.m_groundObject;
|
||||
|
||||
@@ -695,7 +690,7 @@ void btRaycastVehicle::updateFriction(btScalar timeStep)
|
||||
groundObject->getCenterOfMassPosition();
|
||||
|
||||
|
||||
btVector3 sideImp = axle[wheel] * sideImpulse[wheel];
|
||||
btVector3 sideImp = m_axle[wheel] * m_sideImpulse[wheel];
|
||||
|
||||
rel_pos[2] *= wheelInfo.m_rollInfluence;
|
||||
m_chassisBody->applyImpulse(sideImp,rel_pos);
|
||||
@@ -706,10 +701,7 @@ void btRaycastVehicle::updateFriction(btScalar timeStep)
|
||||
}
|
||||
}
|
||||
|
||||
btAlignedFree(forwardWS);
|
||||
btAlignedFree(axle);
|
||||
btAlignedFree(forwardImpulse);
|
||||
btAlignedFree(sideImpulse);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -23,6 +23,12 @@ class btVehicleTuning;
|
||||
///rayCast vehicle, very special constraint that turn a rigidbody into a vehicle.
|
||||
class btRaycastVehicle : public btTypedConstraint
|
||||
{
|
||||
|
||||
btAlignedObjectArray<btVector3> m_forwardWS;
|
||||
btAlignedObjectArray<btVector3> m_axle;
|
||||
btAlignedObjectArray<btScalar> m_forwardImpulse;
|
||||
btAlignedObjectArray<btScalar> m_sideImpulse;
|
||||
|
||||
public:
|
||||
class btVehicleTuning
|
||||
{
|
||||
|
||||
@@ -36,3 +36,266 @@ bool btProfiler::mFirstFileOutput = true;
|
||||
btProfiler::BlockTimingMethod btProfiler::mFileOutputMethod;
|
||||
unsigned long int btProfiler::mCycleNumber = 0;
|
||||
#endif //USE_QUICKPROF
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
**
|
||||
** profile.cpp
|
||||
**
|
||||
** Real-Time Hierarchical Profiling for Game Programming Gems 3
|
||||
**
|
||||
** by Greg Hjelstrom & Byon Garrabrant
|
||||
**
|
||||
***************************************************************************************************/
|
||||
|
||||
static btClock gProfileClock;
|
||||
|
||||
inline void Profile_Get_Ticks(_int64 * ticks)
|
||||
{
|
||||
*ticks = gProfileClock.getTimeMicroseconds();
|
||||
}
|
||||
|
||||
inline float Profile_Get_Tick_Rate(void)
|
||||
{
|
||||
// return 1000000.f;
|
||||
return 1000.f;
|
||||
|
||||
}
|
||||
|
||||
/***************************************************************************************************
|
||||
**
|
||||
** CProfileNode
|
||||
**
|
||||
***************************************************************************************************/
|
||||
|
||||
/***********************************************************************************************
|
||||
* INPUT: *
|
||||
* name - pointer to a static string which is the name of this profile node *
|
||||
* parent - parent pointer *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* The name is assumed to be a static pointer, only the pointer is stored and compared for *
|
||||
* efficiency reasons. *
|
||||
*=============================================================================================*/
|
||||
CProfileNode::CProfileNode( const char * name, CProfileNode * parent ) :
|
||||
Name( name ),
|
||||
TotalCalls( 0 ),
|
||||
TotalTime( 0 ),
|
||||
StartTime( 0 ),
|
||||
RecursionCounter( 0 ),
|
||||
Parent( parent ),
|
||||
Child( NULL ),
|
||||
Sibling( NULL )
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
|
||||
CProfileNode::~CProfileNode( void )
|
||||
{
|
||||
delete Child;
|
||||
delete Sibling;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* INPUT: *
|
||||
* name - static string pointer to the name of the node we are searching for *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* All profile names are assumed to be static strings so this function uses pointer compares *
|
||||
* to find the named node. *
|
||||
*=============================================================================================*/
|
||||
CProfileNode * CProfileNode::Get_Sub_Node( const char * name )
|
||||
{
|
||||
// Try to find this sub node
|
||||
CProfileNode * child = Child;
|
||||
while ( child ) {
|
||||
if ( child->Name == name ) {
|
||||
return child;
|
||||
}
|
||||
child = child->Sibling;
|
||||
}
|
||||
|
||||
// We didn't find it, so add it
|
||||
CProfileNode * node = new CProfileNode( name, this );
|
||||
node->Sibling = Child;
|
||||
Child = node;
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
void CProfileNode::Reset( void )
|
||||
{
|
||||
TotalCalls = 0;
|
||||
TotalTime = 0.0f;
|
||||
gProfileClock.reset();
|
||||
|
||||
if ( Child ) {
|
||||
Child->Reset();
|
||||
}
|
||||
if ( Sibling ) {
|
||||
Sibling->Reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CProfileNode::Call( void )
|
||||
{
|
||||
TotalCalls++;
|
||||
if (RecursionCounter++ == 0) {
|
||||
Profile_Get_Ticks(&StartTime);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CProfileNode::Return( void )
|
||||
{
|
||||
if ( --RecursionCounter == 0 && TotalCalls != 0 ) {
|
||||
__int64 time;
|
||||
Profile_Get_Ticks(&time);
|
||||
time-=StartTime;
|
||||
TotalTime += (float)time / Profile_Get_Tick_Rate();
|
||||
}
|
||||
return ( RecursionCounter == 0 );
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
**
|
||||
** CProfileIterator
|
||||
**
|
||||
***************************************************************************************************/
|
||||
CProfileIterator::CProfileIterator( CProfileNode * start )
|
||||
{
|
||||
CurrentParent = start;
|
||||
CurrentChild = CurrentParent->Get_Child();
|
||||
}
|
||||
|
||||
|
||||
void CProfileIterator::First(void)
|
||||
{
|
||||
CurrentChild = CurrentParent->Get_Child();
|
||||
}
|
||||
|
||||
|
||||
void CProfileIterator::Next(void)
|
||||
{
|
||||
CurrentChild = CurrentChild->Get_Sibling();
|
||||
}
|
||||
|
||||
|
||||
bool CProfileIterator::Is_Done(void)
|
||||
{
|
||||
return CurrentChild == NULL;
|
||||
}
|
||||
|
||||
|
||||
void CProfileIterator::Enter_Child( int index )
|
||||
{
|
||||
CurrentChild = CurrentParent->Get_Child();
|
||||
while ( (CurrentChild != NULL) && (index != 0) ) {
|
||||
index--;
|
||||
CurrentChild = CurrentChild->Get_Sibling();
|
||||
}
|
||||
|
||||
if ( CurrentChild != NULL ) {
|
||||
CurrentParent = CurrentChild;
|
||||
CurrentChild = CurrentParent->Get_Child();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CProfileIterator::Enter_Parent( void )
|
||||
{
|
||||
if ( CurrentParent->Get_Parent() != NULL ) {
|
||||
CurrentParent = CurrentParent->Get_Parent();
|
||||
}
|
||||
CurrentChild = CurrentParent->Get_Child();
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
**
|
||||
** CProfileManager
|
||||
**
|
||||
***************************************************************************************************/
|
||||
|
||||
CProfileNode CProfileManager::Root( "Root", NULL );
|
||||
CProfileNode * CProfileManager::CurrentNode = &CProfileManager::Root;
|
||||
int CProfileManager::FrameCounter = 0;
|
||||
__int64 CProfileManager::ResetTime = 0;
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* CProfileManager::Start_Profile -- Begin a named profile *
|
||||
* *
|
||||
* Steps one level deeper into the tree, if a child already exists with the specified name *
|
||||
* then it accumulates the profiling; otherwise a new child node is added to the profile tree. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* name - name of this profiling record *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* The string used is assumed to be a static string; pointer compares are used throughout *
|
||||
* the profiling code for efficiency. *
|
||||
*=============================================================================================*/
|
||||
void CProfileManager::Start_Profile( const char * name )
|
||||
{
|
||||
if (name != CurrentNode->Get_Name()) {
|
||||
CurrentNode = CurrentNode->Get_Sub_Node( name );
|
||||
}
|
||||
|
||||
CurrentNode->Call();
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* CProfileManager::Stop_Profile -- Stop timing and record the results. *
|
||||
*=============================================================================================*/
|
||||
void CProfileManager::Stop_Profile( void )
|
||||
{
|
||||
// Return will indicate whether we should back up to our parent (we may
|
||||
// be profiling a recursive function)
|
||||
if (CurrentNode->Return()) {
|
||||
CurrentNode = CurrentNode->Get_Parent();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* CProfileManager::Reset -- Reset the contents of the profiling system *
|
||||
* *
|
||||
* This resets everything except for the tree structure. All of the timing data is reset. *
|
||||
*=============================================================================================*/
|
||||
void CProfileManager::Reset( void )
|
||||
{
|
||||
Root.Reset();
|
||||
Root.Call();
|
||||
FrameCounter = 0;
|
||||
Profile_Get_Ticks(&ResetTime);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* CProfileManager::Increment_Frame_Counter -- Increment the frame counter *
|
||||
*=============================================================================================*/
|
||||
void CProfileManager::Increment_Frame_Counter( void )
|
||||
{
|
||||
FrameCounter++;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* CProfileManager::Get_Time_Since_Reset -- returns the elapsed time since last reset *
|
||||
*=============================================================================================*/
|
||||
float CProfileManager::Get_Time_Since_Reset( void )
|
||||
{
|
||||
__int64 time;
|
||||
Profile_Get_Ticks(&time);
|
||||
time -= ResetTime;
|
||||
return (float)time / Profile_Get_Tick_Rate();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -707,6 +707,139 @@ std::string btProfiler::createStatsString(BlockTimingMethod method)
|
||||
|
||||
#endif //USE_QUICKPROF
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
**
|
||||
** profile.h
|
||||
**
|
||||
** Real-Time Hierarchical Profiling for Game Programming Gems 3
|
||||
**
|
||||
** by Greg Hjelstrom & Byon Garrabrant
|
||||
**
|
||||
***************************************************************************************************/
|
||||
|
||||
/*
|
||||
** A node in the Profile Hierarchy Tree
|
||||
*/
|
||||
class CProfileNode {
|
||||
|
||||
public:
|
||||
CProfileNode( const char * name, CProfileNode * parent );
|
||||
~CProfileNode( void );
|
||||
|
||||
CProfileNode * Get_Sub_Node( const char * name );
|
||||
|
||||
CProfileNode * Get_Parent( void ) { return Parent; }
|
||||
CProfileNode * Get_Sibling( void ) { return Sibling; }
|
||||
CProfileNode * Get_Child( void ) { return Child; }
|
||||
|
||||
void Reset( void );
|
||||
void Call( void );
|
||||
bool Return( void );
|
||||
|
||||
const char * Get_Name( void ) { return Name; }
|
||||
int Get_Total_Calls( void ) { return TotalCalls; }
|
||||
float Get_Total_Time( void ) { return TotalTime; }
|
||||
|
||||
protected:
|
||||
|
||||
const char * Name;
|
||||
int TotalCalls;
|
||||
float TotalTime;
|
||||
__int64 StartTime;
|
||||
int RecursionCounter;
|
||||
|
||||
CProfileNode * Parent;
|
||||
CProfileNode * Child;
|
||||
CProfileNode * Sibling;
|
||||
};
|
||||
|
||||
/*
|
||||
** An iterator to navigate through the tree
|
||||
*/
|
||||
class CProfileIterator
|
||||
{
|
||||
public:
|
||||
// Access all the children of the current parent
|
||||
void First(void);
|
||||
void Next(void);
|
||||
bool Is_Done(void);
|
||||
bool Is_Root(void) { return (CurrentParent->Get_Parent() == 0); }
|
||||
|
||||
void Enter_Child( int index ); // Make the given child the new parent
|
||||
void Enter_Largest_Child( void ); // Make the largest child the new parent
|
||||
void Enter_Parent( void ); // Make the current parent's parent the new parent
|
||||
|
||||
// Access the current child
|
||||
const char * Get_Current_Name( void ) { return CurrentChild->Get_Name(); }
|
||||
int Get_Current_Total_Calls( void ) { return CurrentChild->Get_Total_Calls(); }
|
||||
float Get_Current_Total_Time( void ) { return CurrentChild->Get_Total_Time(); }
|
||||
|
||||
// Access the current parent
|
||||
const char * Get_Current_Parent_Name( void ) { return CurrentParent->Get_Name(); }
|
||||
int Get_Current_Parent_Total_Calls( void ) { return CurrentParent->Get_Total_Calls(); }
|
||||
float Get_Current_Parent_Total_Time( void ) { return CurrentParent->Get_Total_Time(); }
|
||||
|
||||
protected:
|
||||
|
||||
CProfileNode * CurrentParent;
|
||||
CProfileNode * CurrentChild;
|
||||
|
||||
CProfileIterator( CProfileNode * start );
|
||||
friend class CProfileManager;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
** The Manager for the Profile system
|
||||
*/
|
||||
class CProfileManager {
|
||||
public:
|
||||
static void Start_Profile( const char * name );
|
||||
static void Stop_Profile( void );
|
||||
|
||||
static void 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; }
|
||||
|
||||
private:
|
||||
static CProfileNode Root;
|
||||
static CProfileNode * CurrentNode;
|
||||
static int FrameCounter;
|
||||
static __int64 ResetTime;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
** ProfileSampleClass is a simple way to profile a function's scope
|
||||
** Use the PROFILE macro at the start of scope to time
|
||||
*/
|
||||
class CProfileSample {
|
||||
public:
|
||||
CProfileSample( const char * name )
|
||||
{
|
||||
CProfileManager::Start_Profile( name );
|
||||
}
|
||||
|
||||
~CProfileSample( void )
|
||||
{
|
||||
CProfileManager::Stop_Profile();
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined(NO_PROFILE)
|
||||
#define PROFILE( name ) CProfileSample __profile( name )
|
||||
#else
|
||||
#define PROFILE( name )
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#endif //QUICK_PROF_H
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user