mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 06:44:06 +02:00
Merge pull request #4794 from AndrewMeadows/nova
fix crash when script deletes entity
This commit is contained in:
commit
70cfd5a2a5
6 changed files with 85 additions and 98 deletions
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#ifndef hifi_EntityTree_h
|
||||
#define hifi_EntityTree_h
|
||||
|
||||
#include <QSet>
|
||||
#include <QVector>
|
||||
|
||||
#include <Octree.h>
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue