diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index 06632dabb0..dde8a01b26 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -17,7 +17,6 @@ #include #include -#include #include #include #include @@ -36,7 +35,7 @@ const char* LOCAL_MODELS_PERSIST_FILE = "resources/models.svo"; EntityServer::EntityServer(ReceivedMessage& message) : OctreeServer(message), - _entitySimulation(NULL), + _entitySimulation(nullptr), _dynamicDomainVerificationTimer(this) { DependencyManager::set(); diff --git a/assignment-client/src/entities/EntityServer.h b/assignment-client/src/entities/EntityServer.h index 4d3f1ee89f..9bb3a237e0 100644 --- a/assignment-client/src/entities/EntityServer.h +++ b/assignment-client/src/entities/EntityServer.h @@ -16,9 +16,11 @@ #include -#include "EntityItem.h" +#include +#include +#include + #include "EntityServerConsts.h" -#include "EntityTree.h" /// Handles assignments of type EntityServer - sending entities to various clients. @@ -27,9 +29,6 @@ struct ViewerSendingStats { quint64 lastEdited; }; -class SimpleEntitySimulation; -using SimpleEntitySimulationPointer = std::shared_ptr; - class EntityServer : public OctreeServer, public NewlyCreatedEntityHook { Q_OBJECT public: diff --git a/assignment-client/src/scripts/EntityScriptServer.cpp b/assignment-client/src/scripts/EntityScriptServer.cpp index f1a6c97831..514eb62380 100644 --- a/assignment-client/src/scripts/EntityScriptServer.cpp +++ b/assignment-client/src/scripts/EntityScriptServer.cpp @@ -301,10 +301,17 @@ void EntityScriptServer::run() { entityScriptingInterface->setEntityTree(_entityViewer.getTree()); - DependencyManager::set(_entityViewer.getTree()); + auto treePtr = _entityViewer.getTree(); + DependencyManager::set(treePtr); + if (!_entitySimulation) { + SimpleEntitySimulationPointer simpleSimulation { new SimpleEntitySimulation() }; + simpleSimulation->setEntityTree(treePtr); + treePtr->setSimulation(simpleSimulation); + _entitySimulation = simpleSimulation; + } - auto tree = _entityViewer.getTree().get(); + auto tree = treePtr.get(); connect(tree, &EntityTree::deletingEntity, this, &EntityScriptServer::deletingEntity, Qt::QueuedConnection); connect(tree, &EntityTree::addingEntity, this, &EntityScriptServer::addingEntity, Qt::QueuedConnection); connect(tree, &EntityTree::entityServerScriptChanging, this, &EntityScriptServer::entityServerScriptChanging, Qt::QueuedConnection); @@ -451,6 +458,7 @@ void EntityScriptServer::resetEntitiesScriptEngine() { connect(newEngine.data(), &ScriptEngine::update, this, [this] { _entityViewer.queryOctree(); + _entityViewer.getTree()->preUpdate(); _entityViewer.getTree()->update(); }); diff --git a/assignment-client/src/scripts/EntityScriptServer.h b/assignment-client/src/scripts/EntityScriptServer.h index 944fee36a3..b795339174 100644 --- a/assignment-client/src/scripts/EntityScriptServer.h +++ b/assignment-client/src/scripts/EntityScriptServer.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include "../entities/EntityTreeHeadlessViewer.h" @@ -75,6 +76,7 @@ private: static int _entitiesScriptEngineCount; ScriptEnginePointer _entitiesScriptEngine; + SimpleEntitySimulationPointer _entitySimulation; EntityEditPacketSender _entityEditSender; EntityTreeHeadlessViewer _entityViewer; diff --git a/interface/src/avatar/OtherAvatar.cpp b/interface/src/avatar/OtherAvatar.cpp index 8c8c42679b..5673c2443f 100755 --- a/interface/src/avatar/OtherAvatar.cpp +++ b/interface/src/avatar/OtherAvatar.cpp @@ -512,13 +512,13 @@ void OtherAvatar::handleChangedAvatarEntityData() { entity->setParentID(NULL_ID); entity->setParentID(oldParentID); - if (entity->stillHasMyGrabAction()) { + if (entity->stillHasMyGrab()) { // For this case: we want to ignore transform+velocities coming from authoritative OtherAvatar // because the MyAvatar is grabbing and we expect the local grab state // to have enough information to prevent simulation drift. // // Clever readers might realize this could cause problems. For example, - // if an ignored OtherAvagtar were to simultanously grab the object then there would be + // if an ignored OtherAvatar were to simultanously grab the object then there would be // a noticeable discrepancy between participants in the distributed physics simulation, // however the difference would be stable and would not drift. properties.clearTransformOrVelocityChanges(); diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 747d1e9a77..53afb34de5 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -798,7 +798,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef auto lastEdited = lastEditedFromBufferAdjusted; bool otherOverwrites = overwriteLocalData && !weOwnSimulation; // calculate hasGrab once outside the lambda rather than calling it every time inside - bool hasGrab = stillHasGrabAction(); + bool hasGrab = stillHasGrab(); auto shouldUpdate = [lastEdited, otherOverwrites, filterRejection, hasGrab](quint64 updatedTimestamp, bool valueChanged) { if (hasGrab) { return false; @@ -1444,7 +1444,7 @@ void EntityItem::getTransformAndVelocityProperties(EntityItemProperties& propert void EntityItem::upgradeScriptSimulationPriority(uint8_t priority) { uint8_t newPriority = glm::max(priority, _scriptSimulationPriority); - if (newPriority < SCRIPT_GRAB_SIMULATION_PRIORITY && stillHasMyGrabAction()) { + if (newPriority < SCRIPT_GRAB_SIMULATION_PRIORITY && stillHasMyGrab()) { newPriority = SCRIPT_GRAB_SIMULATION_PRIORITY; } if (newPriority != _scriptSimulationPriority) { @@ -1457,7 +1457,7 @@ void EntityItem::upgradeScriptSimulationPriority(uint8_t priority) { void EntityItem::clearScriptSimulationPriority() { // DO NOT markDirtyFlags(Simulation::DIRTY_SIMULATION_OWNERSHIP_PRIORITY) here, because this // is only ever called from the code that actually handles the dirty flags, and it knows best. - _scriptSimulationPriority = stillHasMyGrabAction() ? SCRIPT_GRAB_SIMULATION_PRIORITY : 0; + _scriptSimulationPriority = stillHasMyGrab() ? SCRIPT_GRAB_SIMULATION_PRIORITY : 0; } void EntityItem::setPendingOwnershipPriority(uint8_t priority) { @@ -2204,7 +2204,7 @@ void EntityItem::enableNoBootstrap() { } void EntityItem::disableNoBootstrap() { - if (!stillHasMyGrabAction()) { + if (!stillHasMyGrab()) { _flags &= ~Simulation::SPECIAL_FLAG_NO_BOOTSTRAPPING; _flags |= Simulation::DIRTY_COLLISION_GROUP; // may need to not collide with own avatar @@ -2290,33 +2290,25 @@ bool EntityItem::removeAction(EntitySimulationPointer simulation, const QUuid& a return success; } -bool EntityItem::stillHasGrabAction() const { - return !_grabActions.empty(); +bool EntityItem::stillHasGrab() const { + return !(_grabs.empty()); } -// retutrns 'true' if there exists an action that returns 'true' for EntityActionInterface::isMine() +// returns 'true' if there exists an action that returns 'true' for EntityActionInterface::isMine() // (e.g. the action belongs to the MyAvatar instance) -bool EntityItem::stillHasMyGrabAction() const { - QList holdActions = getActionsOfType(DYNAMIC_TYPE_HOLD); - QList::const_iterator i = holdActions.begin(); - while (i != holdActions.end()) { - EntityDynamicPointer action = *i; - if (action->isMine()) { - return true; - } - i++; +bool EntityItem::stillHasMyGrab() const { + bool foundGrab = false; + if (!_grabs.empty()) { + _grabsLock.withReadLock([&] { + foreach (const GrabPointer &grab, _grabs) { + if (grab->getOwnerID() == Physics::getSessionUUID()) { + foundGrab = true; + break; + } + } + }); } - QList farGrabActions = getActionsOfType(DYNAMIC_TYPE_FAR_GRAB); - i = farGrabActions.begin(); - while (i != farGrabActions.end()) { - EntityDynamicPointer action = *i; - if (action->isMine()) { - return true; - } - i++; - } - - return false; + return foundGrab; } bool EntityItem::removeActionInternal(const QUuid& actionID, EntitySimulationPointer simulation) { diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 5c7596f6dc..3274379ee9 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -569,7 +569,7 @@ public: static void setPrimaryViewFrustumPositionOperator(std::function getPrimaryViewFrustumPositionOperator) { _getPrimaryViewFrustumPositionOperator = getPrimaryViewFrustumPositionOperator; } static glm::vec3 getPrimaryViewFrustumPosition() { return _getPrimaryViewFrustumPositionOperator(); } - bool stillHasMyGrabAction() const; + bool stillHasMyGrab() const; bool needsRenderUpdate() const { return resultWithReadLock([&] { return _needsRenderUpdate; }); } void setNeedsRenderUpdate(bool needsRenderUpdate) { withWriteLock([&] { _needsRenderUpdate = needsRenderUpdate; }); } @@ -585,7 +585,7 @@ protected: void setSimulated(bool simulated) { _simulated = simulated; } const QByteArray getDynamicDataInternal() const; - bool stillHasGrabAction() const; + bool stillHasGrab() const; void setDynamicDataInternal(QByteArray dynamicData); virtual void dimensionsChanged() override; diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index dca3ac595a..6c12c6d019 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -2246,8 +2246,8 @@ void EntityTree::preUpdate() { void EntityTree::update(bool simulate) { PROFILE_RANGE(simulation_physics, "UpdateTree"); PerformanceTimer perfTimer("updateTree"); - withWriteLock([&] { - if (simulate && _simulation) { + if (simulate && _simulation) { + withWriteLock([&] { _simulation->updateEntities(); { PROFILE_RANGE(simulation_physics, "Deletes"); @@ -2265,8 +2265,8 @@ void EntityTree::update(bool simulate) { deleteEntities(idsToDelete, true); } } - } - }); + }); + } } quint64 EntityTree::getAdjustedConsiderSince(quint64 sinceTime) { diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index dc1c79e0eb..52a8c8db16 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -274,6 +274,7 @@ enum class EntityVersion : PacketVersion { TextUnlit, ShadowBiasAndDistance, TextEntityFonts, + ScriptServerKinematicMotion, // Add new versions above here NUM_PACKET_TYPE, diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 67aa7d2d7d..68c8266e9f 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -740,7 +740,8 @@ bool EntityMotionState::shouldSendBid() const { && (_region == workload::Region::R1) && _ownershipState != EntityMotionState::OwnershipState::Unownable && glm::max(glm::max(VOLUNTEER_SIMULATION_PRIORITY, _bumpedPriority), _entity->getScriptSimulationPriority()) >= _entity->getSimulationPriority() - && !_entity->getLocked(); + && !_entity->getLocked() + && (!_body->isStaticOrKinematicObject() || _entity->stillHasMyGrab()); } void EntityMotionState::setRigidBody(btRigidBody* body) {