From 5ad9efbee434539cff2e6b500b44abde9a6bbaa1 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 27 May 2015 20:42:53 -0700 Subject: [PATCH 1/4] allow entities to tell us if they support proper scene rendering --- .../src/EntityTreeRenderer.cpp | 34 ++++++++++++------- .../src/RenderableLightEntityItem.h | 1 + .../src/RenderableModelEntityItem.h | 1 + .../src/RenderableTextEntityItem.h | 1 + .../src/RenderableWebEntityItem.h | 1 + libraries/entities/src/EntityItem.h | 1 + 6 files changed, 26 insertions(+), 13 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index b59ea7e7af..9818657c5a 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -96,9 +96,16 @@ void EntityTreeRenderer::clear() { OctreeRenderer::clear(); _entityScripts.clear(); - // TODO/FIXME - this needs to be fixed... we need to clear all items out of the scene in this case. qDebug() << "EntityTreeRenderer::clear() need to clear the scene... "; - + render::Scene::PendingChanges pendingChanges; + QHashIterator i(_entityToSceneItems); + while (i.hasNext()) { + i.next(); + render::ItemID renderItem = i.value(); + pendingChanges.removeItem(renderItem); + } + _entityToSceneItems.clear(); + _viewState->getMain3DScene()->enqueuePendingChanges(pendingChanges); } void EntityTreeRenderer::init() { @@ -704,8 +711,8 @@ void EntityTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args) } } - // hack for models. :( - if (entityItem->getType() == EntityTypes::Model) { + // hack for models and other entities that don't yet play well with others. :( + if (!entityItem->canRenderInScene()) { // render entityItem AABox entityBox = entityItem->getAABox(); @@ -1076,19 +1083,20 @@ void EntityTreeRenderer::addingEntity(const EntityItemID& entityID) { checkAndCallPreload(entityID); // here's where we add the entity payload to the scene - - render::Scene::PendingChanges pendingChanges; - render::ItemID renderItem = _viewState->getMain3DScene()->allocateID(); - _entityToSceneItems[entityID] = renderItem; EntityItemPointer entity = static_cast(_tree)->findEntityByID(entityID); + if (entity->canRenderInScene()) { + render::Scene::PendingChanges pendingChanges; + render::ItemID renderItem = _viewState->getMain3DScene()->allocateID(); + _entityToSceneItems[entityID] = renderItem; - auto renderData = RenderableEntityItem::Pointer(new RenderableEntityItem(entity)); - auto renderPayload = render::PayloadPointer(new RenderableEntityItem::Payload(renderData)); + auto renderData = RenderableEntityItem::Pointer(new RenderableEntityItem(entity)); + auto renderPayload = render::PayloadPointer(new RenderableEntityItem::Payload(renderData)); - pendingChanges.resetItem(renderItem, renderPayload); + pendingChanges.resetItem(renderItem, renderPayload); - _viewState->getMain3DScene()->enqueuePendingChanges(pendingChanges); - _viewState->getMain3DScene()->processPendingChangesQueue(); + _viewState->getMain3DScene()->enqueuePendingChanges(pendingChanges); + _viewState->getMain3DScene()->processPendingChangesQueue(); + } } void EntityTreeRenderer::entitySciptChanging(const EntityItemID& entityID) { diff --git a/libraries/entities-renderer/src/RenderableLightEntityItem.h b/libraries/entities-renderer/src/RenderableLightEntityItem.h index 427557432c..a90bb0baad 100644 --- a/libraries/entities-renderer/src/RenderableLightEntityItem.h +++ b/libraries/entities-renderer/src/RenderableLightEntityItem.h @@ -22,6 +22,7 @@ public: LightEntityItem(entityItemID, properties) { } + virtual bool canRenderInScene() { return false; } // we don't yet play well with others virtual void render(RenderArgs* args); virtual bool supportsDetailedRayIntersection() const { return true; } virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index f504019e67..335f3a4d25 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -43,6 +43,7 @@ public: virtual void somethingChangedNotification() { _needsInitialSimulation = true; } + virtual bool canRenderInScene() { return false; } // we don't yet play well with others virtual void render(RenderArgs* args); virtual bool supportsDetailedRayIntersection() const { return true; } virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.h b/libraries/entities-renderer/src/RenderableTextEntityItem.h index aa761461ac..eb2cfc16f1 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.h +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.h @@ -27,6 +27,7 @@ public: ~RenderableTextEntityItem() { delete _textRenderer; } virtual void render(RenderArgs* args); + virtual bool canRenderInScene() { return false; } // we don't yet play well with others private: TextRenderer* _textRenderer = TextRenderer::getInstance(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE / 2.0f); diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.h b/libraries/entities-renderer/src/RenderableWebEntityItem.h index 8dad2a0855..2ad4d799b6 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.h +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.h @@ -24,6 +24,7 @@ public: virtual void render(RenderArgs* args); virtual void setSourceUrl(const QString& value); + virtual bool canRenderInScene() { return false; } // we don't yet play well with others private: OffscreenQmlSurface* _webSurface{ nullptr }; diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 8f88b6de07..ed59a347af 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -151,6 +151,7 @@ public: EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { return 0; } + virtual bool canRenderInScene() { return true; } // does your entity property render using Render Items and Payloads virtual void render(RenderArgs* args) { } // by default entity items don't know how to render static int expectedBytes(); From 3f14a7a26297c6db1f78e1c543cedc5ddf41ab5d Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 27 May 2015 21:00:20 -0700 Subject: [PATCH 2/4] allow entities to have multiple items --- .../src/EntityTreeRenderer.cpp | 21 ++++++++++++------- .../src/EntityTreeRenderer.h | 2 +- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 9818657c5a..0f58ecb30a 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -98,11 +98,13 @@ void EntityTreeRenderer::clear() { qDebug() << "EntityTreeRenderer::clear() need to clear the scene... "; render::Scene::PendingChanges pendingChanges; - QHashIterator i(_entityToSceneItems); - while (i.hasNext()) { - i.next(); - render::ItemID renderItem = i.value(); - pendingChanges.removeItem(renderItem); + + QList keys = _entityToSceneItems.uniqueKeys(); + for (auto key : keys) { + QList values = _entityToSceneItems.values(key); + for (auto renderItem : values) { + pendingChanges.removeItem(renderItem); + } } _entityToSceneItems.clear(); _viewState->getMain3DScene()->enqueuePendingChanges(pendingChanges); @@ -1073,8 +1075,11 @@ void EntityTreeRenderer::deletingEntity(const EntityItemID& entityID) { render::Scene::PendingChanges pendingChanges; if (_entityToSceneItems.contains(entityID)) { - render::ItemID renderItem = _entityToSceneItems[entityID]; - pendingChanges.removeItem(renderItem); + + QList values = _entityToSceneItems.values(entityID); + for (render::ItemID renderItem : values) { + pendingChanges.removeItem(renderItem); + } _viewState->getMain3DScene()->enqueuePendingChanges(pendingChanges); } } @@ -1087,7 +1092,7 @@ void EntityTreeRenderer::addingEntity(const EntityItemID& entityID) { if (entity->canRenderInScene()) { render::Scene::PendingChanges pendingChanges; render::ItemID renderItem = _viewState->getMain3DScene()->allocateID(); - _entityToSceneItems[entityID] = renderItem; + _entityToSceneItems.insert(entityID, renderItem); auto renderData = RenderableEntityItem::Pointer(new RenderableEntityItem(entity)); auto renderPayload = render::PayloadPointer(new RenderableEntityItem::Payload(renderData)); diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 22d6703069..90b4859a32 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -187,7 +187,7 @@ private: float _previousStageHour; int _previousStageDay; - QHash _entityToSceneItems; + QMultiHash _entityToSceneItems; }; From 806ee88f1fbe50157b8b691d0de88800999c6d78 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 28 May 2015 09:43:36 -0700 Subject: [PATCH 3/4] place burden of adding/removing to/from scene on entity --- .../src/EntityTreeRenderer.cpp | 48 ++++++------------- .../src/EntityTreeRenderer.h | 2 +- .../src/RenderableBoxEntityItem.h | 7 +++ .../src/RenderableEntityItem.cpp | 6 +-- .../src/RenderableEntityItem.h | 40 +++++++++++++--- .../src/RenderableLineEntityItem.h | 7 +++ .../src/RenderableParticleEffectEntityItem.h | 7 +++ .../src/RenderableSphereEntityItem.h | 8 ++++ libraries/entities/src/EntityItem.h | 9 +++- 9 files changed, 90 insertions(+), 44 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 0f58ecb30a..1f22343a67 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -96,18 +96,11 @@ void EntityTreeRenderer::clear() { OctreeRenderer::clear(); _entityScripts.clear(); - qDebug() << "EntityTreeRenderer::clear() need to clear the scene... "; - render::Scene::PendingChanges pendingChanges; - - QList keys = _entityToSceneItems.uniqueKeys(); - for (auto key : keys) { - QList values = _entityToSceneItems.values(key); - for (auto renderItem : values) { - pendingChanges.removeItem(renderItem); - } + auto scene = _viewState->getMain3DScene(); + foreach(auto entity, _entitiesInScene) { + entity->removeFromScene(entity, scene); } - _entityToSceneItems.clear(); - _viewState->getMain3DScene()->enqueuePendingChanges(pendingChanges); + _entitiesInScene.clear(); } void EntityTreeRenderer::init() { @@ -1072,15 +1065,11 @@ void EntityTreeRenderer::deletingEntity(const EntityItemID& entityID) { _entityScripts.remove(entityID); // here's where we remove the entity payload from the scene - - render::Scene::PendingChanges pendingChanges; - if (_entityToSceneItems.contains(entityID)) { - - QList values = _entityToSceneItems.values(entityID); - for (render::ItemID renderItem : values) { - pendingChanges.removeItem(renderItem); - } - _viewState->getMain3DScene()->enqueuePendingChanges(pendingChanges); + auto entity = static_cast(_tree)->findEntityByID(entityID); + if (entity && _entitiesInScene.contains(entity)) { + auto scene = _viewState->getMain3DScene(); + entity->removeFromScene(entity, scene); + _entitiesInScene.remove(entity); } } @@ -1088,19 +1077,12 @@ void EntityTreeRenderer::addingEntity(const EntityItemID& entityID) { checkAndCallPreload(entityID); // here's where we add the entity payload to the scene - EntityItemPointer entity = static_cast(_tree)->findEntityByID(entityID); - if (entity->canRenderInScene()) { - render::Scene::PendingChanges pendingChanges; - render::ItemID renderItem = _viewState->getMain3DScene()->allocateID(); - _entityToSceneItems.insert(entityID, renderItem); - - auto renderData = RenderableEntityItem::Pointer(new RenderableEntityItem(entity)); - auto renderPayload = render::PayloadPointer(new RenderableEntityItem::Payload(renderData)); - - pendingChanges.resetItem(renderItem, renderPayload); - - _viewState->getMain3DScene()->enqueuePendingChanges(pendingChanges); - _viewState->getMain3DScene()->processPendingChangesQueue(); + auto entity = static_cast(_tree)->findEntityByID(entityID); + if (entity && entity->canRenderInScene()) { + auto scene = _viewState->getMain3DScene(); + if (entity->addToScene(entity, scene)) { + _entitiesInScene.insert(entity); + } } } diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 90b4859a32..234e590b7d 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -187,7 +187,7 @@ private: float _previousStageHour; int _previousStageDay; - QMultiHash _entityToSceneItems; + QSet _entitiesInScene; }; diff --git a/libraries/entities-renderer/src/RenderableBoxEntityItem.h b/libraries/entities-renderer/src/RenderableBoxEntityItem.h index 6ae76b0315..fdc91a7e79 100644 --- a/libraries/entities-renderer/src/RenderableBoxEntityItem.h +++ b/libraries/entities-renderer/src/RenderableBoxEntityItem.h @@ -14,6 +14,7 @@ #include #include "RenderableDebugableEntityItem.h" +#include "RenderableEntityItem.h" class RenderableBoxEntityItem : public BoxEntityItem { public: @@ -24,6 +25,12 @@ 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; }; diff --git a/libraries/entities-renderer/src/RenderableEntityItem.cpp b/libraries/entities-renderer/src/RenderableEntityItem.cpp index 355a004594..23c94e705c 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableEntityItem.cpp @@ -13,17 +13,17 @@ #include "RenderableEntityItem.h" namespace render { - template <> const ItemKey payloadGetKey(const RenderableEntityItem::Pointer& payload) { + template <> const ItemKey payloadGetKey(const RenderableEntityItemProxy::Pointer& payload) { return ItemKey::Builder::opaqueShape(); } - template <> const Item::Bound payloadGetBound(const RenderableEntityItem::Pointer& payload) { + template <> const Item::Bound payloadGetBound(const RenderableEntityItemProxy::Pointer& payload) { if (payload && payload->entity) { return payload->entity->getAABox(); } return render::Item::Bound(); } - template <> void payloadRender(const RenderableEntityItem::Pointer& payload, RenderArgs* args) { + template <> void payloadRender(const RenderableEntityItemProxy::Pointer& payload, RenderArgs* args) { if (args) { args->_elementsTouched++; if (payload && payload->entity) { diff --git a/libraries/entities-renderer/src/RenderableEntityItem.h b/libraries/entities-renderer/src/RenderableEntityItem.h index 028bc5efa5..14c231279c 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.h +++ b/libraries/entities-renderer/src/RenderableEntityItem.h @@ -15,19 +15,47 @@ #include #include -class RenderableEntityItem { + +class RenderableEntityItemProxy { public: - RenderableEntityItem(EntityItemPointer entity) : entity(entity) { } - typedef render::Payload Payload; + RenderableEntityItemProxy(EntityItemPointer entity) : entity(entity) { } + typedef render::Payload Payload; typedef Payload::DataPointer Pointer; EntityItemPointer entity; }; namespace render { - template <> const ItemKey payloadGetKey(const RenderableEntityItem::Pointer& payload); - template <> const Item::Bound payloadGetBound(const RenderableEntityItem::Pointer& payload); - template <> void payloadRender(const RenderableEntityItem::Pointer& payload, RenderArgs* args); + template <> const ItemKey payloadGetKey(const RenderableEntityItemProxy::Pointer& payload); + template <> const Item::Bound payloadGetBound(const RenderableEntityItemProxy::Pointer& payload); + template <> void payloadRender(const RenderableEntityItemProxy::Pointer& payload, RenderArgs* args); } +// Mixin class for implementing basic single item rendering +class SingleRenderableEntityItem { +public: + bool addToScene(EntityItemPointer self, std::shared_ptr scene) { + render::Scene::PendingChanges pendingChanges; + _myItem = scene->allocateID(); + + auto renderData = RenderableEntityItemProxy::Pointer(new RenderableEntityItemProxy(self)); + auto renderPayload = render::PayloadPointer(new RenderableEntityItemProxy::Payload(renderData)); + + pendingChanges.resetItem(_myItem, renderPayload); + + scene->enqueuePendingChanges(pendingChanges); + return true; + } + + void removeFromScene(EntityItemPointer self, std::shared_ptr scene) { + render::Scene::PendingChanges pendingChanges; + pendingChanges.removeItem(_myItem); + scene->enqueuePendingChanges(pendingChanges); + } + +private: + render::ItemID _myItem; +}; + + #endif // hifi_RenderableEntityItem_h diff --git a/libraries/entities-renderer/src/RenderableLineEntityItem.h b/libraries/entities-renderer/src/RenderableLineEntityItem.h index 8f04ca9e9c..001eb48961 100644 --- a/libraries/entities-renderer/src/RenderableLineEntityItem.h +++ b/libraries/entities-renderer/src/RenderableLineEntityItem.h @@ -14,6 +14,7 @@ #include #include "RenderableDebugableEntityItem.h" +#include "RenderableEntityItem.h" class RenderableLineEntityItem : public LineEntityItem { public: @@ -23,6 +24,12 @@ public: LineEntityItem(entityItemID, properties) { } 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; }; diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h index a449278895..4ae9c5b566 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h @@ -13,6 +13,7 @@ #include #include +#include "RenderableEntityItem.h" class RenderableParticleEffectEntityItem : public ParticleEffectEntityItem { public: @@ -22,6 +23,12 @@ 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; + protected: int _cacheID; diff --git a/libraries/entities-renderer/src/RenderableSphereEntityItem.h b/libraries/entities-renderer/src/RenderableSphereEntityItem.h index 3b02541061..3be35b45f7 100644 --- a/libraries/entities-renderer/src/RenderableSphereEntityItem.h +++ b/libraries/entities-renderer/src/RenderableSphereEntityItem.h @@ -14,6 +14,8 @@ #include +#include "RenderableEntityItem.h" + class RenderableSphereEntityItem : public SphereEntityItem { public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); @@ -23,6 +25,12 @@ 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; }; diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index ed59a347af..d620359018 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -12,6 +12,7 @@ #ifndef hifi_EntityItem_h #define hifi_EntityItem_h +#include #include #include @@ -33,6 +34,10 @@ class EntitySimulation; class EntityTreeElement; class EntityTreeElementExtraEncodeData; +namespace render { + class Scene; +} + // these thesholds determine what updates will be ignored (client and server) const float IGNORE_POSITION_DELTA = 0.0001f; const float IGNORE_DIMENSIONS_DELTA = 0.0005f; @@ -151,7 +156,9 @@ public: EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { return 0; } - virtual bool canRenderInScene() { return true; } // does your entity property render using Render Items and Payloads + 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 void render(RenderArgs* args) { } // by default entity items don't know how to render static int expectedBytes(); From 2fba5a0928e943f8192c2abd25949abb6ae4cb1c Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 28 May 2015 12:19:43 -0700 Subject: [PATCH 4/4] more work on simple renderable --- interface/src/Application.cpp | 2 +- interface/src/avatar/AvatarManager.cpp | 6 +-- .../src/EntityTreeRenderer.cpp | 12 ++++-- .../src/RenderableBoxEntityItem.h | 6 +-- .../src/RenderableEntityItem.h | 20 +++++---- .../src/RenderableLineEntityItem.h | 6 +-- .../src/RenderableParticleEffectEntityItem.h | 6 +-- .../src/RenderableSphereEntityItem.h | 6 +-- libraries/entities/CMakeLists.txt | 1 + libraries/entities/src/EntityItem.h | 7 +++- libraries/render/src/render/Scene.cpp | 10 ++--- libraries/render/src/render/Scene.h | 41 ++++++++++--------- 12 files changed, 62 insertions(+), 61 deletions(-) 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() {}