Merge pull request #4994 from AndrewMeadows/isentropic

compute correct deltaTime for extrapolation of moving entity and other fixes
This commit is contained in:
Philip Rosedale 2015-05-29 16:07:10 -07:00
commit 6b9f6ff7bb
6 changed files with 61 additions and 23 deletions

View file

@ -112,8 +112,6 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
PerformanceTimer perfTimer("RMEIrender");
assert(getType() == EntityTypes::Model);
bool drawAsModel = hasModel();
glm::vec3 position = getPosition();
glm::vec3 dimensions = getDimensions();
@ -125,8 +123,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
highlightSimulationOwnership = (getSimulatorID() == myNodeID);
}
bool didDraw = false;
if (drawAsModel && !highlightSimulationOwnership) {
if (hasModel()) {
remapTextures();
glPushMatrix();
{
@ -179,19 +176,20 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
if (args && (args->_renderMode == RenderArgs::SHADOW_RENDER_MODE)) {
if (movingOrAnimating) {
_model->renderInScene(alpha, args);
didDraw = true;
}
} else {
_model->renderInScene(alpha, args);
didDraw = true;
}
}
}
}
glPopMatrix();
}
if (!didDraw) {
if (highlightSimulationOwnership) {
glm::vec4 greenColor(0.0f, 1.0f, 0.0f, 1.0f);
RenderableDebugableEntityItem::renderBoundingBox(this, args, 0.0f, greenColor);
}
} else {
glm::vec4 greenColor(0.0f, 1.0f, 0.0f, 1.0f);
RenderableDebugableEntityItem::renderBoundingBox(this, args, 0.0f, greenColor);
}

View file

@ -480,17 +480,21 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
bytesRead += encodedUpdateDelta.size();
// Newer bitstreams will have a last simulated and a last updated value
quint64 lastSimulatedFromBufferAdjusted = now;
if (args.bitstreamVersion >= VERSION_ENTITIES_HAS_LAST_SIMULATED_TIME) {
// last simulated is stored as ByteCountCoded delta from lastEdited
QByteArray encodedSimulatedDelta = originalDataBuffer.mid(bytesRead); // maximum possible size
ByteCountCoded<quint64> simulatedDeltaCoder = encodedSimulatedDelta;
quint64 simulatedDelta = simulatedDeltaCoder;
if (overwriteLocalData) {
_lastSimulated = lastEditedFromBufferAdjusted + simulatedDelta; // don't adjust for clock skew since we already did that
lastSimulatedFromBufferAdjusted = lastEditedFromBufferAdjusted + simulatedDelta; // don't adjust for clock skew since we already did that
if (lastSimulatedFromBufferAdjusted > now) {
lastSimulatedFromBufferAdjusted = now;
}
#ifdef WANT_DEBUG
qCDebug(entities) << " _lastSimulated:" << debugTime(_lastSimulated, now);
qCDebug(entities) << " _lastEdited:" << debugTime(_lastEdited, now);
qCDebug(entities) << " lastEditedFromBufferAdjusted:" << debugTime(lastEditedFromBufferAdjusted, now);
qCDebug(entities) << " lastSimulatedFromBufferAdjusted:" << debugTime(lastSimulatedFromBufferAdjusted, now);
#endif
}
encodedSimulatedDelta = simulatedDeltaCoder; // determine true length
@ -606,8 +610,8 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
// use our simulation helper routine to get a best estimate of where the entity should be.
const float MIN_TIME_SKIP = 0.0f;
const float MAX_TIME_SKIP = 1.0f; // in seconds
float skipTimeForward = glm::clamp((float)(now - _lastSimulated) / (float)(USECS_PER_SECOND),
MIN_TIME_SKIP, MAX_TIME_SKIP);
float skipTimeForward = glm::clamp((float)(now - lastSimulatedFromBufferAdjusted) / (float)(USECS_PER_SECOND),
MIN_TIME_SKIP, MAX_TIME_SKIP);
if (skipTimeForward > 0.0f) {
#ifdef WANT_DEBUG
qCDebug(entities) << "skipTimeForward:" << skipTimeForward;
@ -617,19 +621,22 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
// we don't want the side effect of flag setting.
simulateKinematicMotion(skipTimeForward, false);
}
_lastSimulated = now;
}
auto nodeList = DependencyManager::get<NodeList>();
const QUuid& myNodeID = nodeList->getSessionUUID();
if (overwriteLocalData && _simulatorID == myNodeID && !_simulatorID.isNull()) {
// we own the simulation, so we keep our transform+velocities and remove any related dirty flags
// rather than accept the values in the packet
_position = savePosition;
_rotation = saveRotation;
_velocity = saveVelocity;
_angularVelocity = saveAngularVelocity;
_dirtyFlags &= ~(EntityItem::DIRTY_TRANSFORM | EntityItem::DIRTY_VELOCITIES);
if (overwriteLocalData) {
if (_simulatorID == myNodeID && !_simulatorID.isNull()) {
// we own the simulation, so we keep our transform+velocities and remove any related dirty flags
// rather than accept the values in the packet
_position = savePosition;
_rotation = saveRotation;
_velocity = saveVelocity;
_angularVelocity = saveAngularVelocity;
_dirtyFlags &= ~(EntityItem::DIRTY_TRANSFORM | EntityItem::DIRTY_VELOCITIES);
} else {
_lastSimulated = now;
}
}
return bytesRead;
@ -918,6 +925,21 @@ EntityItemProperties EntityItem::getProperties() const {
return properties;
}
void EntityItem::getAllTerseUpdateProperties(EntityItemProperties& properties) const {
// a TerseUpdate includes the transform and its derivatives
properties._position = _position;
properties._velocity = _velocity;
properties._rotation = _rotation;
properties._angularVelocity = _angularVelocity;
properties._acceleration = _acceleration;
properties._positionChanged = true;
properties._velocityChanged = true;
properties._rotationChanged = true;
properties._angularVelocityChanged = true;
properties._accelerationChanged = true;
}
bool EntityItem::setProperties(const EntityItemProperties& properties) {
bool somethingChanged = false;

View file

@ -347,6 +347,8 @@ public:
quint64 getLastEditedFromRemote() { return _lastEditedFromRemote; }
void getAllTerseUpdateProperties(EntityItemProperties& properties) const;
protected:
static bool _sendPhysicsUpdates;

View file

@ -1156,4 +1156,7 @@ AABox EntityItemProperties::getAABox() const {
return AABox(rotatedExtentsRelativeToRegistrationPoint);
}
bool EntityItemProperties::hasTerseUpdateChanges() const {
// a TerseUpdate includes the transform and its derivatives
return _positionChanged || _velocityChanged || _rotationChanged || _angularVelocityChanged || _accelerationChanged;
}

View file

@ -195,6 +195,8 @@ public:
void setVoxelDataDirty() { _voxelDataChanged = true; }
bool hasTerseUpdateChanges() const;
private:
QUuid _id;
bool _idSet;
@ -215,6 +217,7 @@ private:
QStringList _textureNames;
glm::vec3 _naturalDimensions;
};
Q_DECLARE_METATYPE(EntityItemProperties);
QScriptValue EntityItemPropertiesToScriptValue(QScriptEngine* engine, const EntityItemProperties& properties);
QScriptValue EntityItemNonDefaultPropertiesToScriptValue(QScriptEngine* engine, const EntityItemProperties& properties);

View file

@ -146,7 +146,17 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties&
EntityItemProperties modifiedProperties = properties;
entity->setLastBroadcast(usecTimestampNow());
modifiedProperties.setType(entity->getType());
bidForSimulationOwnership(modifiedProperties);
if (modifiedProperties.hasTerseUpdateChanges()) {
// we make a bid for (or assert) our simulation ownership
auto nodeList = DependencyManager::get<NodeList>();
const QUuid myNodeID = nodeList->getSessionUUID();
modifiedProperties.setSimulatorID(myNodeID);
if (entity->getSimulatorID() == myNodeID) {
// we think we already own simulation, so make sure we send ALL TerseUpdate properties
entity->getAllTerseUpdateProperties(modifiedProperties);
}
}
queueEntityMessage(PacketTypeEntityEdit, entityID, modifiedProperties);
return id;
}