Merge pull request #4794 from AndrewMeadows/nova

fix crash when script deletes entity
This commit is contained in:
Seth Alves 2015-05-07 16:12:14 -07:00
commit 70cfd5a2a5
6 changed files with 85 additions and 98 deletions

View file

@ -1105,23 +1105,6 @@ void EntityItem::computeShapeInfo(ShapeInfo& info) {
info.setParams(getShapeType(), 0.5f * getDimensions());
}
// these thesholds determine what updates will be ignored (client and server)
const float IGNORE_POSITION_DELTA = 0.0001f;
const float IGNORE_DIMENSIONS_DELTA = 0.0005f;
const float IGNORE_ALIGNMENT_DOT = 0.99997f;
const float IGNORE_LINEAR_VELOCITY_DELTA = 0.001f;
const float IGNORE_DAMPING_DELTA = 0.001f;
const float IGNORE_GRAVITY_DELTA = 0.001f;
const float IGNORE_ANGULAR_VELOCITY_DELTA = 0.0002f;
// these thresholds determine what updates will activate the physical object
const float ACTIVATION_POSITION_DELTA = 0.005f;
const float ACTIVATION_DIMENSIONS_DELTA = 0.005f;
const float ACTIVATION_ALIGNMENT_DOT = 0.99990f;
const float ACTIVATION_LINEAR_VELOCITY_DELTA = 0.01f;
const float ACTIVATION_GRAVITY_DELTA = 0.1f;
const float ACTIVATION_ANGULAR_VELOCITY_DELTA = 0.03f;
void EntityItem::updatePositionInDomainUnits(const glm::vec3& value) {
glm::vec3 position = value * (float)TREE_SCALE;
updatePosition(position);

View file

@ -32,6 +32,24 @@ class EntitySimulation;
class EntityTreeElement;
class EntityTreeElementExtraEncodeData;
// these thesholds determine what updates will be ignored (client and server)
const float IGNORE_POSITION_DELTA = 0.0001f;
const float IGNORE_DIMENSIONS_DELTA = 0.0005f;
const float IGNORE_ALIGNMENT_DOT = 0.99997f;
const float IGNORE_LINEAR_VELOCITY_DELTA = 0.001f;
const float IGNORE_DAMPING_DELTA = 0.001f;
const float IGNORE_GRAVITY_DELTA = 0.001f;
const float IGNORE_ANGULAR_VELOCITY_DELTA = 0.0002f;
// these thresholds determine what updates will activate the physical object
const float ACTIVATION_POSITION_DELTA = 0.005f;
const float ACTIVATION_DIMENSIONS_DELTA = 0.005f;
const float ACTIVATION_ALIGNMENT_DOT = 0.99990f;
const float ACTIVATION_LINEAR_VELOCITY_DELTA = 0.01f;
const float ACTIVATION_GRAVITY_DELTA = 0.1f;
const float ACTIVATION_ANGULAR_VELOCITY_DELTA = 0.03f;
#define DONT_ALLOW_INSTANTIATION virtual void pureVirtualFunctionPlaceHolder() = 0;
#define ALLOW_INSTANTIATION virtual void pureVirtualFunctionPlaceHolder() { };
@ -395,14 +413,4 @@ protected:
bool _simulated; // set by EntitySimulation
};
extern const float IGNORE_POSITION_DELTA;
extern const float IGNORE_DIMENSIONS_DELTA;
extern const float IGNORE_ALIGNMENT_DOT;
extern const float IGNORE_LINEAR_VELOCITY_DELTA;
extern const float IGNORE_DAMPING_DELTA;
extern const float IGNORE_GRAVITY_DELTA;
extern const float IGNORE_ANGULAR_VELOCITY_DELTA;
#endif // hifi_EntityItem_h

View file

@ -12,6 +12,7 @@
#ifndef hifi_EntityTree_h
#define hifi_EntityTree_h
#include <QSet>
#include <QVector>
#include <Octree.h>

View file

@ -27,13 +27,13 @@ EntityMotionState::EntityMotionState(btCollisionShape* shape, EntityItem* entity
_entity(entity),
_sentMoving(false),
_numNonMovingUpdates(0),
_sentStep(0),
_sentPosition(0.0f),
_sentRotation(),
_sentVelocity(0.0f),
_sentAngularVelocity(0.0f),
_sentGravity(0.0f),
_sentAcceleration(0.0f),
_lastStep(0),
_serverPosition(0.0f),
_serverRotation(),
_serverVelocity(0.0f),
_serverAngularVelocity(0.0f),
_serverGravity(0.0f),
_serverAcceleration(0.0f),
_accelerationNearlyGravityCount(0),
_shouldClaimSimulationOwnership(false),
_movingStepsWithoutSimulationOwner(0)
@ -49,16 +49,16 @@ EntityMotionState::~EntityMotionState() {
void EntityMotionState::updateServerPhysicsVariables(uint32_t flags) {
if (flags & EntityItem::DIRTY_POSITION) {
_sentPosition = _entity->getPosition();
_serverPosition = _entity->getPosition();
}
if (flags & EntityItem::DIRTY_ROTATION) {
_sentRotation = _entity->getRotation();
_serverRotation = _entity->getRotation();
}
if (flags & EntityItem::DIRTY_LINEAR_VELOCITY) {
_sentVelocity = _entity->getVelocity();
_serverVelocity = _entity->getVelocity();
}
if (flags & EntityItem::DIRTY_ANGULAR_VELOCITY) {
_sentAngularVelocity = _entity->getAngularVelocity();
_serverAngularVelocity = _entity->getAngularVelocity();
}
}
@ -96,8 +96,8 @@ bool EntityMotionState::isMoving() const {
}
bool EntityMotionState::isMovingVsServer() const {
auto alignmentDot = glm::abs(glm::dot(_sentRotation, _entity->getRotation()));
if (glm::distance(_sentPosition, _entity->getPosition()) > IGNORE_POSITION_DELTA ||
auto alignmentDot = glm::abs(glm::dot(_serverRotation, _entity->getRotation()));
if (glm::distance(_serverPosition, _entity->getPosition()) > IGNORE_POSITION_DELTA ||
alignmentDot < IGNORE_ALIGNMENT_DOT) {
return true;
}
@ -183,26 +183,26 @@ bool EntityMotionState::doesNotNeedToSendUpdate() const {
bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) {
assert(_body);
// if we've never checked before, our _sentStep will be 0, and we need to initialize our state
if (_sentStep == 0) {
// if we've never checked before, our _lastStep will be 0, and we need to initialize our state
if (_lastStep == 0) {
btTransform xform = _body->getWorldTransform();
_sentPosition = bulletToGLM(xform.getOrigin());
_sentRotation = bulletToGLM(xform.getRotation());
_sentVelocity = bulletToGLM(_body->getLinearVelocity());
_sentAngularVelocity = bulletToGLM(_body->getAngularVelocity());
_sentStep = simulationStep;
_serverPosition = bulletToGLM(xform.getOrigin());
_serverRotation = bulletToGLM(xform.getRotation());
_serverVelocity = bulletToGLM(_body->getLinearVelocity());
_serverAngularVelocity = bulletToGLM(_body->getAngularVelocity());
_lastStep = simulationStep;
return false;
}
#ifdef WANT_DEBUG
glm::vec3 wasPosition = _sentPosition;
glm::quat wasRotation = _sentRotation;
glm::vec3 wasAngularVelocity = _sentAngularVelocity;
glm::vec3 wasPosition = _serverPosition;
glm::quat wasRotation = _serverRotation;
glm::vec3 wasAngularVelocity = _serverAngularVelocity;
#endif
int numSteps = simulationStep - _sentStep;
int numSteps = simulationStep - _lastStep;
float dt = (float)(numSteps) * PHYSICS_ENGINE_FIXED_SUBSTEP;
_sentStep = simulationStep;
_lastStep = simulationStep;
bool isActive = _body->isActive();
if (!isActive) {
@ -226,16 +226,16 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) {
// due to _worldOffset.
// compute position error
if (glm::length2(_sentVelocity) > 0.0f) {
_sentVelocity += _sentAcceleration * dt;
_sentVelocity *= powf(1.0f - _body->getLinearDamping(), dt);
_sentPosition += dt * _sentVelocity;
if (glm::length2(_serverVelocity) > 0.0f) {
_serverVelocity += _serverAcceleration * dt;
_serverVelocity *= powf(1.0f - _body->getLinearDamping(), dt);
_serverPosition += dt * _serverVelocity;
}
btTransform worldTrans = _body->getWorldTransform();
glm::vec3 position = bulletToGLM(worldTrans.getOrigin());
float dx2 = glm::distance2(position, _sentPosition);
float dx2 = glm::distance2(position, _serverPosition);
const float MAX_POSITION_ERROR_SQUARED = 0.001f; // 0.001 m^2 ~~> 0.03 m
if (dx2 > MAX_POSITION_ERROR_SQUARED) {
@ -244,44 +244,44 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) {
qCDebug(physics) << ".... (dx2 > MAX_POSITION_ERROR_SQUARED) ....";
qCDebug(physics) << "wasPosition:" << wasPosition;
qCDebug(physics) << "bullet position:" << position;
qCDebug(physics) << "_sentPosition:" << _sentPosition;
qCDebug(physics) << "_serverPosition:" << _serverPosition;
qCDebug(physics) << "dx2:" << dx2;
#endif
return true;
}
if (glm::length2(_sentAngularVelocity) > 0.0f) {
if (glm::length2(_serverAngularVelocity) > 0.0f) {
// compute rotation error
float attenuation = powf(1.0f - _body->getAngularDamping(), dt);
_sentAngularVelocity *= attenuation;
_serverAngularVelocity *= attenuation;
// Bullet caps the effective rotation velocity inside its rotation integration step, therefore
// we must integrate with the same algorithm and timestep in order achieve similar results.
for (int i = 0; i < numSteps; ++i) {
_sentRotation = glm::normalize(computeBulletRotationStep(_sentAngularVelocity, PHYSICS_ENGINE_FIXED_SUBSTEP) * _sentRotation);
_serverRotation = glm::normalize(computeBulletRotationStep(_serverAngularVelocity, PHYSICS_ENGINE_FIXED_SUBSTEP) * _serverRotation);
}
}
const float MIN_ROTATION_DOT = 0.99f; // 0.99 dot threshold coresponds to about 16 degrees of slop
glm::quat actualRotation = bulletToGLM(worldTrans.getRotation());
#ifdef WANT_DEBUG
if ((fabsf(glm::dot(actualRotation, _sentRotation)) < MIN_ROTATION_DOT)) {
qCDebug(physics) << ".... ((fabsf(glm::dot(actualRotation, _sentRotation)) < MIN_ROTATION_DOT)) ....";
if ((fabsf(glm::dot(actualRotation, _serverRotation)) < MIN_ROTATION_DOT)) {
qCDebug(physics) << ".... ((fabsf(glm::dot(actualRotation, _serverRotation)) < MIN_ROTATION_DOT)) ....";
qCDebug(physics) << "wasAngularVelocity:" << wasAngularVelocity;
qCDebug(physics) << "_sentAngularVelocity:" << _sentAngularVelocity;
qCDebug(physics) << "_serverAngularVelocity:" << _serverAngularVelocity;
qCDebug(physics) << "length wasAngularVelocity:" << glm::length(wasAngularVelocity);
qCDebug(physics) << "length _sentAngularVelocity:" << glm::length(_sentAngularVelocity);
qCDebug(physics) << "length _serverAngularVelocity:" << glm::length(_serverAngularVelocity);
qCDebug(physics) << "wasRotation:" << wasRotation;
qCDebug(physics) << "bullet actualRotation:" << actualRotation;
qCDebug(physics) << "_sentRotation:" << _sentRotation;
qCDebug(physics) << "_serverRotation:" << _serverRotation;
}
#endif
return (fabsf(glm::dot(actualRotation, _sentRotation)) < MIN_ROTATION_DOT);
return (fabsf(glm::dot(actualRotation, _serverRotation)) < MIN_ROTATION_DOT);
}
bool EntityMotionState::shouldSendUpdate(uint32_t simulationFrame) {
@ -335,42 +335,42 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_
}
btTransform worldTrans = _body->getWorldTransform();
_sentPosition = bulletToGLM(worldTrans.getOrigin());
properties.setPosition(_sentPosition + ObjectMotionState::getWorldOffset());
_serverPosition = bulletToGLM(worldTrans.getOrigin());
properties.setPosition(_serverPosition + ObjectMotionState::getWorldOffset());
_sentRotation = bulletToGLM(worldTrans.getRotation());
properties.setRotation(_sentRotation);
_serverRotation = bulletToGLM(worldTrans.getRotation());
properties.setRotation(_serverRotation);
bool zeroSpeed = true;
bool zeroSpin = true;
if (_body->isActive()) {
_sentVelocity = bulletToGLM(_body->getLinearVelocity());
_sentAngularVelocity = bulletToGLM(_body->getAngularVelocity());
_serverVelocity = bulletToGLM(_body->getLinearVelocity());
_serverAngularVelocity = bulletToGLM(_body->getAngularVelocity());
// if the speeds are very small we zero them out
const float MINIMUM_EXTRAPOLATION_SPEED_SQUARED = 1.0e-4f; // 1cm/sec
zeroSpeed = (glm::length2(_sentVelocity) < MINIMUM_EXTRAPOLATION_SPEED_SQUARED);
zeroSpeed = (glm::length2(_serverVelocity) < MINIMUM_EXTRAPOLATION_SPEED_SQUARED);
if (zeroSpeed) {
_sentVelocity = glm::vec3(0.0f);
_serverVelocity = glm::vec3(0.0f);
}
const float MINIMUM_EXTRAPOLATION_SPIN_SQUARED = 0.004f; // ~0.01 rotation/sec
zeroSpin = glm::length2(_sentAngularVelocity) < MINIMUM_EXTRAPOLATION_SPIN_SQUARED;
zeroSpin = glm::length2(_serverAngularVelocity) < MINIMUM_EXTRAPOLATION_SPIN_SQUARED;
if (zeroSpin) {
_sentAngularVelocity = glm::vec3(0.0f);
_serverAngularVelocity = glm::vec3(0.0f);
}
_sentMoving = ! (zeroSpeed && zeroSpin);
} else {
_sentVelocity = _sentAngularVelocity = glm::vec3(0.0f);
_serverVelocity = _serverAngularVelocity = glm::vec3(0.0f);
_sentMoving = false;
}
properties.setVelocity(_sentVelocity);
_sentGravity = _entity->getGravity();
properties.setVelocity(_serverVelocity);
_serverGravity = _entity->getGravity();
properties.setGravity(_entity->getGravity());
_sentAcceleration = _entity->getAcceleration();
properties.setAcceleration(_sentAcceleration);
properties.setAngularVelocity(_sentAngularVelocity);
_serverAcceleration = _entity->getAcceleration();
properties.setAcceleration(_serverAcceleration);
properties.setAngularVelocity(_serverAngularVelocity);
auto nodeList = DependencyManager::get<NodeList>();
QUuid myNodeID = nodeList->getSessionUUID();
@ -430,7 +430,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_
#endif
}
_sentStep = step;
_lastStep = step;
}
uint32_t EntityMotionState::getAndClearIncomingDirtyFlags() const {

View file

@ -95,14 +95,14 @@ protected:
bool _sentMoving; // true if last update was moving
int _numNonMovingUpdates; // RELIABLE_SEND_HACK for "not so reliable" resends of packets for non-moving objects
// TODO XXX rename _sent* to _server*
uint32_t _sentStep;
glm::vec3 _sentPosition; // in simulation-frame (not world-frame)
glm::quat _sentRotation;;
glm::vec3 _sentVelocity;
glm::vec3 _sentAngularVelocity; // radians per second
glm::vec3 _sentGravity;
glm::vec3 _sentAcceleration;
// these are for the prediction of the remote server's simple extrapolation
uint32_t _lastStep; // last step of server extrapolation
glm::vec3 _serverPosition; // in simulation-frame (not world-frame)
glm::quat _serverRotation;
glm::vec3 _serverVelocity;
glm::vec3 _serverAngularVelocity; // radians per second
glm::vec3 _serverGravity;
glm::vec3 _serverAcceleration;
uint32_t _lastMeasureStep;
glm::vec3 _lastVelocity;

View file

@ -62,15 +62,10 @@ void PhysicalEntitySimulation::removeEntityInternal(EntityItem* entity) {
if (motionState) {
motionState->clearEntity();
entity->setPhysicsInfo(nullptr);
// NOTE: we must remove entity from _pendingAdds immediately because we've disconnected the backpointers between
// motionState and entity and they can't be used to look up each other. However we don't need to remove
// motionState from _pendingChanges at this time becuase it will be removed during getObjectsToDelete().
_pendingAdds.remove(entity);
_pendingRemoves.insert(motionState);
_outgoingChanges.remove(motionState);
}
_pendingAdds.remove(entity);
}
void PhysicalEntitySimulation::changeEntityInternal(EntityItem* entity) {