mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 10:07:58 +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
|
// virtual
|
||||||
bool EntityMotionState::handleEasyChanges(uint32_t& flags) {
|
void EntityMotionState::handleEasyChanges(uint32_t& flags) {
|
||||||
assert(entityTreeIsLocked());
|
assert(entityTreeIsLocked());
|
||||||
updateServerPhysicsVariables();
|
updateServerPhysicsVariables();
|
||||||
ObjectMotionState::handleEasyChanges(flags);
|
ObjectMotionState::handleEasyChanges(flags);
|
||||||
|
@ -137,8 +137,6 @@ bool EntityMotionState::handleEasyChanges(uint32_t& flags) {
|
||||||
if ((flags & Simulation::DIRTY_PHYSICS_ACTIVATION) && !_body->isActive()) {
|
if ((flags & Simulation::DIRTY_PHYSICS_ACTIVATION) && !_body->isActive()) {
|
||||||
_body->activate();
|
_body->activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ public:
|
||||||
virtual ~EntityMotionState();
|
virtual ~EntityMotionState();
|
||||||
|
|
||||||
void updateServerPhysicsVariables();
|
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;
|
virtual bool handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine) override;
|
||||||
|
|
||||||
/// \return PhysicsMotionType based on params set in EntityItem
|
/// \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) {
|
if (flags & Simulation::DIRTY_POSITION) {
|
||||||
btTransform worldTrans = _body->getWorldTransform();
|
btTransform worldTrans = _body->getWorldTransform();
|
||||||
btVector3 newPosition = glmToBullet(getObjectPosition());
|
btVector3 newPosition = glmToBullet(getObjectPosition());
|
||||||
|
@ -183,6 +183,10 @@ bool ObjectMotionState::handleEasyChanges(uint32_t& flags) {
|
||||||
worldTrans.setRotation(newRotation);
|
worldTrans.setRotation(newRotation);
|
||||||
}
|
}
|
||||||
_body->setWorldTransform(worldTrans);
|
_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) {
|
} else if (flags & Simulation::DIRTY_ROTATION) {
|
||||||
btTransform worldTrans = _body->getWorldTransform();
|
btTransform worldTrans = _body->getWorldTransform();
|
||||||
btQuaternion newRotation = glmToBullet(getObjectRotation());
|
btQuaternion newRotation = glmToBullet(getObjectRotation());
|
||||||
|
@ -192,6 +196,10 @@ bool ObjectMotionState::handleEasyChanges(uint32_t& flags) {
|
||||||
}
|
}
|
||||||
worldTrans.setRotation(newRotation);
|
worldTrans.setRotation(newRotation);
|
||||||
_body->setWorldTransform(worldTrans);
|
_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) {
|
if (flags & Simulation::DIRTY_LINEAR_VELOCITY) {
|
||||||
|
@ -232,8 +240,6 @@ bool ObjectMotionState::handleEasyChanges(uint32_t& flags) {
|
||||||
if (flags & Simulation::DIRTY_MASS) {
|
if (flags & Simulation::DIRTY_MASS) {
|
||||||
updateBodyMassProperties();
|
updateBodyMassProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ObjectMotionState::handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine) {
|
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);
|
Simulation::DIRTY_COLLISION_GROUP);
|
||||||
const uint32_t EASY_DIRTY_PHYSICS_FLAGS = (uint32_t)(Simulation::DIRTY_TRANSFORM | Simulation::DIRTY_VELOCITIES |
|
const uint32_t EASY_DIRTY_PHYSICS_FLAGS = (uint32_t)(Simulation::DIRTY_TRANSFORM | Simulation::DIRTY_VELOCITIES |
|
||||||
Simulation::DIRTY_MASS | Simulation::DIRTY_MATERIAL |
|
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:
|
// 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 |
|
const uint32_t DIRTY_PHYSICS_FLAGS = (uint32_t)(HARD_DIRTY_PHYSICS_FLAGS | EASY_DIRTY_PHYSICS_FLAGS);
|
||||||
Simulation::DIRTY_PHYSICS_ACTIVATION);
|
|
||||||
|
|
||||||
// These are the outgoing flags that the PhysicsEngine can affect:
|
// These are the outgoing flags that the PhysicsEngine can affect:
|
||||||
const uint32_t OUTGOING_DIRTY_PHYSICS_FLAGS = Simulation::DIRTY_TRANSFORM | Simulation::DIRTY_VELOCITIES;
|
const uint32_t OUTGOING_DIRTY_PHYSICS_FLAGS = Simulation::DIRTY_TRANSFORM | Simulation::DIRTY_VELOCITIES;
|
||||||
|
@ -80,7 +81,7 @@ public:
|
||||||
ObjectMotionState(btCollisionShape* shape);
|
ObjectMotionState(btCollisionShape* shape);
|
||||||
~ObjectMotionState();
|
~ObjectMotionState();
|
||||||
|
|
||||||
virtual bool handleEasyChanges(uint32_t& flags);
|
virtual void handleEasyChanges(uint32_t& flags);
|
||||||
virtual bool handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine);
|
virtual bool handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine);
|
||||||
|
|
||||||
void updateBodyMaterialProperties();
|
void updateBodyMaterialProperties();
|
||||||
|
|
|
@ -49,6 +49,13 @@ void PhysicsEngine::init() {
|
||||||
// default gravity of the world is zero, so each object must specify its own gravity
|
// default gravity of the world is zero, so each object must specify its own gravity
|
||||||
// TODO: set up gravity zones
|
// TODO: set up gravity zones
|
||||||
_dynamicsWorld->setGravity(btVector3(0.0f, 0.0f, 0.0f));
|
_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);
|
stillNeedChange.push_back(object);
|
||||||
}
|
}
|
||||||
} else if (flags & EASY_DIRTY_PHYSICS_FLAGS) {
|
} else if (flags & EASY_DIRTY_PHYSICS_FLAGS) {
|
||||||
if (object->handleEasyChanges(flags)) {
|
object->handleEasyChanges(flags);
|
||||||
object->clearIncomingDirtyFlags();
|
object->clearIncomingDirtyFlags();
|
||||||
} else {
|
|
||||||
stillNeedChange.push_back(object);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
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;
|
return stillNeedChange;
|
||||||
}
|
}
|
||||||
|
@ -387,6 +400,12 @@ const CollisionEvents& PhysicsEngine::getCollisionEvents() {
|
||||||
|
|
||||||
const VectorOfMotionStates& PhysicsEngine::getOutgoingChanges() {
|
const VectorOfMotionStates& PhysicsEngine::getOutgoingChanges() {
|
||||||
BT_PROFILE("copyOutgoingChanges");
|
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();
|
_dynamicsWorld->synchronizeMotionStates();
|
||||||
_hasOutgoingChanges = false;
|
_hasOutgoingChanges = false;
|
||||||
return _dynamicsWorld->getChangedMotionStates();
|
return _dynamicsWorld->getChangedMotionStates();
|
||||||
|
|
|
@ -13,9 +13,9 @@
|
||||||
#define hifi_PhysicsEngine_h
|
#define hifi_PhysicsEngine_h
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <QUuid>
|
#include <QUuid>
|
||||||
#include <QVector>
|
|
||||||
#include <btBulletDynamicsCommon.h>
|
#include <btBulletDynamicsCommon.h>
|
||||||
#include <BulletCollision/CollisionDispatch/btGhostObject.h>
|
#include <BulletCollision/CollisionDispatch/btGhostObject.h>
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<ContactKey, ContactInfo> ContactMap;
|
typedef std::map<ContactKey, ContactInfo> ContactMap;
|
||||||
typedef QVector<Collision> CollisionEvents;
|
typedef std::vector<Collision> CollisionEvents;
|
||||||
|
|
||||||
class PhysicsEngine {
|
class PhysicsEngine {
|
||||||
public:
|
public:
|
||||||
|
@ -108,6 +108,7 @@ private:
|
||||||
ContactMap _contactMap;
|
ContactMap _contactMap;
|
||||||
CollisionEvents _collisionEvents;
|
CollisionEvents _collisionEvents;
|
||||||
QHash<QUuid, EntityActionPointer> _objectActions;
|
QHash<QUuid, EntityActionPointer> _objectActions;
|
||||||
|
std::vector<btRigidBody*> _activeStaticBodies;
|
||||||
|
|
||||||
glm::vec3 _originOffset;
|
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;
|
const int16_t BULLET_COLLISION_MASK_DEFAULT = ~ BULLET_COLLISION_GROUP_COLLISIONLESS;
|
||||||
|
|
||||||
// STATIC does not collide with itself (as optimization of physics simulation)
|
// 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_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
|
// MY_AVATAR does not collide with itself
|
||||||
const int16_t BULLET_COLLISION_MASK_MY_AVATAR = ~(BULLET_COLLISION_GROUP_COLLISIONLESS | BULLET_COLLISION_GROUP_MY_AVATAR);
|
const int16_t BULLET_COLLISION_MASK_MY_AVATAR = ~(BULLET_COLLISION_GROUP_COLLISIONLESS | BULLET_COLLISION_GROUP_MY_AVATAR);
|
||||||
|
|
Loading…
Reference in a new issue