mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:44:02 +02:00
update Aabb's of static objects when they move
This commit is contained in:
parent
dcf28937cf
commit
bb59860cfe
7 changed files with 45 additions and 20 deletions
|
@ -94,7 +94,7 @@ void EntityMotionState::updateServerPhysicsVariables() {
|
|||
}
|
||||
|
||||
// virtual
|
||||
bool EntityMotionState::handleEasyChanges(uint32_t& flags) {
|
||||
void EntityMotionState::handleEasyChanges(uint32_t& flags) {
|
||||
assert(entityTreeIsLocked());
|
||||
updateServerPhysicsVariables();
|
||||
ObjectMotionState::handleEasyChanges(flags);
|
||||
|
@ -137,8 +137,6 @@ bool EntityMotionState::handleEasyChanges(uint32_t& flags) {
|
|||
if ((flags & Simulation::DIRTY_PHYSICS_ACTIVATION) && !_body->isActive()) {
|
||||
_body->activate();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ public:
|
|||
virtual ~EntityMotionState();
|
||||
|
||||
void updateServerPhysicsVariables();
|
||||
virtual bool handleEasyChanges(uint32_t& flags) override;
|
||||
virtual void handleEasyChanges(uint32_t& flags) override;
|
||||
virtual bool handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine) override;
|
||||
|
||||
/// \return PhysicsMotionType based on params set in EntityItem
|
||||
|
|
|
@ -164,7 +164,7 @@ void ObjectMotionState::setRigidBody(btRigidBody* body) {
|
|||
}
|
||||
}
|
||||
|
||||
bool ObjectMotionState::handleEasyChanges(uint32_t& flags) {
|
||||
void ObjectMotionState::handleEasyChanges(uint32_t& flags) {
|
||||
if (flags & Simulation::DIRTY_POSITION) {
|
||||
btTransform worldTrans = _body->getWorldTransform();
|
||||
btVector3 newPosition = glmToBullet(getObjectPosition());
|
||||
|
@ -183,6 +183,10 @@ bool ObjectMotionState::handleEasyChanges(uint32_t& flags) {
|
|||
worldTrans.setRotation(newRotation);
|
||||
}
|
||||
_body->setWorldTransform(worldTrans);
|
||||
if (!(flags & HARD_DIRTY_PHYSICS_FLAGS) && _body->isStaticObject()) {
|
||||
// force activate static body so its Aabb is updated later
|
||||
_body->activate(true);
|
||||
}
|
||||
} else if (flags & Simulation::DIRTY_ROTATION) {
|
||||
btTransform worldTrans = _body->getWorldTransform();
|
||||
btQuaternion newRotation = glmToBullet(getObjectRotation());
|
||||
|
@ -192,6 +196,10 @@ bool ObjectMotionState::handleEasyChanges(uint32_t& flags) {
|
|||
}
|
||||
worldTrans.setRotation(newRotation);
|
||||
_body->setWorldTransform(worldTrans);
|
||||
if (!(flags & HARD_DIRTY_PHYSICS_FLAGS) && _body->isStaticObject()) {
|
||||
// force activate static body so its Aabb is updated later
|
||||
_body->activate(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & Simulation::DIRTY_LINEAR_VELOCITY) {
|
||||
|
@ -232,8 +240,6 @@ bool ObjectMotionState::handleEasyChanges(uint32_t& flags) {
|
|||
if (flags & Simulation::DIRTY_MASS) {
|
||||
updateBodyMassProperties();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectMotionState::handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine) {
|
||||
|
|
|
@ -50,11 +50,12 @@ const uint32_t HARD_DIRTY_PHYSICS_FLAGS = (uint32_t)(Simulation::DIRTY_MOTION_TY
|
|||
Simulation::DIRTY_COLLISION_GROUP);
|
||||
const uint32_t EASY_DIRTY_PHYSICS_FLAGS = (uint32_t)(Simulation::DIRTY_TRANSFORM | Simulation::DIRTY_VELOCITIES |
|
||||
Simulation::DIRTY_MASS | Simulation::DIRTY_MATERIAL |
|
||||
Simulation::DIRTY_SIMULATOR_ID | Simulation::DIRTY_SIMULATION_OWNERSHIP_PRIORITY);
|
||||
Simulation::DIRTY_SIMULATOR_ID | Simulation::DIRTY_SIMULATION_OWNERSHIP_PRIORITY |
|
||||
Simulation::DIRTY_PHYSICS_ACTIVATION);
|
||||
|
||||
|
||||
// These are the set of incoming flags that the PhysicsEngine needs to hear about:
|
||||
const uint32_t DIRTY_PHYSICS_FLAGS = (uint32_t)(HARD_DIRTY_PHYSICS_FLAGS | EASY_DIRTY_PHYSICS_FLAGS |
|
||||
Simulation::DIRTY_PHYSICS_ACTIVATION);
|
||||
const uint32_t DIRTY_PHYSICS_FLAGS = (uint32_t)(HARD_DIRTY_PHYSICS_FLAGS | EASY_DIRTY_PHYSICS_FLAGS);
|
||||
|
||||
// These are the outgoing flags that the PhysicsEngine can affect:
|
||||
const uint32_t OUTGOING_DIRTY_PHYSICS_FLAGS = Simulation::DIRTY_TRANSFORM | Simulation::DIRTY_VELOCITIES;
|
||||
|
@ -80,7 +81,7 @@ public:
|
|||
ObjectMotionState(btCollisionShape* shape);
|
||||
~ObjectMotionState();
|
||||
|
||||
virtual bool handleEasyChanges(uint32_t& flags);
|
||||
virtual void handleEasyChanges(uint32_t& flags);
|
||||
virtual bool handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine);
|
||||
|
||||
void updateBodyMaterialProperties();
|
||||
|
|
|
@ -49,6 +49,13 @@ void PhysicsEngine::init() {
|
|||
// default gravity of the world is zero, so each object must specify its own gravity
|
||||
// TODO: set up gravity zones
|
||||
_dynamicsWorld->setGravity(btVector3(0.0f, 0.0f, 0.0f));
|
||||
|
||||
// By default Bullet will update the Aabb's of all objects every frame, even statics.
|
||||
// This can waste CPU cycles so we configure Bullet to only update ACTIVE objects here.
|
||||
// However, this means when a static object is moved we must manually update its Aabb
|
||||
// in order for its broadphase collision queries to work correctly. Look at how we use
|
||||
// _activeStaticBodies to track and update the Aabb's of moved static objects.
|
||||
_dynamicsWorld->setForceUpdateAllAabbs(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -188,12 +195,18 @@ VectorOfMotionStates PhysicsEngine::changeObjects(const VectorOfMotionStates& ob
|
|||
stillNeedChange.push_back(object);
|
||||
}
|
||||
} else if (flags & EASY_DIRTY_PHYSICS_FLAGS) {
|
||||
if (object->handleEasyChanges(flags)) {
|
||||
object->clearIncomingDirtyFlags();
|
||||
} else {
|
||||
stillNeedChange.push_back(object);
|
||||
}
|
||||
object->handleEasyChanges(flags);
|
||||
object->clearIncomingDirtyFlags();
|
||||
}
|
||||
if (object->getMotionType() == MOTION_TYPE_STATIC && object->isActive()) {
|
||||
_activeStaticBodies.push_back(object->getRigidBody());
|
||||
}
|
||||
}
|
||||
// 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)
|
||||
// so we must do it ourselves
|
||||
for (size_t i = 0; i < _activeStaticBodies.size(); ++i) {
|
||||
_dynamicsWorld->updateSingleAabb(_activeStaticBodies[i]);
|
||||
}
|
||||
return stillNeedChange;
|
||||
}
|
||||
|
@ -387,6 +400,12 @@ const CollisionEvents& PhysicsEngine::getCollisionEvents() {
|
|||
|
||||
const VectorOfMotionStates& PhysicsEngine::getOutgoingChanges() {
|
||||
BT_PROFILE("copyOutgoingChanges");
|
||||
// Bullet will not deactivate static objects (it doesn't expect them to be active)
|
||||
// so we must deactivate them ourselves
|
||||
for (size_t i = 0; i < _activeStaticBodies.size(); ++i) {
|
||||
_activeStaticBodies[i]->forceActivationState(ISLAND_SLEEPING);
|
||||
}
|
||||
_activeStaticBodies.clear();
|
||||
_dynamicsWorld->synchronizeMotionStates();
|
||||
_hasOutgoingChanges = false;
|
||||
return _dynamicsWorld->getChangedMotionStates();
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
#define hifi_PhysicsEngine_h
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
#include <QUuid>
|
||||
#include <QVector>
|
||||
#include <btBulletDynamicsCommon.h>
|
||||
#include <BulletCollision/CollisionDispatch/btGhostObject.h>
|
||||
|
||||
|
@ -41,7 +41,7 @@ public:
|
|||
};
|
||||
|
||||
typedef std::map<ContactKey, ContactInfo> ContactMap;
|
||||
typedef QVector<Collision> CollisionEvents;
|
||||
typedef std::vector<Collision> CollisionEvents;
|
||||
|
||||
class PhysicsEngine {
|
||||
public:
|
||||
|
@ -108,6 +108,7 @@ private:
|
|||
ContactMap _contactMap;
|
||||
CollisionEvents _collisionEvents;
|
||||
QHash<QUuid, EntityActionPointer> _objectActions;
|
||||
std::vector<btRigidBody*> _activeStaticBodies;
|
||||
|
||||
glm::vec3 _originOffset;
|
||||
|
||||
|
|
|
@ -51,10 +51,10 @@ const int16_t BULLET_COLLISION_GROUP_COLLISIONLESS = 1 << 14;
|
|||
const int16_t BULLET_COLLISION_MASK_DEFAULT = ~ BULLET_COLLISION_GROUP_COLLISIONLESS;
|
||||
|
||||
// STATIC does not collide with itself (as optimization of physics simulation)
|
||||
const int16_t BULLET_COLLISION_MASK_STATIC = ~ (BULLET_COLLISION_GROUP_COLLISIONLESS | BULLET_COLLISION_GROUP_STATIC);
|
||||
const int16_t BULLET_COLLISION_MASK_STATIC = ~ (BULLET_COLLISION_GROUP_COLLISIONLESS | BULLET_COLLISION_GROUP_KINEMATIC | BULLET_COLLISION_GROUP_STATIC);
|
||||
|
||||
const int16_t BULLET_COLLISION_MASK_DYNAMIC = BULLET_COLLISION_MASK_DEFAULT;
|
||||
const int16_t BULLET_COLLISION_MASK_KINEMATIC = BULLET_COLLISION_MASK_DEFAULT;
|
||||
const int16_t BULLET_COLLISION_MASK_KINEMATIC = BULLET_COLLISION_MASK_STATIC;
|
||||
|
||||
// MY_AVATAR does not collide with itself
|
||||
const int16_t BULLET_COLLISION_MASK_MY_AVATAR = ~(BULLET_COLLISION_GROUP_COLLISIONLESS | BULLET_COLLISION_GROUP_MY_AVATAR);
|
||||
|
|
Loading…
Reference in a new issue