From abb40ca0805c1db540115c22a2e944130cd97c3a Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 14 Apr 2015 09:00:36 -0700 Subject: [PATCH] cleanup: split stats dump out of stepSimulation --- interface/src/Application.cpp | 1 + libraries/physics/src/PhysicsEngine.cpp | 127 ++++++++++++------------ libraries/physics/src/PhysicsEngine.h | 3 +- 3 files changed, 67 insertions(+), 64 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 82447257fb..73be96c26b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2226,6 +2226,7 @@ void Application::update(float deltaTime) { PerformanceTimer perfTimer("physics"); _myAvatar->relayDriveKeysToCharacterController(); _physicsEngine.stepSimulation(); + _physicsEngine.dumpStatsIfNecessary(); } if (!_aboutToQuit) { diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 50f52a7efc..209e23e006 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -288,77 +288,73 @@ void PhysicsEngine::init(EntityEditPacketSender* packetSender) { } void PhysicsEngine::stepSimulation() { - { - lock(); - CProfileManager::Reset(); - BT_PROFILE("stepSimulation"); - // NOTE: the grand order of operations is: - // (1) pull incoming changes - // (2) step simulation - // (3) synchronize outgoing motion states - // (4) send outgoing packets + lock(); + CProfileManager::Reset(); + BT_PROFILE("stepSimulation"); + // NOTE: the grand order of operations is: + // (1) pull incoming changes + // (2) step simulation + // (3) synchronize outgoing motion states + // (4) send outgoing packets - // This is step (1) pull incoming changes - relayIncomingChangesToSimulation(); - - const int MAX_NUM_SUBSTEPS = 4; - const float MAX_TIMESTEP = (float)MAX_NUM_SUBSTEPS * PHYSICS_ENGINE_FIXED_SUBSTEP; - float dt = 1.0e-6f * (float)(_clock.getTimeMicroseconds()); - _clock.reset(); - float timeStep = btMin(dt, MAX_TIMESTEP); - - // TODO: move character->preSimulation() into relayIncomingChanges - if (_characterController) { - if (_characterController->needsRemoval()) { - _characterController->setDynamicsWorld(NULL); - } - _characterController->updateShapeIfNecessary(); - if (_characterController->needsAddition()) { - _characterController->setDynamicsWorld(_dynamicsWorld); - } - _characterController->preSimulation(timeStep); + // This is step (1) pull incoming changes + relayIncomingChangesToSimulation(); + + const int MAX_NUM_SUBSTEPS = 4; + const float MAX_TIMESTEP = (float)MAX_NUM_SUBSTEPS * PHYSICS_ENGINE_FIXED_SUBSTEP; + float dt = 1.0e-6f * (float)(_clock.getTimeMicroseconds()); + _clock.reset(); + float timeStep = btMin(dt, MAX_TIMESTEP); + + // TODO: move character->preSimulation() into relayIncomingChanges + if (_characterController) { + if (_characterController->needsRemoval()) { + _characterController->setDynamicsWorld(NULL); } - - // This is step (2) step simulation - int numSubsteps = _dynamicsWorld->stepSimulation(timeStep, MAX_NUM_SUBSTEPS, PHYSICS_ENGINE_FIXED_SUBSTEP); - _numSubsteps += (uint32_t)numSubsteps; - stepNonPhysicalKinematics(usecTimestampNow()); - unlock(); - - // TODO: make all of this harvest stuff into one function: relayOutgoingChanges() - if (numSubsteps > 0) { - BT_PROFILE("postSimulation"); - // This is step (3) which is done outside of stepSimulation() so we can lock _entityTree. - // - // Unfortunately we have to unlock the simulation (above) before we try to lock the _entityTree - // to avoid deadlock -- the _entityTree may try to lock its EntitySimulation (from which this - // PhysicsEngine derives) when updating/adding/deleting entities so we need to wait for our own - // lock on the tree before we re-lock ourselves. - // - // TODO: untangle these lock sequences. - _entityTree->lockForWrite(); - lock(); - _dynamicsWorld->synchronizeMotionStates(); - - if (_characterController) { - _characterController->postSimulation(); - } - - unlock(); - _entityTree->unlock(); - - computeCollisionEvents(); + _characterController->updateShapeIfNecessary(); + if (_characterController->needsAddition()) { + _characterController->setDynamicsWorld(_dynamicsWorld); } + _characterController->preSimulation(timeStep); } - if (_dumpNextStats) { - _dumpNextStats = false; - CProfileManager::dumpAll(); + + // This is step (2) step simulation + int numSubsteps = _dynamicsWorld->stepSimulation(timeStep, MAX_NUM_SUBSTEPS, PHYSICS_ENGINE_FIXED_SUBSTEP); + _numSubsteps += (uint32_t)numSubsteps; + stepNonPhysicalKinematics(usecTimestampNow()); + unlock(); + + // TODO: make all of this harvest stuff into one function: relayOutgoingChanges() + if (numSubsteps > 0) { + BT_PROFILE("postSimulation"); + // This is step (3) which is done outside of stepSimulation() so we can lock _entityTree. + // + // Unfortunately we have to unlock the simulation (above) before we try to lock the _entityTree + // to avoid deadlock -- the _entityTree may try to lock its EntitySimulation (from which this + // PhysicsEngine derives) when updating/adding/deleting entities so we need to wait for our own + // lock on the tree before we re-lock ourselves. + // + // TODO: untangle these lock sequences. + ObjectMotionState::setSimulationStep(_numSubsteps); + _entityTree->lockForWrite(); + lock(); + _dynamicsWorld->synchronizeMotionStates(); + + if (_characterController) { + _characterController->postSimulation(); + } + + unlock(); + _entityTree->unlock(); + + computeCollisionEvents(); } } void PhysicsEngine::stepNonPhysicalKinematics(const quint64& now) { BT_PROFILE("nonPhysicalKinematics"); QSet::iterator stateItr = _nonPhysicalKinematicObjects.begin(); + // TODO?: need to occasionally scan for stopped non-physical kinematics objects while (stateItr != _nonPhysicalKinematicObjects.end()) { ObjectMotionState* motionState = *stateItr; motionState->stepKinematicSimulation(now); @@ -366,8 +362,6 @@ void PhysicsEngine::stepNonPhysicalKinematics(const quint64& now) { } } -// TODO?: need to occasionally scan for stopped non-physical kinematics objects - void PhysicsEngine::computeCollisionEvents() { BT_PROFILE("computeCollisionEvents"); // update all contacts every frame @@ -445,6 +439,13 @@ void PhysicsEngine::computeCollisionEvents() { } } +void PhysicsEngine::dumpStatsIfNecessary() { + if (_dumpNextStats) { + _dumpNextStats = false; + CProfileManager::dumpAll(); + } +} + // Bullet collision flags are as follows: // CF_STATIC_OBJECT= 1, // CF_KINEMATIC_OBJECT= 2, diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index 01717be175..6e1f430237 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -68,9 +68,10 @@ public: void stepSimulation(); void stepNonPhysicalKinematics(const quint64& now); - void computeCollisionEvents(); + void dumpStatsIfNecessary(); + /// \param offset position of simulation origin in domain-frame void setOriginOffset(const glm::vec3& offset) { _originOffset = offset; }