::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([&] {
+ return _pulseProperties;
+ });
+}
\ No newline at end of file
diff --git a/libraries/entities/src/TextEntityItem.h b/libraries/entities/src/TextEntityItem.h
index 5c22d8edf0..5ca6823052 100644
--- a/libraries/entities/src/TextEntityItem.h
+++ b/libraries/entities/src/TextEntityItem.h
@@ -14,6 +14,8 @@
#include "EntityItem.h"
+#include "PulsePropertyGroup.h"
+
class TextEntityItem : public EntityItem {
public:
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
@@ -33,7 +35,7 @@ public:
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
- EntityTreeElementExtraEncodeDataPointer modelTreeElementExtraEncodeData,
+ EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData,
EntityPropertyFlags& requestedProperties,
EntityPropertyFlags& propertyFlags,
EntityPropertyFlags& propertiesDidntFit,
@@ -94,6 +96,8 @@ public:
float getBottomMargin() const;
void setBottomMargin(float value);
+ PulsePropertyGroup getPulseProperties() const;
+
private:
QString _text;
float _lineHeight;
@@ -101,6 +105,7 @@ private:
float _textAlpha;
glm::u8vec3 _backgroundColor;
float _backgroundAlpha;
+ PulsePropertyGroup _pulseProperties;
BillboardMode _billboardMode;
float _leftMargin;
float _rightMargin;
diff --git a/libraries/entities/src/WebEntityItem.cpp b/libraries/entities/src/WebEntityItem.cpp
index c0cdb081a2..459d512311 100644
--- a/libraries/entities/src/WebEntityItem.cpp
+++ b/libraries/entities/src/WebEntityItem.cpp
@@ -45,6 +45,9 @@ EntityItemProperties WebEntityItem::getProperties(const EntityPropertyFlags& des
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getColor);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(alpha, getAlpha);
+ withReadLock([&] {
+ _pulseProperties.getProperties(properties);
+ });
COPY_ENTITY_PROPERTY_TO_PROPERTIES(sourceUrl, getSourceUrl);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(dpi, getDPI);
@@ -60,6 +63,10 @@ bool WebEntityItem::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(sourceUrl, setSourceUrl);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(dpi, setDPI);
@@ -91,6 +98,13 @@ int WebEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, i
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_SOURCE_URL, QString, setSourceUrl);
READ_ENTITY_PROPERTY(PROP_DPI, uint16_t, setDPI);
@@ -105,6 +119,7 @@ EntityPropertyFlags WebEntityItem::getEntityProperties(EncodeBitstreamParams& pa
EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params);
requestedProperties += PROP_COLOR;
requestedProperties += PROP_ALPHA;
+ requestedProperties += _pulseProperties.getEntityProperties(params);
requestedProperties += PROP_SOURCE_URL;
requestedProperties += PROP_DPI;
@@ -115,7 +130,7 @@ EntityPropertyFlags WebEntityItem::getEntityProperties(EncodeBitstreamParams& pa
}
void WebEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
- EntityTreeElementExtraEncodeDataPointer modelTreeElementExtraEncodeData,
+ EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData,
EntityPropertyFlags& requestedProperties,
EntityPropertyFlags& propertyFlags,
EntityPropertyFlags& propertiesDidntFit,
@@ -125,6 +140,10 @@ void WebEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBitst
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_SOURCE_URL, getSourceUrl());
APPEND_ENTITY_PROPERTY(PROP_DPI, getDPI());
@@ -285,4 +304,10 @@ WebInputMode WebEntityItem::getInputMode() const {
return resultWithReadLock([&] {
return _inputMode;
});
+}
+
+PulsePropertyGroup WebEntityItem::getPulseProperties() const {
+ return resultWithReadLock([&] {
+ return _pulseProperties;
+ });
}
\ No newline at end of file
diff --git a/libraries/entities/src/WebEntityItem.h b/libraries/entities/src/WebEntityItem.h
index c566bcb5f7..a0a2d65253 100644
--- a/libraries/entities/src/WebEntityItem.h
+++ b/libraries/entities/src/WebEntityItem.h
@@ -11,6 +11,8 @@
#include "EntityItem.h"
+#include "PulsePropertyGroup.h"
+
class WebEntityItem : public EntityItem {
public:
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
@@ -30,7 +32,7 @@ public:
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
- EntityTreeElementExtraEncodeDataPointer modelTreeElementExtraEncodeData,
+ EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData,
EntityPropertyFlags& requestedProperties,
EntityPropertyFlags& propertyFlags,
EntityPropertyFlags& propertiesDidntFit,
@@ -75,9 +77,12 @@ public:
void setInputMode(const WebInputMode& value);
WebInputMode getInputMode() const;
+ PulsePropertyGroup getPulseProperties() const;
+
protected:
glm::u8vec3 _color;
float _alpha { 1.0f };
+ PulsePropertyGroup _pulseProperties;
QString _sourceUrl;
uint16_t _dpi;
diff --git a/libraries/fbx/src/FBXSerializer.cpp b/libraries/fbx/src/FBXSerializer.cpp
index 07102253e4..38465d2809 100644
--- a/libraries/fbx/src/FBXSerializer.cpp
+++ b/libraries/fbx/src/FBXSerializer.cpp
@@ -1480,9 +1480,6 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr
}
}
- extracted.mesh.createMeshTangents(generateTangents);
- extracted.mesh.createBlendShapeTangents(generateTangents);
-
// find the clusters with which the mesh is associated
QVector clusterIDs;
foreach (const QString& childID, _connectionChildMap.values(it.key())) {
diff --git a/libraries/gl/src/gl/Config.cpp b/libraries/gl/src/gl/Config.cpp
index 0e3a174e91..94bb91a3e9 100644
--- a/libraries/gl/src/gl/Config.cpp
+++ b/libraries/gl/src/gl/Config.cpp
@@ -118,6 +118,8 @@ void gl::setSwapInterval(int interval) {
wglSwapIntervalEXT(interval);
#elif defined(Q_OS_MAC)
CGLSetParameter(CGLGetCurrentContext(), kCGLCPSwapInterval, &interval);
+#elif defined(Q_OS_ANDROID)
+ eglSwapInterval(eglGetCurrentDisplay(), interval);
#else
Q_UNUSED(interval);
#endif
diff --git a/libraries/gl/src/gl/Context.cpp b/libraries/gl/src/gl/Context.cpp
index 371e6454e6..7d27b42909 100644
--- a/libraries/gl/src/gl/Context.cpp
+++ b/libraries/gl/src/gl/Context.cpp
@@ -34,22 +34,9 @@ bool Context::USE_CUSTOM_CONTEXT { true };
#endif
bool Context::enableDebugLogger() {
-#if defined(Q_OS_MAC)
- // OSX does not support GL_KHR_debug or GL_ARB_debug_output
- return false;
-#else
-#if defined(DEBUG) || defined(USE_GLES)
- static bool enableDebugLogger = true;
-#else
- static const QString DEBUG_FLAG("HIFI_DEBUG_OPENGL");
- static bool enableDebugLogger = QProcessEnvironment::systemEnvironment().contains(DEBUG_FLAG);
-#endif
- return enableDebugLogger;
-#endif
+ return gl::debugContextEnabled();
}
-
-
std::atomic Context::_totalSwapchainMemoryUsage { 0 };
size_t Context::getSwapchainMemoryUsage() { return _totalSwapchainMemoryUsage.load(); }
diff --git a/libraries/gl/src/gl/ContextQt.cpp b/libraries/gl/src/gl/ContextQt.cpp
index b6b6ad3596..82724dfd62 100644
--- a/libraries/gl/src/gl/ContextQt.cpp
+++ b/libraries/gl/src/gl/ContextQt.cpp
@@ -52,6 +52,11 @@ void Context::moveToThread(QThread* thread) {
}
void Context::debugMessageHandler(const QOpenGLDebugMessage& debugMessage) {
+ auto type = debugMessage.type();
+ if (type == QOpenGLDebugMessage::PerformanceType) {
+ return;
+ }
+
auto severity = debugMessage.severity();
switch (severity) {
case QOpenGLDebugMessage::NotificationSeverity:
@@ -60,13 +65,13 @@ void Context::debugMessageHandler(const QOpenGLDebugMessage& debugMessage) {
default:
break;
}
- qDebug(glLogging) << debugMessage;
+ qWarning(glLogging) << debugMessage;
return;
}
void Context::setupDebugLogging(QOpenGLContext *context) {
QOpenGLDebugLogger *logger = new QOpenGLDebugLogger(context);
- QObject::connect(logger, &QOpenGLDebugLogger::messageLogged, nullptr, [](const QOpenGLDebugMessage& message){
+ QObject::connect(logger, &QOpenGLDebugLogger::messageLogged, context, [](const QOpenGLDebugMessage& message){
Context::debugMessageHandler(message);
});
if (logger->initialize()) {
diff --git a/libraries/gl/src/gl/GLHelpers.cpp b/libraries/gl/src/gl/GLHelpers.cpp
index 15a41c3dc1..2c02fdca03 100644
--- a/libraries/gl/src/gl/GLHelpers.cpp
+++ b/libraries/gl/src/gl/GLHelpers.cpp
@@ -198,11 +198,48 @@ namespace gl {
bool checkGLErrorDebug(const char* name) {
-#ifdef DEBUG
+ // Disabling error checking macro on Android debug builds for now,
+ // as it throws off performance testing, which must be done on
+ // Debug builds
+#if defined(DEBUG) && !defined(Q_OS_ANDROID)
return checkGLError(name);
#else
Q_UNUSED(name);
return false;
#endif
}
+
+ // Enables annotation of captures made by tools like renderdoc
+ bool khrDebugEnabled() {
+ static std::once_flag once;
+ static bool khrDebug = false;
+ std::call_once(once, [&] {
+ khrDebug = nullptr != glPushDebugGroupKHR;
+ });
+ return khrDebug;
+ }
+
+ // Enables annotation of captures made by tools like renderdoc
+ bool extDebugMarkerEnabled() {
+ static std::once_flag once;
+ static bool extMarker = false;
+ std::call_once(once, [&] {
+ extMarker = nullptr != glPushGroupMarkerEXT;
+ });
+ return extMarker;
+ }
+
+ bool debugContextEnabled() {
+#if defined(Q_OS_MAC)
+ // OSX does not support GL_KHR_debug or GL_ARB_debug_output
+ static bool enableDebugLogger = false;
+#elif defined(DEBUG) || defined(USE_GLES)
+ //static bool enableDebugLogger = true;
+ static bool enableDebugLogger = false;
+#else
+ static const QString DEBUG_FLAG("HIFI_DEBUG_OPENGL");
+ static bool enableDebugLogger = QProcessEnvironment::systemEnvironment().contains(DEBUG_FLAG);
+#endif
+ return enableDebugLogger;
+ }
}
diff --git a/libraries/gl/src/gl/GLHelpers.h b/libraries/gl/src/gl/GLHelpers.h
index 1865442ef6..2a798e6e98 100644
--- a/libraries/gl/src/gl/GLHelpers.h
+++ b/libraries/gl/src/gl/GLHelpers.h
@@ -37,7 +37,13 @@ bool isRenderThread();
namespace gl {
void globalLock();
void globalRelease(bool finish = true);
-
+
+ bool debugContextEnabled();
+
+ bool khrDebugEnabled();
+
+ bool extDebugMarkerEnabled();
+
void withSavedContext(const std::function& f);
bool checkGLError(const char* name);
diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp
index 295b9becb8..82f4f97e3b 100644
--- a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp
+++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp
@@ -392,8 +392,38 @@ void GLBackend::renderPassDraw(const Batch& batch) {
}
}
+// Support annotating captures in tools like Renderdoc
+class GlDuration {
+public:
+#ifdef USE_GLES
+ GlDuration(const char* name) {
+ // We need to use strlen here instead of -1, because the Snapdragon profiler
+ // will crash otherwise
+ glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, strlen(name), name);
+ }
+ ~GlDuration() {
+ glPopDebugGroup();
+ }
+#else
+ GlDuration(const char* name) {
+ if (::gl::khrDebugEnabled()) {
+ glPushDebugGroupKHR(GL_DEBUG_SOURCE_APPLICATION_KHR, 0, -1, name);
+ }
+ }
+ ~GlDuration() {
+ if (::gl::khrDebugEnabled()) {
+ glPopDebugGroupKHR();
+ }
+ }
+#endif
+};
+
+#define GL_PROFILE_RANGE(category, name) \
+ PROFILE_RANGE(category, name); \
+ GlDuration glProfileRangeThis(name);
+
void GLBackend::render(const Batch& batch) {
- PROFILE_RANGE(render_gpu_gl, batch.getName());
+ GL_PROFILE_RANGE(render_gpu_gl, batch.getName().c_str());
_transform._skybox = _stereo._skybox = batch.isSkyboxEnabled();
// Allow the batch to override the rendering stereo settings
@@ -406,7 +436,7 @@ void GLBackend::render(const Batch& batch) {
_transform._projectionJitter = Vec2(0.0f, 0.0f);
{
- PROFILE_RANGE(render_gpu_gl_detail, "Transfer");
+ GL_PROFILE_RANGE(render_gpu_gl_detail, "Transfer");
renderPassTransfer(batch);
}
@@ -416,7 +446,7 @@ void GLBackend::render(const Batch& batch) {
}
#endif
{
- PROFILE_RANGE(render_gpu_gl_detail, _stereo.isStereo() ? "Render Stereo" : "Render");
+ GL_PROFILE_RANGE(render_gpu_gl_detail, _stereo.isStereo() ? "Render Stereo" : "Render");
renderPassDraw(batch);
}
#ifdef GPU_STEREO_DRAWCALL_INSTANCED
diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h
index 07f7df9277..b5a279a54c 100644
--- a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h
+++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h
@@ -54,153 +54,8 @@
#define GPU_STEREO_CAMERA_BUFFER
#endif
-//
-// GL Backend pointer storage mechanism
-// One of the following three defines must be defined.
-// GPU_POINTER_STORAGE_SHARED
-
-// The platonic ideal, use references to smart pointers.
-// However, this produces artifacts because there are too many places in the code right now that
-// create temporary values (undesirable smart pointer duplications) and then those temp variables
-// get passed on and have their reference taken, and then invalidated
-// GPU_POINTER_STORAGE_REF
-
-// Raw pointer manipulation. Seems more dangerous than the reference wrappers,
-// but in practice, the danger of grabbing a reference to a temporary variable
-// is causing issues
-// GPU_POINTER_STORAGE_RAW
-
-#if defined(USE_GLES)
-#define GPU_POINTER_STORAGE_SHARED
-#else
-#define GPU_POINTER_STORAGE_RAW
-#endif
-
namespace gpu { namespace gl {
-#if defined(GPU_POINTER_STORAGE_SHARED)
-template
-static inline bool compare(const std::shared_ptr& a, const std::shared_ptr& b) {
- return a == b;
-}
-
-template
-static inline T* acquire(const std::shared_ptr& pointer) {
- return pointer.get();
-}
-
-template
-static inline void reset(std::shared_ptr