mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 08:21:24 +02:00
CollisionWorld only updates _active_ Aabbs
we manually set/clear active state of static objects that need their Aabbs updated also fixing a bug when starting kinematic motion
This commit is contained in:
parent
e1602b57fa
commit
25fbf926df
6 changed files with 50 additions and 31 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -422,19 +420,18 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, const Q
|
||||||
const float ACCELERATION_EQUIVALENT_EPSILON_RATIO = 0.1f;
|
const float ACCELERATION_EQUIVALENT_EPSILON_RATIO = 0.1f;
|
||||||
if (accVsGravity < ACCELERATION_EQUIVALENT_EPSILON_RATIO * gravityLength) {
|
if (accVsGravity < ACCELERATION_EQUIVALENT_EPSILON_RATIO * gravityLength) {
|
||||||
// acceleration measured during the most recent simulation step was close to gravity.
|
// acceleration measured during the most recent simulation step was close to gravity.
|
||||||
if (getAccelerationNearlyGravityCount() < STEPS_TO_DECIDE_BALLISTIC) {
|
if (_accelerationNearlyGravityCount < STEPS_TO_DECIDE_BALLISTIC) {
|
||||||
// only increment this if we haven't reached the threshold yet. this is to avoid
|
// only increment this if we haven't reached the threshold yet, to avoid overflowing the counter
|
||||||
// overflowing the counter.
|
++_accelerationNearlyGravityCount;
|
||||||
incrementAccelerationNearlyGravityCount();
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// acceleration wasn't similar to this entities gravity, so reset the went-ballistic counter
|
// acceleration wasn't similar to this entity's gravity, reset the counter
|
||||||
resetAccelerationNearlyGravityCount();
|
_accelerationNearlyGravityCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if this entity has been accelerated at close to gravity for a certain number of simulation-steps, let
|
// if this entity has been accelerated at close to gravity for a certain number of simulation-steps, let
|
||||||
// the entity server's estimates include gravity.
|
// the entity server's estimates include gravity.
|
||||||
if (getAccelerationNearlyGravityCount() >= STEPS_TO_DECIDE_BALLISTIC) {
|
if (_accelerationNearlyGravityCount >= STEPS_TO_DECIDE_BALLISTIC) {
|
||||||
_entity->setAcceleration(_entity->getGravity());
|
_entity->setAcceleration(_entity->getGravity());
|
||||||
} else {
|
} else {
|
||||||
_entity->setAcceleration(glm::vec3(0.0f));
|
_entity->setAcceleration(glm::vec3(0.0f));
|
||||||
|
|
|
@ -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
|
||||||
|
@ -51,10 +51,6 @@ public:
|
||||||
virtual uint32_t getIncomingDirtyFlags() override;
|
virtual uint32_t getIncomingDirtyFlags() override;
|
||||||
virtual void clearIncomingDirtyFlags() override;
|
virtual void clearIncomingDirtyFlags() override;
|
||||||
|
|
||||||
void incrementAccelerationNearlyGravityCount() { _accelerationNearlyGravityCount++; }
|
|
||||||
void resetAccelerationNearlyGravityCount() { _accelerationNearlyGravityCount = 0; }
|
|
||||||
uint8_t getAccelerationNearlyGravityCount() { return _accelerationNearlyGravityCount; }
|
|
||||||
|
|
||||||
virtual float getObjectRestitution() const override { return _entity->getRestitution(); }
|
virtual float getObjectRestitution() const override { return _entity->getRestitution(); }
|
||||||
virtual float getObjectFriction() const override { return _entity->getFriction(); }
|
virtual float getObjectFriction() const override { return _entity->getFriction(); }
|
||||||
virtual float getObjectLinearDamping() const override { return _entity->getDamping(); }
|
virtual float getObjectLinearDamping() const override { return _entity->getDamping(); }
|
||||||
|
|
|
@ -39,7 +39,7 @@ const glm::vec3& ObjectMotionState::getWorldOffset() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
uint32_t worldSimulationStep = 0;
|
uint32_t worldSimulationStep = 1;
|
||||||
void ObjectMotionState::setWorldSimulationStep(uint32_t step) {
|
void ObjectMotionState::setWorldSimulationStep(uint32_t step) {
|
||||||
assert(step > worldSimulationStep);
|
assert(step > worldSimulationStep);
|
||||||
worldSimulationStep = step;
|
worldSimulationStep = step;
|
||||||
|
@ -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) {
|
||||||
|
@ -292,6 +298,10 @@ void ObjectMotionState::updateBodyVelocities() {
|
||||||
_body->setActivationState(ACTIVE_TAG);
|
_body->setActivationState(ACTIVE_TAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ObjectMotionState::updateLastKinematicStep() {
|
||||||
|
_lastKinematicStep = ObjectMotionState::getWorldSimulationStep() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
void ObjectMotionState::updateBodyMassProperties() {
|
void ObjectMotionState::updateBodyMassProperties() {
|
||||||
float mass = getMass();
|
float mass = getMass();
|
||||||
btVector3 inertia(0.0f, 0.0f, 0.0f);
|
btVector3 inertia(0.0f, 0.0f, 0.0f);
|
||||||
|
|
|
@ -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,11 +81,12 @@ 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();
|
||||||
void updateBodyVelocities();
|
void updateBodyVelocities();
|
||||||
|
void updateLastKinematicStep();
|
||||||
virtual void updateBodyMassProperties();
|
virtual void updateBodyMassProperties();
|
||||||
|
|
||||||
MotionStateType getType() const { return _type; }
|
MotionStateType getType() const { return _type; }
|
||||||
|
|
|
@ -50,6 +50,7 @@ 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));
|
||||||
|
_dynamicsWorld->setForceUpdateAllAabbs(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +81,7 @@ void PhysicsEngine::addObjectToDynamicsWorld(ObjectMotionState* motionState) {
|
||||||
body->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT);
|
body->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT);
|
||||||
body->updateInertiaTensor();
|
body->updateInertiaTensor();
|
||||||
motionState->updateBodyVelocities();
|
motionState->updateBodyVelocities();
|
||||||
|
motionState->updateLastKinematicStep();
|
||||||
const float KINEMATIC_LINEAR_VELOCITY_THRESHOLD = 0.01f; // 1 cm/sec
|
const float KINEMATIC_LINEAR_VELOCITY_THRESHOLD = 0.01f; // 1 cm/sec
|
||||||
const float KINEMATIC_ANGULAR_VELOCITY_THRESHOLD = 0.01f; // ~1 deg/sec
|
const float KINEMATIC_ANGULAR_VELOCITY_THRESHOLD = 0.01f; // ~1 deg/sec
|
||||||
body->setSleepingThresholds(KINEMATIC_LINEAR_VELOCITY_THRESHOLD, KINEMATIC_ANGULAR_VELOCITY_THRESHOLD);
|
body->setSleepingThresholds(KINEMATIC_LINEAR_VELOCITY_THRESHOLD, KINEMATIC_ANGULAR_VELOCITY_THRESHOLD);
|
||||||
|
@ -189,12 +191,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 outselves
|
||||||
|
for (int i = 0; i < _activeStaticBodies.size(); ++i) {
|
||||||
|
_dynamicsWorld->updateSingleAabb(_activeStaticBodies[i]);
|
||||||
}
|
}
|
||||||
return stillNeedChange;
|
return stillNeedChange;
|
||||||
}
|
}
|
||||||
|
@ -389,6 +397,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 (int 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:
|
||||||
|
@ -110,6 +110,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;
|
||||||
QUuid _sessionID;
|
QUuid _sessionID;
|
||||||
|
@ -121,7 +122,6 @@ private:
|
||||||
|
|
||||||
bool _dumpNextStats = false;
|
bool _dumpNextStats = false;
|
||||||
bool _hasOutgoingChanges = false;
|
bool _hasOutgoingChanges = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::shared_ptr<PhysicsEngine> PhysicsEnginePointer;
|
typedef std::shared_ptr<PhysicsEngine> PhysicsEnginePointer;
|
||||||
|
|
Loading…
Reference in a new issue