diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index b198edc245..63c80ed27a 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -915,14 +915,9 @@ void MyAvatar::simulate(float deltaTime, bool inView) { auto entityTreeRenderer = qApp->getEntities(); EntityTreePointer entityTree = entityTreeRenderer ? entityTreeRenderer->getTree() : nullptr; if (entityTree) { - bool zoneAllowsFlying = true; - bool collisionlessAllowed = true; + std::pair zoneInteractionProperties; entityTree->withWriteLock([&] { - std::shared_ptr zone = entityTreeRenderer->myAvatarZone(); - if (zone) { - zoneAllowsFlying = zone->getFlyingAllowed(); - collisionlessAllowed = zone->getGhostingAllowed(); - } + zoneInteractionProperties = entityTreeRenderer->getZoneInteractionProperties(); EntityEditPacketSender* packetSender = qApp->getEntityEditPacketSender(); forEachDescendant([&](SpatiallyNestablePointer object) { // we need to update attached queryAACubes in our own local tree so point-select always works @@ -935,6 +930,8 @@ void MyAvatar::simulate(float deltaTime, bool inView) { }); }); bool isPhysicsEnabled = qApp->isPhysicsEnabled(); + bool zoneAllowsFlying = zoneInteractionProperties.first; + bool collisionlessAllowed = zoneInteractionProperties.second; _characterController.setFlyingAllowed((zoneAllowsFlying && _enableFlying) || !isPhysicsEnabled); _characterController.setCollisionlessAllowed(collisionlessAllowed); } diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 44025fc8f4..2b3a915235 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -1289,6 +1289,17 @@ CalculateEntityLoadingPriority EntityTreeRenderer::_calculateEntityLoadingPriori return 0.0f; }; +std::pair EntityTreeRenderer::getZoneInteractionProperties() { + for (auto& zone : _layeredZones) { + // Only domain entities control flying allowed and ghosting allowed + if (zone.zone && zone.zone->isDomainEntity()) { + return { zone.zone->getFlyingAllowed(), zone.zone->getGhostingAllowed() }; + } + } + + return { true, true }; +} + bool EntityTreeRenderer::wantsKeyboardFocus(const EntityItemID& id) const { auto renderable = renderableForEntityId(id); if (!renderable) { diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index d9f594a20b..725416e2cc 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -105,7 +105,7 @@ public: // For Scene.shouldRenderEntities QList& getEntitiesLastInScene() { return _entityIDsLastInScene; } - std::shared_ptr myAvatarZone() { return _layeredZones.getZone(); } + std::pair getZoneInteractionProperties(); bool wantsKeyboardFocus(const EntityItemID& id) const; QObject* getEventHandler(const EntityItemID& id); diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 7cafaece7a..c1488a5893 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -1414,8 +1414,9 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * @property {Entities.Bloom} bloom - The bloom properties of the zone. * * @property {boolean} flyingAllowed=true - If true then visitors can fly in the zone; otherwise they cannot. + * Only works on domain entities. * @property {boolean} ghostingAllowed=true - If true then visitors with avatar collisions turned off will not - * collide with content in the zone; otherwise visitors will always collide with content in the zone. + * collide with content in the zone; otherwise visitors will always collide with content in the zone. Only works on domain entities. * @property {string} filterURL="" - The URL of a JavaScript file that filters changes to properties of entities within the * zone. It is periodically executed for each entity in the zone. It can, for example, be used to not allow changes to diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index 1ebb488458..66ce5f32bf 100755 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -683,7 +683,7 @@ void CharacterController::updateState() { return; } if (_pendingFlags & PENDING_FLAG_RECOMPUTE_FLYING) { - SET_STATE(CharacterController::State::Hover, "recomputeFlying"); + SET_STATE(CharacterController::State::Hover, "recomputeFlying"); _hasSupport = false; _stepHeight = _minStepHeight; // clears memory of last step obstacle _pendingFlags &= ~PENDING_FLAG_RECOMPUTE_FLYING; @@ -795,15 +795,13 @@ void CharacterController::updateState() { // Transition to hover if we are above the fall threshold SET_STATE(State::Hover, "above fall threshold"); } - } else if (!rayHasHit && !_hasSupport) { - SET_STATE(State::Hover, "no ground detected"); } break; } case State::Hover: btScalar horizontalSpeed = (velocity - velocity.dot(_currentUp) * _currentUp).length(); bool flyingFast = horizontalSpeed > (MAX_WALKING_SPEED * 0.75f); - if (!_flyingAllowed && rayHasHit) { + if (!_flyingAllowed) { SET_STATE(State::InAir, "flying not allowed"); } else if ((_floorDistance < MIN_HOVER_HEIGHT) && !jumpButtonHeld && !flyingFast) { SET_STATE(State::InAir, "near ground");