mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 04:48:54 +02:00
flag kinematic objs when changed in stepSimulation()
This commit is contained in:
parent
b102081f2f
commit
f652e983a9
7 changed files with 62 additions and 30 deletions
|
@ -119,8 +119,7 @@ void AvatarActionHold::doKinematicUpdate(float deltaTimeStep) {
|
||||||
worldTrans.setRotation(glmToBullet(_rotationalTarget));
|
worldTrans.setRotation(glmToBullet(_rotationalTarget));
|
||||||
rigidBody->setWorldTransform(worldTrans);
|
rigidBody->setWorldTransform(worldTrans);
|
||||||
|
|
||||||
ownerEntity->setPosition(_positionalTarget);
|
motionState->dirtyInternalKinematicChanges();
|
||||||
ownerEntity->setRotation(_rotationalTarget);
|
|
||||||
|
|
||||||
_previousPositionalTarget = _positionalTarget;
|
_previousPositionalTarget = _positionalTarget;
|
||||||
_previousRotationalTarget = _rotationalTarget;
|
_previousRotationalTarget = _rotationalTarget;
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
ObjectAction::ObjectAction(EntityActionType type, const QUuid& id, EntityItemPointer ownerEntity) :
|
ObjectAction::ObjectAction(EntityActionType type, const QUuid& id, EntityItemPointer ownerEntity) :
|
||||||
btActionInterface(),
|
btActionInterface(),
|
||||||
EntityActionInterface(type, id),
|
EntityActionInterface(type, id),
|
||||||
_active(false),
|
|
||||||
_ownerEntity(ownerEntity) {
|
_ownerEntity(ownerEntity) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,8 @@ public:
|
||||||
virtual quint64 getExpires() { return _expires; }
|
virtual quint64 getExpires() { return _expires; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
quint64 localTimeToServerTime(quint64 timeValue) const;
|
||||||
|
quint64 serverTimeToLocalTime(quint64 timeValue) const;
|
||||||
|
|
||||||
virtual btRigidBody* getRigidBody();
|
virtual btRigidBody* getRigidBody();
|
||||||
virtual glm::vec3 getPosition();
|
virtual glm::vec3 getPosition();
|
||||||
|
@ -62,14 +64,10 @@ protected:
|
||||||
virtual void setAngularVelocity(glm::vec3 angularVelocity);
|
virtual void setAngularVelocity(glm::vec3 angularVelocity);
|
||||||
virtual void activateBody();
|
virtual void activateBody();
|
||||||
|
|
||||||
bool _active;
|
|
||||||
EntityItemWeakPointer _ownerEntity;
|
EntityItemWeakPointer _ownerEntity;
|
||||||
|
|
||||||
quint64 _expires; // in seconds since epoch
|
|
||||||
QString _tag;
|
QString _tag;
|
||||||
|
quint64 _expires { 0 }; // in seconds since epoch
|
||||||
quint64 localTimeToServerTime(quint64 timeValue) const;
|
bool _active { false };
|
||||||
quint64 serverTimeToLocalTime(quint64 timeValue) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int getEntityServerClockSkew() const;
|
int getEntityServerClockSkew() const;
|
||||||
|
|
|
@ -20,17 +20,17 @@
|
||||||
// origin of physics simulation in world-frame
|
// origin of physics simulation in world-frame
|
||||||
glm::vec3 _worldOffset(0.0f);
|
glm::vec3 _worldOffset(0.0f);
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void ObjectMotionState::setWorldOffset(const glm::vec3& offset) {
|
void ObjectMotionState::setWorldOffset(const glm::vec3& offset) {
|
||||||
_worldOffset = offset;
|
_worldOffset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
const glm::vec3& ObjectMotionState::getWorldOffset() {
|
const glm::vec3& ObjectMotionState::getWorldOffset() {
|
||||||
return _worldOffset;
|
return _worldOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
uint32_t worldSimulationStep = 0;
|
uint32_t worldSimulationStep = 0;
|
||||||
void ObjectMotionState::setWorldSimulationStep(uint32_t step) {
|
void ObjectMotionState::setWorldSimulationStep(uint32_t step) {
|
||||||
assert(step > worldSimulationStep);
|
assert(step > worldSimulationStep);
|
||||||
|
@ -41,7 +41,7 @@ uint32_t ObjectMotionState::getWorldSimulationStep() {
|
||||||
return worldSimulationStep;
|
return worldSimulationStep;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
ShapeManager* shapeManager = nullptr;
|
ShapeManager* shapeManager = nullptr;
|
||||||
void ObjectMotionState::setShapeManager(ShapeManager* manager) {
|
void ObjectMotionState::setShapeManager(ShapeManager* manager) {
|
||||||
assert(manager);
|
assert(manager);
|
||||||
|
@ -85,7 +85,7 @@ glm::vec3 ObjectMotionState::getBodyLinearVelocity() const {
|
||||||
|
|
||||||
glm::vec3 ObjectMotionState::getBodyLinearVelocityGTSigma() const {
|
glm::vec3 ObjectMotionState::getBodyLinearVelocityGTSigma() const {
|
||||||
// NOTE: the threshold to use here relates to the linear displacement threshold (dX) for sending updates
|
// NOTE: the threshold to use here relates to the linear displacement threshold (dX) for sending updates
|
||||||
// to objects that are tracked server-side (e.g. entities which use dX = 2mm). Hence an object moving
|
// to objects that are tracked server-side (e.g. entities which use dX = 2mm). Hence an object moving
|
||||||
// just under this velocity threshold would trigger an update about V/dX times per second.
|
// just under this velocity threshold would trigger an update about V/dX times per second.
|
||||||
const float MIN_LINEAR_SPEED_SQUARED = 0.0036f; // 6 mm/sec
|
const float MIN_LINEAR_SPEED_SQUARED = 0.0036f; // 6 mm/sec
|
||||||
|
|
||||||
|
|
|
@ -44,12 +44,12 @@ enum MotionStateType {
|
||||||
MOTIONSTATE_TYPE_AVATAR
|
MOTIONSTATE_TYPE_AVATAR
|
||||||
};
|
};
|
||||||
|
|
||||||
// The update flags trigger two varieties of updates: "hard" which require the body to be pulled
|
// The update flags trigger two varieties of updates: "hard" which require the body to be pulled
|
||||||
// and re-added to the physics engine and "easy" which just updates the body properties.
|
// and re-added to the physics engine and "easy" which just updates the body properties.
|
||||||
const uint32_t HARD_DIRTY_PHYSICS_FLAGS = (uint32_t)(Simulation::DIRTY_MOTION_TYPE | Simulation::DIRTY_SHAPE |
|
const uint32_t HARD_DIRTY_PHYSICS_FLAGS = (uint32_t)(Simulation::DIRTY_MOTION_TYPE | Simulation::DIRTY_SHAPE |
|
||||||
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_SIMULATOR_OWNERSHIP);
|
Simulation::DIRTY_SIMULATOR_ID | Simulation::DIRTY_SIMULATOR_OWNERSHIP);
|
||||||
|
|
||||||
// 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:
|
||||||
|
@ -66,7 +66,7 @@ class PhysicsEngine;
|
||||||
class ObjectMotionState : public btMotionState {
|
class ObjectMotionState : public btMotionState {
|
||||||
public:
|
public:
|
||||||
// These poroperties of the PhysicsEngine are "global" within the context of all ObjectMotionStates
|
// These poroperties of the PhysicsEngine are "global" within the context of all ObjectMotionStates
|
||||||
// (assuming just one PhysicsEngine). They are cached as statics for fast calculations in the
|
// (assuming just one PhysicsEngine). They are cached as statics for fast calculations in the
|
||||||
// ObjectMotionState context.
|
// ObjectMotionState context.
|
||||||
static void setWorldOffset(const glm::vec3& offset);
|
static void setWorldOffset(const glm::vec3& offset);
|
||||||
static const glm::vec3& getWorldOffset();
|
static const glm::vec3& getWorldOffset();
|
||||||
|
@ -121,7 +121,7 @@ public:
|
||||||
virtual float getObjectFriction() const = 0;
|
virtual float getObjectFriction() const = 0;
|
||||||
virtual float getObjectLinearDamping() const = 0;
|
virtual float getObjectLinearDamping() const = 0;
|
||||||
virtual float getObjectAngularDamping() const = 0;
|
virtual float getObjectAngularDamping() const = 0;
|
||||||
|
|
||||||
virtual glm::vec3 getObjectPosition() const = 0;
|
virtual glm::vec3 getObjectPosition() const = 0;
|
||||||
virtual glm::quat getObjectRotation() const = 0;
|
virtual glm::quat getObjectRotation() const = 0;
|
||||||
virtual glm::vec3 getObjectLinearVelocity() const = 0;
|
virtual glm::vec3 getObjectLinearVelocity() const = 0;
|
||||||
|
@ -140,6 +140,11 @@ public:
|
||||||
|
|
||||||
bool isActive() const { return _body ? _body->isActive() : false; }
|
bool isActive() const { return _body ? _body->isActive() : false; }
|
||||||
|
|
||||||
|
bool hasInternalKinematicChanges() const { return _hasInternalKinematicChanges; }
|
||||||
|
|
||||||
|
void dirtyInternalKinematicChanges() { _hasInternalKinematicChanges = true; }
|
||||||
|
void clearInternalKinematicChanges() { _hasInternalKinematicChanges = false; }
|
||||||
|
|
||||||
friend class PhysicsEngine;
|
friend class PhysicsEngine;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -160,6 +165,7 @@ protected:
|
||||||
float _mass;
|
float _mass;
|
||||||
|
|
||||||
uint32_t _lastKinematicStep;
|
uint32_t _lastKinematicStep;
|
||||||
|
bool _hasInternalKinematicChanges { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef QSet<ObjectMotionState*> SetOfMotionStates;
|
typedef QSet<ObjectMotionState*> SetOfMotionStates;
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied warranty.
|
* This software is provided 'as-is', without any express or implied warranty.
|
||||||
* In no event will the authors be held liable for any damages arising from the use of this software.
|
* In no event will the authors be held liable for any damages arising from the use of this software.
|
||||||
* Permission is granted to anyone to use this software for any purpose,
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
* including commercial applications, and to alter it and redistribute it freely,
|
* including commercial applications, and to alter it and redistribute it freely,
|
||||||
* subject to the following restrictions:
|
* subject to the following restrictions:
|
||||||
*
|
*
|
||||||
* 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
* 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||||
|
@ -75,7 +75,7 @@ int ThreadSafeDynamicsWorld::stepSimulationWithSubstepCallback(btScalar timeStep
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: We do NOT call synchronizeMotionState() after each substep (to avoid multiple locks on the
|
// NOTE: We do NOT call synchronizeMotionStates() after each substep (to avoid multiple locks on the
|
||||||
// object data outside of the physics engine). A consequence of this is that the transforms of the
|
// object data outside of the physics engine). A consequence of this is that the transforms of the
|
||||||
// external objects only ever update at the end of the full step.
|
// external objects only ever update at the end of the full step.
|
||||||
|
|
||||||
|
@ -87,6 +87,33 @@ int ThreadSafeDynamicsWorld::stepSimulationWithSubstepCallback(btScalar timeStep
|
||||||
return subSteps;
|
return subSteps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// call this instead of non-virtual btDiscreteDynamicsWorld::synchronizeSingleMotionState()
|
||||||
|
void ThreadSafeDynamicsWorld::synchronizeMotionState(btRigidBody* body) {
|
||||||
|
btAssert(body);
|
||||||
|
if (body->getMotionState() && !body->isStaticObject()) {
|
||||||
|
//we need to call the update at least once, even for sleeping objects
|
||||||
|
//otherwise the 'graphics' transform never updates properly
|
||||||
|
///@todo: add 'dirty' flag
|
||||||
|
//if (body->getActivationState() != ISLAND_SLEEPING)
|
||||||
|
{
|
||||||
|
if (body->isKinematicObject()) {
|
||||||
|
ObjectMotionState* objectMotionState = static_cast<ObjectMotionState*>(body->getMotionState());
|
||||||
|
if (!objectMotionState->hasInternalKinematicChanges()) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
objectMotionState->clearInternalKinematicChanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
btTransform interpolatedTransform;
|
||||||
|
btTransformUtil::integrateTransform(body->getInterpolationWorldTransform(),
|
||||||
|
body->getInterpolationLinearVelocity(),body->getInterpolationAngularVelocity(),
|
||||||
|
(m_latencyMotionStateInterpolation && m_fixedTimeStep) ? m_localTime - m_fixedTimeStep : m_localTime*body->getHitFraction(),
|
||||||
|
interpolatedTransform);
|
||||||
|
body->getMotionState()->setWorldTransform(interpolatedTransform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ThreadSafeDynamicsWorld::synchronizeMotionStates() {
|
void ThreadSafeDynamicsWorld::synchronizeMotionStates() {
|
||||||
_changedMotionStates.clear();
|
_changedMotionStates.clear();
|
||||||
BT_PROFILE("synchronizeMotionStates");
|
BT_PROFILE("synchronizeMotionStates");
|
||||||
|
@ -97,22 +124,22 @@ void ThreadSafeDynamicsWorld::synchronizeMotionStates() {
|
||||||
btRigidBody* body = btRigidBody::upcast(colObj);
|
btRigidBody* body = btRigidBody::upcast(colObj);
|
||||||
if (body) {
|
if (body) {
|
||||||
if (body->getMotionState()) {
|
if (body->getMotionState()) {
|
||||||
synchronizeSingleMotionState(body);
|
synchronizeMotionState(body);
|
||||||
_changedMotionStates.push_back(static_cast<ObjectMotionState*>(body->getMotionState()));
|
_changedMotionStates.push_back(static_cast<ObjectMotionState*>(body->getMotionState()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//iterate over all active rigid bodies
|
//iterate over all active rigid bodies
|
||||||
for (int i=0;i<m_nonStaticRigidBodies.size();i++) {
|
for (int i=0;i<m_nonStaticRigidBodies.size();i++) {
|
||||||
btRigidBody* body = m_nonStaticRigidBodies[i];
|
btRigidBody* body = m_nonStaticRigidBodies[i];
|
||||||
if (body->isActive()) {
|
if (body->isActive()) {
|
||||||
if (body->getMotionState()) {
|
if (body->getMotionState()) {
|
||||||
synchronizeSingleMotionState(body);
|
synchronizeMotionState(body);
|
||||||
_changedMotionStates.push_back(static_cast<ObjectMotionState*>(body->getMotionState()));
|
_changedMotionStates.push_back(static_cast<ObjectMotionState*>(body->getMotionState()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied warranty.
|
* This software is provided 'as-is', without any express or implied warranty.
|
||||||
* In no event will the authors be held liable for any damages arising from the use of this software.
|
* In no event will the authors be held liable for any damages arising from the use of this software.
|
||||||
* Permission is granted to anyone to use this software for any purpose,
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
* including commercial applications, and to alter it and redistribute it freely,
|
* including commercial applications, and to alter it and redistribute it freely,
|
||||||
* subject to the following restrictions:
|
* subject to the following restrictions:
|
||||||
*
|
*
|
||||||
* 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
* 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||||
|
@ -43,13 +43,16 @@ public:
|
||||||
void synchronizeMotionStates();
|
void synchronizeMotionStates();
|
||||||
|
|
||||||
// btDiscreteDynamicsWorld::m_localTime is the portion of real-time that has not yet been simulated
|
// btDiscreteDynamicsWorld::m_localTime is the portion of real-time that has not yet been simulated
|
||||||
// but is used for MotionState::setWorldTransform() extrapolation (a feature that Bullet uses to provide
|
// but is used for MotionState::setWorldTransform() extrapolation (a feature that Bullet uses to provide
|
||||||
// smoother rendering of objects when the physics simulation loop is ansynchronous to the render loop).
|
// smoother rendering of objects when the physics simulation loop is ansynchronous to the render loop).
|
||||||
float getLocalTimeAccumulation() const { return m_localTime; }
|
float getLocalTimeAccumulation() const { return m_localTime; }
|
||||||
|
|
||||||
VectorOfMotionStates& getChangedMotionStates() { return _changedMotionStates; }
|
VectorOfMotionStates& getChangedMotionStates() { return _changedMotionStates; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// call this instead of non-virtual btDiscreteDynamicsWorld::synchronizeSingleMotionState()
|
||||||
|
void synchronizeMotionState(btRigidBody* body);
|
||||||
|
|
||||||
VectorOfMotionStates _changedMotionStates;
|
VectorOfMotionStates _changedMotionStates;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue