diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5bc1040a34..7de903edf2 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3406,7 +3406,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se } } - render::Scene::PendingChanges pendingChanges; + render::PendingChanges pendingChanges; // Make sure the WorldBox is in the scene if (WorldBoxRenderData::_item == 0) { diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index a4b437c009..8f8a3a8ef3 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -67,7 +67,7 @@ void AvatarManager::init() { auto avatarPayloadPointer = Avatar::PayloadPointer(avatarPayload); static_cast(_myAvatar.get())->_renderItemID = scene->allocateID(); - render::Scene::PendingChanges pendingChanges; + render::PendingChanges pendingChanges; pendingChanges.resetItem(static_cast(_myAvatar.get())->_renderItemID, avatarPayloadPointer); scene->enqueuePendingChanges(pendingChanges); @@ -152,7 +152,7 @@ AvatarSharedPointer AvatarManager::addAvatar(const QUuid& sessionUUID, const QWe auto avatarPayloadPointer = Avatar::PayloadPointer(avatarPayload); static_cast(avatar.get())->_renderItemID = scene->allocateID(); - render::Scene::PendingChanges pendingChanges; + render::PendingChanges pendingChanges; pendingChanges.resetItem(static_cast(avatar.get())->_renderItemID, avatarPayloadPointer); scene->enqueuePendingChanges(pendingChanges); @@ -186,7 +186,7 @@ void AvatarManager::removeAvatar(const QUuid& sessionUUID) { } render::ScenePointer scene = Application::getInstance()->getMain3DScene(); - render::Scene::PendingChanges pendingChanges; + render::PendingChanges pendingChanges; pendingChanges.removeItem(avatar->_renderItemID); scene->enqueuePendingChanges(pendingChanges); } diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 1f22343a67..c44f70c74e 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -97,9 +97,11 @@ void EntityTreeRenderer::clear() { _entityScripts.clear(); auto scene = _viewState->getMain3DScene(); + render::PendingChanges pendingChanges; foreach(auto entity, _entitiesInScene) { - entity->removeFromScene(entity, scene); + entity->removeFromScene(entity, scene, pendingChanges); } + scene->enqueuePendingChanges(pendingChanges); _entitiesInScene.clear(); } @@ -1067,8 +1069,10 @@ void EntityTreeRenderer::deletingEntity(const EntityItemID& entityID) { // here's where we remove the entity payload from the scene auto entity = static_cast(_tree)->findEntityByID(entityID); if (entity && _entitiesInScene.contains(entity)) { + render::PendingChanges pendingChanges; auto scene = _viewState->getMain3DScene(); - entity->removeFromScene(entity, scene); + entity->removeFromScene(entity, scene, pendingChanges); + scene->enqueuePendingChanges(pendingChanges); _entitiesInScene.remove(entity); } } @@ -1079,10 +1083,12 @@ void EntityTreeRenderer::addingEntity(const EntityItemID& entityID) { // here's where we add the entity payload to the scene auto entity = static_cast(_tree)->findEntityByID(entityID); if (entity && entity->canRenderInScene()) { + render::PendingChanges pendingChanges; auto scene = _viewState->getMain3DScene(); - if (entity->addToScene(entity, scene)) { + if (entity->addToScene(entity, scene, pendingChanges)) { _entitiesInScene.insert(entity); } + scene->enqueuePendingChanges(pendingChanges); } } diff --git a/libraries/entities-renderer/src/RenderableBoxEntityItem.h b/libraries/entities-renderer/src/RenderableBoxEntityItem.h index fdc91a7e79..06a62706b9 100644 --- a/libraries/entities-renderer/src/RenderableBoxEntityItem.h +++ b/libraries/entities-renderer/src/RenderableBoxEntityItem.h @@ -26,11 +26,7 @@ public: virtual void render(RenderArgs* args); - virtual bool canRenderInScene() { return true; } // we use our _renderHelper to render in scene - virtual bool addToScene(EntityItemPointer self, std::shared_ptr scene) { return _renderHelper.addToScene(self, scene); } - virtual void removeFromScene(EntityItemPointer self, std::shared_ptr scene) { _renderHelper.removeFromScene(self, scene); } -private: - SingleRenderableEntityItem _renderHelper; + SIMPLE_RENDERABLE() }; diff --git a/libraries/entities-renderer/src/RenderableEntityItem.h b/libraries/entities-renderer/src/RenderableEntityItem.h index 14c231279c..92eef7e8ea 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.h +++ b/libraries/entities-renderer/src/RenderableEntityItem.h @@ -32,10 +32,9 @@ namespace render { } // Mixin class for implementing basic single item rendering -class SingleRenderableEntityItem { +class SimpleRenderableEntityItem { public: - bool addToScene(EntityItemPointer self, std::shared_ptr scene) { - render::Scene::PendingChanges pendingChanges; + bool addToScene(EntityItemPointer self, std::shared_ptr scene, render::PendingChanges& pendingChanges) { _myItem = scene->allocateID(); auto renderData = RenderableEntityItemProxy::Pointer(new RenderableEntityItemProxy(self)); @@ -43,14 +42,11 @@ public: pendingChanges.resetItem(_myItem, renderPayload); - scene->enqueuePendingChanges(pendingChanges); return true; } - void removeFromScene(EntityItemPointer self, std::shared_ptr scene) { - render::Scene::PendingChanges pendingChanges; + void removeFromScene(EntityItemPointer self, std::shared_ptr scene, render::PendingChanges& pendingChanges) { pendingChanges.removeItem(_myItem); - scene->enqueuePendingChanges(pendingChanges); } private: @@ -58,4 +54,14 @@ private: }; +#define SIMPLE_RENDERABLE() \ +public: \ + virtual bool canRenderInScene() { return true; } \ + virtual bool addToScene(EntityItemPointer self, std::shared_ptr scene, render::PendingChanges& pendingChanges) { return _renderHelper.addToScene(self, scene, pendingChanges); } \ + virtual void removeFromScene(EntityItemPointer self, std::shared_ptr scene, render::PendingChanges& pendingChanges) { _renderHelper.removeFromScene(self, scene, pendingChanges); } \ +private: \ + SimpleRenderableEntityItem _renderHelper; + + + #endif // hifi_RenderableEntityItem_h diff --git a/libraries/entities-renderer/src/RenderableLineEntityItem.h b/libraries/entities-renderer/src/RenderableLineEntityItem.h index 001eb48961..eb23b3ee48 100644 --- a/libraries/entities-renderer/src/RenderableLineEntityItem.h +++ b/libraries/entities-renderer/src/RenderableLineEntityItem.h @@ -25,11 +25,7 @@ public: virtual void render(RenderArgs* args); - virtual bool canRenderInScene() { return true; } // we use our _renderHelper to render in scene - virtual bool addToScene(EntityItemPointer self, std::shared_ptr scene) { return _renderHelper.addToScene(self, scene); } - virtual void removeFromScene(EntityItemPointer self, std::shared_ptr scene) { _renderHelper.removeFromScene(self, scene); } -private: - SingleRenderableEntityItem _renderHelper; + SIMPLE_RENDERABLE() }; diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h index 4ae9c5b566..66505a2cd2 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h @@ -23,11 +23,7 @@ public: void updateQuads(RenderArgs* args, bool textured); - virtual bool canRenderInScene() { return true; } // we use our _renderHelper to render in scene - virtual bool addToScene(EntityItemPointer self, std::shared_ptr scene) { return _renderHelper.addToScene(self, scene); } - virtual void removeFromScene(EntityItemPointer self, std::shared_ptr scene) { _renderHelper.removeFromScene(self, scene); } -private: - SingleRenderableEntityItem _renderHelper; + SIMPLE_RENDERABLE() protected: diff --git a/libraries/entities-renderer/src/RenderableSphereEntityItem.h b/libraries/entities-renderer/src/RenderableSphereEntityItem.h index 3be35b45f7..b6f7ff996e 100644 --- a/libraries/entities-renderer/src/RenderableSphereEntityItem.h +++ b/libraries/entities-renderer/src/RenderableSphereEntityItem.h @@ -26,11 +26,7 @@ public: virtual void render(RenderArgs* args); - virtual bool canRenderInScene() { return true; } // we use our _renderHelper to render in scene - virtual bool addToScene(EntityItemPointer self, std::shared_ptr scene) { return _renderHelper.addToScene(self, scene); } - virtual void removeFromScene(EntityItemPointer self, std::shared_ptr scene) { _renderHelper.removeFromScene(self, scene); } -private: - SingleRenderableEntityItem _renderHelper; + SIMPLE_RENDERABLE() }; diff --git a/libraries/entities/CMakeLists.txt b/libraries/entities/CMakeLists.txt index d21906fa3f..926fd8b4b2 100644 --- a/libraries/entities/CMakeLists.txt +++ b/libraries/entities/CMakeLists.txt @@ -14,3 +14,4 @@ target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${BULLET_INCLUDE_DIRS}) target_link_libraries(${TARGET_NAME} ${BULLET_LIBRARIES}) link_hifi_libraries(avatars shared octree gpu model fbx networking animation environment) +include_hifi_library_headers(render) diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index d620359018..4e299086e5 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -36,6 +36,7 @@ class EntityTreeElementExtraEncodeData; namespace render { class Scene; + class PendingChanges; } // these thesholds determine what updates will be ignored (client and server) @@ -157,8 +158,10 @@ public: { return 0; } virtual bool canRenderInScene() { return false; } // does your entity property render using Render Items and Payloads - virtual bool addToScene(EntityItemPointer self, std::shared_ptr scene) { return false; } // by default entity items don't add to scene - virtual void removeFromScene(EntityItemPointer self, std::shared_ptr scene) { } // by default entity items don't add to scene + virtual bool addToScene(EntityItemPointer self, std::shared_ptr scene, + render::PendingChanges& pendingChanges) { return false; } // by default entity items don't add to scene + virtual void removeFromScene(EntityItemPointer self, std::shared_ptr scene, + render::PendingChanges& pendingChanges) { } // by default entity items don't add to scene virtual void render(RenderArgs* args) { } // by default entity items don't know how to render static int expectedBytes(); diff --git a/libraries/render/src/render/Scene.cpp b/libraries/render/src/render/Scene.cpp index 8f9c5906ca..329538fe1f 100644 --- a/libraries/render/src/render/Scene.cpp +++ b/libraries/render/src/render/Scene.cpp @@ -68,21 +68,21 @@ void Item::move() { } -void Scene::PendingChanges::resetItem(ItemID id, const PayloadPointer& payload) { +void PendingChanges::resetItem(ItemID id, const PayloadPointer& payload) { _resetItems.push_back(id); _resetPayloads.push_back(payload); } -void Scene::PendingChanges::removeItem(ItemID id) { +void PendingChanges::removeItem(ItemID id) { _removedItems.push_back(id); } -void Scene::PendingChanges::moveItem(ItemID id) { +void PendingChanges::moveItem(ItemID id) { _movedItems.push_back(id); } -void Scene::PendingChanges::merge(PendingChanges& changes) { +void PendingChanges::merge(PendingChanges& changes) { _resetItems.insert(_resetItems.end(), changes._resetItems.begin(), changes._resetItems.end()); _resetPayloads.insert(_resetPayloads.end(), changes._resetPayloads.begin(), changes._resetPayloads.end()); _removedItems.insert(_removedItems.end(), changes._removedItems.begin(), changes._removedItems.end()); @@ -106,7 +106,7 @@ void Scene::enqueuePendingChanges(const PendingChanges& pendingChanges) { _changeQueueMutex.unlock(); } -void consolidateChangeQueue(Scene::PendingChangesQueue& queue, Scene::PendingChanges& singleBatch) { +void consolidateChangeQueue(PendingChangesQueue& queue, PendingChanges& singleBatch) { while (!queue.empty()) { auto pendingChanges = queue.front(); singleBatch.merge(pendingChanges); diff --git a/libraries/render/src/render/Scene.h b/libraries/render/src/render/Scene.h index c7d112e74b..520d3d4577 100644 --- a/libraries/render/src/render/Scene.h +++ b/libraries/render/src/render/Scene.h @@ -303,6 +303,27 @@ public: class Engine; class Observer; +class PendingChanges { +public: + PendingChanges() {} + ~PendingChanges() {} + + void resetItem(ItemID id, const PayloadPointer& payload); + void removeItem(ItemID id); + void moveItem(ItemID id); + + void merge(PendingChanges& changes); + + Payloads _resetPayloads; + ItemIDs _resetItems; + ItemIDs _removedItems; + ItemIDs _movedItems; + +protected: +}; +typedef std::queue PendingChangesQueue; + + // Scene is a container for Items // Items are introduced, modified or erased in the scene through PendingChanges // Once per Frame, the PendingChanges are all flushed @@ -340,26 +361,6 @@ public: typedef std::shared_ptr< Observer > ObserverPointer; typedef std::vector< ObserverPointer > Observers; - class PendingChanges { - public: - PendingChanges() {} - ~PendingChanges() {} - - void resetItem(ItemID id, const PayloadPointer& payload); - void removeItem(ItemID id); - void moveItem(ItemID id); - - void merge(PendingChanges& changes); - - Payloads _resetPayloads; - ItemIDs _resetItems; - ItemIDs _removedItems; - ItemIDs _movedItems; - - protected: - }; - typedef std::queue PendingChangesQueue; - Scene(); ~Scene() {}