mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-10 05:37:43 +02:00
hack for "reliable" packet send when objects stop moving
This commit is contained in:
parent
0f488bca02
commit
b3731e9530
5 changed files with 53 additions and 16 deletions
|
@ -108,7 +108,7 @@ void EntityMotionState::computeShapeInfo(ShapeInfo& info) {
|
||||||
_entity->computeShapeInfo(info);
|
_entity->computeShapeInfo(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender) {
|
void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_t frame) {
|
||||||
#ifdef USE_BULLET_PHYSICS
|
#ifdef USE_BULLET_PHYSICS
|
||||||
if (_outgoingPacketFlags) {
|
if (_outgoingPacketFlags) {
|
||||||
EntityItemProperties properties = _entity->getProperties();
|
EntityItemProperties properties = _entity->getProperties();
|
||||||
|
@ -165,12 +165,22 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender) {
|
||||||
//properties.setLastEdited(now);
|
//properties.setLastEdited(now);
|
||||||
|
|
||||||
glm::vec3 zero(0.0f);
|
glm::vec3 zero(0.0f);
|
||||||
_sentMoving = (_sentVelocity == zero && _sentAngularVelocity == zero && _sentAcceleration == zero);
|
_sentMoving = !(_sentVelocity == zero && _sentAngularVelocity == zero && _sentAcceleration == zero);
|
||||||
|
// RELIABLE_SEND_HACK: count number of updates for entities at rest so we can stop sending them after some limit.
|
||||||
|
if (_sentMoving) {
|
||||||
|
_numNonMovingUpdates = 0;
|
||||||
|
} else {
|
||||||
|
_numNonMovingUpdates++;
|
||||||
|
}
|
||||||
|
|
||||||
EntityItemID id(_entity->getID());
|
EntityItemID id(_entity->getID());
|
||||||
EntityEditPacketSender* entityPacketSender = static_cast<EntityEditPacketSender*>(packetSender);
|
EntityEditPacketSender* entityPacketSender = static_cast<EntityEditPacketSender*>(packetSender);
|
||||||
entityPacketSender->queueEditEntityMessage(PacketTypeEntityAddOrEdit, id, properties);
|
entityPacketSender->queueEditEntityMessage(PacketTypeEntityAddOrEdit, id, properties);
|
||||||
_outgoingPacketFlags = 0;
|
|
||||||
|
// The outgoing flags only itemized WHAT to send, not WHETHER to send, hence we always set them
|
||||||
|
// to the full set. These flags may be momentarily cleared by incoming external changes.
|
||||||
|
_outgoingPacketFlags = DIRTY_PHYSICS_FLAGS;
|
||||||
|
_sentFrame = frame;
|
||||||
}
|
}
|
||||||
#endif // USE_BULLET_PHYSICS
|
#endif // USE_BULLET_PHYSICS
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ public:
|
||||||
|
|
||||||
void computeShapeInfo(ShapeInfo& info);
|
void computeShapeInfo(ShapeInfo& info);
|
||||||
|
|
||||||
void sendUpdate(OctreeEditPacketSender* packetSender);
|
void sendUpdate(OctreeEditPacketSender* packetSender, uint32_t frame);
|
||||||
|
|
||||||
uint32_t getIncomingDirtyFlags() const { return _entity->getDirtyFlags(); }
|
uint32_t getIncomingDirtyFlags() const { return _entity->getDirtyFlags(); }
|
||||||
void clearIncomingDirtyFlags(uint32_t flags) { _entity->clearDirtyFlags(flags); }
|
void clearIncomingDirtyFlags(uint32_t flags) { _entity->clearDirtyFlags(flags); }
|
||||||
|
|
|
@ -52,8 +52,8 @@ ObjectMotionState::ObjectMotionState() :
|
||||||
_motionType(MOTION_TYPE_STATIC),
|
_motionType(MOTION_TYPE_STATIC),
|
||||||
_body(NULL),
|
_body(NULL),
|
||||||
_sentMoving(false),
|
_sentMoving(false),
|
||||||
_weKnowRecipientHasReceivedNotMoving(false),
|
_numNonMovingUpdates(0),
|
||||||
_outgoingPacketFlags(0),
|
_outgoingPacketFlags(DIRTY_PHYSICS_FLAGS),
|
||||||
_sentFrame(0),
|
_sentFrame(0),
|
||||||
_sentPosition(0.0f),
|
_sentPosition(0.0f),
|
||||||
_sentRotation(),
|
_sentRotation(),
|
||||||
|
@ -109,21 +109,48 @@ void ObjectMotionState::getAngularVelocity(glm::vec3& angularVelocityOut) const
|
||||||
bulletToGLM(_body->getAngularVelocity(), angularVelocityOut);
|
bulletToGLM(_body->getAngularVelocity(), angularVelocityOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RELIABLE_SEND_HACK: until we have truly reliable resends of non-moving updates
|
||||||
|
// we alwasy resend packets for objects that have stopped moving up to some max limit.
|
||||||
|
const int MAX_NUM_NON_MOVING_UPDATES = 5;
|
||||||
|
|
||||||
|
bool ObjectMotionState::doesNotNeedToSendUpdate() const {
|
||||||
|
return !_body->isActive() && _numNonMovingUpdates > MAX_NUM_NON_MOVING_UPDATES;
|
||||||
|
}
|
||||||
|
|
||||||
const float FIXED_SUBSTEP = 1.0f / 60.0f;
|
const float FIXED_SUBSTEP = 1.0f / 60.0f;
|
||||||
|
|
||||||
bool ObjectMotionState::shouldSendUpdate(uint32_t simulationFrame, float subStepRemainder) const {
|
bool ObjectMotionState::shouldSendUpdate(uint32_t simulationFrame, float subStepRemainder) const {
|
||||||
assert(_body);
|
assert(_body);
|
||||||
float dt = (float)(simulationFrame - _sentFrame) * FIXED_SUBSTEP + subStepRemainder;
|
float dt = (float)(simulationFrame - _sentFrame) * FIXED_SUBSTEP + subStepRemainder;
|
||||||
const float DEFAULT_UPDATE_PERIOD = 10.0f;
|
bool isActive = _body->isActive();
|
||||||
if (dt > DEFAULT_UPDATE_PERIOD || (_sentMoving && !_body->isActive())) {
|
|
||||||
return true;
|
if (isActive) {
|
||||||
|
const float MAX_UPDATE_PERIOD_FOR_ACTIVE_THINGS = 10.0f;
|
||||||
|
if (dt > MAX_UPDATE_PERIOD_FOR_ACTIVE_THINGS) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (_sentMoving) {
|
||||||
|
if (!isActive) {
|
||||||
|
// this object just went inactive so send an update immediately
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const float NON_MOVING_UPDATE_PERIOD = 1.0f;
|
||||||
|
if (dt > NON_MOVING_UPDATE_PERIOD && _numNonMovingUpdates < MAX_NUM_NON_MOVING_UPDATES) {
|
||||||
|
// RELIABLE_SEND_HACK: since we're not yet using a reliable method for non-moving update packets we repeat these
|
||||||
|
// at a faster rate than the MAX period above, and only send a limited number of them.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Else we measure the error between current and extrapolated transform (according to expected behavior
|
// Else we measure the error between current and extrapolated transform (according to expected behavior
|
||||||
// of remote EntitySimulation) and return true if the error is significant.
|
// of remote EntitySimulation) and return true if the error is significant.
|
||||||
|
|
||||||
// NOTE: math in done the simulation-frame, which is NOT necessarily the same as the world-frame
|
// NOTE: math in done the simulation-frame, which is NOT necessarily the same as the world-frame
|
||||||
// due to _worldOffset.
|
// due to _worldOffset.
|
||||||
|
|
||||||
|
// TODO: Andrew to reconcile Bullet and legacy damping coefficients.
|
||||||
|
|
||||||
// compute position error
|
// compute position error
|
||||||
glm::vec3 extrapolatedPosition = _sentPosition + dt * (_sentVelocity + (0.5f * dt) * _sentAcceleration);
|
glm::vec3 extrapolatedPosition = _sentPosition + dt * (_sentVelocity + (0.5f * dt) * _sentAcceleration);
|
||||||
|
|
||||||
|
@ -131,7 +158,7 @@ bool ObjectMotionState::shouldSendUpdate(uint32_t simulationFrame, float subStep
|
||||||
btTransform worldTrans = _body->getWorldTransform();
|
btTransform worldTrans = _body->getWorldTransform();
|
||||||
bulletToGLM(worldTrans.getOrigin(), position);
|
bulletToGLM(worldTrans.getOrigin(), position);
|
||||||
|
|
||||||
float dx2 = glm::length2(position - extrapolatedPosition);
|
float dx2 = glm::distance2(position, extrapolatedPosition);
|
||||||
const float MAX_POSITION_ERROR_SQUARED = 0.001f; // 0.001 m^2 ~~> 0.03 m
|
const float MAX_POSITION_ERROR_SQUARED = 0.001f; // 0.001 m^2 ~~> 0.03 m
|
||||||
if (dx2 > MAX_POSITION_ERROR_SQUARED) {
|
if (dx2 > MAX_POSITION_ERROR_SQUARED) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -81,9 +81,9 @@ public:
|
||||||
virtual void clearIncomingDirtyFlags(uint32_t flags) = 0;
|
virtual void clearIncomingDirtyFlags(uint32_t flags) = 0;
|
||||||
void clearOutgoingPacketFlags(uint32_t flags) { _outgoingPacketFlags &= ~flags; }
|
void clearOutgoingPacketFlags(uint32_t flags) { _outgoingPacketFlags &= ~flags; }
|
||||||
|
|
||||||
bool doesNotNeedToSendUpdate() const { return !_body->isActive() && _weKnowRecipientHasReceivedNotMoving; }
|
bool doesNotNeedToSendUpdate() const;
|
||||||
virtual bool shouldSendUpdate(uint32_t simulationFrame, float subStepRemainder) const;
|
virtual bool shouldSendUpdate(uint32_t simulationFrame, float subStepRemainder) const;
|
||||||
virtual void sendUpdate(OctreeEditPacketSender* packetSender) = 0;
|
virtual void sendUpdate(OctreeEditPacketSender* packetSender, uint32_t frame) = 0;
|
||||||
|
|
||||||
virtual MotionType computeMotionType() const = 0;
|
virtual MotionType computeMotionType() const = 0;
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ protected:
|
||||||
btRigidBody* _body;
|
btRigidBody* _body;
|
||||||
|
|
||||||
bool _sentMoving; // true if last update was moving
|
bool _sentMoving; // true if last update was moving
|
||||||
bool _weKnowRecipientHasReceivedNotMoving;
|
int _numNonMovingUpdates; // RELIABLE_SEND_HACK for "not so reliable" resends of packets for non-moving objects
|
||||||
|
|
||||||
uint32_t _outgoingPacketFlags;
|
uint32_t _outgoingPacketFlags;
|
||||||
uint32_t _sentFrame;
|
uint32_t _sentFrame;
|
||||||
|
|
|
@ -13,9 +13,9 @@
|
||||||
// TODO DONE: make MotionState::setWorldTransform() put itself on _incomingChanges list
|
// TODO DONE: make MotionState::setWorldTransform() put itself on _incomingChanges list
|
||||||
// TODO DONE: give PhysicsEngine instance an _entityPacketSender
|
// TODO DONE: give PhysicsEngine instance an _entityPacketSender
|
||||||
// TODO DONE: make sure code compiles when BULLET is not found
|
// TODO DONE: make sure code compiles when BULLET is not found
|
||||||
// TODO: make sure incoming and outgoing pipelines are connected
|
// TODO DONE: make sure incoming and outgoing pipelines are connected
|
||||||
// TODO: provide some sort of "reliable" send for "stopped" update
|
|
||||||
// TODO: test entity updates (second viewer sees physics results from first)
|
// TODO: test entity updates (second viewer sees physics results from first)
|
||||||
|
// TODO: provide some sort of "reliable" send for "stopped" update
|
||||||
|
|
||||||
#include "PhysicsEngine.h"
|
#include "PhysicsEngine.h"
|
||||||
#ifdef USE_BULLET_PHYSICS
|
#ifdef USE_BULLET_PHYSICS
|
||||||
|
@ -57,7 +57,7 @@ void PhysicsEngine::updateEntitiesInternal(const quint64& now) {
|
||||||
if (state->doesNotNeedToSendUpdate()) {
|
if (state->doesNotNeedToSendUpdate()) {
|
||||||
stateItr = _outgoingPackets.erase(stateItr);
|
stateItr = _outgoingPackets.erase(stateItr);
|
||||||
} else if (state->shouldSendUpdate(frame, subStepRemainder)) {
|
} else if (state->shouldSendUpdate(frame, subStepRemainder)) {
|
||||||
state->sendUpdate(_entityPacketSender);
|
state->sendUpdate(_entityPacketSender, frame);
|
||||||
++stateItr;
|
++stateItr;
|
||||||
} else {
|
} else {
|
||||||
++stateItr;
|
++stateItr;
|
||||||
|
|
Loading…
Reference in a new issue