added hierarchical profiling (needs more cleanup)

avoid dynamic allocations in btRaycastVehicle
This commit is contained in:
ejcoumans
2007-11-21 03:00:40 +00:00
parent 89382c0dc4
commit cab75b53ec
19 changed files with 695 additions and 128 deletions

View File

@@ -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);

View File

@@ -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();

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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();

View File

@@ -372,9 +372,6 @@ void RagdollDemo::displayCallback()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (m_dynamicsWorld)
m_dynamicsWorld->updateAabbs();
renderme();
glFlush();

View File

@@ -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();

View File

@@ -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
{

View File

@@ -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;

View File

@@ -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");
}

View File

@@ -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

View File

@@ -48,6 +48,7 @@ void btContinuousDynamicsWorld::internalSingleStepSimulation( btScalar timeStep)
startProfiling(timeStep);
///update aabbs information
updateAabbs();
//static int frame=0;

View File

@@ -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

View File

@@ -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();

View File

@@ -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);
}

View File

@@ -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
{

View File

@@ -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();
}

View File

@@ -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