From 806ee88f1fbe50157b8b691d0de88800999c6d78 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 28 May 2015 09:43:36 -0700 Subject: [PATCH] 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();