diff --git a/libraries/render-utils/src/ZoneRenderer.cpp b/libraries/render-utils/src/ZoneRenderer.cpp index e2bf9a5d22..2cabe58c33 100644 --- a/libraries/render-utils/src/ZoneRenderer.cpp +++ b/libraries/render-utils/src/ZoneRenderer.cpp @@ -19,7 +19,7 @@ const Selection::Name ZoneRendererTask::ZONES_SELECTION { "RankedZones" }; void ZoneRendererTask::build(JobModel& task, const Varying& input, Varying& ouput) { - const auto zoneItems = task.addJob("FilterZones", input, ZONES_SELECTION.c_str()); + const auto zoneItems = task.addJob("FilterZones", input, ZONES_SELECTION.c_str()); // just draw them... task.addJob("DrawZones", zoneItems); diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index e8537e3452..1b4cd48ffc 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -150,6 +150,7 @@ const gpu::PipelinePointer DrawBounds::getPipeline() { _cornerLocation = program->getUniforms().findLocation("inBoundPos"); _scaleLocation = program->getUniforms().findLocation("inBoundDim"); + _colorLocation = program->getUniforms().findLocation("inColor"); auto state = std::make_shared(); state->setDepthTest(true, false, gpu::LESS_EQUAL); @@ -184,12 +185,16 @@ void DrawBounds::run(const SceneContextPointer& sceneContext, const RenderContex assert(_scaleLocation >= 0); // Render bounds + float numItems = (float) items.size(); + float itemNum = 0.0f; for (const auto& item : items) { batch._glUniform3fv(_cornerLocation, 1, (const float*)(&item.bound.getCorner())); batch._glUniform3fv(_scaleLocation, 1, (const float*)(&item.bound.getScale())); + batch._glUniform4fv(_colorLocation, 1, (const float*)(&glm::vec4(glm::vec3(itemNum / numItems), 1.0f))); static const int NUM_VERTICES_PER_CUBE = 24; batch.draw(gpu::LINES, NUM_VERTICES_PER_CUBE, 0); + itemNum += 1.0f; } }); } diff --git a/libraries/render/src/render/DrawTask.h b/libraries/render/src/render/DrawTask.h index d1856cb66e..9a74802888 100755 --- a/libraries/render/src/render/DrawTask.h +++ b/libraries/render/src/render/DrawTask.h @@ -67,6 +67,7 @@ private: gpu::PipelinePointer _boundsPipeline; int _cornerLocation { -1 }; int _scaleLocation { -1 }; + int _colorLocation { -1 }; }; } diff --git a/libraries/render/src/render/FilterTask.cpp b/libraries/render/src/render/FilterTask.cpp index 22d5feffe4..76b42b0813 100644 --- a/libraries/render/src/render/FilterTask.cpp +++ b/libraries/render/src/render/FilterTask.cpp @@ -52,12 +52,13 @@ void SliceItems::run(const SceneContextPointer& sceneContext, const RenderContex } void SelectItems::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemBounds& outItems) { - auto& scene = sceneContext->_scene; - - outItems.clear(); - auto selection = scene->getSelection(_name); + auto selection = sceneContext->_scene->getSelection(_name); const auto& selectedItems = selection.getItems(); + outItems.clear(); + if (!selectedItems.empty()) { + outItems.reserve(selectedItems.size()); + for (auto src : inItems) { if (selection.contains(src.id)) { outItems.emplace_back(src); @@ -66,6 +67,37 @@ void SelectItems::run(const SceneContextPointer& sceneContext, const RenderConte } } +void SelectSortItems::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemBounds& outItems) { + auto selection = sceneContext->_scene->getSelection(_name); + const auto& selectedItems = selection.getItems(); + outItems.clear(); + + if (!selectedItems.empty()) { + struct Pair { int src; int dst; }; + std::vector indices; + indices.reserve(selectedItems.size()); + + // Collect + for (int srcIndex = 0; (srcIndex < inItems.size()) && (indices.size() < selectedItems.size()) ; srcIndex++ ) { + int index = selection.find(inItems[srcIndex].id); + if (index != Selection::NOT_FOUND) { + indices.emplace_back( Pair{ srcIndex, index } ); + } + } + + // Then sort + if (!indices.empty()) { + std::sort(indices.begin(), indices.end(), [] (Pair a, Pair b) { + return (a.dst < b.dst); + }); + + for (auto& pair: indices) { + outItems.emplace_back(inItems[pair.src]); + } + } + } +} + void MetaToSubItems::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemIDs& outItems) { auto& scene = sceneContext->_scene; diff --git a/libraries/render/src/render/FilterTask.h b/libraries/render/src/render/FilterTask.h index 46a9ef25bd..00019fa1ae 100644 --- a/libraries/render/src/render/FilterTask.h +++ b/libraries/render/src/render/FilterTask.h @@ -121,6 +121,17 @@ namespace render { void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemBounds& outItems); }; + // Same as SelectItems but reorder the output to match the selection order + class SelectSortItems { + public: + using JobModel = Job::ModelIO; + + std::string _name; + SelectSortItems(const Selection::Name& name) : _name(name) {} + + void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemBounds& outItems); + }; + // From meta-Items, generate the sub-items class MetaToSubItems { public: diff --git a/libraries/render/src/render/Selection.cpp b/libraries/render/src/render/Selection.cpp index 5ac0f415f4..46941ae440 100644 --- a/libraries/render/src/render/Selection.cpp +++ b/libraries/render/src/render/Selection.cpp @@ -56,11 +56,13 @@ Selection::Selection(const Name& name, const ItemIDs& items) : { } -bool Selection::contains(ItemID id) const { +int Selection::find(ItemID id) const { + int index = 0; for (auto selected : _items) { if (selected == id) { - return true; + return index; } + index++; } - return false; -} \ No newline at end of file + return NOT_FOUND; +} diff --git a/libraries/render/src/render/Selection.h b/libraries/render/src/render/Selection.h index 6c5f6aab10..2c7ce710cd 100644 --- a/libraries/render/src/render/Selection.h +++ b/libraries/render/src/render/Selection.h @@ -34,7 +34,12 @@ namespace render { const ItemIDs& getItems() const { return _items; } bool isEmpty() const { return _items.empty(); } - bool contains(ItemID id) const; + + // Test if the ID is in the selection, return the index or -1 if not present + static const int NOT_FOUND{ -1 }; + + int find(ItemID id) const; + bool contains(ItemID id) const { return find(id) > NOT_FOUND; } protected: Name _name; diff --git a/libraries/render/src/render/drawItemBounds.slv b/libraries/render/src/render/drawItemBounds.slv index cf1eab7163..af1e31fbf4 100644 --- a/libraries/render/src/render/drawItemBounds.slv +++ b/libraries/render/src/render/drawItemBounds.slv @@ -20,7 +20,7 @@ uniform vec3 inBoundPos; uniform vec3 inBoundDim; -uniform ivec4 inCellLocation; +uniform vec4 inColor; out vec4 varColor; out vec2 varTexcoord; @@ -59,9 +59,7 @@ void main(void) { TransformObject obj = getTransformObject(); <$transformModelToClipPos(cam, obj, pos, gl_Position)$> - bool subcell = bool((inCellLocation.z)); - float cellDepth = float(inCellLocation.w); - varColor = vec4(colorWheel(fract(cellDepth / 5.0)), 1.0 - float(subcell)); + varColor = vec4(colorWheel(inColor.x), 1.0); varTexcoord = vec2(cubeVec.w, length(inBoundDim)); } \ No newline at end of file