::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/EntityItemPropertiesMacros.h b/libraries/entities/src/EntityItemPropertiesMacros.h
index fa14f52b48..7064f3e62e 100644
--- a/libraries/entities/src/EntityItemPropertiesMacros.h
+++ b/libraries/entities/src/EntityItemPropertiesMacros.h
@@ -383,13 +383,29 @@ inline QRect QRect_convertFromScriptValue(const QScriptValue& v, bool& isValid)
} \
}
-#define COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(P, S) \
- QScriptValue P = object.property(#P); \
- if (P.isValid()) { \
- QString newValue = P.toVariant().toString(); \
- if (_defaultSettings || newValue != get##S##AsString()) { \
- set##S##FromString(newValue); \
- } \
+#define COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(P, S) \
+ { \
+ QScriptValue P = object.property(#P); \
+ if (P.isValid()) { \
+ QString newValue = P.toVariant().toString(); \
+ if (_defaultSettings || newValue != get##S##AsString()) { \
+ set##S##FromString(newValue); \
+ } \
+ } \
+ }
+
+#define COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_ENUM(G, P, S) \
+ { \
+ QScriptValue G = object.property(#G); \
+ if (G.isValid()) { \
+ QScriptValue P = G.property(#P); \
+ if (P.isValid()) { \
+ QString newValue = P.toVariant().toString(); \
+ if (_defaultSettings || newValue != get##S##AsString()) { \
+ set##S##FromString(newValue); \
+ } \
+ } \
+ } \
}
#define DEFINE_PROPERTY_GROUP(N, n, T) \
diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h
index 5c136c4820..b11ecff5bb 100644
--- a/libraries/entities/src/EntityPropertyFlags.h
+++ b/libraries/entities/src/EntityPropertyFlags.h
@@ -106,12 +106,17 @@ enum EntityPropertyList {
PROP_LOCAL_VELOCITY,
PROP_LOCAL_ANGULAR_VELOCITY,
PROP_LOCAL_DIMENSIONS,
-
+
// These properties are used by multiple subtypes but aren't in the base EntityItem
PROP_SHAPE_TYPE,
PROP_COMPOUND_SHAPE_URL,
PROP_COLOR,
PROP_ALPHA,
+ PROP_PULSE_MIN,
+ PROP_PULSE_MAX,
+ PROP_PULSE_PERIOD,
+ PROP_PULSE_COLOR_MODE,
+ PROP_PULSE_ALPHA_MODE,
PROP_TEXTURES,
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -326,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 ad078190dd..95057bedbc 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 2e8914c8a7..8ad654c638 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/GridEntityItem.cpp b/libraries/entities/src/GridEntityItem.cpp
index b4709239ed..d8d070416b 100644
--- a/libraries/entities/src/GridEntityItem.cpp
+++ b/libraries/entities/src/GridEntityItem.cpp
@@ -35,6 +35,9 @@ EntityItemProperties GridEntityItem::getProperties(const EntityPropertyFlags& de
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getColor);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(alpha, getAlpha);
+ withReadLock([&] {
+ _pulseProperties.getProperties(properties);
+ });
COPY_ENTITY_PROPERTY_TO_PROPERTIES(followCamera, getFollowCamera);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(majorGridEvery, getMajorGridEvery);
@@ -48,6 +51,10 @@ bool GridEntityItem::setProperties(const EntityItemProperties& properties) {
SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(alpha, setAlpha);
+ withWriteLock([&] {
+ bool pulsePropertiesChanged = _pulseProperties.setProperties(properties);
+ somethingChanged |= pulsePropertiesChanged;
+ });
SET_ENTITY_PROPERTY_FROM_PROPERTIES(followCamera, setFollowCamera);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(majorGridEvery, setMajorGridEvery);
@@ -76,6 +83,13 @@ int GridEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
READ_ENTITY_PROPERTY(PROP_COLOR, u8vec3Color, setColor);
READ_ENTITY_PROPERTY(PROP_ALPHA, float, setAlpha);
+ withWriteLock([&] {
+ int bytesFromPulse = _pulseProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args,
+ propertyFlags, overwriteLocalData,
+ somethingChanged);
+ bytesRead += bytesFromPulse;
+ dataAt += bytesFromPulse;
+ });
READ_ENTITY_PROPERTY(PROP_GRID_FOLLOW_CAMERA, bool, setFollowCamera);
READ_ENTITY_PROPERTY(PROP_MAJOR_GRID_EVERY, uint32_t, setMajorGridEvery);
@@ -89,6 +103,7 @@ EntityPropertyFlags GridEntityItem::getEntityProperties(EncodeBitstreamParams& p
requestedProperties += PROP_COLOR;
requestedProperties += PROP_ALPHA;
+ requestedProperties += _pulseProperties.getEntityProperties(params);
requestedProperties += PROP_GRID_FOLLOW_CAMERA;
requestedProperties += PROP_MAJOR_GRID_EVERY;
@@ -98,7 +113,7 @@ EntityPropertyFlags GridEntityItem::getEntityProperties(EncodeBitstreamParams& p
}
void GridEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
- EntityTreeElementExtraEncodeDataPointer modelTreeElementExtraEncodeData,
+ EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData,
EntityPropertyFlags& requestedProperties,
EntityPropertyFlags& propertyFlags,
EntityPropertyFlags& propertiesDidntFit,
@@ -109,6 +124,10 @@ void GridEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBits
APPEND_ENTITY_PROPERTY(PROP_COLOR, getColor());
APPEND_ENTITY_PROPERTY(PROP_ALPHA, getAlpha());
+ withReadLock([&] {
+ _pulseProperties.appendSubclassData(packetData, params, entityTreeElementExtraEncodeData, requestedProperties,
+ propertyFlags, propertiesDidntFit, propertyCount, appendState);
+ });
APPEND_ENTITY_PROPERTY(PROP_GRID_FOLLOW_CAMERA, getFollowCamera());
APPEND_ENTITY_PROPERTY(PROP_MAJOR_GRID_EVERY, getMajorGridEvery());
@@ -175,4 +194,10 @@ float GridEntityItem::getMinorGridEvery() const {
return resultWithReadLock([&] {
return _minorGridEvery;
});
+}
+
+PulsePropertyGroup GridEntityItem::getPulseProperties() const {
+ return resultWithReadLock([&] {
+ return _pulseProperties;
+ });
}
\ No newline at end of file
diff --git a/libraries/entities/src/GridEntityItem.h b/libraries/entities/src/GridEntityItem.h
index 6209aee73d..165d9b50f5 100644
--- a/libraries/entities/src/GridEntityItem.h
+++ b/libraries/entities/src/GridEntityItem.h
@@ -11,6 +11,8 @@
#include "EntityItem.h"
+#include "PulsePropertyGroup.h"
+
class GridEntityItem : public EntityItem {
using Pointer = std::shared_ptr;
public:
@@ -29,7 +31,7 @@ public:
EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
- EntityTreeElementExtraEncodeDataPointer modelTreeElementExtraEncodeData,
+ EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData,
EntityPropertyFlags& requestedProperties,
EntityPropertyFlags& propertyFlags,
EntityPropertyFlags& propertiesDidntFit,
@@ -59,9 +61,13 @@ public:
void setMinorGridEvery(float minorGridEvery);
float getMinorGridEvery() const;
+ PulsePropertyGroup getPulseProperties() const;
+
protected:
glm::u8vec3 _color;
float _alpha;
+ PulsePropertyGroup _pulseProperties;
+
bool _followCamera { true };
uint32_t _majorGridEvery { DEFAULT_MAJOR_GRID_EVERY };
float _minorGridEvery { DEFAULT_MINOR_GRID_EVERY };
diff --git a/libraries/entities/src/ImageEntityItem.cpp b/libraries/entities/src/ImageEntityItem.cpp
index cdff1b5390..1e8e4511cf 100644
--- a/libraries/entities/src/ImageEntityItem.cpp
+++ b/libraries/entities/src/ImageEntityItem.cpp
@@ -32,6 +32,9 @@ EntityItemProperties ImageEntityItem::getProperties(const EntityPropertyFlags& d
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getColor);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(alpha, getAlpha);
+ withReadLock([&] {
+ _pulseProperties.getProperties(properties);
+ });
COPY_ENTITY_PROPERTY_TO_PROPERTIES(imageURL, getImageURL);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(emissive, getEmissive);
@@ -47,6 +50,10 @@ bool ImageEntityItem::setProperties(const EntityItemProperties& properties) {
SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(alpha, setAlpha);
+ withWriteLock([&] {
+ bool pulsePropertiesChanged = _pulseProperties.setProperties(properties);
+ somethingChanged |= pulsePropertiesChanged;
+ });
SET_ENTITY_PROPERTY_FROM_PROPERTIES(imageURL, setImageURL);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(emissive, setEmissive);
@@ -77,6 +84,13 @@ int ImageEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
READ_ENTITY_PROPERTY(PROP_COLOR, u8vec3Color, setColor);
READ_ENTITY_PROPERTY(PROP_ALPHA, float, setAlpha);
+ withWriteLock([&] {
+ int bytesFromPulse = _pulseProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args,
+ propertyFlags, overwriteLocalData,
+ somethingChanged);
+ bytesRead += bytesFromPulse;
+ dataAt += bytesFromPulse;
+ });
READ_ENTITY_PROPERTY(PROP_IMAGE_URL, QString, setImageURL);
READ_ENTITY_PROPERTY(PROP_EMISSIVE, bool, setEmissive);
@@ -92,6 +106,7 @@ EntityPropertyFlags ImageEntityItem::getEntityProperties(EncodeBitstreamParams&
requestedProperties += PROP_COLOR;
requestedProperties += PROP_ALPHA;
+ requestedProperties += _pulseProperties.getEntityProperties(params);
requestedProperties += PROP_IMAGE_URL;
requestedProperties += PROP_EMISSIVE;
@@ -103,7 +118,7 @@ EntityPropertyFlags ImageEntityItem::getEntityProperties(EncodeBitstreamParams&
}
void ImageEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
- EntityTreeElementExtraEncodeDataPointer modelTreeElementExtraEncodeData,
+ EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData,
EntityPropertyFlags& requestedProperties,
EntityPropertyFlags& propertyFlags,
EntityPropertyFlags& propertiesDidntFit,
@@ -114,6 +129,10 @@ void ImageEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBit
APPEND_ENTITY_PROPERTY(PROP_COLOR, getColor());
APPEND_ENTITY_PROPERTY(PROP_ALPHA, getAlpha());
+ withReadLock([&] {
+ _pulseProperties.appendSubclassData(packetData, params, entityTreeElementExtraEncodeData, requestedProperties,
+ propertyFlags, propertiesDidntFit, propertyCount, appendState);
+ });
APPEND_ENTITY_PROPERTY(PROP_IMAGE_URL, getImageURL());
APPEND_ENTITY_PROPERTY(PROP_EMISSIVE, getEmissive());
@@ -266,4 +285,10 @@ float ImageEntityItem::getAlpha() const {
return resultWithReadLock([&] {
return _alpha;
});
+}
+
+PulsePropertyGroup ImageEntityItem::getPulseProperties() const {
+ return resultWithReadLock([&] {
+ return _pulseProperties;
+ });
}
\ No newline at end of file
diff --git a/libraries/entities/src/ImageEntityItem.h b/libraries/entities/src/ImageEntityItem.h
index 228f86ca03..05218016b3 100644
--- a/libraries/entities/src/ImageEntityItem.h
+++ b/libraries/entities/src/ImageEntityItem.h
@@ -11,6 +11,8 @@
#include "EntityItem.h"
+#include "PulsePropertyGroup.h"
+
class ImageEntityItem : public EntityItem {
using Pointer = std::shared_ptr;
public:
@@ -29,7 +31,7 @@ public:
EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
- EntityTreeElementExtraEncodeDataPointer modelTreeElementExtraEncodeData,
+ EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData,
EntityPropertyFlags& requestedProperties,
EntityPropertyFlags& propertyFlags,
EntityPropertyFlags& propertiesDidntFit,
@@ -72,6 +74,8 @@ public:
void setAlpha(float alpha);
float getAlpha() const;
+ PulsePropertyGroup getPulseProperties() const;
+
protected:
QString _imageURL;
bool _emissive { false };
@@ -81,6 +85,7 @@ protected:
glm::u8vec3 _color;
float _alpha;
+ PulsePropertyGroup _pulseProperties;
};
#endif // hifi_ImageEntityItem_h
diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp
index 7426318979..b916ecc3de 100644
--- a/libraries/entities/src/ParticleEffectEntityItem.cpp
+++ b/libraries/entities/src/ParticleEffectEntityItem.cpp
@@ -412,6 +412,9 @@ EntityItemProperties ParticleEffectEntityItem::getProperties(const EntityPropert
COPY_ENTITY_PROPERTY_TO_PROPERTIES(shapeType, getShapeType);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getColor);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(alpha, getAlpha);
+ withReadLock([&] {
+ _pulseProperties.getProperties(properties);
+ });
COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(maxParticles, getMaxParticles);
@@ -463,6 +466,10 @@ bool ParticleEffectEntityItem::setProperties(const EntityItemProperties& propert
SET_ENTITY_PROPERTY_FROM_PROPERTIES(shapeType, setShapeType);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(alpha, setAlpha);
+ withWriteLock([&] {
+ bool pulsePropertiesChanged = _pulseProperties.setProperties(properties);
+ somethingChanged |= pulsePropertiesChanged;
+ });
SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(maxParticles, setMaxParticles);
@@ -535,6 +542,13 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch
READ_ENTITY_PROPERTY(PROP_SHAPE_TYPE, ShapeType, setShapeType);
READ_ENTITY_PROPERTY(PROP_COLOR, u8vec3Color, setColor);
READ_ENTITY_PROPERTY(PROP_ALPHA, float, setAlpha);
+ withWriteLock([&] {
+ int bytesFromPulse = _pulseProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args,
+ propertyFlags, overwriteLocalData,
+ somethingChanged);
+ bytesRead += bytesFromPulse;
+ dataAt += bytesFromPulse;
+ });
READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures);
READ_ENTITY_PROPERTY(PROP_MAX_PARTICLES, quint32, setMaxParticles);
@@ -586,6 +600,7 @@ EntityPropertyFlags ParticleEffectEntityItem::getEntityProperties(EncodeBitstrea
requestedProperties += PROP_SHAPE_TYPE;
requestedProperties += PROP_COLOR;
requestedProperties += PROP_ALPHA;
+ requestedProperties += _pulseProperties.getEntityProperties(params);
requestedProperties += PROP_TEXTURES;
requestedProperties += PROP_MAX_PARTICLES;
@@ -643,6 +658,10 @@ void ParticleEffectEntityItem::appendSubclassData(OctreePacketData* packetData,
APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, (uint32_t)getShapeType());
APPEND_ENTITY_PROPERTY(PROP_COLOR, getColor());
APPEND_ENTITY_PROPERTY(PROP_ALPHA, getAlpha());
+ withReadLock([&] {
+ _pulseProperties.appendSubclassData(packetData, params, entityTreeElementExtraEncodeData, requestedProperties,
+ propertyFlags, propertiesDidntFit, propertyCount, appendState);
+ });
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, getTextures());
APPEND_ENTITY_PROPERTY(PROP_MAX_PARTICLES, getMaxParticles());
@@ -786,4 +805,10 @@ particle::Properties ParticleEffectEntityItem::getParticleProperties() const {
}
return result;
+}
+
+PulsePropertyGroup ParticleEffectEntityItem::getPulseProperties() const {
+ return resultWithReadLock([&] {
+ return _pulseProperties;
+ });
}
\ No newline at end of file
diff --git a/libraries/entities/src/ParticleEffectEntityItem.h b/libraries/entities/src/ParticleEffectEntityItem.h
index 89f1e834ea..0755d7868b 100644
--- a/libraries/entities/src/ParticleEffectEntityItem.h
+++ b/libraries/entities/src/ParticleEffectEntityItem.h
@@ -16,14 +16,15 @@
#include "EntityItem.h"
#include "ColorUtils.h"
+#include "PulsePropertyGroup.h"
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;
@@ -341,9 +342,11 @@ public:
virtual bool supportsDetailedIntersection() const override { return false; }
particle::Properties getParticleProperties() const;
+ PulsePropertyGroup getPulseProperties() const;
protected:
particle::Properties _particleProperties;
+ PulsePropertyGroup _pulseProperties;
bool _isEmitting { true };
ShapeType _shapeType { SHAPE_TYPE_NONE };
diff --git a/libraries/entities/src/PulsePropertyGroup.cpp b/libraries/entities/src/PulsePropertyGroup.cpp
new file mode 100644
index 0000000000..54f81750da
--- /dev/null
+++ b/libraries/entities/src/PulsePropertyGroup.cpp
@@ -0,0 +1,249 @@
+//
+// PulsePropertyGroup.cpp
+//
+// Created by Sam Gondelman on 1/15/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 "PulsePropertyGroup.h"
+
+#include
+
+#include "EntityItemProperties.h"
+#include "EntityItemPropertiesMacros.h"
+
+QHash stringToPulseModeLookup;
+
+void addPulseMode(PulseMode mode) {
+ stringToPulseModeLookup[PulseModeHelpers::getNameForPulseMode(mode)] = mode;
+}
+
+void buildStringToPulseModeLookup() {
+ addPulseMode(PulseMode::NONE);
+ addPulseMode(PulseMode::IN_PHASE);
+ addPulseMode(PulseMode::OUT_PHASE);
+}
+
+QString PulsePropertyGroup::getColorModeAsString() const {
+ return PulseModeHelpers::getNameForPulseMode(_colorMode);
+}
+
+void PulsePropertyGroup::setColorModeFromString(const QString& pulseMode) {
+ if (stringToPulseModeLookup.empty()) {
+ buildStringToPulseModeLookup();
+ }
+ auto pulseModeItr = stringToPulseModeLookup.find(pulseMode.toLower());
+ if (pulseModeItr != stringToPulseModeLookup.end()) {
+ _colorMode = pulseModeItr.value();
+ _colorModeChanged = true;
+ }
+}
+
+QString PulsePropertyGroup::getAlphaModeAsString() const {
+ return PulseModeHelpers::getNameForPulseMode(_alphaMode);
+}
+
+void PulsePropertyGroup::setAlphaModeFromString(const QString& pulseMode) {
+ if (stringToPulseModeLookup.empty()) {
+ buildStringToPulseModeLookup();
+ }
+ auto pulseModeItr = stringToPulseModeLookup.find(pulseMode.toLower());
+ if (pulseModeItr != stringToPulseModeLookup.end()) {
+ _alphaMode = pulseModeItr.value();
+ _alphaModeChanged = true;
+ }
+}
+
+void PulsePropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties,
+ QScriptEngine* engine, bool skipDefaults,
+ EntityItemProperties& defaultEntityProperties) const {
+ COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_PULSE_MIN, Pulse, pulse, Min, min);
+ COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_PULSE_MAX, Pulse, pulse, Max, max);
+ COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_PULSE_PERIOD, Pulse, pulse, Period, period);
+ COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_PULSE_COLOR_MODE, Pulse, pulse, ColorMode, colorMode, getColorModeAsString);
+ COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_PULSE_ALPHA_MODE, Pulse, pulse, AlphaMode, alphaMode, getAlphaModeAsString);
+}
+
+void PulsePropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) {
+ COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(pulse, min, float, setMin);
+ COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(pulse, max, float, setMax);
+ COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(pulse, period, float, setPeriod);
+ COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_ENUM(pulse, colorMode, ColorMode);
+ COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_ENUM(pulse, alphaMode, AlphaMode);
+}
+
+void PulsePropertyGroup::merge(const PulsePropertyGroup& other) {
+ COPY_PROPERTY_IF_CHANGED(min);
+ COPY_PROPERTY_IF_CHANGED(max);
+ COPY_PROPERTY_IF_CHANGED(period);
+ COPY_PROPERTY_IF_CHANGED(colorMode);
+ COPY_PROPERTY_IF_CHANGED(alphaMode);
+}
+
+void PulsePropertyGroup::debugDump() const {
+ qCDebug(entities) << " PulsePropertyGroup: ---------------------------------------------";
+ qCDebug(entities) << " _min:" << _min;
+ qCDebug(entities) << " _max:" << _max;
+ qCDebug(entities) << " _period:" << _period;
+ qCDebug(entities) << " _colorMode:" << getColorModeAsString();
+ qCDebug(entities) << " _alphaMode:" << getAlphaModeAsString();
+}
+
+void PulsePropertyGroup::listChangedProperties(QList& out) {
+ if (minChanged()) {
+ out << "pulse-min";
+ }
+ if (maxChanged()) {
+ out << "pulse-max";
+ }
+ if (periodChanged()) {
+ out << "pulse-period";
+ }
+ if (colorModeChanged()) {
+ out << "pulse-colorMode";
+ }
+ if (alphaModeChanged()) {
+ out << "pulse-alphaMode";
+ }
+}
+
+bool PulsePropertyGroup::appendToEditPacket(OctreePacketData* packetData,
+ EntityPropertyFlags& requestedProperties,
+ EntityPropertyFlags& propertyFlags,
+ EntityPropertyFlags& propertiesDidntFit,
+ int& propertyCount,
+ OctreeElement::AppendState& appendState) const {
+
+ bool successPropertyFits = true;
+
+ APPEND_ENTITY_PROPERTY(PROP_PULSE_MIN, getMin());
+ APPEND_ENTITY_PROPERTY(PROP_PULSE_MAX, getMax());
+ APPEND_ENTITY_PROPERTY(PROP_PULSE_PERIOD, getPeriod());
+ APPEND_ENTITY_PROPERTY(PROP_PULSE_COLOR_MODE, (uint32_t)getColorMode());
+ APPEND_ENTITY_PROPERTY(PROP_PULSE_ALPHA_MODE, (uint32_t)getAlphaMode());
+
+ return true;
+}
+
+bool PulsePropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyFlags,
+ const unsigned char*& dataAt , int& processedBytes) {
+
+ int bytesRead = 0;
+ bool overwriteLocalData = true;
+ bool somethingChanged = false;
+
+ READ_ENTITY_PROPERTY(PROP_PULSE_MIN, float, setMin);
+ READ_ENTITY_PROPERTY(PROP_PULSE_MAX, float, setMax);
+ READ_ENTITY_PROPERTY(PROP_PULSE_PERIOD, float, setPeriod);
+ READ_ENTITY_PROPERTY(PROP_PULSE_COLOR_MODE, PulseMode, setColorMode);
+ READ_ENTITY_PROPERTY(PROP_PULSE_ALPHA_MODE, PulseMode, setAlphaMode);
+
+ DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_PULSE_MIN, Min);
+ DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_PULSE_MAX, Max);
+ DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_PULSE_PERIOD, Period);
+ DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_PULSE_COLOR_MODE, ColorMode);
+ DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_PULSE_ALPHA_MODE, AlphaMode);
+
+ processedBytes += bytesRead;
+
+ Q_UNUSED(somethingChanged);
+
+ return true;
+}
+
+void PulsePropertyGroup::markAllChanged() {
+ _minChanged = true;
+ _maxChanged = true;
+ _periodChanged = true;
+ _colorModeChanged = true;
+ _alphaModeChanged = true;
+}
+
+EntityPropertyFlags PulsePropertyGroup::getChangedProperties() const {
+ EntityPropertyFlags changedProperties;
+
+ CHECK_PROPERTY_CHANGE(PROP_PULSE_MIN, min);
+ CHECK_PROPERTY_CHANGE(PROP_PULSE_MAX, max);
+ CHECK_PROPERTY_CHANGE(PROP_PULSE_PERIOD, period);
+ CHECK_PROPERTY_CHANGE(PROP_PULSE_COLOR_MODE, colorMode);
+ CHECK_PROPERTY_CHANGE(PROP_PULSE_ALPHA_MODE, alphaMode);
+
+ return changedProperties;
+}
+
+void PulsePropertyGroup::getProperties(EntityItemProperties& properties) const {
+ COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Pulse, Min, getMin);
+ COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Pulse, Max, getMax);
+ COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Pulse, Period, getPeriod);
+ COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Pulse, ColorMode, getColorMode);
+ COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Pulse, AlphaMode, getAlphaMode);
+}
+
+bool PulsePropertyGroup::setProperties(const EntityItemProperties& properties) {
+ bool somethingChanged = false;
+
+ SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Pulse, Min, min, setMin);
+ SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Pulse, Max, max, setMax);
+ SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Pulse, Period, period, setPeriod);
+ SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Pulse, ColorMode, colorMode, setColorMode);
+ SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Pulse, AlphaMode, alphaMode, setAlphaMode);
+
+ return somethingChanged;
+}
+
+EntityPropertyFlags PulsePropertyGroup::getEntityProperties(EncodeBitstreamParams& params) const {
+ EntityPropertyFlags requestedProperties;
+
+ requestedProperties += PROP_PULSE_MIN;
+ requestedProperties += PROP_PULSE_MAX;
+ requestedProperties += PROP_PULSE_PERIOD;
+ requestedProperties += PROP_PULSE_COLOR_MODE;
+ requestedProperties += PROP_PULSE_ALPHA_MODE;
+
+ return requestedProperties;
+}
+
+void PulsePropertyGroup::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_PULSE_MIN, getMin());
+ APPEND_ENTITY_PROPERTY(PROP_PULSE_MAX, getMax());
+ APPEND_ENTITY_PROPERTY(PROP_PULSE_PERIOD, getPeriod());
+ APPEND_ENTITY_PROPERTY(PROP_PULSE_COLOR_MODE, (uint32_t)getColorMode());
+ APPEND_ENTITY_PROPERTY(PROP_PULSE_ALPHA_MODE, (uint32_t)getAlphaMode());
+}
+
+int PulsePropertyGroup::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_PULSE_MIN, float, setMin);
+ READ_ENTITY_PROPERTY(PROP_PULSE_MAX, float, setMax);
+ READ_ENTITY_PROPERTY(PROP_PULSE_PERIOD, float, setPeriod);
+ READ_ENTITY_PROPERTY(PROP_PULSE_COLOR_MODE, PulseMode, setColorMode);
+ READ_ENTITY_PROPERTY(PROP_PULSE_ALPHA_MODE, PulseMode, setAlphaMode);
+
+ return bytesRead;
+}
+
+bool PulsePropertyGroup::operator==(const PulsePropertyGroup& a) const {
+ return (a._min == _min) &&
+ (a._max == _max) &&
+ (a._period == _period) &&
+ (a._colorMode == _colorMode) &&
+ (a._alphaMode == _alphaMode);
+}
\ No newline at end of file
diff --git a/libraries/entities/src/PulsePropertyGroup.h b/libraries/entities/src/PulsePropertyGroup.h
new file mode 100644
index 0000000000..f54db39149
--- /dev/null
+++ b/libraries/entities/src/PulsePropertyGroup.h
@@ -0,0 +1,99 @@
+//
+// PulsePropertyGroup.h
+//
+// Created by Sam Gondelman on 1/15/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_PulsePropertyGroup_h
+#define hifi_PulsePropertyGroup_h
+
+#include
+
+#include
+
+#include
+
+#include "PropertyGroup.h"
+#include "EntityItemPropertiesMacros.h"
+
+class EntityItemProperties;
+class EncodeBitstreamParams;
+class OctreePacketData;
+class ReadBitstreamToTreeParams;
+
+/**jsdoc
+ * Pulse is defined by the following properties.
+ * @typedef {object} Entities.Pulse
+ *
+ * @property {number} min=0 - The minimum value of the pulse multiplier.
+ * @property {number} max=1 - The maximum value of the pulse multiplier.
+ * @property {number} period=1 - The duration of the color and alpha pulse, in seconds. A pulse multiplier value goes from
+ * min
to max
, then max
to min
in one period.
+ * @property {PulseMode} colorMode="none" - If "in", the color is pulsed in phase with the pulse period; if "out"
+ * the color is pulsed out of phase with the pulse period.
+ * @property {PulseMode} alphaMode="none" - If "in", the alpha is pulsed in phase with the pulse period; if "out"
+ * the alpha is pulsed out of phase with the pulse period.
+ */
+
+class PulsePropertyGroup : 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 PulsePropertyGroup& 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 PulsePropertyGroup& a) const;
+ bool operator!=(const PulsePropertyGroup& a) const { return !(*this == a); }
+
+ DEFINE_PROPERTY(PROP_PULSE_MIN, Min, min, float, 0.0f);
+ DEFINE_PROPERTY(PROP_PULSE_MAX, Max, max, float, 1.0f);
+ DEFINE_PROPERTY(PROP_PULSE_PERIOD, Period, period, float, 1.0f);
+ DEFINE_PROPERTY_REF_ENUM(PROP_PULSE_COLOR_MODE, ColorMode, colorMode, PulseMode, PulseMode::NONE);
+ DEFINE_PROPERTY_REF_ENUM(PROP_PULSE_ALPHA_MODE, AlphaMode, alphaMode, PulseMode, PulseMode::NONE);
+};
+
+#endif // hifi_PulsePropertyGroup_h
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/entities/src/ShapeEntityItem.cpp b/libraries/entities/src/ShapeEntityItem.cpp
index 819cbf9dad..869ae2985f 100644
--- a/libraries/entities/src/ShapeEntityItem.cpp
+++ b/libraries/entities/src/ShapeEntityItem.cpp
@@ -119,6 +119,9 @@ EntityItemProperties ShapeEntityItem::getProperties(const EntityPropertyFlags& d
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getColor);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(alpha, getAlpha);
+ withReadLock([&] {
+ _pulseProperties.getProperties(properties);
+ });
properties.setShape(entity::stringFromShape(getShape()));
properties._shapeChanged = false;
@@ -159,6 +162,10 @@ bool ShapeEntityItem::setProperties(const EntityItemProperties& properties) {
SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(alpha, setAlpha);
+ withWriteLock([&] {
+ bool pulsePropertiesChanged = _pulseProperties.setProperties(properties);
+ somethingChanged |= pulsePropertiesChanged;
+ });
SET_ENTITY_PROPERTY_FROM_PROPERTIES(shape, setShape);
if (somethingChanged) {
@@ -184,6 +191,13 @@ int ShapeEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
READ_ENTITY_PROPERTY(PROP_COLOR, glm::u8vec3, setColor);
READ_ENTITY_PROPERTY(PROP_ALPHA, float, setAlpha);
+ withWriteLock([&] {
+ int bytesFromPulse = _pulseProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args,
+ propertyFlags, overwriteLocalData,
+ somethingChanged);
+ bytesRead += bytesFromPulse;
+ dataAt += bytesFromPulse;
+ });
READ_ENTITY_PROPERTY(PROP_SHAPE, QString, setShape);
return bytesRead;
@@ -193,12 +207,13 @@ EntityPropertyFlags ShapeEntityItem::getEntityProperties(EncodeBitstreamParams&
EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params);
requestedProperties += PROP_COLOR;
requestedProperties += PROP_ALPHA;
+ requestedProperties += _pulseProperties.getEntityProperties(params);
requestedProperties += PROP_SHAPE;
return requestedProperties;
}
void ShapeEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
- EntityTreeElementExtraEncodeDataPointer modelTreeElementExtraEncodeData,
+ EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData,
EntityPropertyFlags& requestedProperties,
EntityPropertyFlags& propertyFlags,
EntityPropertyFlags& propertiesDidntFit,
@@ -208,6 +223,10 @@ void ShapeEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBit
bool successPropertyFits = true;
APPEND_ENTITY_PROPERTY(PROP_COLOR, getColor());
APPEND_ENTITY_PROPERTY(PROP_ALPHA, getAlpha());
+ withReadLock([&] {
+ _pulseProperties.appendSubclassData(packetData, params, entityTreeElementExtraEncodeData, requestedProperties,
+ propertyFlags, propertiesDidntFit, propertyCount, appendState);
+ });
APPEND_ENTITY_PROPERTY(PROP_SHAPE, entity::stringFromShape(getShape()));
}
@@ -416,4 +435,10 @@ void ShapeEntityItem::computeShapeInfo(ShapeInfo& info) {
// This value specifies how the shape should be treated by physics calculations.
ShapeType ShapeEntityItem::getShapeType() const {
return _collisionShapeType;
+}
+
+PulsePropertyGroup ShapeEntityItem::getPulseProperties() const {
+ return resultWithReadLock([&] {
+ return _pulseProperties;
+ });
}
\ No newline at end of file
diff --git a/libraries/entities/src/ShapeEntityItem.h b/libraries/entities/src/ShapeEntityItem.h
index 417f0c6173..28edf2e1a2 100644
--- a/libraries/entities/src/ShapeEntityItem.h
+++ b/libraries/entities/src/ShapeEntityItem.h
@@ -11,6 +11,8 @@
#include "EntityItem.h"
+#include "PulsePropertyGroup.h"
+
namespace entity {
enum Shape {
Triangle,
@@ -58,7 +60,7 @@ public:
EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
- EntityTreeElementExtraEncodeDataPointer modelTreeElementExtraEncodeData,
+ EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData,
EntityPropertyFlags& requestedProperties,
EntityPropertyFlags& propertyFlags,
EntityPropertyFlags& propertiesDidntFit,
@@ -99,9 +101,12 @@ public:
virtual void computeShapeInfo(ShapeInfo& info) override;
virtual ShapeType getShapeType() const override;
+ PulsePropertyGroup getPulseProperties() const;
+
protected:
glm::u8vec3 _color;
float _alpha { 1.0f };
+ PulsePropertyGroup _pulseProperties;
entity::Shape _shape { entity::Shape::Sphere };
//! This is SHAPE_TYPE_ELLIPSOID rather than SHAPE_TYPE_NONE to maintain
diff --git a/libraries/entities/src/SimulationOwner.h b/libraries/entities/src/SimulationOwner.h
index bd444d28dd..f574234354 100644
--- a/libraries/entities/src/SimulationOwner.h
+++ b/libraries/entities/src/SimulationOwner.h
@@ -96,11 +96,11 @@ const uint8_t RECRUIT_SIMULATION_PRIORITY = VOLUNTEER_SIMULATION_PRIORITY + 1;
// When poking objects with scripts an observer will bid at SCRIPT_EDIT priority.
const uint8_t SCRIPT_GRAB_SIMULATION_PRIORITY = 128;
const uint8_t SCRIPT_POKE_SIMULATION_PRIORITY = SCRIPT_GRAB_SIMULATION_PRIORITY - 1;
-const uint8_t AVATAR_ENTITY_SIMULATION_PRIORITY = 255;
// PERSONAL priority (needs a better name) is the level at which a simulation observer owns its own avatar
// which really just means: things that collide with it will be bid at a priority level one lower
const uint8_t PERSONAL_SIMULATION_PRIORITY = SCRIPT_GRAB_SIMULATION_PRIORITY;
+const uint8_t AVATAR_ENTITY_SIMULATION_PRIORITY = PERSONAL_SIMULATION_PRIORITY;
class SimulationOwner {
diff --git a/libraries/entities/src/TextEntityItem.cpp b/libraries/entities/src/TextEntityItem.cpp
index 80c4c896bd..a743d0a7a9 100644
--- a/libraries/entities/src/TextEntityItem.cpp
+++ b/libraries/entities/src/TextEntityItem.cpp
@@ -49,6 +49,10 @@ void TextEntityItem::setUnscaledDimensions(const glm::vec3& value) {
EntityItemProperties TextEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const {
EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class
+ withReadLock([&] {
+ _pulseProperties.getProperties(properties);
+ });
+
COPY_ENTITY_PROPERTY_TO_PROPERTIES(text, getText);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(lineHeight, getLineHeight);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(textColor, getTextColor);
@@ -67,6 +71,11 @@ bool TextEntityItem::setProperties(const EntityItemProperties& properties) {
bool somethingChanged = false;
somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class
+ withWriteLock([&] {
+ bool pulsePropertiesChanged = _pulseProperties.setProperties(properties);
+ somethingChanged |= pulsePropertiesChanged;
+ });
+
SET_ENTITY_PROPERTY_FROM_PROPERTIES(text, setText);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(lineHeight, setLineHeight);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(textColor, setTextColor);
@@ -101,6 +110,14 @@ int TextEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
int bytesRead = 0;
const unsigned char* dataAt = data;
+ withWriteLock([&] {
+ int bytesFromPulse = _pulseProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args,
+ propertyFlags, overwriteLocalData,
+ somethingChanged);
+ bytesRead += bytesFromPulse;
+ dataAt += bytesFromPulse;
+ });
+
READ_ENTITY_PROPERTY(PROP_TEXT, QString, setText);
READ_ENTITY_PROPERTY(PROP_LINE_HEIGHT, float, setLineHeight);
READ_ENTITY_PROPERTY(PROP_TEXT_COLOR, glm::u8vec3, setTextColor);
@@ -118,6 +135,8 @@ int TextEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
EntityPropertyFlags TextEntityItem::getEntityProperties(EncodeBitstreamParams& params) const {
EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params);
+
+ requestedProperties += _pulseProperties.getEntityProperties(params);
requestedProperties += PROP_TEXT;
requestedProperties += PROP_LINE_HEIGHT;
requestedProperties += PROP_TEXT_COLOR;
@@ -129,11 +148,12 @@ EntityPropertyFlags TextEntityItem::getEntityProperties(EncodeBitstreamParams& p
requestedProperties += PROP_RIGHT_MARGIN;
requestedProperties += PROP_TOP_MARGIN;
requestedProperties += PROP_BOTTOM_MARGIN;
+
return requestedProperties;
}
void TextEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
- EntityTreeElementExtraEncodeDataPointer modelTreeElementExtraEncodeData,
+ EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData,
EntityPropertyFlags& requestedProperties,
EntityPropertyFlags& propertyFlags,
EntityPropertyFlags& propertiesDidntFit,
@@ -142,6 +162,11 @@ void TextEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBits
bool successPropertyFits = true;
+ withReadLock([&] {
+ _pulseProperties.appendSubclassData(packetData, params, entityTreeElementExtraEncodeData, requestedProperties,
+ propertyFlags, propertiesDidntFit, propertyCount, appendState);
+ });
+
APPEND_ENTITY_PROPERTY(PROP_TEXT, getText());
APPEND_ENTITY_PROPERTY(PROP_LINE_HEIGHT, getLineHeight());
APPEND_ENTITY_PROPERTY(PROP_TEXT_COLOR, getTextColor());
@@ -345,3 +370,9 @@ float TextEntityItem::getBottomMargin() const {
return _bottomMargin;
});
}
+
+PulsePropertyGroup TextEntityItem::getPulseProperties() const {
+ return resultWithReadLock