From 2040fb4507c0aae989163df75cd5eac902171c8d Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Tue, 29 Sep 2015 09:32:34 -0700 Subject: [PATCH] fix skybox not always loading when you haven't moved or if the texture is slow in loading --- .../src/EntityTreeRenderer.cpp | 42 ++++++++++++++----- .../src/EntityTreeRenderer.h | 3 ++ 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index db86c91c02..7dea243145 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -113,9 +113,7 @@ void EntityTreeRenderer::init() { DependencyManager::get()->setEntitiesScriptEngine(_entitiesScriptEngine); } - // make sure our "last avatar position" is something other than our current position, so that on our - // first chance, we'll check for enter/leave entity events. - _lastAvatarPosition = _viewState->getAvatarPosition() + glm::vec3((float)TREE_SCALE); + forceRecheckEntities(); // setup our state to force checking our inside/outsideness of entities connect(entityTree.get(), &EntityTree::deletingEntity, this, &EntityTreeRenderer::deletingEntity, Qt::QueuedConnection); connect(entityTree.get(), &EntityTree::addingEntity, this, &EntityTreeRenderer::addingEntity, Qt::QueuedConnection); @@ -141,6 +139,13 @@ void EntityTreeRenderer::update() { // check to see if the avatar has moved and if we need to handle enter/leave entity logic 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 (_pendingSkyboxTextureDownload) { + applyZonePropertiesToScene(_bestZone); + } + // Even if we're not moving the mouse, if we started clicking on an entity and we have // not yet released the hold then this is still considered a holdingClickOnEntity event // and we want to simulate this message here as well as in mouse move @@ -156,7 +161,7 @@ void EntityTreeRenderer::update() { void EntityTreeRenderer::checkEnterLeaveEntities() { if (_tree && !_shuttingDown) { glm::vec3 avatarPosition = _viewState->getAvatarPosition(); - + if (avatarPosition != _lastAvatarPosition) { float radius = 1.0f; // for now, assume 1 meter radius QVector foundEntities; @@ -238,13 +243,17 @@ void EntityTreeRenderer::leaveAllEntities() { _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); } _currentEntitiesInside.clear(); - - // make sure our "last avatar position" is something other than our current position, so that on our - // first chance, we'll check for enter/leave entity events. - _lastAvatarPosition = _viewState->getAvatarPosition() + glm::vec3((float)TREE_SCALE); + forceRecheckEntities(); } } +void EntityTreeRenderer::forceRecheckEntities() { + // make sure our "last avatar position" is something other than our current position, + // so that on our next chance, we'll check for enter/leave entity events. + _lastAvatarPosition = _viewState->getAvatarPosition() + glm::vec3((float)TREE_SCALE); +} + + void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptr zone) { QSharedPointer scene = DependencyManager::get(); if (zone) { @@ -289,7 +298,8 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptroverrideEnvironmentData(data); scene->getSkyStage()->setBackgroundMode(model::SunSkyStage::SKY_DOME); - + _pendingSkyboxTextureDownload = false; + } else { _viewState->endOverrideEnvironmentData(); auto stage = scene->getSkyStage(); @@ -308,17 +318,26 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptrgetSkyboxProperties().getURL().isEmpty()) { skybox->setCubemap(gpu::TexturePointer()); + _pendingSkyboxTextureDownload = false; } else { // Update the Texture of the Skybox with the one pointed by this zone auto cubeMap = DependencyManager::get()->getTexture(zone->getSkyboxProperties().getURL(), CUBE_TEXTURE); - skybox->setCubemap(cubeMap->getGPUTexture()); + + if (cubeMap->getGPUTexture()) { + skybox->setCubemap(cubeMap->getGPUTexture()); + _pendingSkyboxTextureDownload = false; + } else { + _pendingSkyboxTextureDownload = true; + } } stage->setBackgroundMode(model::SunSkyStage::SKY_BOX); } else { stage->setBackgroundMode(model::SunSkyStage::SKY_DOME); // let the application atmosphere through + _pendingSkyboxTextureDownload = false; } } } else { + _pendingSkyboxTextureDownload = false; if (_hasPreviousZone) { scene->setKeyLightColor(_previousKeyLightColor); scene->setKeyLightIntensity(_previousKeyLightIntensity); @@ -642,6 +661,8 @@ void EntityTreeRenderer::deletingEntity(const EntityItemID& entityID) { _entitiesScriptEngine->unloadEntityScript(entityID); } + forceRecheckEntities(); // reset our state to force checking our inside/outsideness of entities + // here's where we remove the entity payload from the scene if (_entitiesInScene.contains(entityID)) { auto entity = _entitiesInScene.take(entityID); @@ -653,6 +674,7 @@ void EntityTreeRenderer::deletingEntity(const EntityItemID& entityID) { } void EntityTreeRenderer::addingEntity(const EntityItemID& entityID) { + forceRecheckEntities(); // reset our state to force checking our inside/outsideness of entities checkAndCallPreload(entityID); auto entity = std::static_pointer_cast(_tree)->findEntityByID(entityID); if (entity) { diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 76220952ef..08ff1ac296 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -138,7 +138,10 @@ private: QScriptValueList createEntityArgs(const EntityItemID& entityID); void checkEnterLeaveEntities(); void leaveAllEntities(); + void forceRecheckEntities(); + glm::vec3 _lastAvatarPosition; + bool _pendingSkyboxTextureDownload = false; QVector _currentEntitiesInside; bool _wantScripts;