recently moved static objects added to changelist

since static objects are not active this will make the interface
release ownership of recently changed static objects
This commit is contained in:
Andrew Meadows 2017-06-01 10:05:26 -07:00
parent e34f979ed9
commit 74827fc4c8
3 changed files with 28 additions and 20 deletions

View file

@ -129,6 +129,9 @@ void PhysicsEngine::addObjectToDynamicsWorld(ObjectMotionState* motionState) {
} }
body->setCollisionFlags(btCollisionObject::CF_STATIC_OBJECT); body->setCollisionFlags(btCollisionObject::CF_STATIC_OBJECT);
body->updateInertiaTensor(); body->updateInertiaTensor();
if (motionState->isLocallyOwned()) {
_activeStaticBodies.insert(body);
}
break; break;
} }
} }
@ -174,19 +177,9 @@ void PhysicsEngine::removeObjects(const VectorOfMotionStates& objects) {
// frame (because the framerate is faster than our physics simulation rate). When this happens we must scan // frame (because the framerate is faster than our physics simulation rate). When this happens we must scan
// _activeStaticBodies for objects that were recently deleted so we don't try to access a dangling pointer. // _activeStaticBodies for objects that were recently deleted so we don't try to access a dangling pointer.
for (auto object : objects) { for (auto object : objects) {
btRigidBody* body = object->getRigidBody(); std::set<btRigidBody*>::iterator itr = _activeStaticBodies.find(object->getRigidBody());
if (itr != _activeStaticBodies.end()) {
std::vector<btRigidBody*>::reverse_iterator itr = _activeStaticBodies.rbegin(); _activeStaticBodies.erase(itr);
while (itr != _activeStaticBodies.rend()) {
if (body == *itr) {
if (*itr != *(_activeStaticBodies.rbegin())) {
// swap with rbegin
*itr = *(_activeStaticBodies.rbegin());
}
_activeStaticBodies.pop_back();
break;
}
++itr;
} }
} }
} }
@ -245,14 +238,16 @@ VectorOfMotionStates PhysicsEngine::changeObjects(const VectorOfMotionStates& ob
object->clearIncomingDirtyFlags(); object->clearIncomingDirtyFlags();
} }
if (object->getMotionType() == MOTION_TYPE_STATIC && object->isActive()) { if (object->getMotionType() == MOTION_TYPE_STATIC && object->isActive()) {
_activeStaticBodies.push_back(object->getRigidBody()); _activeStaticBodies.insert(object->getRigidBody());
} }
} }
// active static bodies have changed (in an Easy way) and need their Aabbs updated // active static bodies have changed (in an Easy way) and need their Aabbs updated
// but we've configured Bullet to NOT update them automatically (for improved performance) // but we've configured Bullet to NOT update them automatically (for improved performance)
// so we must do it ourselves // so we must do it ourselves
for (size_t i = 0; i < _activeStaticBodies.size(); ++i) { std::set<btRigidBody*>::const_iterator itr = _activeStaticBodies.begin();
_dynamicsWorld->updateSingleAabb(_activeStaticBodies[i]); while (itr != _activeStaticBodies.end()) {
_dynamicsWorld->updateSingleAabb(*itr);
++itr;
} }
return stillNeedChange; return stillNeedChange;
} }
@ -496,13 +491,23 @@ const CollisionEvents& PhysicsEngine::getCollisionEvents() {
const VectorOfMotionStates& PhysicsEngine::getChangedMotionStates() { const VectorOfMotionStates& PhysicsEngine::getChangedMotionStates() {
BT_PROFILE("copyOutgoingChanges"); BT_PROFILE("copyOutgoingChanges");
_dynamicsWorld->synchronizeMotionStates();
// Bullet will not deactivate static objects (it doesn't expect them to be active) // Bullet will not deactivate static objects (it doesn't expect them to be active)
// so we must deactivate them ourselves // so we must deactivate them ourselves
for (size_t i = 0; i < _activeStaticBodies.size(); ++i) { std::set<btRigidBody*>::const_iterator itr = _activeStaticBodies.begin();
_activeStaticBodies[i]->forceActivationState(ISLAND_SLEEPING); while (itr != _activeStaticBodies.end()) {
btRigidBody* body = *itr;
body->forceActivationState(ISLAND_SLEEPING);
ObjectMotionState* motionState = static_cast<ObjectMotionState*>(body->getUserPointer());
if (motionState) {
_dynamicsWorld->addChangedMotionState(motionState);
}
++itr;
} }
_activeStaticBodies.clear(); _activeStaticBodies.clear();
_dynamicsWorld->synchronizeMotionStates();
_hasOutgoingChanges = false; _hasOutgoingChanges = false;
return _dynamicsWorld->getChangedMotionStates(); return _dynamicsWorld->getChangedMotionStates();
} }

View file

@ -13,6 +13,7 @@
#define hifi_PhysicsEngine_h #define hifi_PhysicsEngine_h
#include <stdint.h> #include <stdint.h>
#include <set>
#include <vector> #include <vector>
#include <QUuid> #include <QUuid>
@ -114,7 +115,7 @@ private:
CollisionEvents _collisionEvents; CollisionEvents _collisionEvents;
QHash<QUuid, EntityDynamicPointer> _objectDynamics; QHash<QUuid, EntityDynamicPointer> _objectDynamics;
QHash<btRigidBody*, QSet<QUuid>> _objectDynamicsByBody; QHash<btRigidBody*, QSet<QUuid>> _objectDynamicsByBody;
std::vector<btRigidBody*> _activeStaticBodies; std::set<btRigidBody*> _activeStaticBodies;
glm::vec3 _originOffset; glm::vec3 _originOffset;

View file

@ -51,6 +51,8 @@ public:
const VectorOfMotionStates& getChangedMotionStates() const { return _changedMotionStates; } const VectorOfMotionStates& getChangedMotionStates() const { return _changedMotionStates; }
const VectorOfMotionStates& getDeactivatedMotionStates() const { return _deactivatedStates; } const VectorOfMotionStates& getDeactivatedMotionStates() const { return _deactivatedStates; }
void addChangedMotionState(ObjectMotionState* motionState) { _changedMotionStates.push_back(motionState); }
private: private:
// call this instead of non-virtual btDiscreteDynamicsWorld::synchronizeSingleMotionState() // call this instead of non-virtual btDiscreteDynamicsWorld::synchronizeSingleMotionState()
void synchronizeMotionState(btRigidBody* body); void synchronizeMotionState(btRigidBody* body);