move worldOffset into ObjectMotionState

add more methods for getting/clearing incoming/outgoing flags
This commit is contained in:
Andrew Meadows 2014-12-11 10:52:34 -08:00
parent d9f183458a
commit 11f1ad1d7f
4 changed files with 36 additions and 28 deletions

View file

@ -17,20 +17,6 @@
#endif // USE_BULLET_PHYSICS
#include "EntityMotionState.h"
// TODO: store _worldOffset in a more central location -- VoxelTree and others also need to know about it
// origin of physics simulation in world frame
glm::vec3 _worldOffset(0.0f);
// static
void EntityMotionState::setWorldOffset(const glm::vec3& offset) {
_worldOffset = offset;
}
// static
const glm::vec3& getWorldOffset() {
return _worldOffset;
}
EntityMotionState::EntityMotionState(EntityItem* entity)
: _entity(entity),
_outgoingPhysicsDirtyFlags(0) {
@ -55,14 +41,12 @@ MotionType EntityMotionState::computeMotionType() const {
// it is an opportunity for outside code to update the object's simulation position
void EntityMotionState::getWorldTransform (btTransform &worldTrans) const {
btVector3 pos;
glmToBullet(_entity->getPositionInMeters() - _worldOffset, pos);
glmToBullet(_entity->getPositionInMeters() - ObjectMotionState::getWorldOffset(), pos);
worldTrans.setOrigin(pos);
btQuaternion rot;
glmToBullet(_entity->getRotation(), rot);
worldTrans.setRotation(rot);
applyVelocities();
}
// This callback is invoked by the physics simulation at the end of each simulation frame...
@ -72,7 +56,7 @@ void EntityMotionState::setWorldTransform (const btTransform &worldTrans) {
if (! (dirytFlags & EntityItem::DIRTY_POSITION)) {
glm::vec3 pos;
bulletToGLM(worldTrans.getOrigin(), pos);
_entity->setPositionInMeters(pos + _worldOffset);
_entity->setPositionInMeters(pos + ObjectMotionState::getWorldOffset());
glm::quat rot;
bulletToGLM(worldTrans.getRotation(), rot);
@ -122,7 +106,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender) {
btTransform worldTrans = _body->getWorldTransform();
bulletToGLM(worldTrans.getOrigin(), _sentPosition);
properties.setPosition(_sentPosition);
properties.setPosition(_sentPosition + ObjectMotionState::getWorldOffset());
bulletToGLM(worldTrans.getRotation(), _sentRotation);
properties.setRotation(_sentRotation);
@ -144,7 +128,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender) {
if (_outgoingPhysicsDirtyFlags & EntityItem::DIRTY_POSITION) {
btTransform worldTrans = _body->getWorldTransform();
bulletToGLM(worldTrans.getOrigin(), _sentPosition);
properties.setPosition(_sentPosition);
properties.setPosition(_sentPosition + ObjectMotionState::getWorldOffset());
bulletToGLM(worldTrans.getRotation(), _sentRotation);
properties.setRotation(_sentRotation);

View file

@ -32,14 +32,6 @@ class EntityItem;
class EntityMotionState : public ObjectMotionState {
public:
// The WorldOffset is used to keep the positions of objects in the simulation near the origin, to
// reduce numerical error when computing vector differences. In other words: The EntityMotionState
// class translates between the simulation-frame and the world-frame as known by the render pipeline,
// various object trees, etc. The EntityMotionState class uses a static "worldOffset" to help in
// the translations.
static void setWorldOffset(const glm::vec3& offset);
static const glm::vec3& getWorldOffset();
EntityMotionState(EntityItem* item);
virtual ~EntityMotionState();
@ -62,6 +54,10 @@ public:
void sendUpdate(OctreeEditPacketSender* packetSender);
uint32_t getIncomingDirtyFlags() const { return _entity->getDirtyFlags(); }
void clearIncomingDirtyFlags(uint32_t flags) { _entity->clearDirtyFlags(flags); }
void clearConflictingDirtyFlags() { _outgoingDirtyFlags &= ~_entity->getDirtyFlags(); }
protected:
EntityItem* _entity;
uint32_t _outgoingPhysicsDirtyFlags;

View file

@ -29,6 +29,19 @@ const float MAX_FRICTION = 10.0f;
const float DEFAULT_RESTITUTION = 0.0f;
// origin of physics simulation in world frame
glm::vec3 _worldOffset(0.0f);
// static
void ObjectMotionState::setWorldOffset(const glm::vec3& offset) {
_worldOffset = offset;
}
// static
const glm::vec3& ObjectMotionState::getWorldOffset() {
return _worldOffset;
}
ObjectMotionState::ObjectMotionState() :
_density(DEFAULT_DENSITY),
_volume(DEFAULT_VOLUME),
@ -108,6 +121,9 @@ bool ObjectMotionState::shouldSendUpdate(uint32_t simulationFrame, float subStep
return true;
}
// NOTE: math in done the simulation-frame, which is NOT necessarily the same
// as the world-frame due to _worldOffset
// compute position error
glm::vec3 expectedPosition = _sentPosition + dt * (_sentVelocity + (0.5f * dt) * _sentAcceleration);

View file

@ -43,6 +43,14 @@ class OctreeEditPacketSender;
class ObjectMotionState : public btMotionState {
public:
// The WorldOffset is used to keep the positions of objects in the simulation near the origin, to
// reduce numerical error when computing vector differences. In other words: The EntityMotionState
// class translates between the simulation-frame and the world-frame as known by the render pipeline,
// various object trees, etc. The EntityMotionState class uses a static "worldOffset" to help in
// the translations.
static void setWorldOffset(const glm::vec3& offset);
static const glm::vec3& getWorldOffset();
ObjectMotionState();
~ObjectMotionState();
@ -71,7 +79,11 @@ public:
void getVelocity(glm::vec3& velocityOut) const;
void getAngularVelocity(glm::vec3& angularVelocityOut) const;
virtual uint32_t getIncomingDirtyFlags() const = 0;
virtual void clearIncomingDirtyFlags(uint32_t flags) = 0;
void clearOutgoingDirtyFlags(uint32_t flags) { _outgoingDirtyFlags &= ~flags; }
virtual void clearConflictingDirtyFlags() = 0;
bool isAtRest() const { return !(_body->isActive()) && _weKnowRecipientHasReceivedNotMoving; }
virtual bool shouldSendUpdate(uint32_t simulationFrame, float subStepRemainder) const;
virtual void sendUpdate(OctreeEditPacketSender* packetSender) = 0;