From 38357964192a422fcad5173d0013cd9797371d53 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 16 Jan 2019 14:01:05 -0800 Subject: [PATCH 1/3] deprecate the new property so that people hopefully don't use it --- libraries/entities/src/EntityItemProperties.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 195f168a9d..a6cbae4bf1 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -1102,7 +1102,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * and spinSpread == PI/2, each particle will have a spin in the range PI/23*PI/2. * @property {boolean} rotateWithEntity=false - Whether or not the particles' spin will rotate with the entity. If false, when particleSpin == 0, the particles will point * up in the world. If true, they will point towards the entity's up vector, based on its orientation. - * @property {Entities.Pulse} pulse - The pulse-related properties. + * @property {Entities.Pulse} pulse - The pulse-related properties. Deprecated. * * @property {ShapeType} shapeType="none" - Currently not used. Read-only. * @@ -1231,7 +1231,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * @property {Vec3} dimensions=0.1,0.1,0.1 - The dimensions of the entity. * @property {Color} color=255,255,255 - The color of the entity. * @property {number} alpha=1 - The alpha of the shape. - * @property {Entities.Pulse} pulse - The pulse-related properties. + * @property {Entities.Pulse} pulse - The pulse-related properties. Deprecated. * @example Create a cylinder. * var shape = Entities.addEntity({ * type: "Shape", @@ -1271,7 +1271,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * @property {number} rightMargin=0.0 - The right margin, in meters. * @property {number} topMargin=0.0 - The top margin, in meters. * @property {number} bottomMargin=0.0 - The bottom margin, in meters. - * @property {Entities.Pulse} pulse - The pulse-related properties. + * @property {Entities.Pulse} pulse - The pulse-related properties. Deprecated. * @example Create a text entity. * var text = Entities.addEntity({ * type: "Text", @@ -1301,7 +1301,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * @property {string} scriptURL="" - The URL of a JavaScript file to inject into the Web page. * @property {number} maxFPS=10 - The maximum update rate for the Web content, in frames/second. * @property {WebInputMode} inputMode="touch" - The user input mode to use. - * @property {Entities.Pulse} pulse - The pulse-related properties. + * @property {Entities.Pulse} pulse - The pulse-related properties. Deprecated. * @example Create a Web entity displaying at 1920 x 1080 resolution. * var METERS_TO_INCHES = 39.3701; * var entity = Entities.addEntity({ @@ -1411,7 +1411,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * the full image in that dimension. * @property {Color} color=255,255,255 - The color of the image. * @property {number} alpha=1 - The alpha of the image. - * @property {Entities.Pulse} pulse - The pulse-related properties. + * @property {Entities.Pulse} pulse - The pulse-related properties. Deprecated. * @example Create a image entity. * var image = Entities.addEntity({ * type: "Image", @@ -1435,7 +1435,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * line. Minimum value = 1. * @property {number} minorGridEvery=1 - Real number of meters at which to draw thin grid lines. Minimum value = * 0.001. - * @property {Entities.Pulse} pulse - The pulse-related properties. + * @property {Entities.Pulse} pulse - The pulse-related properties. Deprecated. * @example Create a grid entity. * var grid = Entities.addEntity({ * type: "Grid", From ac513df10334954ab1095ff0e9382ac9e652c329 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 23 Jan 2019 17:33:32 -0800 Subject: [PATCH 2/3] ring gizmo entities --- .../src/RenderableEntityItem.cpp | 22 +- .../src/RenderableGizmoEntityItem.cpp | 289 +++++++++++ .../src/RenderableGizmoEntityItem.h | 48 ++ .../entities/src/EntityItemProperties.cpp | 104 +++- libraries/entities/src/EntityItemProperties.h | 12 +- .../src/EntityItemPropertiesDefaults.h | 1 + libraries/entities/src/EntityPropertyFlags.h | 22 + libraries/entities/src/EntityTypes.cpp | 2 + libraries/entities/src/EntityTypes.h | 3 + libraries/entities/src/GizmoEntityItem.cpp | 200 +++++++ libraries/entities/src/GizmoEntityItem.h | 67 +++ .../entities/src/ParticleEffectEntityItem.h | 4 +- .../entities/src/RingGizmoPropertyGroup.cpp | 489 ++++++++++++++++++ .../entities/src/RingGizmoPropertyGroup.h | 135 +++++ libraries/networking/src/udt/PacketHeaders.h | 1 + libraries/octree/src/OctreePacketData.h | 2 + libraries/render-utils/src/GeometryCache.cpp | 4 +- libraries/render-utils/src/GeometryCache.h | 2 +- libraries/shared/src/GizmoType.cpp | 23 + libraries/shared/src/GizmoType.h | 37 ++ 20 files changed, 1449 insertions(+), 18 deletions(-) create mode 100644 libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp create mode 100644 libraries/entities-renderer/src/RenderableGizmoEntityItem.h create mode 100644 libraries/entities/src/GizmoEntityItem.cpp create mode 100644 libraries/entities/src/GizmoEntityItem.h create mode 100644 libraries/entities/src/RingGizmoPropertyGroup.cpp create mode 100644 libraries/entities/src/RingGizmoPropertyGroup.h create mode 100644 libraries/shared/src/GizmoType.cpp create mode 100644 libraries/shared/src/GizmoType.h diff --git a/libraries/entities-renderer/src/RenderableEntityItem.cpp b/libraries/entities-renderer/src/RenderableEntityItem.cpp index 140fe897af..a194f4d4b7 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableEntityItem.cpp @@ -14,20 +14,20 @@ #include -#include "RenderableLightEntityItem.h" -#include "RenderableLineEntityItem.h" -#include "RenderableModelEntityItem.h" -#include "RenderableParticleEffectEntityItem.h" -#include "RenderablePolyVoxEntityItem.h" -#include "RenderablePolyLineEntityItem.h" #include "RenderableShapeEntityItem.h" +#include "RenderableModelEntityItem.h" #include "RenderableTextEntityItem.h" +#include "RenderableImageEntityItem.h" #include "RenderableWebEntityItem.h" +#include "RenderableParticleEffectEntityItem.h" +#include "RenderableLineEntityItem.h" +#include "RenderablePolyLineEntityItem.h" +#include "RenderablePolyVoxEntityItem.h" +#include "RenderableGridEntityItem.h" +#include "RenderableGizmoEntityItem.h" +#include "RenderableLightEntityItem.h" #include "RenderableZoneEntityItem.h" #include "RenderableMaterialEntityItem.h" -#include "RenderableImageEntityItem.h" -#include "RenderableGridEntityItem.h" - using namespace render; using namespace render::entities; @@ -284,6 +284,10 @@ EntityRenderer::Pointer EntityRenderer::addToScene(EntityTreeRenderer& renderer, result = make_renderer(entity); break; + case Type::Gizmo: + result = make_renderer(entity); + break; + case Type::Light: result = make_renderer(entity); break; diff --git a/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp b/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp new file mode 100644 index 0000000000..f2e95c2159 --- /dev/null +++ b/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp @@ -0,0 +1,289 @@ +// +// Created by Sam Gondelman on 1/22/19 +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "RenderableGizmoEntityItem.h" + +#include +#include + +using namespace render; +using namespace render::entities; + +GizmoEntityRenderer::GizmoEntityRenderer(const EntityItemPointer& entity) : Parent(entity) +{ +} + +GizmoEntityRenderer::~GizmoEntityRenderer() { + auto geometryCache = DependencyManager::get(); + if (geometryCache) { + if (_ringGeometryID) { + geometryCache->releaseID(_ringGeometryID); + } + if (_majorTicksGeometryID) { + geometryCache->releaseID(_majorTicksGeometryID); + } + if (_minorTicksGeometryID) { + geometryCache->releaseID(_minorTicksGeometryID); + } + } +} + +bool GizmoEntityRenderer::isTransparent() const { + bool ringTransparent = _gizmoType == GizmoType::RING && (_ringProperties.getInnerStartAlpha() < 1.0f || + _ringProperties.getInnerEndAlpha() < 1.0f || _ringProperties.getOuterStartAlpha() < 1.0f || + _ringProperties.getOuterEndAlpha() < 1.0f); + + return Parent::isTransparent() || ringTransparent; +} + +bool GizmoEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { + bool needsUpdate = resultWithReadLock([&] { + if (_gizmoType != entity->getGizmoType()) { + return true; + } + + if (_ringProperties != entity->getRingProperties()) { + return true; + } + + return false; + }); + + return needsUpdate; +} + +void GizmoEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { + bool dirty = false; + RingGizmoPropertyGroup ringProperties = entity->getRingProperties(); + withWriteLock([&] { + _gizmoType = entity->getGizmoType(); + if (_ringProperties != ringProperties) { + _ringProperties = ringProperties; + dirty = true; + + } + }); + + if (dirty || _prevPrimitiveMode != _primitiveMode || !_ringGeometryID || !_majorTicksGeometryID || !_minorTicksGeometryID) { + _prevPrimitiveMode = _primitiveMode; + auto geometryCache = DependencyManager::get(); + if (!_ringGeometryID) { + _ringGeometryID = geometryCache->allocateID(); + } + + const float FULL_CIRCLE = 360.0f; + const float SLICES = 180.0f; + const float SLICE_ANGLE_RADIANS = glm::radians(FULL_CIRCLE / SLICES); + if (_primitiveMode == PrimitiveMode::SOLID) { + + QVector points; + QVector colors; + + vec4 innerStartColor = vec4(toGlm(ringProperties.getInnerStartColor()), ringProperties.getInnerStartAlpha()); + vec4 outerStartColor = vec4(toGlm(ringProperties.getOuterStartColor()), ringProperties.getOuterStartAlpha()); + vec4 innerEndColor = vec4(toGlm(ringProperties.getInnerEndColor()), ringProperties.getInnerEndAlpha()); + vec4 outerEndColor = vec4(toGlm(ringProperties.getOuterEndColor()), ringProperties.getOuterEndAlpha()); + float startAtRadians = glm::radians(ringProperties.getStartAngle()); + float endAtRadians = glm::radians(ringProperties.getEndAngle()); + + const auto totalRange = endAtRadians - startAtRadians; + if (ringProperties.getInnerRadius() <= 0) { + _solidPrimitive = gpu::TRIANGLE_FAN; + points << vec3(); + colors << innerStartColor; + for (float angleRadians = startAtRadians; angleRadians < endAtRadians; angleRadians += SLICE_ANGLE_RADIANS) { + float range = (angleRadians - startAtRadians) / totalRange; + points << 0.5f * glm::vec3(cosf(angleRadians), 0.0f, sinf(angleRadians)); + colors << glm::mix(outerStartColor, outerEndColor, range); + } + points << 0.5f * glm::vec3(cosf(endAtRadians), 0.0f, sinf(endAtRadians)); + colors << outerEndColor; + } else { + _solidPrimitive = gpu::TRIANGLE_STRIP; + for (float angleRadians = startAtRadians; angleRadians < endAtRadians; angleRadians += SLICE_ANGLE_RADIANS) { + float range = (angleRadians - startAtRadians) / totalRange; + + points << 0.5f * glm::vec3(cosf(angleRadians) * ringProperties.getInnerRadius(), 0.0f, sinf(angleRadians) * ringProperties.getInnerRadius()); + colors << glm::mix(innerStartColor, innerEndColor, range); + + points << 0.5f * glm::vec3(cosf(angleRadians), 0.0f, sinf(angleRadians)); + colors << glm::mix(outerStartColor, outerEndColor, range); + } + points << 0.5f * glm::vec3(cosf(endAtRadians) * ringProperties.getInnerRadius(), 0.0f, sinf(endAtRadians) * ringProperties.getInnerRadius()); + colors << innerEndColor; + + points << 0.5f * glm::vec3(cosf(endAtRadians), 0.0f, sinf(endAtRadians)); + colors << outerEndColor; + } + geometryCache->updateVertices(_ringGeometryID, points, colors); + } else { + _solidPrimitive = gpu::LINE_STRIP; + QVector points; + + float startAtRadians = glm::radians(ringProperties.getStartAngle()); + float endAtRadians = glm::radians(ringProperties.getEndAngle()); + + float angleRadians = startAtRadians; + glm::vec3 firstPoint = 0.5f * glm::vec3(cosf(angleRadians), 0.0f, sinf(angleRadians)); + points << firstPoint; + + while (angleRadians < endAtRadians) { + angleRadians += SLICE_ANGLE_RADIANS; + glm::vec3 thisPoint = 0.5f * glm::vec3(cosf(angleRadians), 0.0f, sinf(angleRadians)); + points << thisPoint; + } + + // get the last slice portion.... + angleRadians = endAtRadians; + glm::vec3 lastPoint = 0.5f * glm::vec3(cosf(angleRadians), 0.0f, sinf(angleRadians)); + points << lastPoint; + geometryCache->updateVertices(_ringGeometryID, points, glm::vec4(toGlm(ringProperties.getOuterStartColor()), ringProperties.getOuterStartAlpha())); + } + + if (ringProperties.getHasTickMarks()) { + if (ringProperties.getMajorTickMarksAngle() > 0.0f && ringProperties.getMajorTickMarksLength() != 0.0f) { + QVector points; + if (!_majorTicksGeometryID) { + _majorTicksGeometryID = geometryCache->allocateID(); + } + + float startAngle = ringProperties.getStartAngle(); + float tickMarkAngle = ringProperties.getMajorTickMarksAngle(); + float angle = startAngle - fmodf(startAngle, tickMarkAngle) + tickMarkAngle; + + float tickMarkLength = 0.5f * ringProperties.getMajorTickMarksLength(); + float startRadius = (tickMarkLength > 0.0f) ? 0.5f * ringProperties.getInnerRadius() : 0.5f; + float endRadius = startRadius + tickMarkLength; + + while (angle <= ringProperties.getEndAngle()) { + float angleInRadians = glm::radians(angle); + + glm::vec3 thisPointA = startRadius * glm::vec3(cosf(angleInRadians), 0.0f, sinf(angleInRadians)); + glm::vec3 thisPointB = endRadius * glm::vec3(cosf(angleInRadians), 0.0f, sinf(angleInRadians)); + + points << thisPointA << thisPointB; + + angle += tickMarkAngle; + } + + glm::vec4 color(toGlm(ringProperties.getMajorTickMarksColor()), 1.0f); // TODO: alpha + geometryCache->updateVertices(_majorTicksGeometryID, points, color); + } + if (ringProperties.getMinorTickMarksAngle() > 0.0f && ringProperties.getMinorTickMarksLength() != 0.0f) { + QVector points; + if (!_minorTicksGeometryID) { + _minorTicksGeometryID = geometryCache->allocateID(); + } + + float startAngle = ringProperties.getStartAngle(); + float tickMarkAngle = ringProperties.getMinorTickMarksAngle(); + float angle = startAngle - fmodf(startAngle, tickMarkAngle) + tickMarkAngle; + + float tickMarkLength = 0.5f * ringProperties.getMinorTickMarksLength(); + float startRadius = (tickMarkLength > 0.0f) ? 0.5f * ringProperties.getInnerRadius() : 0.5f; + float endRadius = startRadius + tickMarkLength; + + while (angle <= ringProperties.getEndAngle()) { + float angleInRadians = glm::radians(angle); + + glm::vec3 thisPointA = startRadius * glm::vec3(cosf(angleInRadians), 0.0f, sinf(angleInRadians)); + glm::vec3 thisPointB = endRadius * glm::vec3(cosf(angleInRadians), 0.0f, sinf(angleInRadians)); + + points << thisPointA << thisPointB; + + angle += tickMarkAngle; + } + + glm::vec4 color(toGlm(ringProperties.getMinorTickMarksColor()), 1.0f); // TODO: alpha + geometryCache->updateVertices(_minorTicksGeometryID, points, color); + } + } + } + + void* key = (void*)this; + AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this, entity]() { + withWriteLock([&] { + updateModelTransformAndBound(); + _renderTransform = getModelTransform(); + _renderTransform.postScale(entity->getScaledDimensions()); + }); + }); +} + +Item::Bound GizmoEntityRenderer::getBound() { + auto bound = Parent::getBound(); + if (_ringProperties.getHasTickMarks()) { + glm::vec3 scale = bound.getScale(); + for (int i = 0; i < 3; i += 2) { + if (_ringProperties.getMajorTickMarksLength() + _ringProperties.getInnerRadius() > 1.0f) { + scale[i] *= _ringProperties.getMajorTickMarksLength() + _ringProperties.getInnerRadius(); + } else if (_ringProperties.getMajorTickMarksLength() < -2.0f) { + scale[i] *= -_ringProperties.getMajorTickMarksLength() - 1.0f; + } + + if (_ringProperties.getMinorTickMarksLength() + _ringProperties.getInnerRadius() > 1.0f) { + scale[i] *= _ringProperties.getMinorTickMarksLength() + _ringProperties.getInnerRadius(); + } else if (_ringProperties.getMinorTickMarksLength() < -2.0f) { + scale[i] *= -_ringProperties.getMinorTickMarksLength() - 1.0f; + } + } + + bound.setScaleStayCentered(scale); + return bound; + } + return bound; +} + +ShapeKey GizmoEntityRenderer::getShapeKey() { + auto builder = render::ShapeKey::Builder().withoutCullFace(); + if (isTransparent()) { + builder.withTranslucent(); + } + if (_primitiveMode == PrimitiveMode::LINES) { + builder.withUnlit().withDepthBias(); + } + return builder.build(); +} + +void GizmoEntityRenderer::doRender(RenderArgs* args) { + PerformanceTimer perfTimer("RenderableGizmoEntityItem::render"); + Q_ASSERT(args->_batch); + + gpu::Batch& batch = *args->_batch; + auto geometryCache = DependencyManager::get(); + + if (_gizmoType == GizmoType::RING) { + Transform transform; + bool hasTickMarks; + glm::vec4 tickProperties; + withReadLock([&] { + transform = _renderTransform; + hasTickMarks = _ringProperties.getHasTickMarks(); + tickProperties = glm::vec4(_ringProperties.getMajorTickMarksAngle(), _ringProperties.getMajorTickMarksLength(), + _ringProperties.getMinorTickMarksAngle(), _ringProperties.getMinorTickMarksLength()); + }); + + bool wireframe = render::ShapeKey(args->_globalShapeKey).isWireframe() || _primitiveMode == PrimitiveMode::LINES; + geometryCache->bindSimpleProgram(batch, false, isTransparent(), false, wireframe, true, true, _renderLayer != RenderLayer::WORLD); + + batch.setModelTransform(transform); + + // Background circle + geometryCache->renderVertices(batch, wireframe ? gpu::LINE_STRIP : _solidPrimitive, _ringGeometryID); + + // Ticks + if (hasTickMarks) { + if (tickProperties.x > 0.0f && tickProperties.y != 0.0f) { + geometryCache->renderVertices(batch, gpu::LINE_STRIP, _majorTicksGeometryID); + } + if (tickProperties.z > 0.0f && tickProperties.w != 0.0f) { + geometryCache->renderVertices(batch, gpu::LINE_STRIP, _minorTicksGeometryID); + } + } + } +} \ No newline at end of file diff --git a/libraries/entities-renderer/src/RenderableGizmoEntityItem.h b/libraries/entities-renderer/src/RenderableGizmoEntityItem.h new file mode 100644 index 0000000000..2061bb0bca --- /dev/null +++ b/libraries/entities-renderer/src/RenderableGizmoEntityItem.h @@ -0,0 +1,48 @@ +// +// Created by Sam Gondelman on 1/22/19 +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_RenderableGizmoEntityItem_h +#define hifi_RenderableGizmoEntityItem_h + +#include "RenderableEntityItem.h" + +#include + +namespace render { namespace entities { + +class GizmoEntityRenderer : public TypedEntityRenderer { + using Parent = TypedEntityRenderer; + using Pointer = std::shared_ptr; +public: + GizmoEntityRenderer(const EntityItemPointer& entity); + ~GizmoEntityRenderer(); + +protected: + Item::Bound getBound() override; + ShapeKey getShapeKey() override; + + bool isTransparent() const override; + +private: + virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override; + virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override; + virtual void doRender(RenderArgs* args) override; + + GizmoType _gizmoType; + RingGizmoPropertyGroup _ringProperties; + PrimitiveMode _prevPrimitiveMode; + + int _ringGeometryID { 0 }; + int _majorTicksGeometryID { 0 }; + int _minorTicksGeometryID { 0 }; + gpu::Primitive _solidPrimitive { gpu::TRIANGLE_FAN }; + +}; + +} } +#endif // hifi_RenderableGizmoEntityItem_h diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index a6cbae4bf1..b5e98aceb2 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -42,6 +42,7 @@ KeyLightPropertyGroup EntityItemProperties::_staticKeyLight; AmbientLightPropertyGroup EntityItemProperties::_staticAmbientLight; GrabPropertyGroup EntityItemProperties::_staticGrab; PulsePropertyGroup EntityItemProperties::_staticPulse; +RingGizmoPropertyGroup EntityItemProperties::_staticRing; EntityPropertyList PROP_LAST_ITEM = (EntityPropertyList)(PROP_AFTER_LAST_ITEM - 1); @@ -420,6 +421,31 @@ void EntityItemProperties::setInputModeFromString(const QString& webInputMode) { } } +QHash stringToGizmoTypeLookup; + +void addGizmoType(GizmoType mode) { + stringToGizmoTypeLookup[GizmoTypeHelpers::getNameForGizmoType(mode)] = mode; +} + +void buildStringToGizmoTypeLookup() { + addGizmoType(GizmoType::RING); +} + +QString EntityItemProperties::getGizmoTypeAsString() const { + return GizmoTypeHelpers::getNameForGizmoType(_gizmoType); +} + +void EntityItemProperties::setGizmoTypeFromString(const QString& gizmoType) { + if (stringToGizmoTypeLookup.empty()) { + buildStringToGizmoTypeLookup(); + } + auto gizmoTypeItr = stringToGizmoTypeLookup.find(gizmoType.toLower()); + if (gizmoTypeItr != stringToGizmoTypeLookup.end()) { + _gizmoType = gizmoTypeItr.value(); + _gizmoTypeChanged = true; + } +} + EntityPropertyFlags EntityItemProperties::getChangedProperties() const { EntityPropertyFlags changedProperties; @@ -640,6 +666,10 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_MAJOR_GRID_EVERY, majorGridEvery); CHECK_PROPERTY_CHANGE(PROP_MINOR_GRID_EVERY, minorGridEvery); + // Gizmo + CHECK_PROPERTY_CHANGE(PROP_GIZMO_TYPE, gizmoType); + changedProperties += _ring.getChangedProperties(); + return changedProperties; } @@ -833,6 +863,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * @see {@link Entities.EntityProperties-PolyLine|EntityProperties-PolyLine} * @see {@link Entities.EntityProperties-PolyVox|EntityProperties-PolyVox} * @see {@link Entities.EntityProperties-Grid|EntityProperties-Grid} + * @see {@link Entities.EntityProperties-Gizmo|EntityProperties-Gizmo} * @see {@link Entities.EntityProperties-Light|EntityProperties-Light} * @see {@link Entities.EntityProperties-Zone|EntityProperties-Zone} * @see {@link Entities.EntityProperties-Material|EntityProperties-Material} @@ -1446,6 +1477,13 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * minorGridEvery: 0.5, * lifetime: 300 // Delete after 5 minutes. * }); + +/**jsdoc + * The "Gizmo" {@link Entities.EntityType|EntityType} displays an entity that could be used as UI. + * It has properties in addition to the common {@link Entities.EntityProperties|EntityProperties}. + * @typedef {object} Entities.EntityProperties-Gizmo + * @property {GizmoType} gizmoType="ring" - The gizmo type of the entity. + * @property {Entities.RingGizmo} ring - The ring gizmo properties. */ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool skipDefaults, bool allowUnknownCreateTime, @@ -1667,9 +1705,9 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TEXT, text); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LINE_HEIGHT, lineHeight); - COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_TYPED(PROP_TEXT_COLOR, textColor, getTextColor(), u8vec3Color); + COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_TEXT_COLOR, textColor, u8vec3Color); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TEXT_ALPHA, textAlpha); - COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_TYPED(PROP_BACKGROUND_COLOR, backgroundColor, getBackgroundColor(), u8vec3Color); + COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_BACKGROUND_COLOR, backgroundColor, u8vec3Color); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_BACKGROUND_ALPHA, backgroundAlpha); COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_BILLBOARD_MODE, billboardMode, getBillboardModeAsString()); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LEFT_MARGIN, leftMargin); @@ -1799,6 +1837,12 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MINOR_GRID_EVERY, minorGridEvery); } + // Gizmo only + if (_type == EntityTypes::Gizmo) { + COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_GIZMO_TYPE, gizmoType, getGizmoTypeAsString()); + _ring.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties); + } + /**jsdoc * The axis-aligned bounding box of an entity. * @typedef {object} Entities.BoundingBox @@ -2109,6 +2153,10 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(majorGridEvery, uint32_t, setMajorGridEvery); COPY_PROPERTY_FROM_QSCRIPTVALUE(minorGridEvery, float, setMinorGridEvery); + // Gizmo + COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(gizmoType, GizmoType); + _ring.copyFromScriptValue(object, _defaultSettings); + // Handle conversions from old 'textures' property to "imageURL" { QScriptValue V = object.property("textures"); @@ -2371,6 +2419,10 @@ void EntityItemProperties::merge(const EntityItemProperties& other) { COPY_PROPERTY_IF_CHANGED(majorGridEvery); COPY_PROPERTY_IF_CHANGED(minorGridEvery); + // Gizmo + COPY_PROPERTY_IF_CHANGED(gizmoType); + _ring.merge(other._ring); + _lastEdited = usecTimestampNow(); } @@ -2751,6 +2803,32 @@ bool EntityItemProperties::getPropertyInfo(const QString& propertyName, EntityPr ADD_PROPERTY_TO_MAP(PROP_GRID_FOLLOW_CAMERA, FollowCamera, followCamera, bool); ADD_PROPERTY_TO_MAP(PROP_MAJOR_GRID_EVERY, MajorGridEvery, majorGridEvery, uint32_t); ADD_PROPERTY_TO_MAP(PROP_MINOR_GRID_EVERY, MinorGridEvery, minorGridEvery, float); + + // Gizmo + ADD_PROPERTY_TO_MAP(PROP_GIZMO_TYPE, GizmoType, gizmoType, GizmoType); + { // RingGizmo + ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_START_ANGLE, Ring, ring, StartAngle, startAngle, RingGizmoPropertyGroup::MIN_ANGLE, RingGizmoPropertyGroup::MAX_ANGLE); + ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_END_ANGLE, Ring, ring, EndAngle, endAngle, RingGizmoPropertyGroup::MIN_ANGLE, RingGizmoPropertyGroup::MAX_ANGLE); + ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_INNER_RADIUS, Ring, ring, InnerRadius, innerRadius, RingGizmoPropertyGroup::MIN_RADIUS, RingGizmoPropertyGroup::MAX_RADIUS); + + ADD_GROUP_PROPERTY_TO_MAP(PROP_INNER_START_COLOR, Ring, ring, InnerStartColor, innerStartColor); + ADD_GROUP_PROPERTY_TO_MAP(PROP_INNER_END_COLOR, Ring, ring, InnerEndColor, innerEndColor); + ADD_GROUP_PROPERTY_TO_MAP(PROP_OUTER_START_COLOR, Ring, ring, OuterStartColor, outerStartColor); + ADD_GROUP_PROPERTY_TO_MAP(PROP_OUTER_END_COLOR, Ring, ring, OuterEndColor, outerEndColor); + + ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_INNER_START_ALPHA, Ring, ring, InnerStartAlpha, innerStartAlpha, RingGizmoPropertyGroup::MIN_ALPHA, RingGizmoPropertyGroup::MAX_ALPHA); + ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_INNER_END_ALPHA, Ring, ring, InnerEndAlpha, innerEndAlpha, RingGizmoPropertyGroup::MIN_ALPHA, RingGizmoPropertyGroup::MAX_ALPHA); + ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_OUTER_START_ALPHA, Ring, ring, OuterStartAlpha, outerStartAlpha, RingGizmoPropertyGroup::MIN_ALPHA, RingGizmoPropertyGroup::MAX_ALPHA); + ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_OUTER_END_ALPHA, Ring, ring, OuterEndAlpha, outerEndAlpha, RingGizmoPropertyGroup::MIN_ALPHA, RingGizmoPropertyGroup::MAX_ALPHA); + + ADD_GROUP_PROPERTY_TO_MAP(PROP_HAS_TICK_MARKS, Ring, ring, HasTickMarks, hasTickMarks); + ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_MAJOR_TICK_MARKS_ANGLE, Ring, ring, MajorTickMarksAngle, majorTickMarksAngle, RingGizmoPropertyGroup::MIN_ANGLE, RingGizmoPropertyGroup::MAX_ANGLE); + ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_MINOR_TICK_MARKS_ANGLE, Ring, ring, MinorTickMarksAngle, minorTickMarksAngle, RingGizmoPropertyGroup::MIN_ANGLE, RingGizmoPropertyGroup::MAX_ANGLE); + ADD_GROUP_PROPERTY_TO_MAP(PROP_MAJOR_TICK_MARKS_LENGTH, Ring, ring, MajorTickMarksLength, majorTickMarksLength); + ADD_GROUP_PROPERTY_TO_MAP(PROP_MINOR_TICK_MARKS_LENGTH, Ring, ring, MinorTickMarksLength, minorTickMarksLength); + ADD_GROUP_PROPERTY_TO_MAP(PROP_MAJOR_TICK_MARKS_COLOR, Ring, ring, MajorTickMarksColor, majorTickMarksColor); + ADD_GROUP_PROPERTY_TO_MAP(PROP_MINOR_TICK_MARKS_COLOR, Ring, ring, MinorTickMarksColor, minorTickMarksColor); + } }); auto iter = _propertyInfos.find(propertyName); @@ -3173,6 +3251,13 @@ OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketTy APPEND_ENTITY_PROPERTY(PROP_MAJOR_GRID_EVERY, properties.getMajorGridEvery()); APPEND_ENTITY_PROPERTY(PROP_MINOR_GRID_EVERY, properties.getMinorGridEvery()); } + + if (properties.getType() == EntityTypes::Gizmo) { + APPEND_ENTITY_PROPERTY(PROP_GIZMO_TYPE, (uint32_t)properties.getGizmoType()); + _staticRing.setProperties(properties); + _staticRing.appendToEditPacket(packetData, requestedProperties, propertyFlags, + propertiesDidntFit, propertyCount, appendState); + } } if (propertyCount > 0) { @@ -3622,6 +3707,11 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MINOR_GRID_EVERY, float, setMinorGridEvery); } + if (properties.getType() == EntityTypes::Gizmo) { + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_GIZMO_TYPE, GizmoType, setGizmoType); + properties.getRing().decodeFromEditPacket(propertyFlags, dataAt, processedBytes); + } + return valid; } @@ -3955,6 +4045,10 @@ void EntityItemProperties::markAllChanged() { _followCameraChanged = true; _majorGridEveryChanged = true; _minorGridEveryChanged = true; + + // Gizmo + _gizmoTypeChanged = true; + _ring.markAllChanged(); } // The minimum bounding box for the entity. @@ -4628,6 +4722,12 @@ QList EntityItemProperties::listChangedProperties() { out += "minorGridEvery"; } + // Gizmo + if (gizmoTypeChanged()) { + out += "gizmoType"; + } + getRing().listChangedProperties(out); + return out; } diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index d2df8bebe0..212ab6d101 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -44,6 +44,7 @@ #include "LineEntityItem.h" #include "PolyVoxEntityItem.h" #include "GridEntityItem.h" +#include "GizmoEntityItem.h" #include "LightEntityItem.h" #include "ZoneEntityItem.h" @@ -52,12 +53,14 @@ #include "HazePropertyGroup.h" #include "BloomPropertyGroup.h" #include "PulsePropertyGroup.h" +#include "RingGizmoPropertyGroup.h" #include "MaterialMappingMode.h" #include "BillboardMode.h" #include "RenderLayer.h" #include "PrimitiveMode.h" #include "WebInputMode.h" +#include "GizmoType.h" const quint64 UNKNOWN_CREATED_TIME = 0; @@ -101,6 +104,7 @@ class EntityItemProperties { friend class PolyLineEntityItem; friend class PolyVoxEntityItem; friend class GridEntityItem; + friend class GizmoEntityItem; friend class LightEntityItem; friend class ZoneEntityItem; friend class MaterialEntityItem; @@ -228,8 +232,8 @@ public: // Common DEFINE_PROPERTY_REF_ENUM(PROP_SHAPE_TYPE, ShapeType, shapeType, ShapeType, SHAPE_TYPE_NONE); DEFINE_PROPERTY_REF(PROP_COMPOUND_SHAPE_URL, CompoundShapeURL, compoundShapeURL, QString, ""); - DEFINE_PROPERTY_REF(PROP_COLOR, Color, color, u8vec3Color, particle::DEFAULT_COLOR); - DEFINE_PROPERTY(PROP_ALPHA, Alpha, alpha, float, particle::DEFAULT_ALPHA); + DEFINE_PROPERTY_REF(PROP_COLOR, Color, color, u8vec3Color, ENTITY_ITEM_DEFAULT_COLOR); + DEFINE_PROPERTY(PROP_ALPHA, Alpha, alpha, float, ENTITY_ITEM_DEFAULT_ALPHA); DEFINE_PROPERTY_GROUP(Pulse, pulse, PulsePropertyGroup); DEFINE_PROPERTY_REF(PROP_TEXTURES, Textures, textures, QString, ""); @@ -366,6 +370,10 @@ public: DEFINE_PROPERTY(PROP_MAJOR_GRID_EVERY, MajorGridEvery, majorGridEvery, uint32_t, GridEntityItem::DEFAULT_MAJOR_GRID_EVERY); DEFINE_PROPERTY(PROP_MINOR_GRID_EVERY, MinorGridEvery, minorGridEvery, float, GridEntityItem::DEFAULT_MINOR_GRID_EVERY); + // Gizmo + DEFINE_PROPERTY_REF_ENUM(PROP_GIZMO_TYPE, GizmoType, gizmoType, GizmoType, GizmoType::RING); + DEFINE_PROPERTY_GROUP(Ring, ring, RingGizmoPropertyGroup); + static QString getComponentModeAsString(uint32_t mode); std::array::const_iterator findComponent(const QString& mode); diff --git a/libraries/entities/src/EntityItemPropertiesDefaults.h b/libraries/entities/src/EntityItemPropertiesDefaults.h index a1390b88fc..4d7a34bea5 100644 --- a/libraries/entities/src/EntityItemPropertiesDefaults.h +++ b/libraries/entities/src/EntityItemPropertiesDefaults.h @@ -43,6 +43,7 @@ const quint32 ENTITY_ITEM_DEFAULT_ENTITY_INSTANCE_NUMBER = 0; const QString ENTITY_ITEM_DEFAULT_CERTIFICATE_ID = QString(""); const quint32 ENTITY_ITEM_DEFAULT_STATIC_CERTIFICATE_VERSION = 0; +const glm::u8vec3 ENTITY_ITEM_DEFAULT_COLOR = { 255, 255, 255 }; const float ENTITY_ITEM_DEFAULT_ALPHA = 1.0f; const bool ENTITY_ITEM_DEFAULT_VISIBLE = true; const bool ENTITY_ITEM_DEFAULT_VISIBLE_IN_SECONDARY_CAMERA = true; diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index a59cbe854f..b11ecff5bb 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -331,6 +331,28 @@ enum EntityPropertyList { PROP_MAJOR_GRID_EVERY = PROP_DERIVED_1, PROP_MINOR_GRID_EVERY = PROP_DERIVED_2, + // Gizmo + PROP_GIZMO_TYPE = PROP_DERIVED_0, + // Ring + PROP_START_ANGLE = PROP_DERIVED_1, + PROP_END_ANGLE = PROP_DERIVED_2, + PROP_INNER_RADIUS = PROP_DERIVED_3, + PROP_INNER_START_COLOR = PROP_DERIVED_4, + PROP_INNER_END_COLOR = PROP_DERIVED_5, + PROP_OUTER_START_COLOR = PROP_DERIVED_6, + PROP_OUTER_END_COLOR = PROP_DERIVED_7, + PROP_INNER_START_ALPHA = PROP_DERIVED_8, + PROP_INNER_END_ALPHA = PROP_DERIVED_9, + PROP_OUTER_START_ALPHA = PROP_DERIVED_10, + PROP_OUTER_END_ALPHA = PROP_DERIVED_11, + PROP_HAS_TICK_MARKS = PROP_DERIVED_12, + PROP_MAJOR_TICK_MARKS_ANGLE = PROP_DERIVED_13, + PROP_MINOR_TICK_MARKS_ANGLE = PROP_DERIVED_14, + PROP_MAJOR_TICK_MARKS_LENGTH = PROP_DERIVED_15, + PROP_MINOR_TICK_MARKS_LENGTH = PROP_DERIVED_16, + PROP_MAJOR_TICK_MARKS_COLOR = PROP_DERIVED_17, + PROP_MINOR_TICK_MARKS_COLOR = PROP_DERIVED_18, + // WARNING!!! DO NOT ADD PROPS_xxx here unless you really really meant to.... Add them UP above }; diff --git a/libraries/entities/src/EntityTypes.cpp b/libraries/entities/src/EntityTypes.cpp index e511af83b0..c409d8cfb7 100644 --- a/libraries/entities/src/EntityTypes.cpp +++ b/libraries/entities/src/EntityTypes.cpp @@ -30,6 +30,7 @@ #include "PolyLineEntityItem.h" #include "PolyVoxEntityItem.h" #include "GridEntityItem.h" +#include "GizmoEntityItem.h" #include "LightEntityItem.h" #include "ZoneEntityItem.h" #include "MaterialEntityItem.h" @@ -54,6 +55,7 @@ REGISTER_ENTITY_TYPE(Line) REGISTER_ENTITY_TYPE(PolyLine) REGISTER_ENTITY_TYPE(PolyVox) REGISTER_ENTITY_TYPE(Grid) +REGISTER_ENTITY_TYPE(Gizmo) REGISTER_ENTITY_TYPE(Light) REGISTER_ENTITY_TYPE(Zone) REGISTER_ENTITY_TYPE(Material) diff --git a/libraries/entities/src/EntityTypes.h b/libraries/entities/src/EntityTypes.h index 29a695718e..b8cade754b 100644 --- a/libraries/entities/src/EntityTypes.h +++ b/libraries/entities/src/EntityTypes.h @@ -78,6 +78,8 @@ public: * {@link Entities.EntityProperties-PolyVox|EntityProperties-PolyVox} * "Grid"A grid of lines in a plane. * {@link Entities.EntityProperties-Grid|EntityProperties-Grid} + * "Gizmo"An entity with various UI-related properties. + * {@link Entities.EntityProperties-Gizmo|EntityProperties-Gizmo} * "Light"A local lighting effect. * {@link Entities.EntityProperties-Light|EntityProperties-Light} * "Zone"A volume of lighting effects and avatar permissions. @@ -103,6 +105,7 @@ public: PolyLine, PolyVox, Grid, + Gizmo, Light, Zone, Material, diff --git a/libraries/entities/src/GizmoEntityItem.cpp b/libraries/entities/src/GizmoEntityItem.cpp new file mode 100644 index 0000000000..c9f205d289 --- /dev/null +++ b/libraries/entities/src/GizmoEntityItem.cpp @@ -0,0 +1,200 @@ +// +// Created by Sam Gondelman on 1/22/19 +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "GizmoEntityItem.h" + +#include "EntityItemProperties.h" + +EntityItemPointer GizmoEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { + Pointer entity(new GizmoEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); }); + entity->setProperties(properties); + return entity; +} + +// our non-pure virtual subclass for now... +GizmoEntityItem::GizmoEntityItem(const EntityItemID& entityItemID) : EntityItem(entityItemID) { + _type = EntityTypes::Gizmo; +} + +void GizmoEntityItem::setUnscaledDimensions(const glm::vec3& value) { + // NOTE: Gizmo Entities always have a "height" of 1mm. + EntityItem::setUnscaledDimensions(glm::vec3(value.x, ENTITY_ITEM_MIN_DIMENSION, value.z)); +} + +EntityItemProperties GizmoEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const { + EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class + + COPY_ENTITY_PROPERTY_TO_PROPERTIES(gizmoType, getGizmoType); + withReadLock([&] { + _ringProperties.getProperties(properties); + }); + + return properties; +} + +bool GizmoEntityItem::setProperties(const EntityItemProperties& properties) { + bool somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class + + SET_ENTITY_PROPERTY_FROM_PROPERTIES(gizmoType, setGizmoType); + withWriteLock([&] { + bool ringPropertiesChanged = _ringProperties.setProperties(properties); + somethingChanged |= ringPropertiesChanged; + }); + + if (somethingChanged) { + bool wantDebug = false; + if (wantDebug) { + uint64_t now = usecTimestampNow(); + int elapsed = now - getLastEdited(); + qCDebug(entities) << "GizmoEntityItem::setProperties() AFTER update... edited AGO=" << elapsed << + "now=" << now << " getLastEdited()=" << getLastEdited(); + } + setLastEdited(properties.getLastEdited()); + } + return somethingChanged; +} + +int GizmoEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, + ReadBitstreamToTreeParams& args, + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) { + + int bytesRead = 0; + const unsigned char* dataAt = data; + + READ_ENTITY_PROPERTY(PROP_GIZMO_TYPE, GizmoType, setGizmoType); + withWriteLock([&] { + int bytesFromRing = _ringProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, + propertyFlags, overwriteLocalData, + somethingChanged); + bytesRead += bytesFromRing; + dataAt += bytesFromRing; + }); + + return bytesRead; +} + +EntityPropertyFlags GizmoEntityItem::getEntityProperties(EncodeBitstreamParams& params) const { + EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params); + + requestedProperties += PROP_GIZMO_TYPE; + requestedProperties += _ringProperties.getEntityProperties(params); + + return requestedProperties; +} + +void GizmoEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, + EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const { + + bool successPropertyFits = true; + + APPEND_ENTITY_PROPERTY(PROP_GIZMO_TYPE, (uint32_t)getGizmoType()); + withReadLock([&] { + _ringProperties.appendSubclassData(packetData, params, entityTreeElementExtraEncodeData, requestedProperties, + propertyFlags, propertiesDidntFit, propertyCount, appendState); + }); +} + +bool GizmoEntityItem::supportsDetailedIntersection() const { + return _gizmoType == GizmoType::RING; +} + +#include + +bool GizmoEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, + OctreeElementPointer& element, + float& distance, BoxFace& face, glm::vec3& surfaceNormal, + QVariantMap& extraInfo, bool precisionPicking) const { + glm::vec3 dimensions = getScaledDimensions(); + glm::vec2 xyDimensions(dimensions.x, dimensions.z); + glm::quat rotation = glm::angleAxis((float)M_PI_2, Vectors::RIGHT) * getWorldOrientation(); + glm::vec3 position = getWorldPosition() + rotation * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint())); + + if (findRayRectangleIntersection(origin, direction, rotation, position, xyDimensions, distance)) { + glm::vec3 hitPosition = origin + (distance * direction); + glm::vec3 localHitPosition = glm::inverse(rotation) * (hitPosition - getWorldPosition()); + localHitPosition.x /= xyDimensions.x; + localHitPosition.y /= xyDimensions.y; + float distanceToHit = glm::length(localHitPosition); + + if (0.5f * _ringProperties.getInnerRadius() <= distanceToHit && distanceToHit <= 0.5f) { + glm::vec3 forward = rotation * Vectors::FRONT; + if (glm::dot(forward, direction) > 0.0f) { + face = MAX_Z_FACE; + surfaceNormal = -forward; + } else { + face = MIN_Z_FACE; + surfaceNormal = forward; + } + return true; + } + } + + return false; +} + +bool GizmoEntityItem::findDetailedParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity, const glm::vec3& acceleration, + OctreeElementPointer& element, float& parabolicDistance, + BoxFace& face, glm::vec3& surfaceNormal, + QVariantMap& extraInfo, bool precisionPicking) const { + //// Scale the dimensions by the diameter + glm::vec3 dimensions = getScaledDimensions(); + glm::vec2 xyDimensions(dimensions.x, dimensions.z); + glm::quat rotation = glm::angleAxis((float)M_PI_2, Vectors::RIGHT) * getWorldOrientation(); + glm::vec3 position = getWorldPosition(); + + glm::quat inverseRot = glm::inverse(rotation); + glm::vec3 localOrigin = inverseRot * (origin - position); + glm::vec3 localVelocity = inverseRot * velocity; + glm::vec3 localAcceleration = inverseRot * acceleration; + + if (findParabolaRectangleIntersection(localOrigin, localVelocity, localAcceleration, xyDimensions, parabolicDistance)) { + glm::vec3 localHitPosition = localOrigin + localVelocity * parabolicDistance + 0.5f * localAcceleration * parabolicDistance * parabolicDistance; + localHitPosition.x /= xyDimensions.x; + localHitPosition.y /= xyDimensions.y; + float distanceToHit = glm::length(localHitPosition); + + if (0.5f * _ringProperties.getInnerRadius() <= distanceToHit && distanceToHit <= 0.5f) { + float localIntersectionVelocityZ = localVelocity.z + localAcceleration.z * parabolicDistance; + glm::vec3 forward = rotation * Vectors::FRONT; + if (localIntersectionVelocityZ > 0.0f) { + face = MIN_Z_FACE; + surfaceNormal = forward; + } else { + face = MAX_Z_FACE; + surfaceNormal = -forward; + } + return true; + } + } + + return false; +} + +void GizmoEntityItem::setGizmoType(GizmoType value) { + withWriteLock([&] { + _gizmoType = value; + }); +} + +GizmoType GizmoEntityItem::getGizmoType() const { + return resultWithReadLock([&] { + return _gizmoType; + }); +} + +RingGizmoPropertyGroup GizmoEntityItem::getRingProperties() const { + return resultWithReadLock([&] { + return _ringProperties; + }); +} \ No newline at end of file diff --git a/libraries/entities/src/GizmoEntityItem.h b/libraries/entities/src/GizmoEntityItem.h new file mode 100644 index 0000000000..aa338355b8 --- /dev/null +++ b/libraries/entities/src/GizmoEntityItem.h @@ -0,0 +1,67 @@ +// +// Created by Sam Gondelman on 1/22/19 +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_GizmoEntityItem_h +#define hifi_GizmoEntityItem_h + +#include "EntityItem.h" + +#include "RingGizmoPropertyGroup.h" + +class GizmoEntityItem : public EntityItem { + using Pointer = std::shared_ptr; +public: + static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); + + GizmoEntityItem(const EntityItemID& entityItemID); + + ALLOW_INSTANTIATION // This class can be instantiated + + virtual void setUnscaledDimensions(const glm::vec3& value) override; + + // methods for getting/setting all properties of an entity + EntityItemProperties getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const override; + bool setProperties(const EntityItemProperties& properties) override; + + EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override; + + void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, + EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const override; + + int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, + ReadBitstreamToTreeParams& args, + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) override; + + bool supportsDetailedIntersection() const override; + bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, + OctreeElementPointer& element, float& distance, + BoxFace& face, glm::vec3& surfaceNormal, + QVariantMap& extraInfo, bool precisionPicking) const override; + bool findDetailedParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity, + const glm::vec3& acceleration, OctreeElementPointer& element, float& parabolicDistance, + BoxFace& face, glm::vec3& surfaceNormal, + QVariantMap& extraInfo, bool precisionPicking) const override; + + GizmoType getGizmoType() const; + void setGizmoType(GizmoType value); + + RingGizmoPropertyGroup getRingProperties() const; + +protected: + GizmoType _gizmoType; + RingGizmoPropertyGroup _ringProperties; + +}; + +#endif // hifi_GizmoEntityItem_h diff --git a/libraries/entities/src/ParticleEffectEntityItem.h b/libraries/entities/src/ParticleEffectEntityItem.h index 88ebd47d6e..0755d7868b 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.h +++ b/libraries/entities/src/ParticleEffectEntityItem.h @@ -21,10 +21,10 @@ namespace particle { static const float SCRIPT_MAXIMUM_PI = 3.1416f; // Round up so that reasonable property values work static const float UNINITIALIZED = NAN; - static const u8vec3 DEFAULT_COLOR = { 255, 255, 255 }; + static const u8vec3 DEFAULT_COLOR = ENTITY_ITEM_DEFAULT_COLOR; static const vec3 DEFAULT_COLOR_UNINITIALIZED = { UNINITIALIZED, UNINITIALIZED, UNINITIALIZED }; static const u8vec3 DEFAULT_COLOR_SPREAD = { 0, 0, 0 }; - static const float DEFAULT_ALPHA = 1.0f; + static const float DEFAULT_ALPHA = ENTITY_ITEM_DEFAULT_ALPHA; static const float DEFAULT_ALPHA_SPREAD = 0.0f; static const float DEFAULT_ALPHA_START = UNINITIALIZED; static const float DEFAULT_ALPHA_FINISH = UNINITIALIZED; diff --git a/libraries/entities/src/RingGizmoPropertyGroup.cpp b/libraries/entities/src/RingGizmoPropertyGroup.cpp new file mode 100644 index 0000000000..387cb1d688 --- /dev/null +++ b/libraries/entities/src/RingGizmoPropertyGroup.cpp @@ -0,0 +1,489 @@ +// +// Created by Sam Gondelman on 1/22/19 +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "RingGizmoPropertyGroup.h" + +#include + +#include "EntityItemProperties.h" +#include "EntityItemPropertiesMacros.h" + +const float RingGizmoPropertyGroup::MIN_ANGLE = 0.0f; +const float RingGizmoPropertyGroup::MAX_ANGLE = 360.0f; +const float RingGizmoPropertyGroup::MIN_ALPHA = 0.0f; +const float RingGizmoPropertyGroup::MAX_ALPHA = 1.0f; +const float RingGizmoPropertyGroup::MIN_RADIUS = 0.0f; +const float RingGizmoPropertyGroup::MAX_RADIUS = 0.5f; + +void RingGizmoPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, + QScriptEngine* engine, bool skipDefaults, + EntityItemProperties& defaultEntityProperties) const { + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_START_ANGLE, Ring, ring, StartAngle, startAngle); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_END_ANGLE, Ring, ring, EndAngle, endAngle); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_INNER_RADIUS, Ring, ring, InnerRadius, innerRadius); + + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_INNER_START_COLOR, Ring, ring, InnerStartColor, innerStartColor, u8vec3Color); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_INNER_END_COLOR, Ring, ring, InnerEndColor, innerEndColor, u8vec3Color); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_OUTER_START_COLOR, Ring, ring, OuterStartColor, outerStartColor, u8vec3Color); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_OUTER_END_COLOR, Ring, ring, OuterEndColor, outerEndColor, u8vec3Color); + + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_INNER_START_ALPHA, Ring, ring, InnerStartAlpha, innerStartAlpha); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_INNER_END_ALPHA, Ring, ring, InnerEndAlpha, innerEndAlpha); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_OUTER_START_ALPHA, Ring, ring, OuterStartAlpha, outerStartAlpha); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_OUTER_END_ALPHA, Ring, ring, OuterEndAlpha, outerEndAlpha); + + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAS_TICK_MARKS, Ring, ring, HasTickMarks, hasTickMarks); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_MAJOR_TICK_MARKS_ANGLE, Ring, ring, MajorTickMarksAngle, majorTickMarksAngle); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_MINOR_TICK_MARKS_ANGLE, Ring, ring, MinorTickMarksAngle, minorTickMarksAngle); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_MAJOR_TICK_MARKS_LENGTH, Ring, ring, MajorTickMarksLength, majorTickMarksLength); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_MINOR_TICK_MARKS_LENGTH, Ring, ring, MinorTickMarksLength, minorTickMarksLength); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_MAJOR_TICK_MARKS_COLOR, Ring, ring, MajorTickMarksColor, majorTickMarksColor, u8vec3Color); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_MINOR_TICK_MARKS_COLOR, Ring, ring, MinorTickMarksColor, minorTickMarksColor, u8vec3Color); +} + +void RingGizmoPropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) { + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(ring, startAngle, float, setStartAngle); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(ring, endAngle, float, setEndAngle); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(ring, innerRadius, float, setInnerRadius); + + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(ring, innerStartColor, u8vec3Color, setInnerStartColor); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(ring, innerEndColor, u8vec3Color, setInnerEndColor); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(ring, outerStartColor, u8vec3Color, setOuterStartColor); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(ring, outerEndColor, u8vec3Color, setOuterEndColor); + + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(ring, innerStartAlpha, float, setInnerStartAlpha); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(ring, innerEndAlpha, float, setInnerEndAlpha); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(ring, outerStartAlpha, float, setOuterStartAlpha); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(ring, outerEndAlpha, float, setOuterEndAlpha); + + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(ring, hasTickMarks, bool, setHasTickMarks); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(ring, majorTickMarksAngle, float, setMajorTickMarksAngle); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(ring, minorTickMarksAngle, float, setMinorTickMarksAngle); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(ring, majorTickMarksLength, float, setMajorTickMarksLength); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(ring, minorTickMarksLength, float, setMinorTickMarksLength); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(ring, majorTickMarksColor, u8vec3Color, setMajorTickMarksColor); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(ring, minorTickMarksColor, u8vec3Color, setMinorTickMarksColor); +} + +void RingGizmoPropertyGroup::merge(const RingGizmoPropertyGroup& other) { + COPY_PROPERTY_IF_CHANGED(startAngle); + COPY_PROPERTY_IF_CHANGED(endAngle); + COPY_PROPERTY_IF_CHANGED(innerRadius); + + COPY_PROPERTY_IF_CHANGED(innerStartColor); + COPY_PROPERTY_IF_CHANGED(innerEndColor); + COPY_PROPERTY_IF_CHANGED(outerStartColor); + COPY_PROPERTY_IF_CHANGED(outerEndColor); + + COPY_PROPERTY_IF_CHANGED(innerStartAlpha); + COPY_PROPERTY_IF_CHANGED(innerEndAlpha); + COPY_PROPERTY_IF_CHANGED(outerStartAlpha); + COPY_PROPERTY_IF_CHANGED(outerEndAlpha); + + COPY_PROPERTY_IF_CHANGED(hasTickMarks); + COPY_PROPERTY_IF_CHANGED(majorTickMarksAngle); + COPY_PROPERTY_IF_CHANGED(minorTickMarksAngle); + COPY_PROPERTY_IF_CHANGED(majorTickMarksLength); + COPY_PROPERTY_IF_CHANGED(minorTickMarksLength); + COPY_PROPERTY_IF_CHANGED(majorTickMarksColor); + COPY_PROPERTY_IF_CHANGED(minorTickMarksColor); +} + +void RingGizmoPropertyGroup::debugDump() const { + qCDebug(entities) << " RingGizmoPropertyGroup: ---------------------------------------------"; + qCDebug(entities) << " _startAngle:" << _startAngle; + qCDebug(entities) << " _endAngle:" << _endAngle; + qCDebug(entities) << " _innerRadius:" << _innerRadius; + qCDebug(entities) << " _innerStartColor:" << _innerStartColor; + qCDebug(entities) << " _innerEndColor:" << _innerEndColor; + qCDebug(entities) << " _outerStartColor:" << _outerStartColor; + qCDebug(entities) << " _outerEndColor:" << _outerEndColor; + qCDebug(entities) << " _innerStartAlpha:" << _innerStartAlpha; + qCDebug(entities) << " _innerEndAlpha:" << _innerEndAlpha; + qCDebug(entities) << " _outerStartAlpha:" << _outerStartAlpha; + qCDebug(entities) << " _outerEndAlpha:" << _outerEndAlpha; + qCDebug(entities) << " _hasTickMarks:" << _hasTickMarks; + qCDebug(entities) << " _majorTickMarksAngle:" << _majorTickMarksAngle; + qCDebug(entities) << " _minorTickMarksAngle:" << _minorTickMarksAngle; + qCDebug(entities) << " _majorTickMarksLength:" << _majorTickMarksLength; + qCDebug(entities) << " _minorTickMarksLength:" << _minorTickMarksLength; + qCDebug(entities) << " _majorTickMarksColor:" << _majorTickMarksColor; + qCDebug(entities) << " _minorTickMarksColor:" << _minorTickMarksColor; +} + +void RingGizmoPropertyGroup::listChangedProperties(QList& out) { + if (startAngleChanged()) { + out << "ring-startAngle"; + } + if (endAngleChanged()) { + out << "ring-endAngle"; + } + if (innerRadiusChanged()) { + out << "ring-innerRadius"; + } + + if (innerStartColorChanged()) { + out << "ring-innerStartColor"; + } + if (innerEndColorChanged()) { + out << "ring-innerEndColor"; + } + if (outerStartColorChanged()) { + out << "ring-outerStartColor"; + } + if (outerEndColorChanged()) { + out << "ring-outerEndColor"; + } + + if (innerStartAlphaChanged()) { + out << "ring-innerStartAlpha"; + } + if (innerEndAlphaChanged()) { + out << "ring-innerEndAlpha"; + } + if (outerStartAlphaChanged()) { + out << "ring-outerStartAlpha"; + } + if (outerEndAlphaChanged()) { + out << "ring-outerEndAlpha"; + } + + if (hasTickMarksChanged()) { + out << "ring-hasTickMarks"; + } + if (majorTickMarksAngleChanged()) { + out << "ring-majorTickMarksAngle"; + } + if (minorTickMarksAngleChanged()) { + out << "ring-minorTickMarksAngle"; + } + if (majorTickMarksLengthChanged()) { + out << "ring-majorTickMarksLength"; + } + if (minorTickMarksLengthChanged()) { + out << "ring-minorTickMarksLength"; + } + if (majorTickMarksColorChanged()) { + out << "ring-majorTickMarksColor"; + } + if (minorTickMarksColorChanged()) { + out << "ring-minorTickMarksColor"; + } +} + +bool RingGizmoPropertyGroup::appendToEditPacket(OctreePacketData* packetData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const { + + bool successPropertyFits = true; + + APPEND_ENTITY_PROPERTY(PROP_START_ANGLE, getStartAngle()); + APPEND_ENTITY_PROPERTY(PROP_END_ANGLE, getEndAngle()); + APPEND_ENTITY_PROPERTY(PROP_INNER_RADIUS, getInnerRadius()); + + APPEND_ENTITY_PROPERTY(PROP_INNER_START_COLOR, getInnerStartColor()); + APPEND_ENTITY_PROPERTY(PROP_INNER_END_COLOR, getInnerEndColor()); + APPEND_ENTITY_PROPERTY(PROP_OUTER_START_COLOR, getOuterStartColor()); + APPEND_ENTITY_PROPERTY(PROP_OUTER_END_COLOR, getOuterEndColor()); + + APPEND_ENTITY_PROPERTY(PROP_INNER_START_ALPHA, getInnerStartAlpha()); + APPEND_ENTITY_PROPERTY(PROP_INNER_END_ALPHA, getInnerEndAlpha()); + APPEND_ENTITY_PROPERTY(PROP_OUTER_START_ALPHA, getOuterStartAlpha()); + APPEND_ENTITY_PROPERTY(PROP_OUTER_END_ALPHA, getOuterEndAlpha()); + + APPEND_ENTITY_PROPERTY(PROP_HAS_TICK_MARKS, getHasTickMarks()); + APPEND_ENTITY_PROPERTY(PROP_MAJOR_TICK_MARKS_ANGLE, getMajorTickMarksAngle()); + APPEND_ENTITY_PROPERTY(PROP_MINOR_TICK_MARKS_ANGLE, getMinorTickMarksAngle()); + APPEND_ENTITY_PROPERTY(PROP_MAJOR_TICK_MARKS_LENGTH, getMajorTickMarksLength()); + APPEND_ENTITY_PROPERTY(PROP_MINOR_TICK_MARKS_LENGTH, getMinorTickMarksLength()); + APPEND_ENTITY_PROPERTY(PROP_MAJOR_TICK_MARKS_COLOR, getMajorTickMarksColor()); + APPEND_ENTITY_PROPERTY(PROP_MINOR_TICK_MARKS_COLOR, getMinorTickMarksColor()); + + return true; +} + +bool RingGizmoPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyFlags, + const unsigned char*& dataAt , int& processedBytes) { + + int bytesRead = 0; + bool overwriteLocalData = true; + bool somethingChanged = false; + + READ_ENTITY_PROPERTY(PROP_START_ANGLE, float, setStartAngle); + READ_ENTITY_PROPERTY(PROP_END_ANGLE, float, setEndAngle); + READ_ENTITY_PROPERTY(PROP_INNER_RADIUS, float, setInnerRadius); + + READ_ENTITY_PROPERTY(PROP_INNER_START_COLOR, u8vec3Color, setInnerStartColor); + READ_ENTITY_PROPERTY(PROP_INNER_END_COLOR, u8vec3Color, setInnerEndColor); + READ_ENTITY_PROPERTY(PROP_OUTER_START_COLOR, u8vec3Color, setOuterStartColor); + READ_ENTITY_PROPERTY(PROP_OUTER_END_COLOR, u8vec3Color, setOuterEndColor); + + READ_ENTITY_PROPERTY(PROP_INNER_START_ALPHA, float, setInnerStartAlpha); + READ_ENTITY_PROPERTY(PROP_INNER_END_ALPHA, float, setInnerEndAlpha); + READ_ENTITY_PROPERTY(PROP_OUTER_START_ALPHA, float, setOuterStartAlpha); + READ_ENTITY_PROPERTY(PROP_OUTER_END_ALPHA, float, setOuterEndAlpha); + + READ_ENTITY_PROPERTY(PROP_HAS_TICK_MARKS, bool, setHasTickMarks); + READ_ENTITY_PROPERTY(PROP_MAJOR_TICK_MARKS_ANGLE, float, setMajorTickMarksAngle); + READ_ENTITY_PROPERTY(PROP_MINOR_TICK_MARKS_ANGLE, float, setMinorTickMarksAngle); + READ_ENTITY_PROPERTY(PROP_MAJOR_TICK_MARKS_LENGTH, float, setMajorTickMarksLength); + READ_ENTITY_PROPERTY(PROP_MINOR_TICK_MARKS_LENGTH, float, setMinorTickMarksLength); + READ_ENTITY_PROPERTY(PROP_MAJOR_TICK_MARKS_COLOR, u8vec3Color, setMajorTickMarksColor); + READ_ENTITY_PROPERTY(PROP_MINOR_TICK_MARKS_COLOR, u8vec3Color, setMinorTickMarksColor); + + + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_START_ANGLE, StartAngle); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_END_ANGLE, EndAngle); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_INNER_RADIUS, InnerRadius); + + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_INNER_START_COLOR, InnerStartColor); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_INNER_END_COLOR, InnerEndColor); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_OUTER_START_COLOR, OuterStartColor); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_OUTER_END_COLOR, OuterEndColor); + + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_INNER_START_ALPHA, InnerStartAlpha); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_INNER_END_ALPHA, InnerEndAlpha); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_OUTER_START_ALPHA, OuterStartAlpha); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_OUTER_END_ALPHA, OuterEndAlpha); + + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_HAS_TICK_MARKS, HasTickMarks); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_MAJOR_TICK_MARKS_ANGLE, MajorTickMarksAngle); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_MINOR_TICK_MARKS_ANGLE, MinorTickMarksAngle); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_MAJOR_TICK_MARKS_LENGTH, MajorTickMarksLength); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_MINOR_TICK_MARKS_LENGTH, MinorTickMarksLength); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_MAJOR_TICK_MARKS_COLOR, MajorTickMarksColor); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_MINOR_TICK_MARKS_COLOR, MinorTickMarksColor); + + processedBytes += bytesRead; + + Q_UNUSED(somethingChanged); + + return true; +} + +void RingGizmoPropertyGroup::markAllChanged() { + _startAngleChanged = true; + _endAngleChanged = true; + _innerRadiusChanged = true; + + _innerStartColorChanged = true; + _innerEndColorChanged = true; + _outerStartColorChanged = true; + _outerEndColorChanged = true; + + _innerStartAlphaChanged = true; + _innerEndAlphaChanged = true; + _outerStartAlphaChanged = true; + _outerEndAlphaChanged = true; + + _hasTickMarksChanged = true; + _majorTickMarksAngleChanged = true; + _minorTickMarksAngleChanged = true; + _majorTickMarksLengthChanged = true; + _minorTickMarksLengthChanged = true; + _majorTickMarksColorChanged = true; + _minorTickMarksColorChanged = true; +} + +EntityPropertyFlags RingGizmoPropertyGroup::getChangedProperties() const { + EntityPropertyFlags changedProperties; + + CHECK_PROPERTY_CHANGE(PROP_START_ANGLE, startAngle); + CHECK_PROPERTY_CHANGE(PROP_END_ANGLE, endAngle); + CHECK_PROPERTY_CHANGE(PROP_INNER_RADIUS, innerRadius); + + CHECK_PROPERTY_CHANGE(PROP_INNER_START_COLOR, innerStartColor); + CHECK_PROPERTY_CHANGE(PROP_INNER_END_COLOR, innerEndColor); + CHECK_PROPERTY_CHANGE(PROP_OUTER_START_COLOR, outerStartColor); + CHECK_PROPERTY_CHANGE(PROP_OUTER_END_COLOR, outerEndColor); + + CHECK_PROPERTY_CHANGE(PROP_INNER_START_ALPHA, innerStartAlpha); + CHECK_PROPERTY_CHANGE(PROP_INNER_END_ALPHA, innerEndAlpha); + CHECK_PROPERTY_CHANGE(PROP_OUTER_START_ALPHA, outerStartAlpha); + CHECK_PROPERTY_CHANGE(PROP_OUTER_END_ALPHA, outerEndAlpha); + + CHECK_PROPERTY_CHANGE(PROP_HAS_TICK_MARKS, hasTickMarks); + CHECK_PROPERTY_CHANGE(PROP_MAJOR_TICK_MARKS_ANGLE, majorTickMarksAngle); + CHECK_PROPERTY_CHANGE(PROP_MINOR_TICK_MARKS_ANGLE, minorTickMarksAngle); + CHECK_PROPERTY_CHANGE(PROP_MAJOR_TICK_MARKS_LENGTH, majorTickMarksLength); + CHECK_PROPERTY_CHANGE(PROP_MINOR_TICK_MARKS_LENGTH, minorTickMarksLength); + CHECK_PROPERTY_CHANGE(PROP_MAJOR_TICK_MARKS_COLOR, majorTickMarksColor); + CHECK_PROPERTY_CHANGE(PROP_MINOR_TICK_MARKS_COLOR, minorTickMarksColor); + + return changedProperties; +} + +void RingGizmoPropertyGroup::getProperties(EntityItemProperties& properties) const { + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Ring, StartAngle, getStartAngle); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Ring, EndAngle, getEndAngle); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Ring, InnerRadius, getInnerRadius); + + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Ring, InnerStartColor, getInnerStartColor); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Ring, InnerEndColor, getInnerEndColor); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Ring, OuterStartColor, getOuterStartColor); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Ring, OuterEndColor, getOuterEndColor); + + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Ring, InnerStartAlpha, getInnerStartAlpha); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Ring, InnerEndAlpha, getInnerEndAlpha); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Ring, OuterStartAlpha, getOuterStartAlpha); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Ring, OuterEndAlpha, getOuterEndAlpha); + + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Ring, HasTickMarks, getHasTickMarks); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Ring, MajorTickMarksAngle, getMajorTickMarksAngle); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Ring, MinorTickMarksAngle, getMinorTickMarksAngle); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Ring, MajorTickMarksLength, getMajorTickMarksLength); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Ring, MinorTickMarksLength, getMinorTickMarksLength); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Ring, MajorTickMarksColor, getMajorTickMarksColor); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Ring, MinorTickMarksColor, getMinorTickMarksColor); +} + +bool RingGizmoPropertyGroup::setProperties(const EntityItemProperties& properties) { + bool somethingChanged = false; + + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Ring, StartAngle, startAngle, setStartAngle); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Ring, EndAngle, endAngle, setEndAngle); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Ring, InnerRadius, innerRadius, setInnerRadius); + + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Ring, InnerStartColor, innerStartColor, setInnerStartColor); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Ring, InnerEndColor, innerEndColor, setInnerEndColor); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Ring, OuterStartColor, outerStartColor, setOuterStartColor); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Ring, OuterEndColor, outerEndColor, setOuterEndColor); + + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Ring, InnerStartAlpha, innerStartAlpha, setInnerStartAlpha); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Ring, InnerEndAlpha, innerEndAlpha, setInnerEndAlpha); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Ring, OuterStartAlpha, outerStartAlpha, setOuterStartAlpha); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Ring, OuterEndAlpha, outerEndAlpha, setOuterEndAlpha); + + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Ring, HasTickMarks, hasTickMarks, setHasTickMarks); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Ring, MajorTickMarksAngle, majorTickMarksAngle, setMajorTickMarksAngle); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Ring, MinorTickMarksAngle, minorTickMarksAngle, setMinorTickMarksAngle); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Ring, MajorTickMarksLength, majorTickMarksLength, setMajorTickMarksLength); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Ring, MinorTickMarksLength, minorTickMarksLength, setMinorTickMarksLength); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Ring, MajorTickMarksColor, majorTickMarksColor, setMajorTickMarksColor); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Ring, MinorTickMarksColor, minorTickMarksColor, setMinorTickMarksColor); + + return somethingChanged; +} + +EntityPropertyFlags RingGizmoPropertyGroup::getEntityProperties(EncodeBitstreamParams& params) const { + EntityPropertyFlags requestedProperties; + + requestedProperties += PROP_START_ANGLE; + requestedProperties += PROP_END_ANGLE; + requestedProperties += PROP_INNER_RADIUS; + + requestedProperties += PROP_INNER_START_COLOR; + requestedProperties += PROP_INNER_END_COLOR; + requestedProperties += PROP_OUTER_START_COLOR; + requestedProperties += PROP_OUTER_END_COLOR; + + requestedProperties += PROP_INNER_START_ALPHA; + requestedProperties += PROP_INNER_END_ALPHA; + requestedProperties += PROP_OUTER_START_ALPHA; + requestedProperties += PROP_OUTER_END_ALPHA; + + requestedProperties += PROP_HAS_TICK_MARKS; + requestedProperties += PROP_MAJOR_TICK_MARKS_ANGLE; + requestedProperties += PROP_MINOR_TICK_MARKS_ANGLE; + requestedProperties += PROP_MAJOR_TICK_MARKS_LENGTH; + requestedProperties += PROP_MINOR_TICK_MARKS_LENGTH; + requestedProperties += PROP_MAJOR_TICK_MARKS_COLOR; + requestedProperties += PROP_MINOR_TICK_MARKS_COLOR; + + return requestedProperties; +} + +void RingGizmoPropertyGroup::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, + EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const { + + bool successPropertyFits = true; + + APPEND_ENTITY_PROPERTY(PROP_START_ANGLE, getStartAngle()); + APPEND_ENTITY_PROPERTY(PROP_END_ANGLE, getEndAngle()); + APPEND_ENTITY_PROPERTY(PROP_INNER_RADIUS, getInnerRadius()); + + APPEND_ENTITY_PROPERTY(PROP_INNER_START_COLOR, getInnerStartColor()); + APPEND_ENTITY_PROPERTY(PROP_INNER_END_COLOR, getInnerEndColor()); + APPEND_ENTITY_PROPERTY(PROP_OUTER_START_COLOR, getOuterStartColor()); + APPEND_ENTITY_PROPERTY(PROP_OUTER_END_COLOR, getOuterEndColor()); + + APPEND_ENTITY_PROPERTY(PROP_INNER_START_ALPHA, getInnerStartAlpha()); + APPEND_ENTITY_PROPERTY(PROP_INNER_END_ALPHA, getInnerEndAlpha()); + APPEND_ENTITY_PROPERTY(PROP_OUTER_START_ALPHA, getOuterStartAlpha()); + APPEND_ENTITY_PROPERTY(PROP_OUTER_END_ALPHA, getOuterEndAlpha()); + + APPEND_ENTITY_PROPERTY(PROP_HAS_TICK_MARKS, getHasTickMarks()); + APPEND_ENTITY_PROPERTY(PROP_MAJOR_TICK_MARKS_ANGLE, getMajorTickMarksAngle()); + APPEND_ENTITY_PROPERTY(PROP_MINOR_TICK_MARKS_ANGLE, getMinorTickMarksAngle()); + APPEND_ENTITY_PROPERTY(PROP_MAJOR_TICK_MARKS_LENGTH, getMajorTickMarksLength()); + APPEND_ENTITY_PROPERTY(PROP_MINOR_TICK_MARKS_LENGTH, getMinorTickMarksLength()); + APPEND_ENTITY_PROPERTY(PROP_MAJOR_TICK_MARKS_COLOR, getMajorTickMarksColor()); + APPEND_ENTITY_PROPERTY(PROP_MINOR_TICK_MARKS_COLOR, getMinorTickMarksColor()); +} + +int RingGizmoPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, + ReadBitstreamToTreeParams& args, + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) { + + int bytesRead = 0; + const unsigned char* dataAt = data; + + READ_ENTITY_PROPERTY(PROP_START_ANGLE, float, setStartAngle); + READ_ENTITY_PROPERTY(PROP_END_ANGLE, float, setEndAngle); + READ_ENTITY_PROPERTY(PROP_INNER_RADIUS, float, setInnerRadius); + + READ_ENTITY_PROPERTY(PROP_INNER_START_COLOR, u8vec3Color, setInnerStartColor); + READ_ENTITY_PROPERTY(PROP_INNER_END_COLOR, u8vec3Color, setInnerEndColor); + READ_ENTITY_PROPERTY(PROP_OUTER_START_COLOR, u8vec3Color, setOuterStartColor); + READ_ENTITY_PROPERTY(PROP_OUTER_END_COLOR, u8vec3Color, setOuterEndColor); + + READ_ENTITY_PROPERTY(PROP_INNER_START_ALPHA, float, setInnerStartAlpha); + READ_ENTITY_PROPERTY(PROP_INNER_END_ALPHA, float, setInnerEndAlpha); + READ_ENTITY_PROPERTY(PROP_OUTER_START_ALPHA, float, setOuterStartAlpha); + READ_ENTITY_PROPERTY(PROP_OUTER_END_ALPHA, float, setOuterEndAlpha); + + READ_ENTITY_PROPERTY(PROP_HAS_TICK_MARKS, bool, setHasTickMarks); + READ_ENTITY_PROPERTY(PROP_MAJOR_TICK_MARKS_ANGLE, float, setMajorTickMarksAngle); + READ_ENTITY_PROPERTY(PROP_MINOR_TICK_MARKS_ANGLE, float, setMinorTickMarksAngle); + READ_ENTITY_PROPERTY(PROP_MAJOR_TICK_MARKS_LENGTH, float, setMajorTickMarksLength); + READ_ENTITY_PROPERTY(PROP_MINOR_TICK_MARKS_LENGTH, float, setMinorTickMarksLength); + READ_ENTITY_PROPERTY(PROP_MAJOR_TICK_MARKS_COLOR, u8vec3Color, setMajorTickMarksColor); + READ_ENTITY_PROPERTY(PROP_MINOR_TICK_MARKS_COLOR, u8vec3Color, setMinorTickMarksColor); + + return bytesRead; +} + +bool RingGizmoPropertyGroup::operator==(const RingGizmoPropertyGroup& a) const { + return (a._startAngle == _startAngle) && + (a._endAngle == _endAngle) && + (a._innerRadius == _innerRadius) && + (a._innerStartColor == _innerStartColor) && + (a._innerEndColor == _innerEndColor) && + (a._outerStartColor == _outerStartColor) && + (a._outerEndColor == _outerEndColor) && + (a._innerStartAlpha == _innerStartAlpha) && + (a._innerEndAlpha == _innerEndAlpha) && + (a._outerStartAlpha == _outerStartAlpha) && + (a._outerEndAlpha == _outerEndAlpha) && + (a._hasTickMarks == _hasTickMarks) && + (a._majorTickMarksAngle == _majorTickMarksAngle) && + (a._minorTickMarksAngle == _minorTickMarksAngle) && + (a._majorTickMarksLength == _majorTickMarksLength) && + (a._minorTickMarksLength == _minorTickMarksLength) && + (a._majorTickMarksColor == _majorTickMarksColor) && + (a._minorTickMarksColor == _minorTickMarksColor); +} \ No newline at end of file diff --git a/libraries/entities/src/RingGizmoPropertyGroup.h b/libraries/entities/src/RingGizmoPropertyGroup.h new file mode 100644 index 0000000000..42202eb509 --- /dev/null +++ b/libraries/entities/src/RingGizmoPropertyGroup.h @@ -0,0 +1,135 @@ +// +// Created by Sam Gondelman on 1/22/19 +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_RingGizmoPropertyGroup_h +#define hifi_RingGizmoPropertyGroup_h + +#include + +#include + +#include "PropertyGroup.h" +#include "EntityItemPropertiesMacros.h" +#include "EntityItemPropertiesDefaults.h" + +class EntityItemProperties; +class EncodeBitstreamParams; +class OctreePacketData; +class ReadBitstreamToTreeParams; + +using u8vec3Color = glm::u8vec3; + +/**jsdoc + * A RingGizmo is defined by the following properties. + * @typedef {object} Entities.RingGizmo + * + * @property {number} startAngle=0 - The angle at which the ring will start, in degrees. + * @property {number} endAngle=360 - The angle at which the ring will end, in degrees. + * @property {number} innerRadius=0 - The inner radius of the ring as a fraction of the total radius. 0-1. + + * @property {Color} innerStartColor - The color at the inner start point of the ring. + * @property {Color} innerEndColor - The color at the inner end point of the ring. + * @property {Color} outerStartColor - The color at the outer start point of the ring. + * @property {Color} outerEndColor - The color at the outer end point of the ring. + * @property {number} innerStartAlpha=1 - The alpha at the inner start point of the ring. + * @property {number} innerEndAlpha=1 - The alpha at the inner end point of the ring. + * @property {number} outerStartAlpha=1 - The alpha at the outer start point of the ring. + * @property {number} outerEndAlpha=1 - The alpha at the outer end point of the ring. + + * @property {boolean} hasTickMarks=false - Whether or not to render tick marks. + * @property {number} majorTickMarksAngle - The angle between major tick marks, in degrees. + * @property {number} minorTickMarksAngle - The angle between minor tick marks, in degrees. + * @property {number} majorTickMarksLength - The length of the major tick marks, as a fraction of the radius. A positive value draws tick marks + * outwards from the inner radius; a negative value draws tick marks inwards from the outer radius. + * @property {number} minorTickMarksLength - The length of the minor tick marks, as a fraction of the radius. A positive value draws tick marks + * outwards from the inner radius; a negative value draws tick marks inwards from the outer radius. + * @property {Color} majorTickMarksColor - The color of the major tick marks. + * @property {Color} minorTickMarksColor - The color of the minor tick marks. + */ + +class RingGizmoPropertyGroup : public PropertyGroup { +public: + // EntityItemProperty related helpers + virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, + QScriptEngine* engine, bool skipDefaults, + EntityItemProperties& defaultEntityProperties) const override; + virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) override; + + void merge(const RingGizmoPropertyGroup& other); + + virtual void debugDump() const override; + virtual void listChangedProperties(QList& out) override; + + virtual bool appendToEditPacket(OctreePacketData* packetData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const override; + + virtual bool decodeFromEditPacket(EntityPropertyFlags& propertyFlags, + const unsigned char*& dataAt, int& processedBytes) override; + virtual void markAllChanged() override; + virtual EntityPropertyFlags getChangedProperties() const override; + + // EntityItem related helpers + // methods for getting/setting all properties of an entity + virtual void getProperties(EntityItemProperties& propertiesOut) const override; + + // returns true if something changed + virtual bool setProperties(const EntityItemProperties& properties) override; + + virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override; + + virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, + EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const override; + + virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, + ReadBitstreamToTreeParams& args, + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) override; + + bool operator==(const RingGizmoPropertyGroup& a) const; + bool operator!=(const RingGizmoPropertyGroup& a) const { return !(*this == a); } + + static const float MIN_ANGLE; + static const float MAX_ANGLE; + static const float MIN_ALPHA; + static const float MAX_ALPHA; + static const float MIN_RADIUS; + static const float MAX_RADIUS; + + DEFINE_PROPERTY(PROP_START_ANGLE, StartAngle, startAngle, float, 0.0f); + DEFINE_PROPERTY(PROP_END_ANGLE, EndAngle, endAngle, float, 360.0f); + DEFINE_PROPERTY(PROP_INNER_RADIUS, InnerRadius, innerRadius, float, 0.0f); + + DEFINE_PROPERTY_REF(PROP_INNER_START_COLOR, InnerStartColor, innerStartColor, u8vec3Color, ENTITY_ITEM_DEFAULT_COLOR); + DEFINE_PROPERTY_REF(PROP_INNER_END_COLOR, InnerEndColor, innerEndColor, u8vec3Color, ENTITY_ITEM_DEFAULT_COLOR); + DEFINE_PROPERTY_REF(PROP_OUTER_START_COLOR, OuterStartColor, outerStartColor, u8vec3Color, ENTITY_ITEM_DEFAULT_COLOR); + DEFINE_PROPERTY_REF(PROP_OUTER_END_COLOR, OuterEndColor, outerEndColor, u8vec3Color, ENTITY_ITEM_DEFAULT_COLOR); + + DEFINE_PROPERTY(PROP_INNER_START_ALPHA, InnerStartAlpha, innerStartAlpha, float, ENTITY_ITEM_DEFAULT_ALPHA); + DEFINE_PROPERTY(PROP_INNER_END_ALPHA, InnerEndAlpha, innerEndAlpha, float, ENTITY_ITEM_DEFAULT_ALPHA); + DEFINE_PROPERTY(PROP_OUTER_START_ALPHA, OuterStartAlpha, outerStartAlpha, float, ENTITY_ITEM_DEFAULT_ALPHA); + DEFINE_PROPERTY(PROP_OUTER_END_ALPHA, OuterEndAlpha, outerEndAlpha, float, ENTITY_ITEM_DEFAULT_ALPHA); + + DEFINE_PROPERTY(PROP_HAS_TICK_MARKS, HasTickMarks, hasTickMarks, bool, false); + DEFINE_PROPERTY(PROP_MAJOR_TICK_MARKS_ANGLE, MajorTickMarksAngle, majorTickMarksAngle, float, 0.0f); + DEFINE_PROPERTY(PROP_MINOR_TICK_MARKS_ANGLE, MinorTickMarksAngle, minorTickMarksAngle, float, 0.0f); + DEFINE_PROPERTY(PROP_MAJOR_TICK_MARKS_LENGTH, MajorTickMarksLength, majorTickMarksLength, float, 0.0f); + DEFINE_PROPERTY(PROP_MINOR_TICK_MARKS_LENGTH, MinorTickMarksLength, minorTickMarksLength, float, 0.0f); + DEFINE_PROPERTY_REF(PROP_MAJOR_TICK_MARKS_COLOR, MajorTickMarksColor, majorTickMarksColor, u8vec3Color, ENTITY_ITEM_DEFAULT_COLOR); + DEFINE_PROPERTY_REF(PROP_MINOR_TICK_MARKS_COLOR, MinorTickMarksColor, minorTickMarksColor, u8vec3Color, ENTITY_ITEM_DEFAULT_COLOR); +}; + +#endif // hifi_RingGizmoPropertyGroup_h diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index b5d4e6c8ad..b58efcd334 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -259,6 +259,7 @@ enum class EntityVersion : PacketVersion { MigrateOverlayRenderProperties, MissingWebEntityProperties, PulseProperties, + RingGizmoEntities, // Add new versions above here NUM_PACKET_TYPE, diff --git a/libraries/octree/src/OctreePacketData.h b/libraries/octree/src/OctreePacketData.h index 7c299eb14a..a2fe886810 100644 --- a/libraries/octree/src/OctreePacketData.h +++ b/libraries/octree/src/OctreePacketData.h @@ -39,6 +39,7 @@ #include "PrimitiveMode.h" #include "WebInputMode.h" #include "PulseMode.h" +#include "GizmoType.h" #include "OctreeConstants.h" #include "OctreeElement.h" @@ -271,6 +272,7 @@ public: static int unpackDataFromBytes(const unsigned char* dataBytes, PrimitiveMode& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); } static int unpackDataFromBytes(const unsigned char* dataBytes, WebInputMode& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); } static int unpackDataFromBytes(const unsigned char* dataBytes, PulseMode& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); } + static int unpackDataFromBytes(const unsigned char* dataBytes, GizmoType& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); } static int unpackDataFromBytes(const unsigned char* dataBytes, glm::vec2& result); static int unpackDataFromBytes(const unsigned char* dataBytes, glm::vec3& result); static int unpackDataFromBytes(const unsigned char* dataBytes, glm::u8vec3& result); diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 02f51e558a..7d29b9e792 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -2255,8 +2255,8 @@ gpu::PipelinePointer GeometryCache::getWebBrowserProgram(bool transparent) { return transparent ? _simpleTransparentWebBrowserPipeline : _simpleOpaqueWebBrowserPipeline; } -void GeometryCache::bindSimpleProgram(gpu::Batch& batch, bool textured, bool transparent, bool culled, bool unlit, bool depthBiased, bool isAntiAliased) { - batch.setPipeline(getSimplePipeline(textured, transparent, culled, unlit, depthBiased, false, isAntiAliased)); +void GeometryCache::bindSimpleProgram(gpu::Batch& batch, bool textured, bool transparent, bool culled, bool unlit, bool depthBiased, bool isAntiAliased, bool forward) { + batch.setPipeline(getSimplePipeline(textured, transparent, culled, unlit, depthBiased, false, isAntiAliased, forward)); // If not textured, set a default albedo map if (!textured) { diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index e46bb4a899..5c4cc67adf 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -171,7 +171,7 @@ public: // Bind the pipeline and get the state to render static geometry void bindSimpleProgram(gpu::Batch& batch, bool textured = false, bool transparent = false, bool culled = true, - bool unlit = false, bool depthBias = false, bool isAntiAliased = true); + bool unlit = false, bool depthBias = false, bool isAntiAliased = true, bool forward = false); // Get the pipeline to render static geometry static gpu::PipelinePointer getSimplePipeline(bool textured = false, bool transparent = false, bool culled = true, bool unlit = false, bool depthBias = false, bool fading = false, bool isAntiAliased = true, bool forward = false); diff --git a/libraries/shared/src/GizmoType.cpp b/libraries/shared/src/GizmoType.cpp new file mode 100644 index 0000000000..0e67864a63 --- /dev/null +++ b/libraries/shared/src/GizmoType.cpp @@ -0,0 +1,23 @@ +// +// Created by Sam Gondelman on 1/22/19. +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "GizmoType.h" + +const char* gizmoTypeNames[] = { + "ring", +}; + +static const size_t GIZMO_TYPE_NAMES = (sizeof(gizmoTypeNames) / sizeof(gizmoTypeNames[0])); + +QString GizmoTypeHelpers::getNameForGizmoType(GizmoType mode) { + if (((int)mode <= 0) || ((int)mode >= (int)GIZMO_TYPE_NAMES)) { + mode = (GizmoType)0; + } + + return gizmoTypeNames[(int)mode]; +} \ No newline at end of file diff --git a/libraries/shared/src/GizmoType.h b/libraries/shared/src/GizmoType.h new file mode 100644 index 0000000000..ce57fe97c2 --- /dev/null +++ b/libraries/shared/src/GizmoType.h @@ -0,0 +1,37 @@ +// +// Created by Sam Gondelman on 1/22/19. +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_GizmoType_h +#define hifi_GizmoType_h + +#include "QString" + +/**jsdoc + *

Controls how the Gizmo behaves and renders

+ * + * + * + * + * + * + * + *
ValueDescription
ringA ring gizmo.
+ * @typedef {string} GizmoType + */ + +enum GizmoType { + RING = 0, +}; + +class GizmoTypeHelpers { +public: + static QString getNameForGizmoType(GizmoType mode); +}; + +#endif // hifi_GizmoType_h + From 4d83c7f6df911738607251902445d7730b56f9b2 Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Sun, 27 Jan 2019 00:02:06 -0800 Subject: [PATCH 3/3] fix line rendering mode --- .../entities-renderer/src/RenderableGizmoEntityItem.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp b/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp index f2e95c2159..1a188ca163 100644 --- a/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp @@ -279,11 +279,11 @@ void GizmoEntityRenderer::doRender(RenderArgs* args) { // Ticks if (hasTickMarks) { if (tickProperties.x > 0.0f && tickProperties.y != 0.0f) { - geometryCache->renderVertices(batch, gpu::LINE_STRIP, _majorTicksGeometryID); + geometryCache->renderVertices(batch, gpu::LINES, _majorTicksGeometryID); } if (tickProperties.z > 0.0f && tickProperties.w != 0.0f) { - geometryCache->renderVertices(batch, gpu::LINE_STRIP, _minorTicksGeometryID); + geometryCache->renderVertices(batch, gpu::LINES, _minorTicksGeometryID); } } } -} \ No newline at end of file +}