diff --git a/interface/resources/icons/statusIconAtlas.svg b/interface/resources/icons/statusIconAtlas.svg index 3e15da10cb..72f9bc4af7 100644 --- a/interface/resources/icons/statusIconAtlas.svg +++ b/interface/resources/icons/statusIconAtlas.svg @@ -27,4 +27,5 @@ c-3.9-1.9-7.8-3.7-11.7-5.6c-4-2-4.6-8.1-1.1-10.8c2-1.5,2.4-3.7,2.1-5.9c-0.2-1.8-1-3.5-1.2-5.3c-0.6-6-5.2-10.2-11.1-10.1 c-5.9,0.1-10.4,4.8-10.6,10.9c-0.1,1.4-0.4,2.8-0.9,4.1c-0.6,1.9,0.1,4.9,1.7,6.3c3.8,3.1,3.1,9-1.4,11.2c-3.6,1.7-7.2,3.4-10.8,5.2 c-3.4,1.6-3.6,2.5-0.8,5.1C336.2,80.6,343.8,83.9,353.7,83.9z"/> + diff --git a/libraries/entities-renderer/src/RenderableEntityItem.cpp b/libraries/entities-renderer/src/RenderableEntityItem.cpp index 5013f4d6f8..5504268dce 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableEntityItem.cpp @@ -88,4 +88,13 @@ void makeEntityItemStatusGetters(EntityItemPointer entity, render::Item::Status: return render::Item::Status::Value(0.0f, render::Item::Status::Value::BLUE, (unsigned char)RenderItemStatusIcon::SIMULATION_OWNER); }); + + statusGetters.push_back([entity] () -> render::Item::Status::Value { + if (entity->hasActions()) { + return render::Item::Status::Value(1.0f, render::Item::Status::Value::GREEN, + (unsigned char)RenderItemStatusIcon::HAS_ACTIONS); + } + return render::Item::Status::Value(0.0f, render::Item::Status::Value::GREEN, + (unsigned char)RenderItemStatusIcon::HAS_ACTIONS); + }); } diff --git a/libraries/entities-renderer/src/RenderableEntityItem.h b/libraries/entities-renderer/src/RenderableEntityItem.h index ce5f2d49fa..212b71759f 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.h +++ b/libraries/entities-renderer/src/RenderableEntityItem.h @@ -22,6 +22,7 @@ enum class RenderItemStatusIcon { PACKET_SENT = 1, PACKET_RECEIVED = 2, SIMULATION_OWNER = 3, + HAS_ACTIONS = 4, NONE = 255 }; diff --git a/libraries/render/src/render/DrawStatus.cpp b/libraries/render/src/render/DrawStatus.cpp index 7b344ae63e..3171b8160c 100644 --- a/libraries/render/src/render/DrawStatus.cpp +++ b/libraries/render/src/render/DrawStatus.cpp @@ -68,7 +68,8 @@ const gpu::PipelinePointer DrawStatus::getDrawItemStatusPipeline() { _drawItemStatusPosLoc = program->getUniforms().findLocation("inBoundPos"); _drawItemStatusDimLoc = program->getUniforms().findLocation("inBoundDim"); - _drawItemStatusValueLoc = program->getUniforms().findLocation("inStatus"); + _drawItemStatusValue0Loc = program->getUniforms().findLocation("inStatus0"); + _drawItemStatusValue1Loc = program->getUniforms().findLocation("inStatus1"); auto state = std::make_shared(); @@ -98,6 +99,8 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex assert(renderContext->args->_viewFrustum); RenderArgs* args = renderContext->args; auto& scene = sceneContext->_scene; + const int NUM_STATUS_VEC4_PER_ITEM = 2; + const int VEC4_LENGTH = 4; // FIrst thing, we collect the bound and the status for all the items we want to render int nbItems = 0; @@ -109,8 +112,8 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex _itemStatus = std::make_shared();; } - _itemBounds->resize((inItems.size() * sizeof(AABox))); - _itemStatus->resize((inItems.size() * sizeof(glm::vec4))); + _itemBounds->resize((inItems.size() * sizeof(AABox))); + _itemStatus->resize((inItems.size() * NUM_STATUS_VEC4_PER_ITEM * sizeof(glm::vec4))); AABox* itemAABox = reinterpret_cast (_itemBounds->editData()); glm::ivec4* itemStatus = reinterpret_cast (_itemStatus->editData()); for (auto& item : inItems) { @@ -121,11 +124,31 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex (*itemAABox).setBox(item.bounds.getCorner(), 0.1f); } auto& itemScene = scene->getItem(item.id); - (*itemStatus) = itemScene.getStatusPackedValues(); + + auto itemStatusPointer = itemScene.getStatus(); + if (itemStatusPointer) { + // Query the current status values, this is where the statusGetter lambda get called + auto&& currentStatusValues = itemStatusPointer->getCurrentValues(); + int valueNum = 0; + for (int vec4Num = 0; vec4Num < NUM_STATUS_VEC4_PER_ITEM; vec4Num++) { + (*itemStatus) = glm::ivec4(Item::Status::Value::INVALID.getPackedData()); + for (int component = 0; component < VEC4_LENGTH; component++) { + valueNum = vec4Num * VEC4_LENGTH + component; + if (valueNum < (int)currentStatusValues.size()) { + (*itemStatus)[component] = currentStatusValues[valueNum].getPackedData(); + } + } + itemStatus++; + } + } else { + (*itemStatus) = glm::ivec4(Item::Status::Value::INVALID.getPackedData()); + itemStatus++; + (*itemStatus) = glm::ivec4(Item::Status::Value::INVALID.getPackedData()); + itemStatus++; + } nbItems++; - itemAABox++; - itemStatus++; + itemAABox++; } } } @@ -170,9 +193,9 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex for (int i = 0; i < nbItems; i++) { batch._glUniform3fv(_drawItemStatusPosLoc, 1, (const float*) (itemAABox + i)); batch._glUniform3fv(_drawItemStatusDimLoc, 1, ((const float*) (itemAABox + i)) + VEC3_ADRESS_OFFSET); - batch._glUniform4iv(_drawItemStatusValueLoc, 1, (const int*) (itemStatus + i)); - - batch.draw(gpu::TRIANGLES, 24, 0); + batch._glUniform4iv(_drawItemStatusValue0Loc, 1, (const int*)(itemStatus + NUM_STATUS_VEC4_PER_ITEM * i)); + batch._glUniform4iv(_drawItemStatusValue1Loc, 1, (const int*)(itemStatus + NUM_STATUS_VEC4_PER_ITEM * i + 1)); + batch.draw(gpu::TRIANGLES, 24 * NUM_STATUS_VEC4_PER_ITEM, 0); } } batch.setResourceTexture(0, 0); diff --git a/libraries/render/src/render/DrawStatus.h b/libraries/render/src/render/DrawStatus.h index bb9cb07e4b..83be3112e0 100644 --- a/libraries/render/src/render/DrawStatus.h +++ b/libraries/render/src/render/DrawStatus.h @@ -21,7 +21,8 @@ namespace render { int _drawItemBoundDimLoc = -1; int _drawItemStatusPosLoc = -1; int _drawItemStatusDimLoc = -1; - int _drawItemStatusValueLoc = -1; + int _drawItemStatusValue0Loc = -1; + int _drawItemStatusValue1Loc = -1; gpu::Stream::FormatPointer _drawItemFormat; gpu::PipelinePointer _drawItemBoundsPipeline; diff --git a/libraries/render/src/render/Scene.cpp b/libraries/render/src/render/Scene.cpp index 2081d5267f..18cf1d8335 100644 --- a/libraries/render/src/render/Scene.cpp +++ b/libraries/render/src/render/Scene.cpp @@ -78,14 +78,14 @@ void Item::Status::Value::setIcon(unsigned char icon) { _icon = icon; } -void Item::Status::getPackedValues(glm::ivec4& values) const { - for (unsigned int i = 0; i < (unsigned int)values.length(); i++) { - if (i < _values.size()) { - values[i] = _values[i]().getPackedData(); - } else { - values[i] = Value::INVALID.getPackedData(); - } +Item::Status::Values Item::Status::getCurrentValues() const { + Values currentValues(_values.size()); + auto currentValue = currentValues.begin(); + for (auto& getter : _values) { + (*currentValue) = getter(); + currentValue++; } + return currentValues; } void Item::PayloadInterface::addStatusGetter(const Status::Getter& getter) { @@ -113,15 +113,6 @@ void Item::resetPayload(const PayloadPointer& payload) { } } -glm::ivec4 Item::getStatusPackedValues() const { - glm::ivec4 values(Status::Value::INVALID.getPackedData()); - auto& status = getStatus(); - if (status) { - status->getPackedValues(values); - }; - return values; -} - void PendingChanges::resetItem(ItemID id, const PayloadPointer& payload) { _resetItems.push_back(id); _resetPayloads.push_back(payload); diff --git a/libraries/render/src/render/Scene.h b/libraries/render/src/render/Scene.h index 7176e5753e..6ddd60cce8 100644 --- a/libraries/render/src/render/Scene.h +++ b/libraries/render/src/render/Scene.h @@ -241,7 +241,10 @@ public: void addGetter(const Getter& getter) { _values.push_back(getter); } - void getPackedValues(glm::ivec4& values) const; + size_t getNumValues() const { return _values.size(); } + + using Values = std::vector ; + Values getCurrentValues() const; }; typedef std::shared_ptr StatusPointer; @@ -305,7 +308,6 @@ public: // Access the status const StatusPointer& getStatus() const { return _payload->getStatus(); } - glm::ivec4 getStatusPackedValues() const; protected: PayloadPointer _payload; diff --git a/libraries/render/src/render/drawItemStatus.slv b/libraries/render/src/render/drawItemStatus.slv index 8c4f0724d5..9974146916 100644 --- a/libraries/render/src/render/drawItemStatus.slv +++ b/libraries/render/src/render/drawItemStatus.slv @@ -21,7 +21,8 @@ out vec3 varTexcoord; uniform vec3 inBoundPos; uniform vec3 inBoundDim; -uniform ivec4 inStatus; +uniform ivec4 inStatus0; +uniform ivec4 inStatus1; vec3 paintRainbow(float normalizedHue) { float v = normalizedHue * 6.f; @@ -44,6 +45,17 @@ vec3 paintRainbow(float normalizedHue) { } } +const int INVALID_STATUS = 0xFFFFFFFF; + +int getIconStatus(int icon) { + if (icon < 4) { + return inStatus0[icon]; + } else if (icon < 8) { + return inStatus1[icon - 4]; + } + return INVALID_STATUS; +} + vec3 unpackStatus(int v) { return vec3(clamp(float(int((v >> 0) & 0xFFFF) - 32727) / 32727.0, -1.0, 1.0), clamp(float(uint((v >> 16) & 0xFF)) / 255.0, 0.0, 1.0), @@ -71,9 +83,10 @@ void main(void) { // Which icon are we dealing with ? int iconNum = gl_VertexID / NUM_VERTICES; + int packedIconStatus = getIconStatus(iconNum); // if invalid, just kill - if (inStatus[iconNum] == 0xFFFFFFFF) { + if (packedIconStatus == INVALID_STATUS) { gl_Position = anchorPoint; varColor = vec4(1.0); return; @@ -84,7 +97,7 @@ void main(void) { vec4 quadPos = UNIT_QUAD[twoTriID]; // unpack to get x and y satus - vec3 iconStatus = unpackStatus(inStatus[iconNum]); + vec3 iconStatus = unpackStatus(packedIconStatus); // Use the status for showing a color varColor = vec4(paintRainbow(abs(iconStatus.y)), 1.0);