diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 3bf1e7bc92..bc1f614f79 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -134,14 +134,14 @@ void EntityTreeRenderer::update() { EntityTreePointer tree = std::static_pointer_cast(_tree); tree->update(); - // check to see if the avatar has moved and if we need to handle enter/leave entity logic - checkEnterLeaveEntities(); + // Handle enter/leave entity logic + bool updated = checkEnterLeaveEntities(); - // even if we haven't changed positions, if we previously attempted to set the skybox, but - // have a pending download of the skybox texture, then we should attempt to reapply to - // get the correct texture. - if ((_pendingSkyboxTexture && _skyboxTexture && _skyboxTexture->isLoaded()) || - (_pendingAmbientTexture && _ambientTexture && _ambientTexture->isLoaded())) { + // If we haven't already updated and previously attempted to load a texture, + // check if the texture loaded and apply it + if (!updated && ( + (_pendingSkyboxTexture && _skyboxTexture && _skyboxTexture->isLoaded()) || + (_pendingAmbientTexture && _ambientTexture && _ambientTexture->isLoaded()))) { applyZonePropertiesToScene(_bestZone); } @@ -157,7 +157,7 @@ void EntityTreeRenderer::update() { deleteReleasedModels(); } -void EntityTreeRenderer::checkEnterLeaveEntities() { +bool EntityTreeRenderer::checkEnterLeaveEntities() { if (_tree && !_shuttingDown) { glm::vec3 avatarPosition = _viewState->getAvatarPosition(); @@ -172,7 +172,7 @@ void EntityTreeRenderer::checkEnterLeaveEntities() { std::static_pointer_cast(_tree)->findEntities(avatarPosition, radius, foundEntities); // Whenever you're in an intersection between zones, we will always choose the smallest zone. - _bestZone = NULL; // NOTE: Is this what we want? + _bestZone = nullptr; // NOTE: Is this what we want? _bestZoneVolume = std::numeric_limits::max(); // create a list of entities that actually contain the avatar's position @@ -205,7 +205,6 @@ void EntityTreeRenderer::checkEnterLeaveEntities() { } applyZonePropertiesToScene(_bestZone); - }); // Note: at this point we don't need to worry about the tree being locked, because we only deal with @@ -229,8 +228,11 @@ void EntityTreeRenderer::checkEnterLeaveEntities() { } _currentEntitiesInside = entitiesContainingAvatar; _lastAvatarPosition = avatarPosition; + + return true; } } + return false; } void EntityTreeRenderer::leaveAllEntities() { @@ -851,3 +853,19 @@ void EntityTreeRenderer::updateEntityRenderStatus(bool shouldRenderEntities) { } } } + +void EntityTreeRenderer::updateZone(const EntityItemID& id) { + if (!_bestZone) { + // Get in the zone! + auto zone = getTree()->findEntityByEntityItemID(id); + if (zone && zone->contains(_lastAvatarPosition)) { + _currentEntitiesInside << id; + emit enterEntity(id); + _entitiesScriptEngine->callEntityScriptMethod(id, "enterEntity"); + _bestZone = std::dynamic_pointer_cast(zone); + } + } + if (_bestZone && _bestZone->getID() == id) { + applyZonePropertiesToScene(_bestZone); + } +} diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index f1598221dd..5aadf7d299 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -109,6 +109,7 @@ public slots: void entitySciptChanging(const EntityItemID& entityID, const bool reload); void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision); void updateEntityRenderStatus(bool shouldRenderEntities); + void updateZone(const EntityItemID& id); // optional slots that can be wired to menu items void setDisplayModelBounds(bool value) { _displayModelBounds = value; } @@ -136,11 +137,11 @@ private: EntityItemID _currentClickingOnEntityID; QScriptValueList createEntityArgs(const EntityItemID& entityID); - void checkEnterLeaveEntities(); + bool checkEnterLeaveEntities(); void leaveAllEntities(); void forceRecheckEntities(); - glm::vec3 _lastAvatarPosition; + glm::vec3 _lastAvatarPosition { 0.0f }; QVector _currentEntitiesInside; bool _pendingSkyboxTexture { false }; diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index 44345ac0a2..ef47a777c2 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -18,6 +18,7 @@ #include #include +#include "EntityTreeRenderer.h" #include "RenderableEntityItem.h" // Sphere entities should fit inside a cube entity of the same size, so a sphere that has dimensions 1x1x1 @@ -62,6 +63,10 @@ bool RenderableZoneEntityItem::setProperties(const EntityItemProperties& propert return somethingChanged; } +void RenderableZoneEntityItem::somethingChangedNotification() { + DependencyManager::get()->updateZone(_id); +} + int RenderableZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, EntityPropertyFlags& propertyFlags, bool overwriteLocalData, diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.h b/libraries/entities-renderer/src/RenderableZoneEntityItem.h index 6eb829a48f..4ba862fff8 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.h +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.h @@ -28,6 +28,8 @@ public: { } virtual bool setProperties(const EntityItemProperties& properties); + virtual void somethingChangedNotification() override; + virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, EntityPropertyFlags& propertyFlags, bool overwriteLocalData,