From e334c456ea0900c3432208ee34f9804fe6941a9a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 22 Apr 2015 10:13:13 -0700 Subject: [PATCH 01/26] add a place to keep track of the number of simulation steps where acceleration was close to gravity for a given Entity --- libraries/entities/src/EntityItem.cpp | 1 + libraries/entities/src/EntityItem.h | 1 + 2 files changed, 2 insertions(+) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 12fb1ba99d..205b615642 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -74,6 +74,7 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) { _created = UNKNOWN_CREATED_TIME; _dirtyFlags = 0; _changedOnServer = 0; + _accelerationNearlyGravityCount = 0; _element = NULL; _simulatorIDChangedTime = 0; _shouldClaimSimulationOwnership = false; diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index ad856698a2..ff4b975824 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -343,6 +343,7 @@ protected: glm::vec3 _velocity; glm::vec3 _gravity; glm::vec3 _acceleration; + quint8 _accelerationNearlyGravityCount; float _damping; float _lifetime; QString _script; From 3f705f3172f7cb599a4f50e8a2e6ffafdc23dcfc Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 22 Apr 2015 10:39:13 -0700 Subject: [PATCH 02/26] keep track of the number of simulation steps each entity has been accelerated at nearly its gravity. if we get 4 in a row, start sending acceleration equal to gravity to the entity server, so it will include gravity in its estimates --- libraries/entities/src/EntityItem.h | 4 ++++ libraries/physics/src/EntityMotionState.cpp | 23 ++++++++++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index ff4b975824..a4903044d9 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -311,6 +311,10 @@ public: static void setSendPhysicsUpdates(bool value) { _sendPhysicsUpdates = value; } static bool getSendPhysicsUpdates() { return _sendPhysicsUpdates; } + void incrementAccelerationNearlyGravityCount() { _accelerationNearlyGravityCount++; } + void resetAccelerationNearlyGravityCount() { _accelerationNearlyGravityCount = 0; } + quint8 getAccelerationNearlyGravityCount() { return _accelerationNearlyGravityCount; } + protected: static bool _sendPhysicsUpdates; diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index e5a12a2b66..86a60e5b99 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -18,7 +18,8 @@ #include "PhysicsHelpers.h" #include "PhysicsLogging.h" -static const float MEASURED_ACCELERATION_CLOSE_TO_ZERO = 0.05f; +static const float ACCELERATION_EQUIVALENT_EPSILON_RATIO = 0.1f; +static const quint8 STEPS_TO_DECIDE_BALLISTIC = 4; QSet* _outgoingEntityList; @@ -214,10 +215,26 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ if (_outgoingPacketFlags) { EntityItemProperties properties = _entity->getProperties(); - if (glm::length(_measuredAcceleration) < MEASURED_ACCELERATION_CLOSE_TO_ZERO) { - _entity->setAcceleration(glm::vec3(0.0f)); + float gravityLength = glm::length(_entity->getGravity()); + float accVsGravity = glm::abs(glm::length(_measuredAcceleration) - gravityLength); + if (accVsGravity < ACCELERATION_EQUIVALENT_EPSILON_RATIO * gravityLength) { + // acceleration measured during the most recent simulation step was close to gravity. + if (_entity->getAccelerationNearlyGravityCount() < STEPS_TO_DECIDE_BALLISTIC) { + // only increment this if we haven't reached the threshold yet. this is to avoid + // overflowing the counter. + _entity->incrementAccelerationNearlyGravityCount(); + } } else { + // acceleration wasn't similar to this entities gravity, so reset the went-ballistic counter + _entity->resetAccelerationNearlyGravityCount(); + } + + // if this entity has been accelerated at close to gravity for a certain number of frames, let + // the entity server's estimates include gravity. + if (_entity->getAccelerationNearlyGravityCount() >= STEPS_TO_DECIDE_BALLISTIC) { _entity->setAcceleration(_entity->getGravity()); + } else { + _entity->setAcceleration(glm::vec3(0.0f)); } if (_outgoingPacketFlags & EntityItem::DIRTY_POSITION) { From 32673efc80ccc9e92a65cdadbac454e571fca41f Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 22 Apr 2015 10:51:45 -0700 Subject: [PATCH 03/26] compute collision events inside lock to avoid a rare crash --- libraries/physics/src/PhysicsEngine.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 44bba990ac..d4963aaf81 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -348,10 +348,10 @@ void PhysicsEngine::stepSimulation() { _characterController->postSimulation(); } + computeCollisionEvents(); + unlock(); _entityTree->unlock(); - - computeCollisionEvents(); } } From 41166c1a42327d48c42bd164fa0e089668c12f4c Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 22 Apr 2015 11:18:18 -0700 Subject: [PATCH 04/26] allow entity server to time-out entity-simulation ownership rather than having interfaces give it up --- libraries/physics/src/EntityMotionState.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 86a60e5b99..c29abf9571 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -294,8 +294,8 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ properties.setSimulatorID(myNodeID); } else if (simulatorID == myNodeID && zeroSpeed && zeroSpin) { // we are the simulator and the object has stopped. give up "simulator" status - _entity->setSimulatorID(QUuid()); - properties.setSimulatorID(QUuid()); + // _entity->setSimulatorID(QUuid()); + // properties.setSimulatorID(QUuid()); } // RELIABLE_SEND_HACK: count number of updates for entities at rest so we can stop sending them after some limit. From dc30ca02104fa86661a57e4f2b40e4e5253e58bb Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 22 Apr 2015 12:51:29 -0700 Subject: [PATCH 05/26] experimenting --- libraries/physics/src/EntityMotionState.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index c29abf9571..a8a4a31544 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -290,12 +290,12 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ } else if (simulatorID.isNull() && !(zeroSpeed && zeroSpin)) { // The object is moving and nobody thinks they own the motion. set this Node as the simulator - _entity->setSimulatorID(myNodeID); - properties.setSimulatorID(myNodeID); + // _entity->setSimulatorID(myNodeID); + // properties.setSimulatorID(myNodeID); } else if (simulatorID == myNodeID && zeroSpeed && zeroSpin) { // we are the simulator and the object has stopped. give up "simulator" status - // _entity->setSimulatorID(QUuid()); - // properties.setSimulatorID(QUuid()); + _entity->setSimulatorID(QUuid()); + properties.setSimulatorID(QUuid()); } // RELIABLE_SEND_HACK: count number of updates for entities at rest so we can stop sending them after some limit. From a6750eafd8b0a7e6f90c30305c0773fb2c2d5270 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 22 Apr 2015 13:03:59 -0700 Subject: [PATCH 06/26] experimenting --- libraries/physics/src/EntityMotionState.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index a8a4a31544..90c7a56b16 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -284,8 +284,8 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ QUuid simulatorID = _entity->getSimulatorID(); if (_entity->getShouldClaimSimulationOwnership()) { - _entity->setSimulatorID(myNodeID); - properties.setSimulatorID(myNodeID); + // _entity->setSimulatorID(myNodeID); + // properties.setSimulatorID(myNodeID); _entity->setShouldClaimSimulationOwnership(false); } else if (simulatorID.isNull() && !(zeroSpeed && zeroSpin)) { @@ -294,8 +294,8 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ // properties.setSimulatorID(myNodeID); } else if (simulatorID == myNodeID && zeroSpeed && zeroSpin) { // we are the simulator and the object has stopped. give up "simulator" status - _entity->setSimulatorID(QUuid()); - properties.setSimulatorID(QUuid()); + // _entity->setSimulatorID(QUuid()); + // properties.setSimulatorID(QUuid()); } // RELIABLE_SEND_HACK: count number of updates for entities at rest so we can stop sending them after some limit. From 7382b0b19f64b4315de07134859d2d94486f9bfe Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 22 Apr 2015 13:17:20 -0700 Subject: [PATCH 07/26] experimenting --- libraries/physics/src/EntityMotionState.cpp | 24 ++++++++++----------- libraries/physics/src/PhysicsEngine.cpp | 13 +++++++++-- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 90c7a56b16..750e5ef64d 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -281,22 +281,22 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ auto nodeList = DependencyManager::get(); QUuid myNodeID = nodeList->getSessionUUID(); - QUuid simulatorID = _entity->getSimulatorID(); + // QUuid simulatorID = _entity->getSimulatorID(); if (_entity->getShouldClaimSimulationOwnership()) { - // _entity->setSimulatorID(myNodeID); - // properties.setSimulatorID(myNodeID); + _entity->setSimulatorID(myNodeID); + properties.setSimulatorID(myNodeID); _entity->setShouldClaimSimulationOwnership(false); } - else if (simulatorID.isNull() && !(zeroSpeed && zeroSpin)) { - // The object is moving and nobody thinks they own the motion. set this Node as the simulator - // _entity->setSimulatorID(myNodeID); - // properties.setSimulatorID(myNodeID); - } else if (simulatorID == myNodeID && zeroSpeed && zeroSpin) { - // we are the simulator and the object has stopped. give up "simulator" status - // _entity->setSimulatorID(QUuid()); - // properties.setSimulatorID(QUuid()); - } + // else if (simulatorID.isNull() && !(zeroSpeed && zeroSpin)) { + // // The object is moving and nobody thinks they own the motion. set this Node as the simulator + // _entity->setSimulatorID(myNodeID); + // properties.setSimulatorID(myNodeID); + // } else if (simulatorID == myNodeID && zeroSpeed && zeroSpin) { + // // we are the simulator and the object has stopped. give up "simulator" status + // _entity->setSimulatorID(QUuid()); + // properties.setSimulatorID(QUuid()); + // } // RELIABLE_SEND_HACK: count number of updates for entities at rest so we can stop sending them after some limit. if (_sentMoving) { diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index d4963aaf81..3033ff5973 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -389,7 +389,9 @@ void PhysicsEngine::computeCollisionEvents() { } void* a = objectA->getUserPointer(); + EntityItem* entityA = a ? static_cast(a)->getEntity() : NULL; void* b = objectB->getUserPointer(); + EntityItem* entityB = b ? static_cast(b)->getEntity() : NULL; if (a || b) { // the manifold has up to 4 distinct points, but only extract info from the first _contactMap[ContactKey(a, b)].update(_numContactFrames, contactManifold->getContactPoint(0), _originOffset); @@ -397,13 +399,20 @@ void PhysicsEngine::computeCollisionEvents() { // if our character capsule is colliding with something dynamic, claim simulation ownership. // see EntityMotionState::sendUpdate if (objectA == characterCollisionObject && !objectB->isStaticOrKinematicObject() && b) { - EntityItem* entityB = static_cast(b)->getEntity(); entityB->setShouldClaimSimulationOwnership(true); } if (objectB == characterCollisionObject && !objectA->isStaticOrKinematicObject() && a) { - EntityItem* entityA = static_cast(a)->getEntity(); entityA->setShouldClaimSimulationOwnership(true); } + + if (entityA && entityB) { + if (entityA->getShouldClaimSimulationOwnership()) { + entityB->setShouldClaimSimulationOwnership(true); + } + else if (entityB->getShouldClaimSimulationOwnership()) { + entityA->setShouldClaimSimulationOwnership(true); + } + } } } } From 27ed0c4a9866ab4ddcb67f3f1fd4e3164bbf869b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 22 Apr 2015 13:21:06 -0700 Subject: [PATCH 08/26] experimenting --- libraries/physics/src/PhysicsEngine.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 3033ff5973..f33933fb3f 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -405,7 +405,9 @@ void PhysicsEngine::computeCollisionEvents() { entityA->setShouldClaimSimulationOwnership(true); } - if (entityA && entityB) { + if (entityA && entityB && + !objectA->isStaticOrKinematicObject() && + !objectB->isStaticOrKinematicObject()) { if (entityA->getShouldClaimSimulationOwnership()) { entityB->setShouldClaimSimulationOwnership(true); } From ee000f91aea414f3c19a98d5b75dd7cd57c73775 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 22 Apr 2015 13:27:19 -0700 Subject: [PATCH 09/26] experimenting --- libraries/physics/src/PhysicsEngine.cpp | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index f33933fb3f..3cc8017722 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -369,6 +369,9 @@ void PhysicsEngine::stepNonPhysicalKinematics(const quint64& now) { void PhysicsEngine::computeCollisionEvents() { BT_PROFILE("computeCollisionEvents"); + auto nodeList = DependencyManager::get(); + QUuid myNodeID = nodeList->getSessionUUID(); + const btCollisionObject* characterCollisionObject = _characterController ? _characterController->getCollisionObject() : NULL; @@ -398,20 +401,26 @@ void PhysicsEngine::computeCollisionEvents() { // if our character capsule is colliding with something dynamic, claim simulation ownership. // see EntityMotionState::sendUpdate - if (objectA == characterCollisionObject && !objectB->isStaticOrKinematicObject() && b) { - entityB->setShouldClaimSimulationOwnership(true); - } - if (objectB == characterCollisionObject && !objectA->isStaticOrKinematicObject() && a) { - entityA->setShouldClaimSimulationOwnership(true); - } + // if (objectA == characterCollisionObject && !objectB->isStaticOrKinematicObject() && b) { + // entityB->setShouldClaimSimulationOwnership(true); + // } + // if (objectB == characterCollisionObject && !objectA->isStaticOrKinematicObject() && a) { + // entityA->setShouldClaimSimulationOwnership(true); + // } + // collisions cause infections spread of simulation-ownership. we also attempt to take + // ownership of anything that collides with our avatar. if (entityA && entityB && !objectA->isStaticOrKinematicObject() && !objectB->isStaticOrKinematicObject()) { - if (entityA->getShouldClaimSimulationOwnership()) { + if (entityA->getSimulatorID() == myNodeID || + entityA->getShouldClaimSimulationOwnership() || + objectA == characterCollisionObject) { entityB->setShouldClaimSimulationOwnership(true); } - else if (entityB->getShouldClaimSimulationOwnership()) { + if (entityB->getSimulatorID() == myNodeID || + entityB->getShouldClaimSimulationOwnership() || + objectB == characterCollisionObject) { entityA->setShouldClaimSimulationOwnership(true); } } From 69ee33a3925362be30fa893dfcaa4dfa032b0a82 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 22 Apr 2015 13:29:28 -0700 Subject: [PATCH 10/26] experimenting --- libraries/physics/src/EntityMotionState.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 750e5ef64d..643d152d27 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -331,6 +331,8 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ qCDebug(physics) << "EntityMotionState::sendUpdate()... calling queueEditEntityMessage()..."; #endif + qDebug() << "sending"; + entityPacketSender->queueEditEntityMessage(PacketTypeEntityAddOrEdit, id, properties); } else { #ifdef WANT_DEBUG From cd3ee39fcc3e46e5b21e5fb262dfdf17e4f7683c Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 22 Apr 2015 13:42:04 -0700 Subject: [PATCH 11/26] experimenting --- libraries/entities/src/EntityScriptingInterface.cpp | 2 ++ libraries/physics/src/PhysicsEngine.cpp | 11 ++--------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 53335beda0..8d73fd8e95 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -71,9 +71,11 @@ void setSimId(EntityItemProperties& propertiesWithSimID, EntityItem* entity) { propertiesWithSimID.containsPositionChange()) { propertiesWithSimID.setSimulatorID(myNodeID); entity->setSimulatorID(myNodeID); + qDebug() << "script claiming ownership"; } else if (entity->getSimulatorID() == myNodeID) { propertiesWithSimID.setSimulatorID(QUuid()); // give up simulation ownership entity->setSimulatorID(QUuid()); + qDebug() << "script releasing ownership"; } } diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 3cc8017722..e4e9c547df 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -399,15 +399,6 @@ void PhysicsEngine::computeCollisionEvents() { // the manifold has up to 4 distinct points, but only extract info from the first _contactMap[ContactKey(a, b)].update(_numContactFrames, contactManifold->getContactPoint(0), _originOffset); - // if our character capsule is colliding with something dynamic, claim simulation ownership. - // see EntityMotionState::sendUpdate - // if (objectA == characterCollisionObject && !objectB->isStaticOrKinematicObject() && b) { - // entityB->setShouldClaimSimulationOwnership(true); - // } - // if (objectB == characterCollisionObject && !objectA->isStaticOrKinematicObject() && a) { - // entityA->setShouldClaimSimulationOwnership(true); - // } - // collisions cause infections spread of simulation-ownership. we also attempt to take // ownership of anything that collides with our avatar. if (entityA && entityB && @@ -417,11 +408,13 @@ void PhysicsEngine::computeCollisionEvents() { entityA->getShouldClaimSimulationOwnership() || objectA == characterCollisionObject) { entityB->setShouldClaimSimulationOwnership(true); + qDebug() << "collision claiming ownership"; } if (entityB->getSimulatorID() == myNodeID || entityB->getShouldClaimSimulationOwnership() || objectB == characterCollisionObject) { entityA->setShouldClaimSimulationOwnership(true); + qDebug() << "collision claiming ownership"; } } } From 36dbbd0c9d00caf3f2323fa2f43fcf5c7a2db9a9 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 22 Apr 2015 14:14:12 -0700 Subject: [PATCH 12/26] experimenting --- libraries/physics/src/EntityMotionState.cpp | 3 ++- libraries/physics/src/PhysicsEngine.cpp | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 643d152d27..2a779d019a 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -200,7 +200,8 @@ bool EntityMotionState::shouldSendUpdate(uint32_t simulationFrame) { const QUuid& myNodeID = nodeList->getSessionUUID(); const QUuid& simulatorID = _entity->getSimulatorID(); - if (!simulatorID.isNull() && simulatorID != myNodeID) { + // if (!simulatorID.isNull() && simulatorID != myNodeID) { + if (simulatorID != myNodeID) { // some other Node owns the simulating of this, so don't broadcast the results of local simulation. return false; } diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index e4e9c547df..43a42e0bd4 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -407,14 +407,24 @@ void PhysicsEngine::computeCollisionEvents() { if (entityA->getSimulatorID() == myNodeID || entityA->getShouldClaimSimulationOwnership() || objectA == characterCollisionObject) { + + qDebug() << "collision claiming ownership" + << (entityA->getSimulatorID() == myNodeID) + << (entityA->getShouldClaimSimulationOwnership()) + << (objectA == characterCollisionObject); + entityB->setShouldClaimSimulationOwnership(true); - qDebug() << "collision claiming ownership"; } if (entityB->getSimulatorID() == myNodeID || entityB->getShouldClaimSimulationOwnership() || objectB == characterCollisionObject) { + + qDebug() << "collision claiming ownership" + << (entityB->getSimulatorID() == myNodeID) + << (entityB->getShouldClaimSimulationOwnership()) + << (objectB == characterCollisionObject); + entityA->setShouldClaimSimulationOwnership(true); - qDebug() << "collision claiming ownership"; } } } From c30d742f7d445adb950b2625a5d3fe5c634a2acb Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 22 Apr 2015 14:22:09 -0700 Subject: [PATCH 13/26] experimenting --- libraries/physics/src/PhysicsEngine.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 43a42e0bd4..8063f5cde7 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -408,10 +408,10 @@ void PhysicsEngine::computeCollisionEvents() { entityA->getShouldClaimSimulationOwnership() || objectA == characterCollisionObject) { - qDebug() << "collision claiming ownership" + qDebug() << "collision claiming ownership 0" << (entityA->getSimulatorID() == myNodeID) << (entityA->getShouldClaimSimulationOwnership()) - << (objectA == characterCollisionObject); + << (objectA == characterCollisionObject) << myNodeID; entityB->setShouldClaimSimulationOwnership(true); } @@ -419,10 +419,10 @@ void PhysicsEngine::computeCollisionEvents() { entityB->getShouldClaimSimulationOwnership() || objectB == characterCollisionObject) { - qDebug() << "collision claiming ownership" + qDebug() << "collision claiming ownership 1" << (entityB->getSimulatorID() == myNodeID) << (entityB->getShouldClaimSimulationOwnership()) - << (objectB == characterCollisionObject); + << (objectB == characterCollisionObject) << myNodeID; entityA->setShouldClaimSimulationOwnership(true); } From 92ceff1a0311f4af8ee8980e4b62a2189abe3b4f Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 22 Apr 2015 14:53:23 -0700 Subject: [PATCH 14/26] clean up EntityItem constructors --- libraries/entities/src/EntityItem.cpp | 110 +++++++++++--------------- libraries/entities/src/EntityItem.h | 3 - 2 files changed, 45 insertions(+), 68 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 205b615642..a5d87dee99 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -25,76 +25,56 @@ bool EntityItem::_sendPhysicsUpdates = true; -void EntityItem::initFromEntityItemID(const EntityItemID& entityItemID) { - _id = entityItemID.id; - _creatorTokenID = entityItemID.creatorTokenID; - - // init values with defaults before calling setProperties +EntityItem::EntityItem(const EntityItemID& entityItemID) : + _type(EntityTypes::Unknown), + _id(entityItemID.id), + _creatorTokenID(entityItemID.creatorTokenID), + _newlyCreated(false), + _lastSimulated(0), + _lastUpdated(0), + _lastEdited(0), + _lastEditedFromRemote(0), + _lastEditedFromRemoteInRemoteTime(0), + _created(UNKNOWN_CREATED_TIME), + _changedOnServer(0), + _position(ENTITY_ITEM_ZERO_VEC3), + _dimensions(ENTITY_ITEM_DEFAULT_DIMENSIONS), + _rotation(ENTITY_ITEM_DEFAULT_ROTATION), + _glowLevel(ENTITY_ITEM_DEFAULT_GLOW_LEVEL), + _localRenderAlpha(ENTITY_ITEM_DEFAULT_LOCAL_RENDER_ALPHA), + _density(ENTITY_ITEM_DEFAULT_DENSITY), + _volumeMultiplier(1.0f), + _velocity(ENTITY_ITEM_DEFAULT_VELOCITY), + _gravity(ENTITY_ITEM_DEFAULT_GRAVITY), + _acceleration(ENTITY_ITEM_DEFAULT_ACCELERATION), + _accelerationNearlyGravityCount(0), + _damping(ENTITY_ITEM_DEFAULT_DAMPING), + _lifetime(ENTITY_ITEM_DEFAULT_LIFETIME), + _script(ENTITY_ITEM_DEFAULT_SCRIPT), + _registrationPoint(ENTITY_ITEM_DEFAULT_REGISTRATION_POINT), + _angularVelocity(ENTITY_ITEM_DEFAULT_ANGULAR_VELOCITY), + _angularDamping(ENTITY_ITEM_DEFAULT_ANGULAR_DAMPING), + _visible(ENTITY_ITEM_DEFAULT_VISIBLE), + _ignoreForCollisions(ENTITY_ITEM_DEFAULT_IGNORE_FOR_COLLISIONS), + _collisionsWillMove(ENTITY_ITEM_DEFAULT_COLLISIONS_WILL_MOVE), + _locked(ENTITY_ITEM_DEFAULT_LOCKED), + _userData(ENTITY_ITEM_DEFAULT_USER_DATA), + _simulatorID(ENTITY_ITEM_DEFAULT_SIMULATOR_ID), + _simulatorIDChangedTime(0), + _shouldClaimSimulationOwnership(false), + _marketplaceID(ENTITY_ITEM_DEFAULT_MARKETPLACE_ID), + _physicsInfo(NULL), + _dirtyFlags(0), + _element(NULL) +{ quint64 now = usecTimestampNow(); _lastSimulated = now; _lastUpdated = now; - _lastEdited = 0; - _lastEditedFromRemote = 0; - _lastEditedFromRemoteInRemoteTime = 0; - _created = UNKNOWN_CREATED_TIME; - _changedOnServer = 0; - - _position = ENTITY_ITEM_ZERO_VEC3; - _dimensions = ENTITY_ITEM_DEFAULT_DIMENSIONS; - _density = ENTITY_ITEM_DEFAULT_DENSITY; - _rotation = ENTITY_ITEM_DEFAULT_ROTATION; - _glowLevel = ENTITY_ITEM_DEFAULT_GLOW_LEVEL; - _localRenderAlpha = ENTITY_ITEM_DEFAULT_LOCAL_RENDER_ALPHA; - _velocity = ENTITY_ITEM_DEFAULT_VELOCITY; - _gravity = ENTITY_ITEM_DEFAULT_GRAVITY; - _acceleration = ENTITY_ITEM_DEFAULT_ACCELERATION; - _damping = ENTITY_ITEM_DEFAULT_DAMPING; - _lifetime = ENTITY_ITEM_DEFAULT_LIFETIME; - _script = ENTITY_ITEM_DEFAULT_SCRIPT; - _registrationPoint = ENTITY_ITEM_DEFAULT_REGISTRATION_POINT; - _angularVelocity = ENTITY_ITEM_DEFAULT_ANGULAR_VELOCITY; - _angularDamping = ENTITY_ITEM_DEFAULT_ANGULAR_DAMPING; - _visible = ENTITY_ITEM_DEFAULT_VISIBLE; - _ignoreForCollisions = ENTITY_ITEM_DEFAULT_IGNORE_FOR_COLLISIONS; - _collisionsWillMove = ENTITY_ITEM_DEFAULT_COLLISIONS_WILL_MOVE; - _locked = ENTITY_ITEM_DEFAULT_LOCKED; - _userData = ENTITY_ITEM_DEFAULT_USER_DATA; - _simulatorID = ENTITY_ITEM_DEFAULT_SIMULATOR_ID; - _marketplaceID = ENTITY_ITEM_DEFAULT_MARKETPLACE_ID; } -EntityItem::EntityItem(const EntityItemID& entityItemID) { - _type = EntityTypes::Unknown; - quint64 now = usecTimestampNow(); - _lastSimulated = now; - _lastUpdated = now; - _lastEdited = 0; - _lastEditedFromRemote = 0; - _lastEditedFromRemoteInRemoteTime = 0; - _created = UNKNOWN_CREATED_TIME; - _dirtyFlags = 0; - _changedOnServer = 0; - _accelerationNearlyGravityCount = 0; - _element = NULL; - _simulatorIDChangedTime = 0; - _shouldClaimSimulationOwnership = false; - initFromEntityItemID(entityItemID); -} - -EntityItem::EntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) { - _type = EntityTypes::Unknown; - quint64 now = usecTimestampNow(); - _lastSimulated = now; - _lastUpdated = now; - _lastEdited = 0; - _lastEditedFromRemote = 0; - _lastEditedFromRemoteInRemoteTime = 0; - _created = UNKNOWN_CREATED_TIME; - _dirtyFlags = 0; - _changedOnServer = 0; - _element = NULL; - _simulatorIDChangedTime = 0; - initFromEntityItemID(entityItemID); +EntityItem::EntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : + EntityItem(entityItemID) +{ setProperties(properties); } diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index a4903044d9..5d19c11dc5 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -318,9 +318,6 @@ public: protected: static bool _sendPhysicsUpdates; - - virtual void initFromEntityItemID(const EntityItemID& entityItemID); // maybe useful to allow subclasses to init - EntityTypes::EntityType _type; QUuid _id; uint32_t _creatorTokenID; From 3450597d70dc360bce8c4dd6c40767b0e6a5b4ee Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 22 Apr 2015 15:03:23 -0700 Subject: [PATCH 15/26] remove some debugging prints --- libraries/entities/src/EntityItem.cpp | 3 +-- libraries/physics/src/EntityMotionState.cpp | 16 ++-------------- libraries/physics/src/PhysicsEngine.cpp | 16 +--------------- 3 files changed, 4 insertions(+), 31 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index a5d87dee99..5a141af581 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -72,8 +72,7 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) : _lastUpdated = now; } -EntityItem::EntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : - EntityItem(entityItemID) +EntityItem::EntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : EntityItem(entityItemID) { setProperties(properties); } diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 2a779d019a..e77271710f 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -200,7 +200,6 @@ bool EntityMotionState::shouldSendUpdate(uint32_t simulationFrame) { const QUuid& myNodeID = nodeList->getSessionUUID(); const QUuid& simulatorID = _entity->getSimulatorID(); - // if (!simulatorID.isNull() && simulatorID != myNodeID) { if (simulatorID != myNodeID) { // some other Node owns the simulating of this, so don't broadcast the results of local simulation. return false; @@ -280,24 +279,13 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ properties.setAngularVelocity(_sentAngularVelocity); } - auto nodeList = DependencyManager::get(); - QUuid myNodeID = nodeList->getSessionUUID(); - // QUuid simulatorID = _entity->getSimulatorID(); - if (_entity->getShouldClaimSimulationOwnership()) { + auto nodeList = DependencyManager::get(); + QUuid myNodeID = nodeList->getSessionUUID(); _entity->setSimulatorID(myNodeID); properties.setSimulatorID(myNodeID); _entity->setShouldClaimSimulationOwnership(false); } - // else if (simulatorID.isNull() && !(zeroSpeed && zeroSpin)) { - // // The object is moving and nobody thinks they own the motion. set this Node as the simulator - // _entity->setSimulatorID(myNodeID); - // properties.setSimulatorID(myNodeID); - // } else if (simulatorID == myNodeID && zeroSpeed && zeroSpin) { - // // we are the simulator and the object has stopped. give up "simulator" status - // _entity->setSimulatorID(QUuid()); - // properties.setSimulatorID(QUuid()); - // } // RELIABLE_SEND_HACK: count number of updates for entities at rest so we can stop sending them after some limit. if (_sentMoving) { diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 8063f5cde7..ae76e1c785 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -401,29 +401,15 @@ void PhysicsEngine::computeCollisionEvents() { // collisions cause infections spread of simulation-ownership. we also attempt to take // ownership of anything that collides with our avatar. - if (entityA && entityB && - !objectA->isStaticOrKinematicObject() && - !objectB->isStaticOrKinematicObject()) { + if (entityA && entityB && !objectA->isStaticOrKinematicObject() && !objectB->isStaticOrKinematicObject()) { if (entityA->getSimulatorID() == myNodeID || entityA->getShouldClaimSimulationOwnership() || objectA == characterCollisionObject) { - - qDebug() << "collision claiming ownership 0" - << (entityA->getSimulatorID() == myNodeID) - << (entityA->getShouldClaimSimulationOwnership()) - << (objectA == characterCollisionObject) << myNodeID; - entityB->setShouldClaimSimulationOwnership(true); } if (entityB->getSimulatorID() == myNodeID || entityB->getShouldClaimSimulationOwnership() || objectB == characterCollisionObject) { - - qDebug() << "collision claiming ownership 1" - << (entityB->getSimulatorID() == myNodeID) - << (entityB->getShouldClaimSimulationOwnership()) - << (objectB == characterCollisionObject) << myNodeID; - entityA->setShouldClaimSimulationOwnership(true); } } From 6678922f5ccdcb4a287cca10c745516d2a8ce4cd Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 22 Apr 2015 15:09:56 -0700 Subject: [PATCH 16/26] put back code for interface giving up simulator status when something stops --- libraries/physics/src/EntityMotionState.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index e77271710f..bf59998637 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -279,14 +279,22 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ properties.setAngularVelocity(_sentAngularVelocity); } + auto nodeList = DependencyManager::get(); + QUuid myNodeID = nodeList->getSessionUUID(); + QUuid simulatorID = _entity->getSimulatorID(); + if (_entity->getShouldClaimSimulationOwnership()) { - auto nodeList = DependencyManager::get(); - QUuid myNodeID = nodeList->getSessionUUID(); _entity->setSimulatorID(myNodeID); properties.setSimulatorID(myNodeID); _entity->setShouldClaimSimulationOwnership(false); } + if (simulatorID == myNodeID && zeroSpeed && zeroSpin) { + // we are the simulator and the object has stopped. give up "simulator" status + _entity->setSimulatorID(QUuid()); + properties.setSimulatorID(QUuid()); + } + // RELIABLE_SEND_HACK: count number of updates for entities at rest so we can stop sending them after some limit. if (_sentMoving) { _numNonMovingUpdates = 0; From 7781808beadb56ab6a4adb427cd05a68f1bff826 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 22 Apr 2015 15:25:09 -0700 Subject: [PATCH 17/26] remove debug prints, fix a comment --- libraries/entities/src/EntityScriptingInterface.cpp | 2 -- libraries/physics/src/EntityMotionState.cpp | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 8d73fd8e95..53335beda0 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -71,11 +71,9 @@ void setSimId(EntityItemProperties& propertiesWithSimID, EntityItem* entity) { propertiesWithSimID.containsPositionChange()) { propertiesWithSimID.setSimulatorID(myNodeID); entity->setSimulatorID(myNodeID); - qDebug() << "script claiming ownership"; } else if (entity->getSimulatorID() == myNodeID) { propertiesWithSimID.setSimulatorID(QUuid()); // give up simulation ownership entity->setSimulatorID(QUuid()); - qDebug() << "script releasing ownership"; } } diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index bf59998637..20472b625c 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -229,7 +229,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ _entity->resetAccelerationNearlyGravityCount(); } - // if this entity has been accelerated at close to gravity for a certain number of frames, let + // if this entity has been accelerated at close to gravity for a certain number of simulation-steps, let // the entity server's estimates include gravity. if (_entity->getAccelerationNearlyGravityCount() >= STEPS_TO_DECIDE_BALLISTIC) { _entity->setAcceleration(_entity->getGravity()); From 07a848c9ce44f5231a4550e0728aed901e6935ac Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 22 Apr 2015 15:50:39 -0700 Subject: [PATCH 18/26] added bump call in physics engine for when an entity is deleted and may have something resting on top of it --- libraries/entities/src/EntitySimulation.h | 2 ++ libraries/entities/src/EntityTree.cpp | 3 ++ libraries/physics/src/PhysicsEngine.cpp | 34 ++++++++++++++++++++++- libraries/physics/src/PhysicsEngine.h | 1 + 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/libraries/entities/src/EntitySimulation.h b/libraries/entities/src/EntitySimulation.h index 1eb4fdc951..913f431186 100644 --- a/libraries/entities/src/EntitySimulation.h +++ b/libraries/entities/src/EntitySimulation.h @@ -61,6 +61,8 @@ public: void clearEntities(); + virtual void bump(EntityItem* bumpEntity) {} + EntityTree* getEntityTree() { return _entityTree; } signals: diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 5b15aa26b4..a41deb174f 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -269,6 +269,9 @@ void EntityTree::deleteEntity(const EntityItemID& entityID, bool force, bool ign return; } + // in case something is resting on top of this, give it a bump in the simulation. + _simulation->bump(existingEntity); + if (existingEntity->getLocked() && !force) { if (!ignoreWarnings) { qCDebug(entities) << "ERROR! EntityTree::deleteEntity() trying to delete locked entity. entityID=" << entityID; diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index ae76e1c785..074500f719 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -366,6 +366,39 @@ void PhysicsEngine::stepNonPhysicalKinematics(const quint64& now) { } } + +void PhysicsEngine::bump(EntityItem* bumpEntity) { + // If this node is doing something like deleting an entity, scan for contacts involving the + // entity. For each found, flag the other entity involved as being simulated by this node. + lock(); + int numManifolds = _collisionDispatcher->getNumManifolds(); + for (int i = 0; i < numManifolds; ++i) { + btPersistentManifold* contactManifold = _collisionDispatcher->getManifoldByIndexInternal(i); + if (contactManifold->getNumContacts() > 0) { + const btCollisionObject* objectA = static_cast(contactManifold->getBody0()); + const btCollisionObject* objectB = static_cast(contactManifold->getBody1()); + if (objectA && objectB) { + void* a = objectA->getUserPointer(); + void* b = objectB->getUserPointer(); + if (a && b) { + EntityItem* entityA = a ? static_cast(a)->getEntity() : NULL; + EntityItem* entityB = b ? static_cast(b)->getEntity() : NULL; + if (entityA && entityB) { + if (entityA == bumpEntity) { + entityB->setShouldClaimSimulationOwnership(true); + } + if (entityB == bumpEntity) { + entityA->setShouldClaimSimulationOwnership(true); + } + } + } + } + } + } + unlock(); +} + + void PhysicsEngine::computeCollisionEvents() { BT_PROFILE("computeCollisionEvents"); @@ -422,7 +455,6 @@ void PhysicsEngine::computeCollisionEvents() { // scan known contacts and trigger events ContactMap::iterator contactItr = _contactMap.begin(); - while (contactItr != _contactMap.end()) { ObjectMotionState* A = static_cast(contactItr->first._a); ObjectMotionState* B = static_cast(contactItr->first._b); diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index 6e1f430237..63ec96d04e 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -68,6 +68,7 @@ public: void stepSimulation(); void stepNonPhysicalKinematics(const quint64& now); + virtual void bump(EntityItem* bumpEntity); void computeCollisionEvents(); void dumpStatsIfNecessary(); From 96b4517e6ede70d4f02f55c5a552560780898af7 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 22 Apr 2015 16:05:31 -0700 Subject: [PATCH 19/26] when removing something from bullet, attempt to wake up anything that was touching it --- libraries/entities/src/EntitySimulation.h | 2 -- libraries/entities/src/EntityTree.cpp | 3 --- libraries/physics/src/EntityMotionState.cpp | 2 -- libraries/physics/src/PhysicsEngine.cpp | 8 ++++++++ libraries/physics/src/PhysicsEngine.h | 2 +- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/libraries/entities/src/EntitySimulation.h b/libraries/entities/src/EntitySimulation.h index 913f431186..1eb4fdc951 100644 --- a/libraries/entities/src/EntitySimulation.h +++ b/libraries/entities/src/EntitySimulation.h @@ -61,8 +61,6 @@ public: void clearEntities(); - virtual void bump(EntityItem* bumpEntity) {} - EntityTree* getEntityTree() { return _entityTree; } signals: diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index a41deb174f..5b15aa26b4 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -269,9 +269,6 @@ void EntityTree::deleteEntity(const EntityItemID& entityID, bool force, bool ign return; } - // in case something is resting on top of this, give it a bump in the simulation. - _simulation->bump(existingEntity); - if (existingEntity->getLocked() && !force) { if (!ignoreWarnings) { qCDebug(entities) << "ERROR! EntityTree::deleteEntity() trying to delete locked entity. entityID=" << entityID; diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 20472b625c..382cc5a734 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -328,8 +328,6 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ qCDebug(physics) << "EntityMotionState::sendUpdate()... calling queueEditEntityMessage()..."; #endif - qDebug() << "sending"; - entityPacketSender->queueEditEntityMessage(PacketTypeEntityAddOrEdit, id, properties); } else { #ifdef WANT_DEBUG diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 074500f719..88d6112772 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -386,9 +386,15 @@ void PhysicsEngine::bump(EntityItem* bumpEntity) { if (entityA && entityB) { if (entityA == bumpEntity) { entityB->setShouldClaimSimulationOwnership(true); + if (!objectB->isActive()) { + objectB->setActivationState(ACTIVE_TAG); + } } if (entityB == bumpEntity) { entityA->setShouldClaimSimulationOwnership(true); + if (!objectA->isActive()) { + objectA->setActivationState(ACTIVE_TAG); + } } } } @@ -564,6 +570,8 @@ void PhysicsEngine::addObject(const ShapeInfo& shapeInfo, btCollisionShape* shap void PhysicsEngine::removeObjectFromBullet(ObjectMotionState* motionState) { assert(motionState); + EntityItem* entity = static_cast(motionState)->getEntity(); + bump(entity); btRigidBody* body = motionState->getRigidBody(); if (body) { const btCollisionShape* shape = body->getCollisionShape(); diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index 63ec96d04e..148261c6d2 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -68,7 +68,6 @@ public: void stepSimulation(); void stepNonPhysicalKinematics(const quint64& now); - virtual void bump(EntityItem* bumpEntity); void computeCollisionEvents(); void dumpStatsIfNecessary(); @@ -99,6 +98,7 @@ private: // return 'true' of update was successful bool updateObjectHard(btRigidBody* body, ObjectMotionState* motionState, uint32_t flags); void updateObjectEasy(btRigidBody* body, ObjectMotionState* motionState, uint32_t flags); + void bump(EntityItem* bumpEntity); btClock _clock; btDefaultCollisionConfiguration* _collisionConfig = NULL; From 864f8cb3b3e051f12c28efc57d2d76f14d0588f1 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 22 Apr 2015 16:10:25 -0700 Subject: [PATCH 20/26] fix comment --- libraries/physics/src/PhysicsEngine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 88d6112772..50990d708c 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -438,7 +438,7 @@ void PhysicsEngine::computeCollisionEvents() { // the manifold has up to 4 distinct points, but only extract info from the first _contactMap[ContactKey(a, b)].update(_numContactFrames, contactManifold->getContactPoint(0), _originOffset); - // collisions cause infections spread of simulation-ownership. we also attempt to take + // collisions cause infectious spread of simulation-ownership. we also attempt to take // ownership of anything that collides with our avatar. if (entityA && entityB && !objectA->isStaticOrKinematicObject() && !objectB->isStaticOrKinematicObject()) { if (entityA->getSimulatorID() == myNodeID || From 5a7f8a2f5a03428152ce0bea3e359708a4c3feb3 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 22 Apr 2015 17:06:21 -0700 Subject: [PATCH 21/26] git rid of unneeded bump code. re-indent billiards.js and rez in balls with some y velocity so they fall to the table --- examples/example/games/billiards.js | 254 +++++++++--------- .../entities/src/EntityScriptingInterface.cpp | 23 +- libraries/physics/src/PhysicsEngine.cpp | 44 +-- libraries/physics/src/PhysicsEngine.h | 1 - 4 files changed, 145 insertions(+), 177 deletions(-) diff --git a/examples/example/games/billiards.js b/examples/example/games/billiards.js index d4bc71ba37..8e890515c0 100644 --- a/examples/example/games/billiards.js +++ b/examples/example/games/billiards.js @@ -39,126 +39,130 @@ hitSounds.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "Collisions-ballhitsandc HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; var screenSize = Controller.getViewportDimensions(); var reticle = Overlays.addOverlay("image", { - x: screenSize.x / 2 - 16, - y: screenSize.y / 2 - 16, - width: 32, - height: 32, - imageURL: HIFI_PUBLIC_BUCKET + "images/billiardsReticle.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1 - }); + x: screenSize.x / 2 - 16, + y: screenSize.y / 2 - 16, + width: 32, + height: 32, + imageURL: HIFI_PUBLIC_BUCKET + "images/billiardsReticle.png", + color: { red: 255, green: 255, blue: 255}, + alpha: 1 +}); function makeTable(pos) { - // Top - tableParts.push(Entities.addEntity( + // Top + tableParts.push(Entities.addEntity( { type: "Box", - position: pos, - dimensions: { x: LENGTH * SCALE, y: HEIGHT, z: WIDTH * SCALE }, - color: { red: 0, green: 255, blue: 0 } })); - // Long Bumpers - tableParts.push(Entities.addEntity( + position: pos, + dimensions: { x: LENGTH * SCALE, y: HEIGHT, z: WIDTH * SCALE }, + color: { red: 0, green: 255, blue: 0 } })); + // Long Bumpers + tableParts.push(Entities.addEntity( { type: "Box", - position: { x: pos.x - LENGTH / 2.0, - y: pos.y + (HEIGHT / 2.0 + BUMPER_HEIGHT / 2.0), - z: pos.z - (WIDTH / 2.0 + BUMPER_WIDTH / 2.0) * SCALE }, - dimensions: { x: (LENGTH - 3.0 * HOLE_SIZE) * SCALE / 2.0, y: BUMPER_HEIGHT, z: BUMPER_WIDTH * SCALE }, - color: { red: 237, green: 201, blue: 175 } })); - tableParts.push(Entities.addEntity( + position: { x: pos.x - LENGTH / 2.0, + y: pos.y + (HEIGHT / 2.0 + BUMPER_HEIGHT / 2.0), + z: pos.z - (WIDTH / 2.0 + BUMPER_WIDTH / 2.0) * SCALE }, + dimensions: { x: (LENGTH - 3.0 * HOLE_SIZE) * SCALE / 2.0, y: BUMPER_HEIGHT, z: BUMPER_WIDTH * SCALE }, + color: { red: 237, green: 201, blue: 175 } })); + tableParts.push(Entities.addEntity( { type: "Box", - position: { x: pos.x + LENGTH / 2.0, - y: pos.y + (HEIGHT / 2.0 + BUMPER_HEIGHT / 2.0), - z: pos.z - (WIDTH / 2.0 + BUMPER_WIDTH / 2.0) * SCALE }, - dimensions: { x: (LENGTH - 3.0 * HOLE_SIZE) * SCALE / 2.0, y: BUMPER_HEIGHT, z: BUMPER_WIDTH * SCALE }, - color: { red: 237, green: 201, blue: 175 } })); + position: { x: pos.x + LENGTH / 2.0, + y: pos.y + (HEIGHT / 2.0 + BUMPER_HEIGHT / 2.0), + z: pos.z - (WIDTH / 2.0 + BUMPER_WIDTH / 2.0) * SCALE }, + dimensions: { x: (LENGTH - 3.0 * HOLE_SIZE) * SCALE / 2.0, y: BUMPER_HEIGHT, z: BUMPER_WIDTH * SCALE }, + color: { red: 237, green: 201, blue: 175 } })); - tableParts.push(Entities.addEntity( + tableParts.push(Entities.addEntity( { type: "Box", - position: { x: pos.x - LENGTH / 2.0, - y: pos.y + (HEIGHT / 2.0 + BUMPER_HEIGHT / 2.0), - z: pos.z + (WIDTH / 2.0 + BUMPER_WIDTH / 2.0) * SCALE }, - dimensions: { x: (LENGTH - 3.0 * HOLE_SIZE) * SCALE / 2.0, y: BUMPER_HEIGHT, z: BUMPER_WIDTH * SCALE }, - color: { red: 237, green: 201, blue: 175 } })); - tableParts.push(Entities.addEntity( + position: { x: pos.x - LENGTH / 2.0, + y: pos.y + (HEIGHT / 2.0 + BUMPER_HEIGHT / 2.0), + z: pos.z + (WIDTH / 2.0 + BUMPER_WIDTH / 2.0) * SCALE }, + dimensions: { x: (LENGTH - 3.0 * HOLE_SIZE) * SCALE / 2.0, y: BUMPER_HEIGHT, z: BUMPER_WIDTH * SCALE }, + color: { red: 237, green: 201, blue: 175 } })); + tableParts.push(Entities.addEntity( { type: "Box", - position: { x: pos.x + LENGTH / 2.0, - y: pos.y + (HEIGHT / 2.0 + BUMPER_HEIGHT / 2.0), - z: pos.z + (WIDTH / 2.0 + BUMPER_WIDTH / 2.0) * SCALE }, - dimensions: { x: (LENGTH - 3.0 * HOLE_SIZE) * SCALE / 2.0, y: BUMPER_HEIGHT, z: BUMPER_WIDTH * SCALE }, - color: { red: 237, green: 201, blue: 175 } })); - // End bumpers - tableParts.push(Entities.addEntity( + position: { x: pos.x + LENGTH / 2.0, + y: pos.y + (HEIGHT / 2.0 + BUMPER_HEIGHT / 2.0), + z: pos.z + (WIDTH / 2.0 + BUMPER_WIDTH / 2.0) * SCALE }, + dimensions: { x: (LENGTH - 3.0 * HOLE_SIZE) * SCALE / 2.0, y: BUMPER_HEIGHT, z: BUMPER_WIDTH * SCALE }, + color: { red: 237, green: 201, blue: 175 } })); + // End bumpers + tableParts.push(Entities.addEntity( { type: "Box", - position: { x: pos.x + (LENGTH / 2.0 + BUMPER_WIDTH / 2.0) * SCALE, - y: pos.y + (HEIGHT / 2.0 + BUMPER_HEIGHT / 2.0), - z: pos.z }, - dimensions: { z: (WIDTH - 2.0 * HOLE_SIZE) * SCALE, y: BUMPER_HEIGHT, x: BUMPER_WIDTH * SCALE }, - color: { red: 237, green: 201, blue: 175 } })); + position: { x: pos.x + (LENGTH / 2.0 + BUMPER_WIDTH / 2.0) * SCALE, + y: pos.y + (HEIGHT / 2.0 + BUMPER_HEIGHT / 2.0), + z: pos.z }, + dimensions: { z: (WIDTH - 2.0 * HOLE_SIZE) * SCALE, y: BUMPER_HEIGHT, x: BUMPER_WIDTH * SCALE }, + color: { red: 237, green: 201, blue: 175 } })); - tableParts.push(Entities.addEntity( + tableParts.push(Entities.addEntity( { type: "Box", - position: { x: pos.x - (LENGTH / 2.0 + BUMPER_WIDTH / 2.0) * SCALE, - y: pos.y + (HEIGHT / 2.0 + BUMPER_HEIGHT / 2.0), - z: pos.z }, - dimensions: { z: (WIDTH - 2.0 * HOLE_SIZE) * SCALE, y: BUMPER_HEIGHT, x: BUMPER_WIDTH * SCALE }, - color: { red: 237, green: 201, blue: 175 } })); + position: { x: pos.x - (LENGTH / 2.0 + BUMPER_WIDTH / 2.0) * SCALE, + y: pos.y + (HEIGHT / 2.0 + BUMPER_HEIGHT / 2.0), + z: pos.z }, + dimensions: { z: (WIDTH - 2.0 * HOLE_SIZE) * SCALE, y: BUMPER_HEIGHT, x: BUMPER_WIDTH * SCALE }, + color: { red: 237, green: 201, blue: 175 } })); } function makeBalls(pos) { - // Object balls + // Object balls var whichBall = [ 1, 14, 15, 4, 8, 7, 12, 9, 3, 13, 10, 5, 6, 11, 2 ]; var ballNumber = 0; - var ballPosition = { x: pos.x + (LENGTH / 4.0) * SCALE, y: pos.y + HEIGHT / 2.0 + DROP_HEIGHT, z: pos.z }; - for (var row = 1; row <= 5; row++) { - ballPosition.z = pos.z - ((row - 1.0) / 2.0 * (BALL_SIZE + BALL_GAP) * SCALE); - for (var spot = 0; spot < row; spot++) { - balls.push(Entities.addEntity( + var ballPosition = { x: pos.x + (LENGTH / 4.0) * SCALE, y: pos.y + HEIGHT / 2.0 + DROP_HEIGHT, z: pos.z }; + for (var row = 1; row <= 5; row++) { + ballPosition.z = pos.z - ((row - 1.0) / 2.0 * (BALL_SIZE + BALL_GAP) * SCALE); + for (var spot = 0; spot < row; spot++) { + balls.push(Entities.addEntity( { type: "Model", - modelURL: "https://s3.amazonaws.com/hifi-public/models/props/Pool/ball_" + whichBall[ballNumber].toString() + ".fbx", - position: ballPosition, - dimensions: { x: BALL_SIZE * SCALE, y: BALL_SIZE * SCALE, z: BALL_SIZE * SCALE }, - rotation: Quat.fromPitchYawRollDegrees((Math.random() - 0.5) * 20, (Math.random() - 0.5) * 20, (Math.random() - 0.5) * 20), - color: { red: 255, green: 255, blue: 255 }, - gravity: { x: 0, y: GRAVITY, z: 0 }, - ignoreCollisions: false, - damping: 0.50, - shapeType: "sphere", - collisionsWillMove: true })); - ballPosition.z += (BALL_SIZE + BALL_GAP) * SCALE; + modelURL: "https://s3.amazonaws.com/hifi-public/models/props/Pool/ball_" + + whichBall[ballNumber].toString() + ".fbx", + position: ballPosition, + dimensions: { x: BALL_SIZE * SCALE, y: BALL_SIZE * SCALE, z: BALL_SIZE * SCALE }, + rotation: Quat.fromPitchYawRollDegrees((Math.random() - 0.5) * 20, + (Math.random() - 0.5) * 20, + (Math.random() - 0.5) * 20), + color: { red: 255, green: 255, blue: 255 }, + gravity: { x: 0, y: GRAVITY, z: 0 }, + velocity: {x: 0, y: -0.2, z: 0 }, + ignoreCollisions: false, + damping: 0.50, + shapeType: "sphere", + collisionsWillMove: true })); + ballPosition.z += (BALL_SIZE + BALL_GAP) * SCALE; ballNumber++; - } - ballPosition.x += (BALL_GAP + Math.sqrt(3.0) / 2.0 * BALL_SIZE) * SCALE; } + ballPosition.x += (BALL_GAP + Math.sqrt(3.0) / 2.0 * BALL_SIZE) * SCALE; + } // Cue Ball cuePosition = { x: pos.x - (LENGTH / 4.0) * SCALE, y: pos.y + HEIGHT / 2.0 + DROP_HEIGHT, z: pos.z }; cueBall = Entities.addEntity( - { type: "Model", - modelURL: "https://s3.amazonaws.com/hifi-public/models/props/Pool/cue_ball.fbx", - position: cuePosition, - dimensions: { x: BALL_SIZE * SCALE, y: BALL_SIZE * SCALE, z: BALL_SIZE * SCALE }, - color: { red: 255, green: 255, blue: 255 }, - gravity: { x: 0, y: GRAVITY, z: 0 }, - angularVelocity: { x: 0, y: 0, z: 0 }, - velocity: {x: 0, y: 0, z: 0 }, - ignoreCollisions: false, - damping: 0.50, - shapeType: "sphere", - collisionsWillMove: true }); - + { type: "Model", + modelURL: "https://s3.amazonaws.com/hifi-public/models/props/Pool/cue_ball.fbx", + position: cuePosition, + dimensions: { x: BALL_SIZE * SCALE, y: BALL_SIZE * SCALE, z: BALL_SIZE * SCALE }, + color: { red: 255, green: 255, blue: 255 }, + gravity: { x: 0, y: GRAVITY, z: 0 }, + angularVelocity: { x: 0, y: 0, z: 0 }, + velocity: {x: 0, y: -0.2, z: 0 }, + ignoreCollisions: false, + damping: 0.50, + shapeType: "sphere", + collisionsWillMove: true }); + } function isObjectBall(id) { - for (var i; i < balls.length; i++) { - if (balls[i].id == id) { - return true; - } - } - return false; + for (var i; i < balls.length; i++) { + if (balls[i].id == id) { + return true; + } + } + return false; } function shootCue(velocity) { - var DISTANCE_FROM_CAMERA = BALL_SIZE * 5.0 * SCALE; + var DISTANCE_FROM_CAMERA = BALL_SIZE * 5.0 * SCALE; var camera = Camera.getPosition(); var forwardVector = Quat.getFront(Camera.getOrientation()); var cuePosition = Vec3.sum(camera, Vec3.multiply(forwardVector, DISTANCE_FROM_CAMERA)); @@ -180,14 +184,14 @@ function shootCue(velocity) { density: 8000, ignoreCollisions: false, collisionsWillMove: true - }); + }); print("Shot, velocity = " + velocity); } function keyReleaseEvent(event) { - if ((startStroke > 0) && event.text == "SPACE") { - var endTime = new Date().getTime(); - var delta = endTime - startStroke; + if ((startStroke > 0) && event.text == "SPACE") { + var endTime = new Date().getTime(); + var delta = endTime - startStroke; shootCue(delta / 100.0); startStroke = 0; } @@ -201,49 +205,49 @@ function keyPressEvent(event) { } function cleanup() { - for (var i = 0; i < tableParts.length; i++) { - if (!tableParts[i].isKnownID) { - tableParts[i] = Entities.identifyEntity(tableParts[i]); - } - Entities.deleteEntity(tableParts[i]); + for (var i = 0; i < tableParts.length; i++) { + if (!tableParts[i].isKnownID) { + tableParts[i] = Entities.identifyEntity(tableParts[i]); } - for (var i = 0; i < balls.length; i++) { - if (!balls[i].isKnownID) { - balls[i] = Entities.identifyEntity(balls[i]); - } - Entities.deleteEntity(balls[i]); + Entities.deleteEntity(tableParts[i]); + } + for (var i = 0; i < balls.length; i++) { + if (!balls[i].isKnownID) { + balls[i] = Entities.identifyEntity(balls[i]); } - Overlays.deleteOverlay(reticle); - Entities.deleteEntity(cueBall); + Entities.deleteEntity(balls[i]); + } + Overlays.deleteOverlay(reticle); + Entities.deleteEntity(cueBall); } function update(deltaTime) { - if (!cueBall.isKnownID) { - cueBall = Entities.identifyEntity(cueBall); - } else { - // Check if cue ball has fallen off table, re-drop if so - var cueProperties = Entities.getEntityProperties(cueBall); - if (cueProperties.position.y < tableCenter.y) { - // Replace the cueball - Entities.editEntity(cueBall, { position: cuePosition } ); + if (!cueBall.isKnownID) { + cueBall = Entities.identifyEntity(cueBall); + } else { + // Check if cue ball has fallen off table, re-drop if so + var cueProperties = Entities.getEntityProperties(cueBall); + if (cueProperties.position.y < tableCenter.y) { + // Replace the cueball + Entities.editEntity(cueBall, { position: cuePosition } ); - } } + } } function entityCollisionWithEntity(entity1, entity2, collision) { - /* - NOT WORKING YET - if ((entity1.id == cueBall.id) || (entity2.id == cueBall.id)) { - print("Cue ball collision!"); - //audioOptions.position = Vec3.sum(Camera.getPosition(), Quat.getFront(Camera.getOrientation())); - //Audio.playSound(hitSounds[0], { position: Vec3.sum(Camera.getPosition(), Quat.getFront(Camera.getOrientation())) }); - } + /* + NOT WORKING YET + if ((entity1.id == cueBall.id) || (entity2.id == cueBall.id)) { + print("Cue ball collision!"); + //audioOptions.position = Vec3.sum(Camera.getPosition(), Quat.getFront(Camera.getOrientation())); + //Audio.playSound(hitSounds[0], { position: Vec3.sum(Camera.getPosition(), Quat.getFront(Camera.getOrientation())) }); + } - else if (isObjectBall(entity1.id) || isObjectBall(entity2.id)) { - print("Object ball collision"); - } */ + else if (isObjectBall(entity1.id) || isObjectBall(entity2.id)) { + print("Object ball collision"); + } */ } tableCenter = Vec3.sum(MyAvatar.position, Vec3.multiply(4.0, Quat.getFront(Camera.getOrientation()))); diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 53335beda0..fa726ee7db 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -65,16 +65,19 @@ void setSimId(EntityItemProperties& propertiesWithSimID, EntityItem* entity) { auto nodeList = DependencyManager::get(); const QUuid myNodeID = nodeList->getSessionUUID(); - // if this entity has non-zero physics/simulation related values, claim simulation ownership - if (propertiesWithSimID.velocityChanged() || - propertiesWithSimID.rotationChanged() || - propertiesWithSimID.containsPositionChange()) { - propertiesWithSimID.setSimulatorID(myNodeID); - entity->setSimulatorID(myNodeID); - } else if (entity->getSimulatorID() == myNodeID) { - propertiesWithSimID.setSimulatorID(QUuid()); // give up simulation ownership - entity->setSimulatorID(QUuid()); - } + // // if this entity has non-zero physics/simulation related values, claim simulation ownership + // if (propertiesWithSimID.velocityChanged() || + // propertiesWithSimID.rotationChanged() || + // propertiesWithSimID.containsPositionChange()) { + // propertiesWithSimID.setSimulatorID(myNodeID); + // entity->setSimulatorID(myNodeID); + // } else if (entity->getSimulatorID() == myNodeID) { + // propertiesWithSimID.setSimulatorID(QUuid()); // give up simulation ownership + // entity->setSimulatorID(QUuid()); + // } + + propertiesWithSimID.setSimulatorID(myNodeID); + entity->setSimulatorID(myNodeID); } diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 50990d708c..7a569a4987 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -366,45 +366,6 @@ void PhysicsEngine::stepNonPhysicalKinematics(const quint64& now) { } } - -void PhysicsEngine::bump(EntityItem* bumpEntity) { - // If this node is doing something like deleting an entity, scan for contacts involving the - // entity. For each found, flag the other entity involved as being simulated by this node. - lock(); - int numManifolds = _collisionDispatcher->getNumManifolds(); - for (int i = 0; i < numManifolds; ++i) { - btPersistentManifold* contactManifold = _collisionDispatcher->getManifoldByIndexInternal(i); - if (contactManifold->getNumContacts() > 0) { - const btCollisionObject* objectA = static_cast(contactManifold->getBody0()); - const btCollisionObject* objectB = static_cast(contactManifold->getBody1()); - if (objectA && objectB) { - void* a = objectA->getUserPointer(); - void* b = objectB->getUserPointer(); - if (a && b) { - EntityItem* entityA = a ? static_cast(a)->getEntity() : NULL; - EntityItem* entityB = b ? static_cast(b)->getEntity() : NULL; - if (entityA && entityB) { - if (entityA == bumpEntity) { - entityB->setShouldClaimSimulationOwnership(true); - if (!objectB->isActive()) { - objectB->setActivationState(ACTIVE_TAG); - } - } - if (entityB == bumpEntity) { - entityA->setShouldClaimSimulationOwnership(true); - if (!objectA->isActive()) { - objectA->setActivationState(ACTIVE_TAG); - } - } - } - } - } - } - } - unlock(); -} - - void PhysicsEngine::computeCollisionEvents() { BT_PROFILE("computeCollisionEvents"); @@ -570,9 +531,10 @@ void PhysicsEngine::addObject(const ShapeInfo& shapeInfo, btCollisionShape* shap void PhysicsEngine::removeObjectFromBullet(ObjectMotionState* motionState) { assert(motionState); - EntityItem* entity = static_cast(motionState)->getEntity(); - bump(entity); btRigidBody* body = motionState->getRigidBody(); + // set the about-to-be-deleted entity active in order to wake up the island it's part of. this is done + // so that anything resting on top of it will fall. + body->setActivationState(ACTIVE_TAG); if (body) { const btCollisionShape* shape = body->getCollisionShape(); _dynamicsWorld->removeRigidBody(body); diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index 148261c6d2..6e1f430237 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -98,7 +98,6 @@ private: // return 'true' of update was successful bool updateObjectHard(btRigidBody* body, ObjectMotionState* motionState, uint32_t flags); void updateObjectEasy(btRigidBody* body, ObjectMotionState* motionState, uint32_t flags); - void bump(EntityItem* bumpEntity); btClock _clock; btDefaultCollisionConfiguration* _collisionConfig = NULL; From d51f5a0ae85b5ca923dd6e36621e61e3cd2ad1d1 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 22 Apr 2015 17:22:37 -0700 Subject: [PATCH 22/26] remove commented out code --- libraries/entities/src/EntityScriptingInterface.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index fa726ee7db..32589c711b 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -64,18 +64,6 @@ void EntityScriptingInterface::setEntityTree(EntityTree* modelTree) { void setSimId(EntityItemProperties& propertiesWithSimID, EntityItem* entity) { auto nodeList = DependencyManager::get(); const QUuid myNodeID = nodeList->getSessionUUID(); - - // // if this entity has non-zero physics/simulation related values, claim simulation ownership - // if (propertiesWithSimID.velocityChanged() || - // propertiesWithSimID.rotationChanged() || - // propertiesWithSimID.containsPositionChange()) { - // propertiesWithSimID.setSimulatorID(myNodeID); - // entity->setSimulatorID(myNodeID); - // } else if (entity->getSimulatorID() == myNodeID) { - // propertiesWithSimID.setSimulatorID(QUuid()); // give up simulation ownership - // entity->setSimulatorID(QUuid()); - // } - propertiesWithSimID.setSimulatorID(myNodeID); entity->setSimulatorID(myNodeID); } From 4ca076ed940dea8429d1965a692f8c5f8ac59515 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 22 Apr 2015 18:53:49 -0700 Subject: [PATCH 23/26] put PhysicsEngine::bump back in. some things get missed if we just set the one thing active --- libraries/physics/src/PhysicsEngine.cpp | 43 ++++++++++++++++++++++++- libraries/physics/src/PhysicsEngine.h | 1 + 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 7a569a4987..e1551a0488 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -529,12 +529,53 @@ void PhysicsEngine::addObject(const ShapeInfo& shapeInfo, btCollisionShape* shap motionState->resetMeasuredAcceleration(); } +void PhysicsEngine::bump(EntityItem* bumpEntity) { + // If this node is doing something like deleting an entity, scan for contacts involving the + // entity. For each found, flag the other entity involved as being simulated by this node. + lock(); + int numManifolds = _collisionDispatcher->getNumManifolds(); + for (int i = 0; i < numManifolds; ++i) { + btPersistentManifold* contactManifold = _collisionDispatcher->getManifoldByIndexInternal(i); + if (contactManifold->getNumContacts() > 0) { + const btCollisionObject* objectA = static_cast(contactManifold->getBody0()); + const btCollisionObject* objectB = static_cast(contactManifold->getBody1()); + if (objectA && objectB) { + void* a = objectA->getUserPointer(); + void* b = objectB->getUserPointer(); + if (a && b) { + EntityItem* entityA = a ? static_cast(a)->getEntity() : NULL; + EntityItem* entityB = b ? static_cast(b)->getEntity() : NULL; + if (entityA && entityB) { + if (entityA == bumpEntity) { + entityB->setShouldClaimSimulationOwnership(true); + if (!objectB->isActive()) { + objectB->setActivationState(ACTIVE_TAG); + } + } + if (entityB == bumpEntity) { + entityA->setShouldClaimSimulationOwnership(true); + if (!objectA->isActive()) { + objectA->setActivationState(ACTIVE_TAG); + } + } + } + } + } + } + } + unlock(); +} + void PhysicsEngine::removeObjectFromBullet(ObjectMotionState* motionState) { assert(motionState); btRigidBody* body = motionState->getRigidBody(); + // set the about-to-be-deleted entity active in order to wake up the island it's part of. this is done // so that anything resting on top of it will fall. - body->setActivationState(ACTIVE_TAG); + // body->setActivationState(ACTIVE_TAG); + EntityItem* entity = static_cast(motionState)->getEntity(); + bump(entity); + if (body) { const btCollisionShape* shape = body->getCollisionShape(); _dynamicsWorld->removeRigidBody(body); diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index 6e1f430237..148261c6d2 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -98,6 +98,7 @@ private: // return 'true' of update was successful bool updateObjectHard(btRigidBody* body, ObjectMotionState* motionState, uint32_t flags); void updateObjectEasy(btRigidBody* body, ObjectMotionState* motionState, uint32_t flags); + void bump(EntityItem* bumpEntity); btClock _clock; btDefaultCollisionConfiguration* _collisionConfig = NULL; From 9e96026c5276ff673904e8437310a79cebb57439 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 22 Apr 2015 21:36:36 -0700 Subject: [PATCH 24/26] move _accelerationNearlyGravityCount and _shouldClaimSimulationOwnership from EntityItem to EntityMotionState --- libraries/entities/src/EntityItem.cpp | 2 -- libraries/entities/src/EntityItem.h | 8 ------- libraries/physics/src/EntityMotionState.cpp | 21 ++++++++++-------- libraries/physics/src/EntityMotionState.h | 9 ++++++++ libraries/physics/src/PhysicsEngine.cpp | 24 ++++++++++++--------- 5 files changed, 35 insertions(+), 29 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 5a141af581..1a52db6c67 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -47,7 +47,6 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) : _velocity(ENTITY_ITEM_DEFAULT_VELOCITY), _gravity(ENTITY_ITEM_DEFAULT_GRAVITY), _acceleration(ENTITY_ITEM_DEFAULT_ACCELERATION), - _accelerationNearlyGravityCount(0), _damping(ENTITY_ITEM_DEFAULT_DAMPING), _lifetime(ENTITY_ITEM_DEFAULT_LIFETIME), _script(ENTITY_ITEM_DEFAULT_SCRIPT), @@ -61,7 +60,6 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) : _userData(ENTITY_ITEM_DEFAULT_USER_DATA), _simulatorID(ENTITY_ITEM_DEFAULT_SIMULATOR_ID), _simulatorIDChangedTime(0), - _shouldClaimSimulationOwnership(false), _marketplaceID(ENTITY_ITEM_DEFAULT_MARKETPLACE_ID), _physicsInfo(NULL), _dirtyFlags(0), diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 5d19c11dc5..6fd17cc7d5 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -258,8 +258,6 @@ public: QUuid getSimulatorID() const { return _simulatorID; } void setSimulatorID(const QUuid& value); quint64 getSimulatorIDChangedTime() const { return _simulatorIDChangedTime; } - void setShouldClaimSimulationOwnership(bool value) { _shouldClaimSimulationOwnership = value; } - bool getShouldClaimSimulationOwnership() { return _shouldClaimSimulationOwnership; } const QString& getMarketplaceID() const { return _marketplaceID; } void setMarketplaceID(const QString& value) { _marketplaceID = value; } @@ -311,10 +309,6 @@ public: static void setSendPhysicsUpdates(bool value) { _sendPhysicsUpdates = value; } static bool getSendPhysicsUpdates() { return _sendPhysicsUpdates; } - void incrementAccelerationNearlyGravityCount() { _accelerationNearlyGravityCount++; } - void resetAccelerationNearlyGravityCount() { _accelerationNearlyGravityCount = 0; } - quint8 getAccelerationNearlyGravityCount() { return _accelerationNearlyGravityCount; } - protected: static bool _sendPhysicsUpdates; @@ -344,7 +338,6 @@ protected: glm::vec3 _velocity; glm::vec3 _gravity; glm::vec3 _acceleration; - quint8 _accelerationNearlyGravityCount; float _damping; float _lifetime; QString _script; @@ -358,7 +351,6 @@ protected: QString _userData; QUuid _simulatorID; // id of Node which is currently responsible for simulating this Entity quint64 _simulatorIDChangedTime; // when was _simulatorID last updated? - bool _shouldClaimSimulationOwnership; QString _marketplaceID; // NOTE: Damping is applied like this: v *= pow(1 - damping, dt) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 382cc5a734..d1571fbcc5 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -35,8 +35,11 @@ void EntityMotionState::enqueueOutgoingEntity(EntityItem* entity) { _outgoingEntityList->insert(entity); } -EntityMotionState::EntityMotionState(EntityItem* entity) - : _entity(entity) { +EntityMotionState::EntityMotionState(EntityItem* entity) : + _entity(entity), + _accelerationNearlyGravityCount(0), + _shouldClaimSimulationOwnership(false) +{ _type = MOTION_STATE_TYPE_ENTITY; assert(entity != NULL); } @@ -192,7 +195,7 @@ bool EntityMotionState::shouldSendUpdate(uint32_t simulationFrame) { return false; } - if (_entity->getShouldClaimSimulationOwnership()) { + if (getShouldClaimSimulationOwnership()) { return true; } @@ -219,19 +222,19 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ float accVsGravity = glm::abs(glm::length(_measuredAcceleration) - gravityLength); if (accVsGravity < ACCELERATION_EQUIVALENT_EPSILON_RATIO * gravityLength) { // acceleration measured during the most recent simulation step was close to gravity. - if (_entity->getAccelerationNearlyGravityCount() < STEPS_TO_DECIDE_BALLISTIC) { + if (getAccelerationNearlyGravityCount() < STEPS_TO_DECIDE_BALLISTIC) { // only increment this if we haven't reached the threshold yet. this is to avoid // overflowing the counter. - _entity->incrementAccelerationNearlyGravityCount(); + incrementAccelerationNearlyGravityCount(); } } else { // acceleration wasn't similar to this entities gravity, so reset the went-ballistic counter - _entity->resetAccelerationNearlyGravityCount(); + resetAccelerationNearlyGravityCount(); } // if this entity has been accelerated at close to gravity for a certain number of simulation-steps, let // the entity server's estimates include gravity. - if (_entity->getAccelerationNearlyGravityCount() >= STEPS_TO_DECIDE_BALLISTIC) { + if (getAccelerationNearlyGravityCount() >= STEPS_TO_DECIDE_BALLISTIC) { _entity->setAcceleration(_entity->getGravity()); } else { _entity->setAcceleration(glm::vec3(0.0f)); @@ -283,10 +286,10 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ QUuid myNodeID = nodeList->getSessionUUID(); QUuid simulatorID = _entity->getSimulatorID(); - if (_entity->getShouldClaimSimulationOwnership()) { + if (getShouldClaimSimulationOwnership()) { _entity->setSimulatorID(myNodeID); properties.setSimulatorID(myNodeID); - _entity->setShouldClaimSimulationOwnership(false); + setShouldClaimSimulationOwnership(false); } if (simulatorID == myNodeID && zeroSpeed && zeroSpin) { diff --git a/libraries/physics/src/EntityMotionState.h b/libraries/physics/src/EntityMotionState.h index 2b965a39d3..d3678a81fe 100644 --- a/libraries/physics/src/EntityMotionState.h +++ b/libraries/physics/src/EntityMotionState.h @@ -64,8 +64,17 @@ public: EntityItem* getEntity() const { return _entity; } + void incrementAccelerationNearlyGravityCount() { _accelerationNearlyGravityCount++; } + void resetAccelerationNearlyGravityCount() { _accelerationNearlyGravityCount = 0; } + quint8 getAccelerationNearlyGravityCount() { return _accelerationNearlyGravityCount; } + + void setShouldClaimSimulationOwnership(bool value) { _shouldClaimSimulationOwnership = value; } + bool getShouldClaimSimulationOwnership() { return _shouldClaimSimulationOwnership; } + protected: EntityItem* _entity; + quint8 _accelerationNearlyGravityCount; + bool _shouldClaimSimulationOwnership; }; #endif // hifi_EntityMotionState_h diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index e1551a0488..0a122c5fd6 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -392,9 +392,11 @@ void PhysicsEngine::computeCollisionEvents() { } void* a = objectA->getUserPointer(); - EntityItem* entityA = a ? static_cast(a)->getEntity() : NULL; + EntityMotionState* entityMotionStateA = static_cast(a); + EntityItem* entityA = entityMotionStateA ? entityMotionStateA->getEntity() : NULL; void* b = objectB->getUserPointer(); - EntityItem* entityB = b ? static_cast(b)->getEntity() : NULL; + EntityMotionState* entityMotionStateB = static_cast(b); + EntityItem* entityB = entityMotionStateB ? entityMotionStateB->getEntity() : NULL; if (a || b) { // the manifold has up to 4 distinct points, but only extract info from the first _contactMap[ContactKey(a, b)].update(_numContactFrames, contactManifold->getContactPoint(0), _originOffset); @@ -403,14 +405,14 @@ void PhysicsEngine::computeCollisionEvents() { // ownership of anything that collides with our avatar. if (entityA && entityB && !objectA->isStaticOrKinematicObject() && !objectB->isStaticOrKinematicObject()) { if (entityA->getSimulatorID() == myNodeID || - entityA->getShouldClaimSimulationOwnership() || + entityMotionStateA->getShouldClaimSimulationOwnership() || objectA == characterCollisionObject) { - entityB->setShouldClaimSimulationOwnership(true); + entityMotionStateB->setShouldClaimSimulationOwnership(true); } if (entityB->getSimulatorID() == myNodeID || - entityB->getShouldClaimSimulationOwnership() || + entityMotionStateA->getShouldClaimSimulationOwnership() || objectB == characterCollisionObject) { - entityA->setShouldClaimSimulationOwnership(true); + entityMotionStateB->setShouldClaimSimulationOwnership(true); } } } @@ -543,17 +545,19 @@ void PhysicsEngine::bump(EntityItem* bumpEntity) { void* a = objectA->getUserPointer(); void* b = objectB->getUserPointer(); if (a && b) { - EntityItem* entityA = a ? static_cast(a)->getEntity() : NULL; - EntityItem* entityB = b ? static_cast(b)->getEntity() : NULL; + EntityMotionState* entityMotionStateA = static_cast(a); + EntityMotionState* entityMotionStateB = static_cast(b); + EntityItem* entityA = entityMotionStateA ? entityMotionStateA->getEntity() : NULL; + EntityItem* entityB = entityMotionStateB ? entityMotionStateB->getEntity() : NULL; if (entityA && entityB) { if (entityA == bumpEntity) { - entityB->setShouldClaimSimulationOwnership(true); + entityMotionStateB->setShouldClaimSimulationOwnership(true); if (!objectB->isActive()) { objectB->setActivationState(ACTIVE_TAG); } } if (entityB == bumpEntity) { - entityA->setShouldClaimSimulationOwnership(true); + entityMotionStateA->setShouldClaimSimulationOwnership(true); if (!objectA->isActive()) { objectA->setActivationState(ACTIVE_TAG); } From 10e53783964feed07b76272d32da43eca8ee0dc8 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 23 Apr 2015 09:13:18 -0700 Subject: [PATCH 25/26] fix mangled if --- libraries/physics/src/PhysicsEngine.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 0a122c5fd6..f187f5727d 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -410,9 +410,9 @@ void PhysicsEngine::computeCollisionEvents() { entityMotionStateB->setShouldClaimSimulationOwnership(true); } if (entityB->getSimulatorID() == myNodeID || - entityMotionStateA->getShouldClaimSimulationOwnership() || + entityMotionStateB->getShouldClaimSimulationOwnership() || objectB == characterCollisionObject) { - entityMotionStateB->setShouldClaimSimulationOwnership(true); + entityMotionStateA->setShouldClaimSimulationOwnership(true); } } } From 2ca592de8b63080ac9d329db1ba3d57f472d7428 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 23 Apr 2015 10:02:29 -0700 Subject: [PATCH 26/26] fix logic with infectious simulation ownership --- libraries/physics/src/EntityMotionState.h | 7 ++-- libraries/physics/src/ObjectMotionState.h | 6 ++++ libraries/physics/src/PhysicsEngine.cpp | 42 ++++++++++++----------- 3 files changed, 31 insertions(+), 24 deletions(-) diff --git a/libraries/physics/src/EntityMotionState.h b/libraries/physics/src/EntityMotionState.h index d3678a81fe..07f82aaa42 100644 --- a/libraries/physics/src/EntityMotionState.h +++ b/libraries/physics/src/EntityMotionState.h @@ -62,14 +62,13 @@ public: virtual uint32_t getIncomingDirtyFlags() const; virtual void clearIncomingDirtyFlags(uint32_t flags) { _entity->clearDirtyFlags(flags); } - EntityItem* getEntity() const { return _entity; } - void incrementAccelerationNearlyGravityCount() { _accelerationNearlyGravityCount++; } void resetAccelerationNearlyGravityCount() { _accelerationNearlyGravityCount = 0; } quint8 getAccelerationNearlyGravityCount() { return _accelerationNearlyGravityCount; } - void setShouldClaimSimulationOwnership(bool value) { _shouldClaimSimulationOwnership = value; } - bool getShouldClaimSimulationOwnership() { return _shouldClaimSimulationOwnership; } + virtual EntityItem* getEntity() const { return _entity; } + virtual void setShouldClaimSimulationOwnership(bool value) { _shouldClaimSimulationOwnership = value; } + virtual bool getShouldClaimSimulationOwnership() { return _shouldClaimSimulationOwnership; } protected: EntityItem* _entity; diff --git a/libraries/physics/src/ObjectMotionState.h b/libraries/physics/src/ObjectMotionState.h index ad9ef861b9..9e0917a3ab 100644 --- a/libraries/physics/src/ObjectMotionState.h +++ b/libraries/physics/src/ObjectMotionState.h @@ -111,6 +111,12 @@ public: virtual bool isMoving() const = 0; friend class PhysicsEngine; + + // these are here so we can call into EntityMotionObject with a base-class pointer + virtual EntityItem* getEntity() const { return NULL; } + virtual void setShouldClaimSimulationOwnership(bool value) { } + virtual bool getShouldClaimSimulationOwnership() { return false; } + protected: void setRigidBody(btRigidBody* body); diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index f187f5727d..45f3c97e30 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -391,29 +391,31 @@ void PhysicsEngine::computeCollisionEvents() { continue; } - void* a = objectA->getUserPointer(); - EntityMotionState* entityMotionStateA = static_cast(a); - EntityItem* entityA = entityMotionStateA ? entityMotionStateA->getEntity() : NULL; - void* b = objectB->getUserPointer(); - EntityMotionState* entityMotionStateB = static_cast(b); - EntityItem* entityB = entityMotionStateB ? entityMotionStateB->getEntity() : NULL; + ObjectMotionState* a = static_cast(objectA->getUserPointer()); + ObjectMotionState* b = static_cast(objectB->getUserPointer()); + EntityItem* entityA = a ? a->getEntity() : NULL; + EntityItem* entityB = b ? b->getEntity() : NULL; + bool aIsDynamic = entityA && !objectA->isStaticOrKinematicObject(); + bool bIsDynamic = entityB && !objectB->isStaticOrKinematicObject(); + if (a || b) { // the manifold has up to 4 distinct points, but only extract info from the first _contactMap[ContactKey(a, b)].update(_numContactFrames, contactManifold->getContactPoint(0), _originOffset); - - // collisions cause infectious spread of simulation-ownership. we also attempt to take - // ownership of anything that collides with our avatar. - if (entityA && entityB && !objectA->isStaticOrKinematicObject() && !objectB->isStaticOrKinematicObject()) { - if (entityA->getSimulatorID() == myNodeID || - entityMotionStateA->getShouldClaimSimulationOwnership() || - objectA == characterCollisionObject) { - entityMotionStateB->setShouldClaimSimulationOwnership(true); - } - if (entityB->getSimulatorID() == myNodeID || - entityMotionStateB->getShouldClaimSimulationOwnership() || - objectB == characterCollisionObject) { - entityMotionStateA->setShouldClaimSimulationOwnership(true); - } + } + // collisions cause infectious spread of simulation-ownership. we also attempt to take + // ownership of anything that collides with our avatar. + if ((aIsDynamic && entityA->getSimulatorID() == myNodeID) || + (a && a->getShouldClaimSimulationOwnership()) || + (objectA == characterCollisionObject)) { + if (bIsDynamic) { + b->setShouldClaimSimulationOwnership(true); + } + } + if ((bIsDynamic && entityB->getSimulatorID() == myNodeID) || + (b && b->getShouldClaimSimulationOwnership()) || + (objectB == characterCollisionObject)) { + if (aIsDynamic) { + a->setShouldClaimSimulationOwnership(true); } } }