Merge pull request #16146 from AndrewMeadows/ess-with-simulation

BUGZ-1385: allow entity-script-server to move entities kinematically
This commit is contained in:
Shannon Romano 2019-09-09 07:51:28 -07:00 committed by GitHub
commit c7db287458
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 47 additions and 45 deletions

View file

@ -17,7 +17,6 @@
#include <QJsonDocument> #include <QJsonDocument>
#include <EntityTree.h> #include <EntityTree.h>
#include <SimpleEntitySimulation.h>
#include <ResourceCache.h> #include <ResourceCache.h>
#include <ScriptCache.h> #include <ScriptCache.h>
#include <EntityEditFilters.h> #include <EntityEditFilters.h>
@ -36,7 +35,7 @@ const char* LOCAL_MODELS_PERSIST_FILE = "resources/models.svo";
EntityServer::EntityServer(ReceivedMessage& message) : EntityServer::EntityServer(ReceivedMessage& message) :
OctreeServer(message), OctreeServer(message),
_entitySimulation(NULL), _entitySimulation(nullptr),
_dynamicDomainVerificationTimer(this) _dynamicDomainVerificationTimer(this)
{ {
DependencyManager::set<ResourceManager>(); DependencyManager::set<ResourceManager>();

View file

@ -16,9 +16,11 @@
#include <memory> #include <memory>
#include "EntityItem.h" #include <EntityItem.h>
#include <EntityTree.h>
#include <SimpleEntitySimulation.h>
#include "EntityServerConsts.h" #include "EntityServerConsts.h"
#include "EntityTree.h"
/// Handles assignments of type EntityServer - sending entities to various clients. /// Handles assignments of type EntityServer - sending entities to various clients.
@ -27,9 +29,6 @@ struct ViewerSendingStats {
quint64 lastEdited; quint64 lastEdited;
}; };
class SimpleEntitySimulation;
using SimpleEntitySimulationPointer = std::shared_ptr<SimpleEntitySimulation>;
class EntityServer : public OctreeServer, public NewlyCreatedEntityHook { class EntityServer : public OctreeServer, public NewlyCreatedEntityHook {
Q_OBJECT Q_OBJECT
public: public:

View file

@ -301,10 +301,17 @@ void EntityScriptServer::run() {
entityScriptingInterface->setEntityTree(_entityViewer.getTree()); entityScriptingInterface->setEntityTree(_entityViewer.getTree());
DependencyManager::set<AssignmentParentFinder>(_entityViewer.getTree()); auto treePtr = _entityViewer.getTree();
DependencyManager::set<AssignmentParentFinder>(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::deletingEntity, this, &EntityScriptServer::deletingEntity, Qt::QueuedConnection);
connect(tree, &EntityTree::addingEntity, this, &EntityScriptServer::addingEntity, Qt::QueuedConnection); connect(tree, &EntityTree::addingEntity, this, &EntityScriptServer::addingEntity, Qt::QueuedConnection);
connect(tree, &EntityTree::entityServerScriptChanging, this, &EntityScriptServer::entityServerScriptChanging, 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] { connect(newEngine.data(), &ScriptEngine::update, this, [this] {
_entityViewer.queryOctree(); _entityViewer.queryOctree();
_entityViewer.getTree()->preUpdate();
_entityViewer.getTree()->update(); _entityViewer.getTree()->update();
}); });

View file

@ -21,6 +21,7 @@
#include <EntityEditPacketSender.h> #include <EntityEditPacketSender.h>
#include <plugins/CodecPlugin.h> #include <plugins/CodecPlugin.h>
#include <ScriptEngine.h> #include <ScriptEngine.h>
#include <SimpleEntitySimulation.h>
#include <ThreadedAssignment.h> #include <ThreadedAssignment.h>
#include "../entities/EntityTreeHeadlessViewer.h" #include "../entities/EntityTreeHeadlessViewer.h"
@ -75,6 +76,7 @@ private:
static int _entitiesScriptEngineCount; static int _entitiesScriptEngineCount;
ScriptEnginePointer _entitiesScriptEngine; ScriptEnginePointer _entitiesScriptEngine;
SimpleEntitySimulationPointer _entitySimulation;
EntityEditPacketSender _entityEditSender; EntityEditPacketSender _entityEditSender;
EntityTreeHeadlessViewer _entityViewer; EntityTreeHeadlessViewer _entityViewer;

View file

@ -512,13 +512,13 @@ void OtherAvatar::handleChangedAvatarEntityData() {
entity->setParentID(NULL_ID); entity->setParentID(NULL_ID);
entity->setParentID(oldParentID); entity->setParentID(oldParentID);
if (entity->stillHasMyGrabAction()) { if (entity->stillHasMyGrab()) {
// For this case: we want to ignore transform+velocities coming from authoritative OtherAvatar // 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 // because the MyAvatar is grabbing and we expect the local grab state
// to have enough information to prevent simulation drift. // to have enough information to prevent simulation drift.
// //
// Clever readers might realize this could cause problems. For example, // 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, // a noticeable discrepancy between participants in the distributed physics simulation,
// however the difference would be stable and would not drift. // however the difference would be stable and would not drift.
properties.clearTransformOrVelocityChanges(); properties.clearTransformOrVelocityChanges();

View file

@ -798,7 +798,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
auto lastEdited = lastEditedFromBufferAdjusted; auto lastEdited = lastEditedFromBufferAdjusted;
bool otherOverwrites = overwriteLocalData && !weOwnSimulation; bool otherOverwrites = overwriteLocalData && !weOwnSimulation;
// calculate hasGrab once outside the lambda rather than calling it every time inside // 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) { auto shouldUpdate = [lastEdited, otherOverwrites, filterRejection, hasGrab](quint64 updatedTimestamp, bool valueChanged) {
if (hasGrab) { if (hasGrab) {
return false; return false;
@ -1444,7 +1444,7 @@ void EntityItem::getTransformAndVelocityProperties(EntityItemProperties& propert
void EntityItem::upgradeScriptSimulationPriority(uint8_t priority) { void EntityItem::upgradeScriptSimulationPriority(uint8_t priority) {
uint8_t newPriority = glm::max(priority, _scriptSimulationPriority); 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; newPriority = SCRIPT_GRAB_SIMULATION_PRIORITY;
} }
if (newPriority != _scriptSimulationPriority) { if (newPriority != _scriptSimulationPriority) {
@ -1457,7 +1457,7 @@ void EntityItem::upgradeScriptSimulationPriority(uint8_t priority) {
void EntityItem::clearScriptSimulationPriority() { void EntityItem::clearScriptSimulationPriority() {
// DO NOT markDirtyFlags(Simulation::DIRTY_SIMULATION_OWNERSHIP_PRIORITY) here, because this // 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. // 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) { void EntityItem::setPendingOwnershipPriority(uint8_t priority) {
@ -2204,7 +2204,7 @@ void EntityItem::enableNoBootstrap() {
} }
void EntityItem::disableNoBootstrap() { void EntityItem::disableNoBootstrap() {
if (!stillHasMyGrabAction()) { if (!stillHasMyGrab()) {
_flags &= ~Simulation::SPECIAL_FLAG_NO_BOOTSTRAPPING; _flags &= ~Simulation::SPECIAL_FLAG_NO_BOOTSTRAPPING;
_flags |= Simulation::DIRTY_COLLISION_GROUP; // may need to not collide with own avatar _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; return success;
} }
bool EntityItem::stillHasGrabAction() const { bool EntityItem::stillHasGrab() const {
return !_grabActions.empty(); 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) // (e.g. the action belongs to the MyAvatar instance)
bool EntityItem::stillHasMyGrabAction() const { bool EntityItem::stillHasMyGrab() const {
QList<EntityDynamicPointer> holdActions = getActionsOfType(DYNAMIC_TYPE_HOLD); bool foundGrab = false;
QList<EntityDynamicPointer>::const_iterator i = holdActions.begin(); if (!_grabs.empty()) {
while (i != holdActions.end()) { _grabsLock.withReadLock([&] {
EntityDynamicPointer action = *i; foreach (const GrabPointer &grab, _grabs) {
if (action->isMine()) { if (grab->getOwnerID() == Physics::getSessionUUID()) {
return true; foundGrab = true;
} break;
i++; }
}
});
} }
QList<EntityDynamicPointer> farGrabActions = getActionsOfType(DYNAMIC_TYPE_FAR_GRAB); return foundGrab;
i = farGrabActions.begin();
while (i != farGrabActions.end()) {
EntityDynamicPointer action = *i;
if (action->isMine()) {
return true;
}
i++;
}
return false;
} }
bool EntityItem::removeActionInternal(const QUuid& actionID, EntitySimulationPointer simulation) { bool EntityItem::removeActionInternal(const QUuid& actionID, EntitySimulationPointer simulation) {

View file

@ -569,7 +569,7 @@ public:
static void setPrimaryViewFrustumPositionOperator(std::function<glm::vec3()> getPrimaryViewFrustumPositionOperator) { _getPrimaryViewFrustumPositionOperator = getPrimaryViewFrustumPositionOperator; } static void setPrimaryViewFrustumPositionOperator(std::function<glm::vec3()> getPrimaryViewFrustumPositionOperator) { _getPrimaryViewFrustumPositionOperator = getPrimaryViewFrustumPositionOperator; }
static glm::vec3 getPrimaryViewFrustumPosition() { return _getPrimaryViewFrustumPositionOperator(); } static glm::vec3 getPrimaryViewFrustumPosition() { return _getPrimaryViewFrustumPositionOperator(); }
bool stillHasMyGrabAction() const; bool stillHasMyGrab() const;
bool needsRenderUpdate() const { return resultWithReadLock<bool>([&] { return _needsRenderUpdate; }); } bool needsRenderUpdate() const { return resultWithReadLock<bool>([&] { return _needsRenderUpdate; }); }
void setNeedsRenderUpdate(bool needsRenderUpdate) { withWriteLock([&] { _needsRenderUpdate = needsRenderUpdate; }); } void setNeedsRenderUpdate(bool needsRenderUpdate) { withWriteLock([&] { _needsRenderUpdate = needsRenderUpdate; }); }
@ -585,7 +585,7 @@ protected:
void setSimulated(bool simulated) { _simulated = simulated; } void setSimulated(bool simulated) { _simulated = simulated; }
const QByteArray getDynamicDataInternal() const; const QByteArray getDynamicDataInternal() const;
bool stillHasGrabAction() const; bool stillHasGrab() const;
void setDynamicDataInternal(QByteArray dynamicData); void setDynamicDataInternal(QByteArray dynamicData);
virtual void dimensionsChanged() override; virtual void dimensionsChanged() override;

View file

@ -2246,8 +2246,8 @@ void EntityTree::preUpdate() {
void EntityTree::update(bool simulate) { void EntityTree::update(bool simulate) {
PROFILE_RANGE(simulation_physics, "UpdateTree"); PROFILE_RANGE(simulation_physics, "UpdateTree");
PerformanceTimer perfTimer("updateTree"); PerformanceTimer perfTimer("updateTree");
withWriteLock([&] { if (simulate && _simulation) {
if (simulate && _simulation) { withWriteLock([&] {
_simulation->updateEntities(); _simulation->updateEntities();
{ {
PROFILE_RANGE(simulation_physics, "Deletes"); PROFILE_RANGE(simulation_physics, "Deletes");
@ -2265,8 +2265,8 @@ void EntityTree::update(bool simulate) {
deleteEntities(idsToDelete, true); deleteEntities(idsToDelete, true);
} }
} }
} });
}); }
} }
quint64 EntityTree::getAdjustedConsiderSince(quint64 sinceTime) { quint64 EntityTree::getAdjustedConsiderSince(quint64 sinceTime) {

View file

@ -274,6 +274,7 @@ enum class EntityVersion : PacketVersion {
TextUnlit, TextUnlit,
ShadowBiasAndDistance, ShadowBiasAndDistance,
TextEntityFonts, TextEntityFonts,
ScriptServerKinematicMotion,
// Add new versions above here // Add new versions above here
NUM_PACKET_TYPE, NUM_PACKET_TYPE,

View file

@ -740,7 +740,8 @@ bool EntityMotionState::shouldSendBid() const {
&& (_region == workload::Region::R1) && (_region == workload::Region::R1)
&& _ownershipState != EntityMotionState::OwnershipState::Unownable && _ownershipState != EntityMotionState::OwnershipState::Unownable
&& glm::max(glm::max(VOLUNTEER_SIMULATION_PRIORITY, _bumpedPriority), _entity->getScriptSimulationPriority()) >= _entity->getSimulationPriority() && 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) { void EntityMotionState::setRigidBody(btRigidBody* body) {