guard(_reactionLock);
- for (int i = 0; i < NUM_AVATAR_REACTIONS; i++) {
+ for (int i = 0; i < TRIGGER_REACTION_NAMES.size(); i++) {
+ params.reactionTriggers[i] = _reactionTriggers[i];
+ }
+
+ for (int i = 0; i < BEGIN_END_REACTION_NAMES.size(); i++) {
// copy current state into params.
params.reactionEnabledFlags[i] = _reactionEnabledRefCounts[i] > 0;
- params.reactionTriggers[i] = _reactionTriggers[i];
+ }
+ for (int i = 0; i < TRIGGER_REACTION_NAMES.size(); i++) {
// clear reaction triggers here as well
_reactionTriggers[i] = false;
}
diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h
index db373c6402..ad45df892b 100644
--- a/interface/src/avatar/MyAvatar.h
+++ b/interface/src/avatar/MyAvatar.h
@@ -609,8 +609,10 @@ public:
* the avatar will move in unpredictable ways. For more information about avatar joint orientation standards, see
* Avatar Standards.
* @function MyAvatar.overrideAnimation
- * @param {string} url - The URL to the animation file. Animation files need to be FBX format, but only need to contain the
- * avatar skeleton and animation data.
+ * @param {string} url - The URL to the animation file. Animation files may be in glTF or FBX format, but only need to
+ * contain the avatar skeleton and animation data. glTF models may be in JSON or binary format (".gltf" or ".glb" URLs
+ * respectively).
+ * Warning: glTF animations currently do not always animate correctly.
* @param {number} fps - The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
* @param {boolean} loop - true
if the animation should loop, false
if it shouldn't.
* @param {number} firstFrame - The frame to start the animation at.
@@ -630,8 +632,10 @@ public:
* Use {@link MyAvatar.restoreHandAnimation} to restore the default poses.
* @function MyAvatar.overrideHandAnimation
* @param isLeft {boolean} true
to override the left hand, false
to override the right hand.
- * @param {string} url - The URL of the animation file. Animation files need to be FBX format, but only need to contain the
- * avatar skeleton and animation data.
+ * @param {string} url - The URL of the animation file. Animation files need to be in glTF or FBX format, but only need to
+ * contain the avatar skeleton and animation data. glTF models may be in JSON or binary format (".gltf" or ".glb" URLs
+ * respectively).
+ * Warning: glTF animations currently do not always animate correctly.
* @param {number} fps - The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
* @param {boolean} loop - true
if the animation should loop, false
if it shouldn't.
* @param {number} firstFrame - The frame to start the animation at.
@@ -702,19 +706,22 @@ public:
* Each avatar has an avatar-animation.json file that defines a set of animation roles. Animation roles map to easily
* understandable actions that the avatar can perform, such as "idleStand"
, "idleTalk"
, or
* "walkFwd"
. To get the full list of roles, use {@ link MyAvatar.getAnimationRoles}.
- * For each role, the avatar-animation.json defines when the animation is used, the animation clip (FBX) used, and how
- * animations are blended together with procedural data (such as look at vectors, hand sensors etc.).
- * overrideRoleAnimation()
is used to change the animation clip (FBX) associated with a specified animation
- * role. To end the role animation and restore the default, use {@link MyAvatar.restoreRoleAnimation}.
- * Note: Hand roles only affect the hand. Other 'main' roles, like 'idleStand', 'idleTalk', 'takeoffStand' are full body.
+ * For each role, the avatar-animation.json defines when the animation is used, the animation clip (glTF or FBX) used, and
+ * how animations are blended together with procedural data (such as look at vectors, hand sensors etc.).
+ * overrideRoleAnimation()
is used to change the animation clip (glTF or FBX) associated with a specified
+ * animation role. To end the role animation and restore the default, use {@link MyAvatar.restoreRoleAnimation}.
+ * Note: Hand roles only affect the hand. Other "main" roles, like "idleStand", "idleTalk", and "takeoffStand", are full
+ * body.
* Note: When using pre-built animation data, it's critical that the joint orientation of the source animation and target
* rig are equivalent, since the animation data applies absolute values onto the joints. If the orientations are different,
* the avatar will move in unpredictable ways. For more information about avatar joint orientation standards, see
* Avatar Standards.
* @function MyAvatar.overrideRoleAnimation
* @param {string} role - The animation role to override
- * @param {string} url - The URL to the animation file. Animation files need to be in FBX format, but only need to contain
- * the avatar skeleton and animation data.
+ * @param {string} url - The URL to the animation file. Animation files need to be in glTF or FBX format, but only need to
+ * contain the avatar skeleton and animation data. glTF models may be in JSON or binary format (".gltf" or ".glb" URLs
+ * respectively).
+ *
Warning: glTF animations currently do not always animate correctly.
* @param {number} fps - The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
* @param {boolean} loop - true
if the animation should loop, false
if it shouldn't.
* @param {number} firstFrame - The frame the animation should start at.
@@ -739,9 +746,9 @@ public:
* Each avatar has an avatar-animation.json file that defines a set of animation roles. Animation roles map to easily
* understandable actions that the avatar can perform, such as "idleStand"
, "idleTalk"
, or
* "walkFwd"
. To get the full list of roles, use {@link MyAvatar.getAnimationRoles}. For each role,
- * the avatar-animation.json defines when the animation is used, the animation clip (FBX) used, and how animations are
- * blended together with procedural data (such as look-at vectors, hand sensors etc.). You can change the animation clip
- * (FBX) associated with a specified animation role using {@link MyAvatar.overrideRoleAnimation}.
+ * the avatar-animation.json defines when the animation is used, the animation clip (glTF or FBX) used, and how animations
+ * are blended together with procedural data (such as look-at vectors, hand sensors etc.). You can change the animation
+ * clip (glTF or FBX) associated with a specified animation role using {@link MyAvatar.overrideRoleAnimation}.
* restoreRoleAnimation()
is used to restore a specified animation role's default animation clip. If you have
* not specified an override animation for the specified role, this function has no effect.
* @function MyAvatar.restoreRoleAnimation
@@ -2042,17 +2049,19 @@ public slots:
void setEnableDebugDrawDefaultPose(bool isEnabled);
/**jsdoc
- * Displays animation debug graphics. By default it shows the animation poses used for rendering.
- * However, the property MyAvatar.setDebugDrawAnimPoseName can be used to draw a specific animation node.
+ * Displays animation debug graphics. By default, the animation poses used for rendering are displayed. However,
+ * {@link MyAvatar.setDebugDrawAnimPoseName} can be used to set a specific animation node to display.
* @function MyAvatar.setEnableDebugDrawAnimPose
* @param {boolean} enabled - true
to show the debug graphics, false
to hide.
*/
void setEnableDebugDrawAnimPose(bool isEnabled);
/**jsdoc
- * If set it determines which animation debug graphics to draw, when MyAvatar.setEnableDebugDrawAnimPose is set to true.
+ * Sets the animation node to display when animation debug graphics are enabled with
+ * {@link MyAvatar.setEnableDebugDrawAnimPose}.
* @function MyAvatar.setDebugDrawAnimPoseName
- * @param {boolean} enabled - true
to show the debug graphics, false
to hide.
+ * @param {string} poseName - The name of the animation node to display debug graphics for. Use ""
to reset to
+ * default.
*/
void setDebugDrawAnimPoseName(QString poseName);
@@ -2213,13 +2222,23 @@ public slots:
virtual void setModelScale(float scale) override;
/**jsdoc
- * MyAvatar.getReactions
+ * MyAvatar.getTriggerReactions
+ * Returns a list of reactions names that can be triggered using MyAvatar.triggerReaction().
* @returns {string[]} Array of reaction names.
*/
- QStringList getReactions() const;
+ QStringList getTriggerReactions() const;
+
+
+ /**jsdoc
+ * MyAvatar.getBeginReactions
+ * Returns a list of reactions names that can be enabled using MyAvatar.beginReaction() and MyAvatar.endReaction().
+ * @returns {string[]} Array of reaction names.
+ */
+ QStringList getBeginEndReactions() const;
/**jsdoc
* MyAvatar.triggerReaction
+ * Plays the given reaction on the avatar, once the reaction is complete it will automatically complete. Only reaction names returned from MyAvatar.getTriggerReactions() are available.
* @param {string} reactionName - reaction name
* @returns {bool} false if the given reaction is not supported.
*/
@@ -2227,6 +2246,9 @@ public slots:
/**jsdoc
* MyAvatar.beginReaction
+ * Plays the given reaction on the avatar. The avatar will continue to play the reaction until stopped via the MyAvatar.endReaction() call or superseeded by another reaction.
+ * Only reaction names returned from MyAvatar.getBeginEndReactions() are available.
+ * NOTE: the caller is responsible for calling the corresponding MyAvatar.endReaction(), otherwise the avatar might become stuck in the reaction forever.
* @param {string} reactionName - reaction name
* @returns {bool} false if the given reaction is not supported.
*/
@@ -2234,6 +2256,7 @@ public slots:
/**jsdoc
* MyAvatar.endReaction
+ * Used to stop a given reaction that was started via MyAvatar.beginReaction().
* @param {string} reactionName - reaction name
* @returns {bool} false if the given reaction is not supported.
*/
@@ -2872,8 +2895,9 @@ private:
QScriptEngine* _scriptEngine { nullptr };
bool _needToSaveAvatarEntitySettings { false };
- int _reactionEnabledRefCounts[NUM_AVATAR_REACTIONS] { 0, 0, 0, 0, 0 };
- bool _reactionTriggers[NUM_AVATAR_REACTIONS] { false, false, false, false, false };
+ bool _reactionTriggers[NUM_AVATAR_TRIGGER_REACTIONS] { false, false };
+ int _reactionEnabledRefCounts[NUM_AVATAR_BEGIN_END_REACTIONS] { 0, 0, 0 };
+
mutable std::mutex _reactionLock;
};
diff --git a/interface/src/avatar/MyAvatarHeadTransformNode.cpp b/interface/src/avatar/MyAvatarHeadTransformNode.cpp
index 1e83a17dd3..5dfb101c8c 100644
--- a/interface/src/avatar/MyAvatarHeadTransformNode.cpp
+++ b/interface/src/avatar/MyAvatarHeadTransformNode.cpp
@@ -1,5 +1,5 @@
//
-// Created by Sabrina Shanman 8/14/2018
+// Created by Sabrina Shanman 2018/08/14
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
@@ -21,4 +21,10 @@ Transform MyAvatarHeadTransformNode::getTransform() {
glm::quat ori = headOri * glm::angleAxis(-PI / 2.0f, Vectors::RIGHT);
return Transform(ori, scale, pos);
-}
\ No newline at end of file
+}
+
+QVariantMap MyAvatarHeadTransformNode::toVariantMap() const {
+ QVariantMap map;
+ map["joint"] = "Avatar";
+ return map;
+}
diff --git a/interface/src/avatar/MyAvatarHeadTransformNode.h b/interface/src/avatar/MyAvatarHeadTransformNode.h
index a7d7144521..b1582508bd 100644
--- a/interface/src/avatar/MyAvatarHeadTransformNode.h
+++ b/interface/src/avatar/MyAvatarHeadTransformNode.h
@@ -1,5 +1,5 @@
//
-// Created by Sabrina Shanman 8/14/2018
+// Created by Sabrina Shanman 2018/08/14
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
@@ -14,6 +14,7 @@ class MyAvatarHeadTransformNode : public TransformNode {
public:
MyAvatarHeadTransformNode() { }
Transform getTransform() override;
+ QVariantMap toVariantMap() const override;
};
-#endif // hifi_MyAvatarHeadTransformNode_h
\ No newline at end of file
+#endif // hifi_MyAvatarHeadTransformNode_h
diff --git a/interface/src/raypick/CollisionPick.cpp b/interface/src/raypick/CollisionPick.cpp
index 83ed61030e..2602bdb0a0 100644
--- a/interface/src/raypick/CollisionPick.cpp
+++ b/interface/src/raypick/CollisionPick.cpp
@@ -1,5 +1,5 @@
//
-// Created by Sabrina Shanman 7/16/2018
+// Created by Sabrina Shanman 2018/07/16
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
@@ -460,4 +460,4 @@ Transform CollisionPick::getResultTransform() const {
Transform transform;
transform.setTranslation(_mathPick.transform.getTranslation());
return transform;
-}
\ No newline at end of file
+}
diff --git a/interface/src/raypick/CollisionPick.h b/interface/src/raypick/CollisionPick.h
index c742c089b4..24317bf19a 100644
--- a/interface/src/raypick/CollisionPick.h
+++ b/interface/src/raypick/CollisionPick.h
@@ -1,5 +1,5 @@
//
-// Created by Sabrina Shanman 7/11/2018
+// Created by Sabrina Shanman 2018/07/11
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
@@ -49,6 +49,7 @@ class CollisionPick : public Pick {
public:
CollisionPick(const PickFilter& filter, float maxDistance, bool enabled, bool scaleWithParent, CollisionRegion collisionRegion, PhysicsEnginePointer physicsEngine);
+ PickType getType() const override { return PickType::Collision; }
CollisionRegion getMathematicalPick() const override;
PickResultPointer getDefaultResult(const QVariantMap& pickVariant) const override {
return std::make_shared(pickVariant, std::vector(), std::vector());
diff --git a/interface/src/raypick/LaserPointer.cpp b/interface/src/raypick/LaserPointer.cpp
index 12daae0351..b97c9b89cb 100644
--- a/interface/src/raypick/LaserPointer.cpp
+++ b/interface/src/raypick/LaserPointer.cpp
@@ -27,6 +27,10 @@ LaserPointer::LaserPointer(const QVariant& rayProps, const RenderStateMap& rende
{
}
+PickQuery::PickType LaserPointer::getType() const {
+ return PickQuery::PickType::Ray;
+}
+
void LaserPointer::editRenderStatePath(const std::string& state, const QVariant& pathProps) {
auto renderState = std::static_pointer_cast(_renderStates[state]);
if (renderState) {
@@ -47,7 +51,7 @@ PickResultPointer LaserPointer::getPickResultCopy(const PickResultPointer& pickR
}
QVariantMap LaserPointer::toVariantMap() const {
- QVariantMap qVariantMap;
+ QVariantMap qVariantMap = Parent::toVariantMap();
QVariantMap qRenderStates;
for (auto iter = _renderStates.cbegin(); iter != _renderStates.cend(); iter++) {
diff --git a/interface/src/raypick/LaserPointer.h b/interface/src/raypick/LaserPointer.h
index 13d108baee..330449a52d 100644
--- a/interface/src/raypick/LaserPointer.h
+++ b/interface/src/raypick/LaserPointer.h
@@ -42,6 +42,8 @@ public:
LaserPointer(const QVariant& rayProps, const RenderStateMap& renderStates, const DefaultRenderStateMap& defaultRenderStates, bool hover, const PointerTriggers& triggers,
bool faceAvatar, bool followNormal, float followNormalStrength, bool centerEndY, bool lockEnd, bool distanceScaleEnd, bool scaleWithParent, bool enabled);
+ PickQuery::PickType getType() const override;
+
QVariantMap toVariantMap() const override;
static std::shared_ptr buildRenderState(const QVariantMap& propMap);
diff --git a/interface/src/raypick/LaserPointerScriptingInterface.cpp b/interface/src/raypick/LaserPointerScriptingInterface.cpp
index 25720b5f9d..16fe65a989 100644
--- a/interface/src/raypick/LaserPointerScriptingInterface.cpp
+++ b/interface/src/raypick/LaserPointerScriptingInterface.cpp
@@ -23,7 +23,7 @@ void LaserPointerScriptingInterface::setIncludeItems(unsigned int uid, const QSc
}
unsigned int LaserPointerScriptingInterface::createLaserPointer(const QVariant& properties) const {
- return DependencyManager::get()->createLaserPointer(properties);
+ return DependencyManager::get()->createPointer(PickQuery::PickType::Ray, properties);
}
void LaserPointerScriptingInterface::editRenderState(unsigned int uid, const QString& renderState, const QVariant& properties) const {
diff --git a/interface/src/raypick/MouseTransformNode.cpp b/interface/src/raypick/MouseTransformNode.cpp
index 9caa4865a2..61af0646e1 100644
--- a/interface/src/raypick/MouseTransformNode.cpp
+++ b/interface/src/raypick/MouseTransformNode.cpp
@@ -1,5 +1,5 @@
//
-// Created by Sabrina Shanman 8/14/2018
+// Created by Sabrina Shanman 2018/08/14
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
@@ -24,4 +24,10 @@ Transform MouseTransformNode::getTransform() {
}
return Transform();
-}
\ No newline at end of file
+}
+
+QVariantMap MouseTransformNode::toVariantMap() const {
+ QVariantMap map;
+ map["joint"] = "Mouse";
+ return map;
+}
diff --git a/interface/src/raypick/MouseTransformNode.h b/interface/src/raypick/MouseTransformNode.h
index 4f340339e4..37d773e805 100644
--- a/interface/src/raypick/MouseTransformNode.h
+++ b/interface/src/raypick/MouseTransformNode.h
@@ -1,5 +1,5 @@
//
-// Created by Sabrina Shanman 8/14/2018
+// Created by Sabrina Shanman 2018/08/14
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
@@ -13,6 +13,7 @@
class MouseTransformNode : public TransformNode {
public:
Transform getTransform() override;
+ QVariantMap toVariantMap() const override;
};
-#endif // hifi_MouseTransformNode_h
\ No newline at end of file
+#endif // hifi_MouseTransformNode_h
diff --git a/interface/src/raypick/ParabolaPick.h b/interface/src/raypick/ParabolaPick.h
index 1175b2b246..0d720914cc 100644
--- a/interface/src/raypick/ParabolaPick.h
+++ b/interface/src/raypick/ParabolaPick.h
@@ -92,6 +92,8 @@ class ParabolaPick : public Pick {
public:
ParabolaPick(const glm::vec3& position, const glm::vec3& direction, float speed, const glm::vec3& acceleration, bool rotateAccelerationWithAvatar, bool rotateAccelerationWithParent, bool scaleWithParent, const PickFilter& filter, float maxDistance, bool enabled);
+ PickType getType() const override { return PickType::Parabola; }
+
PickParabola getMathematicalPick() const override;
PickResultPointer getDefaultResult(const QVariantMap& pickVariant) const override { return std::make_shared(pickVariant); }
diff --git a/interface/src/raypick/ParabolaPointer.cpp b/interface/src/raypick/ParabolaPointer.cpp
index 0589124db8..216248f8b5 100644
--- a/interface/src/raypick/ParabolaPointer.cpp
+++ b/interface/src/raypick/ParabolaPointer.cpp
@@ -30,6 +30,10 @@ ParabolaPointer::ParabolaPointer(const QVariant& rayProps, const RenderStateMap&
{
}
+PickQuery::PickType ParabolaPointer::getType() const {
+ return PickQuery::PickType::Parabola;
+}
+
PickResultPointer ParabolaPointer::getPickResultCopy(const PickResultPointer& pickResult) const {
auto parabolaPickResult = std::dynamic_pointer_cast(pickResult);
if (!parabolaPickResult) {
@@ -72,7 +76,7 @@ void ParabolaPointer::editRenderStatePath(const std::string& state, const QVaria
}
QVariantMap ParabolaPointer::toVariantMap() const {
- QVariantMap qVariantMap;
+ QVariantMap qVariantMap = Parent::toVariantMap();
QVariantMap qRenderStates;
for (auto iter = _renderStates.cbegin(); iter != _renderStates.cend(); iter++) {
diff --git a/interface/src/raypick/ParabolaPointer.h b/interface/src/raypick/ParabolaPointer.h
index 94470971e6..85d09adbdb 100644
--- a/interface/src/raypick/ParabolaPointer.h
+++ b/interface/src/raypick/ParabolaPointer.h
@@ -101,6 +101,8 @@ public:
ParabolaPointer(const QVariant& rayProps, const RenderStateMap& renderStates, const DefaultRenderStateMap& defaultRenderStates, bool hover, const PointerTriggers& triggers,
bool faceAvatar, bool followNormal, float followNormalStrength, bool centerEndY, bool lockEnd, bool distanceScaleEnd, bool scaleWithAvatar, bool enabled);
+ PickQuery::PickType getType() const override;
+
QVariantMap toVariantMap() const override;
static std::shared_ptr buildRenderState(const QVariantMap& propMap);
diff --git a/interface/src/raypick/PickScriptingInterface.cpp b/interface/src/raypick/PickScriptingInterface.cpp
index 12f68c1430..ddc1fe376c 100644
--- a/interface/src/raypick/PickScriptingInterface.cpp
+++ b/interface/src/raypick/PickScriptingInterface.cpp
@@ -34,18 +34,35 @@ static const float WEB_TOUCH_Y_OFFSET = 0.105f; // how far forward (or back wit
static const glm::vec3 TIP_OFFSET = glm::vec3(0.0f, StylusPick::WEB_STYLUS_LENGTH - WEB_TOUCH_Y_OFFSET, 0.0f);
unsigned int PickScriptingInterface::createPick(const PickQuery::PickType type, const QVariant& properties) {
+ std::shared_ptr pick;
+ QVariantMap propMap = properties.toMap();
+
switch (type) {
case PickQuery::PickType::Ray:
- return createRayPick(properties);
+ pick = buildRayPick(propMap);
+ break;
case PickQuery::PickType::Stylus:
- return createStylusPick(properties);
+ pick = buildStylusPick(propMap);
+ break;
case PickQuery::PickType::Parabola:
- return createParabolaPick(properties);
+ pick = buildParabolaPick(propMap);
+ break;
case PickQuery::PickType::Collision:
- return createCollisionPick(properties);
+ pick = buildCollisionPick(propMap);
+ break;
default:
- return PickManager::INVALID_PICK_ID;
+ break;
}
+
+ if (!pick) {
+ return PickManager::INVALID_PICK_ID;
+ }
+
+ propMap["pickType"] = (int)type;
+
+ pick->setScriptParameters(propMap);
+
+ return DependencyManager::get()->addPick(type, pick);
}
PickFilter getPickFilter(unsigned int filter) {
@@ -82,17 +99,18 @@ PickFilter getPickFilter(unsigned int filter) {
* @property {Vec3} [dirOffset] - Synonym for direction
.
* @property {Quat} [orientation] - Alternative property for specifying direction
. The value is applied to the
* default direction
value.
+ * @property {PickType} pickType - The type of pick when getting these properties from {@link Picks.getPickProperties} or {@link Picks.getPickScriptParameters}. A ray pick's type is {@link PickType.Ray}.
+ * @property {Vec3} baseScale - Returned from {@link Picks.getPickProperties} when the pick has a parent with varying scale (usually an avatar or an entity).
+ * Its value is the original scale of the parent at the moment the pick was created, and is used to scale the pointer which owns this pick, if any.
*/
-unsigned int PickScriptingInterface::createRayPick(const QVariant& properties) {
- QVariantMap propMap = properties.toMap();
-
+std::shared_ptr PickScriptingInterface::buildRayPick(const QVariantMap& propMap) {
#if defined (Q_OS_ANDROID)
QString jointName { "" };
if (propMap["joint"].isValid()) {
QString jointName = propMap["joint"].toString();
const QString MOUSE_JOINT = "Mouse";
if (jointName == MOUSE_JOINT) {
- return PointerEvent::INVALID_POINTER_ID;
+ return nullptr;
}
}
#endif
@@ -134,7 +152,7 @@ unsigned int PickScriptingInterface::createRayPick(const QVariant& properties) {
auto rayPick = std::make_shared(position, direction, filter, maxDistance, enabled);
setParentTransform(rayPick, propMap);
- return DependencyManager::get()->addPick(PickQuery::Ray, rayPick);
+ return rayPick;
}
/**jsdoc
@@ -152,10 +170,9 @@ unsigned int PickScriptingInterface::createRayPick(const QVariant& properties) {
* means no maximum.
* @property {Vec3} [tipOffset=0,0.095,0] - The position of the stylus tip relative to the hand position at default avatar
* scale.
+ * @property {PickType} pickType - The type of pick when getting these properties from {@link Picks.getPickProperties} or {@link Picks.getPickScriptParameters}. A stylus pick's type is {@link PickType.Stylus}.
*/
-unsigned int PickScriptingInterface::createStylusPick(const QVariant& properties) {
- QVariantMap propMap = properties.toMap();
-
+std::shared_ptr PickScriptingInterface::buildStylusPick(const QVariantMap& propMap) {
bilateral::Side side = bilateral::Side::Invalid;
{
QVariant handVar = propMap["hand"];
@@ -184,7 +201,7 @@ unsigned int PickScriptingInterface::createStylusPick(const QVariant& properties
tipOffset = vec3FromVariant(propMap["tipOffset"]);
}
- return DependencyManager::get()->addPick(PickQuery::Stylus, std::make_shared(side, filter, maxDistance, enabled, tipOffset));
+ return std::make_shared(side, filter, maxDistance, enabled, tipOffset);
}
// NOTE: Laser pointer still uses scaleWithAvatar. Until scaleWithAvatar is also deprecated for pointers, scaleWithAvatar should not be removed from the pick API.
@@ -228,10 +245,11 @@ unsigned int PickScriptingInterface::createStylusPick(const QVariant& properties
* with the avatar or other parent.
* @property {boolean} [scaleWithAvatar=true] - Synonym for scalewithParent
.
* Deprecated: This property is deprecated and will be removed.
+ * @property {PickType} pickType - The type of pick when getting these properties from {@link Picks.getPickProperties} or {@link Picks.getPickScriptParameters}. A parabola pick's type is {@link PickType.Parabola}.
+ * @property {Vec3} baseScale - Returned from {@link Picks.getPickProperties} when the pick has a parent with varying scale (usually an avatar or an entity).
+ * Its value is the original scale of the parent at the moment the pick was created, and is used to rescale the pick, and/or the pointer which owns this pick, if any.
*/
-unsigned int PickScriptingInterface::createParabolaPick(const QVariant& properties) {
- QVariantMap propMap = properties.toMap();
-
+std::shared_ptr PickScriptingInterface::buildParabolaPick(const QVariantMap& propMap) {
bool enabled = false;
if (propMap["enabled"].isValid()) {
enabled = propMap["enabled"].toBool();
@@ -292,7 +310,7 @@ unsigned int PickScriptingInterface::createParabolaPick(const QVariant& properti
auto parabolaPick = std::make_shared(position, direction, speed, accelerationAxis,
rotateAccelerationWithAvatar, rotateAccelerationWithParent, scaleWithParent, filter, maxDistance, enabled);
setParentTransform(parabolaPick, propMap);
- return DependencyManager::get()->addPick(PickQuery::Parabola, parabolaPick);
+ return parabolaPick;
}
@@ -326,10 +344,11 @@ unsigned int PickScriptingInterface::createParabolaPick(const QVariant& properti
* the collision region. The depth is in world coordinates but scales with the parent if defined.
* @property {CollisionMask} [collisionGroup=8] - The type of objects the collision region collides as. Objects whose collision
* masks overlap with the region's collision group are considered to be colliding with the region.
+ * @property {PickType} pickType - The type of pick when getting these properties from {@link Picks.getPickProperties} or {@link Picks.getPickScriptParameters}. A collision pick's type is {@link PickType.Collision}.
+ * @property {Vec3} baseScale - Returned from {@link Picks.getPickProperties} when the pick has a parent with varying scale (usually an avatar or an entity).
+ * Its value is the original scale of the parent at the moment the pick was created, and is used to rescale the pick, and/or the pointer which owns this pick, if any.
*/
-unsigned int PickScriptingInterface::createCollisionPick(const QVariant& properties) {
- QVariantMap propMap = properties.toMap();
-
+std::shared_ptr PickScriptingInterface::buildCollisionPick(const QVariantMap& propMap) {
bool enabled = false;
if (propMap["enabled"].isValid()) {
enabled = propMap["enabled"].toBool();
@@ -354,7 +373,7 @@ unsigned int PickScriptingInterface::createCollisionPick(const QVariant& propert
auto collisionPick = std::make_shared(filter, maxDistance, enabled, scaleWithParent, collisionRegion, qApp->getPhysicsEngine());
setParentTransform(collisionPick, propMap);
- return DependencyManager::get()->addPick(PickQuery::Collision, collisionPick);
+ return collisionPick;
}
void PickScriptingInterface::enablePick(unsigned int uid) {
@@ -365,10 +384,26 @@ void PickScriptingInterface::disablePick(unsigned int uid) {
DependencyManager::get()->disablePick(uid);
}
+bool PickScriptingInterface::isPickEnabled(unsigned int uid) const {
+ return DependencyManager::get()->isPickEnabled(uid);
+}
+
void PickScriptingInterface::removePick(unsigned int uid) {
DependencyManager::get()->removePick(uid);
}
+QVariantMap PickScriptingInterface::getPickProperties(unsigned int uid) const {
+ return DependencyManager::get()->getPickProperties(uid);
+}
+
+QVariantMap PickScriptingInterface::getPickScriptParameters(unsigned int uid) const {
+ return DependencyManager::get()->getPickScriptParameters(uid);
+}
+
+QVector PickScriptingInterface::getPicks() const {
+ return DependencyManager::get()->getPicks();
+}
+
QVariantMap PickScriptingInterface::getPrevPickResult(unsigned int uid) {
QVariantMap result;
auto pickResult = DependencyManager::get()->getPrevPickResult(uid);
diff --git a/interface/src/raypick/PickScriptingInterface.h b/interface/src/raypick/PickScriptingInterface.h
index 473413ca58..72b28bbc47 100644
--- a/interface/src/raypick/PickScriptingInterface.h
+++ b/interface/src/raypick/PickScriptingInterface.h
@@ -10,7 +10,6 @@
#include
-#include
#include
#include
#include
@@ -98,11 +97,6 @@ class PickScriptingInterface : public QObject, public Dependency {
SINGLETON_DEPENDENCY
public:
- unsigned int createRayPick(const QVariant& properties);
- unsigned int createStylusPick(const QVariant& properties);
- unsigned int createCollisionPick(const QVariant& properties);
- unsigned int createParabolaPick(const QVariant& properties);
-
void registerMetaTypes(QScriptEngine* engine);
/**jsdoc
@@ -134,6 +128,14 @@ public:
*/
Q_INVOKABLE void disablePick(unsigned int uid);
+ /**jsdoc
+ * Get the enabled status of a pick. Enabled picks update their pick results.
+ * @function Picks.isPickEnabled
+ * @param {number} id - The ID of the pick.
+ * @returns {boolean} enabled - Whether or not the pick is enabled.
+ */
+ Q_INVOKABLE bool isPickEnabled(unsigned int uid) const;
+
/**jsdoc
* Removes (deletes) a pick.
* @function Picks.removePick
@@ -141,6 +143,32 @@ public:
*/
Q_INVOKABLE void removePick(unsigned int uid);
+ /**jsdoc
+ * Gets the current properties of the pick.
+ * @function Picks.getPickProperties
+ * @param {number} id - The ID of the pick.
+ * @returns {Picks.RayPickProperties|Picks.ParabolaPickProperties|Picks.StylusPickProperties|Picks.CollisionPickProperties} Properties of the pick, per the pick type
.
+ */
+ Q_INVOKABLE QVariantMap getPickProperties(unsigned int uid) const;
+
+ /**jsdoc
+ * Gets the parameters that were passed in to {@link Picks.createPick} to create the pick,
+ * if the pick was created through a script.
+ * Note that these properties do not reflect the current state of the pick.
+ * See {@link Picks.getPickProperties}.
+ * @function Picks.getPickScriptParameters
+ * @param {number} id - The ID of the pick.
+ * @returns {Picks.RayPickProperties|Picks.ParabolaPickProperties|Picks.StylusPickProperties|Picks.CollisionPickProperties} User-provided properties, per the pick type
.
+ */
+ Q_INVOKABLE QVariantMap getPickScriptParameters(unsigned int uid) const;
+
+ /**jsdoc
+ * Gets all picks which currently exist, including disabled picks.
+ * @function Picks.getPicks
+ * @returns {number[]} picks - The IDs of the picks.
+ */
+ Q_INVOKABLE QVector getPicks() const;
+
/**jsdoc
* Gets the most recent result from a pick. A pick continues to be updated ready to return a result, as long as it is
* enabled.
@@ -419,6 +447,11 @@ public slots:
static constexpr unsigned int INTERSECTED_HUD() { return IntersectionType::HUD; }
protected:
+ static std::shared_ptr buildRayPick(const QVariantMap& properties);
+ static std::shared_ptr buildStylusPick(const QVariantMap& properties);
+ static std::shared_ptr buildCollisionPick(const QVariantMap& properties);
+ static std::shared_ptr buildParabolaPick(const QVariantMap& properties);
+
static void setParentTransform(std::shared_ptr pick, const QVariantMap& propMap);
};
diff --git a/interface/src/raypick/PointerScriptingInterface.cpp b/interface/src/raypick/PointerScriptingInterface.cpp
index f1dcf7bd5d..3520aacbd0 100644
--- a/interface/src/raypick/PointerScriptingInterface.cpp
+++ b/interface/src/raypick/PointerScriptingInterface.cpp
@@ -13,6 +13,7 @@
#include
#include "Application.h"
+#include "PickManager.h"
#include "LaserPointer.h"
#include "StylusPointer.h"
#include "ParabolaPointer.h"
@@ -38,16 +39,48 @@ unsigned int PointerScriptingInterface::createPointer(const PickQuery::PickType&
return result;
}
+ QVariantMap propertyMap = properties.toMap();
+
+ std::shared_ptr pointer;
switch (type) {
case PickQuery::PickType::Ray:
- return createLaserPointer(properties);
+ pointer = buildLaserPointer(propertyMap);
+ break;
case PickQuery::PickType::Stylus:
- return createStylus(properties);
+ pointer = buildStylus(propertyMap);
+ break;
case PickQuery::PickType::Parabola:
- return createParabolaPointer(properties);
+ pointer = buildParabolaPointer(propertyMap);
+ break;
default:
- return PointerEvent::INVALID_POINTER_ID;
+ break;
}
+
+ if (!pointer) {
+ return PointerEvent::INVALID_POINTER_ID;
+ }
+
+ propertyMap["pointerType"] = (int)type;
+
+ pointer->setScriptParameters(propertyMap);
+
+ return DependencyManager::get()->addPointer(pointer);
+}
+
+bool PointerScriptingInterface::isPointerEnabled(unsigned int uid) const {
+ return DependencyManager::get()->isPointerEnabled(uid);
+}
+
+QVector PointerScriptingInterface::getPointers() const {
+ return DependencyManager::get()->getPointers();
+}
+
+QVariantMap PointerScriptingInterface::getPointerProperties(unsigned int uid) const {
+ return DependencyManager::get()->getPointerProperties(uid);
+}
+
+QVariantMap PointerScriptingInterface::getPointerScriptParameters(unsigned int uid) const {
+ return DependencyManager::get()->getPointerScriptParameters(uid);
}
/**jsdoc
@@ -56,6 +89,8 @@ unsigned int PointerScriptingInterface::createPointer(const PickQuery::PickType&
* @property {Pointers.StylusPointerModel} [model] - Override some or all of the default stylus model properties.
* @property {boolean} [hover=false] - true
if the pointer generates {@link Entities} hover events,
* false
if it doesn't.
+ * @property {PickType} pointerType - The type of pointer when getting these properties from {@link Pointers.getPointerProperties} or {@link Pointers.getPointerScriptParameters}. A stylus pointer's type is {@link PickType.Stylus}.
+ * @property {number} [pickID] - Returned from {@link Pointers.getPointerProperties}. The ID of the pick created alongside this pointer.
* @see {@link Picks.StylusPickProperties} for additional properties from the underlying stylus pick.
*/
/**jsdoc
@@ -67,7 +102,7 @@ unsigned int PointerScriptingInterface::createPointer(const PickQuery::PickType&
* offset.
* @property {Quat} [rotationOffset] - The rotation offset of the model from the hand, to override the default rotation offset.
*/
-unsigned int PointerScriptingInterface::createStylus(const QVariant& properties) const {
+std::shared_ptr PointerScriptingInterface::buildStylus(const QVariant& properties) {
QVariantMap propertyMap = properties.toMap();
bool hover = false;
@@ -100,8 +135,7 @@ unsigned int PointerScriptingInterface::createStylus(const QVariant& properties)
}
}
- return DependencyManager::get()->addPointer(std::make_shared(properties, StylusPointer::buildStylus(propertyMap), hover, enabled, modelPositionOffset,
- modelRotationOffset, modelDimensions));
+ return std::make_shared(properties, StylusPointer::buildStylus(propertyMap), hover, enabled, modelPositionOffset, modelRotationOffset, modelDimensions);
}
/**jsdoc
@@ -174,9 +208,11 @@ unsigned int PointerScriptingInterface::createStylus(const QVariant& properties)
* false
if it doesn't.
* @property {Pointers.Trigger[]} [triggers=[]] - A list of ways that a {@link Controller} action or function should trigger
* events on the entity or overlay currently intersected.
+ * @property {PickType} pointerType - The type of pointer when getting these properties from {@link Pointers.getPointerProperties} or {@link Pointers.getPointerScriptParameters}. A laser pointer's type is {@link PickType.Ray}.
+ * @property {number} [pickID] - Returned from {@link Pointers.getPointerProperties}. The ID of the pick created alongside this pointer.
* @see {@link Picks.RayPickProperties} for additional properties from the underlying ray pick.
*/
-unsigned int PointerScriptingInterface::createLaserPointer(const QVariant& properties) const {
+std::shared_ptr PointerScriptingInterface::buildLaserPointer(const QVariant& properties) {
QVariantMap propertyMap = properties.toMap();
#if defined (Q_OS_ANDROID)
@@ -185,7 +221,7 @@ unsigned int PointerScriptingInterface::createLaserPointer(const QVariant& prope
QString jointName = propertyMap["joint"].toString();
const QString MOUSE_JOINT = "Mouse";
if (jointName == MOUSE_JOINT) {
- return PointerEvent::INVALID_POINTER_ID;
+ return nullptr;
}
}
#endif
@@ -283,9 +319,9 @@ unsigned int PointerScriptingInterface::createLaserPointer(const QVariant& prope
}
}
- return DependencyManager::get()->addPointer(std::make_shared(properties, renderStates, defaultRenderStates, hover, triggers,
- faceAvatar, followNormal, followNormalStrength, centerEndY, lockEnd,
- distanceScaleEnd, scaleWithParent, enabled));
+ return std::make_shared(properties, renderStates, defaultRenderStates, hover, triggers,
+ faceAvatar, followNormal, followNormalStrength, centerEndY, lockEnd,
+ distanceScaleEnd, scaleWithParent, enabled);
}
/**jsdoc
@@ -365,9 +401,11 @@ unsigned int PointerScriptingInterface::createLaserPointer(const QVariant& prope
* false
if it doesn't.
* @property {Pointers.Trigger[]} [triggers=[]] - A list of ways that a {@link Controller} action or function should trigger
* events on the entity or overlay currently intersected.
+ * @property {PickType} pointerType - The type of pointer when getting these properties from {@link Pointers.getPointerProperties} or {@link Pointers.getPointerScriptParameters}. A parabola pointer's type is {@link PickType.Parabola}.
+ * @property {number} [pickID] - Returned from {@link Pointers.getPointerProperties}. The ID of the pick created alongside this pointer.
* @see {@link Picks.ParabolaPickProperties} for additional properties from the underlying parabola pick.
*/
-unsigned int PointerScriptingInterface::createParabolaPointer(const QVariant& properties) const {
+std::shared_ptr PointerScriptingInterface::buildParabolaPointer(const QVariant& properties) {
QVariantMap propertyMap = properties.toMap();
bool faceAvatar = false;
@@ -463,9 +501,9 @@ unsigned int PointerScriptingInterface::createParabolaPointer(const QVariant& pr
}
}
- return DependencyManager::get()->addPointer(std::make_shared(properties, renderStates, defaultRenderStates, hover, triggers,
- faceAvatar, followNormal, followNormalStrength, centerEndY, lockEnd, distanceScaleEnd,
- scaleWithParent, enabled));
+ return std::make_shared(properties, renderStates, defaultRenderStates, hover, triggers,
+ faceAvatar, followNormal, followNormalStrength, centerEndY, lockEnd, distanceScaleEnd,
+ scaleWithParent, enabled);
}
void PointerScriptingInterface::editRenderState(unsigned int uid, const QString& renderState, const QVariant& properties) const {
@@ -497,7 +535,3 @@ QVariantMap PointerScriptingInterface::getPrevPickResult(unsigned int uid) const
}
return result;
}
-
-QVariantMap PointerScriptingInterface::getPointerProperties(unsigned int uid) const {
- return DependencyManager::get()->getPointerProperties(uid);
-}
diff --git a/interface/src/raypick/PointerScriptingInterface.h b/interface/src/raypick/PointerScriptingInterface.h
index e6efaae09f..0eed8b4741 100644
--- a/interface/src/raypick/PointerScriptingInterface.h
+++ b/interface/src/raypick/PointerScriptingInterface.h
@@ -11,6 +11,7 @@
#include
#include "DependencyManager.h"
+#include "RegisteredMetaTypes.h"
#include
#include
@@ -31,9 +32,6 @@ class PointerScriptingInterface : public QObject, public Dependency {
SINGLETON_DEPENDENCY
public:
- unsigned int createLaserPointer(const QVariant& properties) const;
- unsigned int createStylus(const QVariant& properties) const;
- unsigned int createParabolaPointer(const QVariant& properties) const;
/**jsdoc
* Specifies that a {@link Controller} action or function should trigger events on the entity or overlay currently
@@ -147,6 +145,14 @@ public:
*/
Q_INVOKABLE void disablePointer(unsigned int uid) const { DependencyManager::get()->disablePointer(uid); }
+ /**jsdoc
+ * Gets the enabled status of a pointer. Enabled pointers update their pick results and generate events.
+ * @function Pointers.isPointerEnabled
+ * @param {number} id - The ID of the pointer.
+ * @returns {boolean} enabled - Whether or not the pointer is enabled.
+ */
+ Q_INVOKABLE bool isPointerEnabled(unsigned int uid) const;
+
/**jsdoc
* Removes (deletes) a pointer.
* @function Pointers.removePointer
@@ -154,6 +160,24 @@ public:
*/
Q_INVOKABLE void removePointer(unsigned int uid) const { DependencyManager::get()->removePointer(uid); }
+ /**jsdoc
+ * Gets the parameters that were passed in to {@link Pointers.createPointer} to create the pointer,
+ * if the pointer was created through a script.
+ * Note that these properties do not reflect the current state of the pointer.
+ * See {@link Pointers.getPointerProperties}.
+ * @function Pointers.getPointerScriptParameters
+ * @param {number} id - The ID of the pointer.
+ * @returns {Pointers.RayPointerProperties|Picks.ParabolaPointerProperties|Picks.StylusPointerProperties} User-provided properties, per the pointer type
.
+ */
+ Q_INVOKABLE QVariantMap getPointerScriptParameters(unsigned int uid) const;
+
+ /**jsdoc
+ * Gets all pointers which currently exist, including disabled pointers.
+ * @function Pointers.getPointers
+ * @returns {number[]} pointers - The IDs of the pointers.
+ */
+ Q_INVOKABLE QVector getPointers() const;
+
/**jsdoc
* Edits a render state of a {@link Pointers.RayPointerProperties|ray} or
* {@link Pointers.ParabolaPointerProperties|parabola} pointer, to change its visual appearance for the state when the
@@ -448,6 +472,11 @@ public:
* });
*/
Q_INVOKABLE QVariantMap getPointerProperties(unsigned int uid) const;
+
+protected:
+ static std::shared_ptr buildLaserPointer(const QVariant& properties);
+ static std::shared_ptr buildStylus(const QVariant& properties);
+ static std::shared_ptr buildParabolaPointer(const QVariant& properties);
};
#endif // hifi_PointerScriptingInterface_h
diff --git a/interface/src/raypick/RayPick.h b/interface/src/raypick/RayPick.h
index 170a0489da..3bd82f4194 100644
--- a/interface/src/raypick/RayPick.h
+++ b/interface/src/raypick/RayPick.h
@@ -88,6 +88,8 @@ public:
Pick(PickRay(position, direction), filter, maxDistance, enabled) {
}
+ PickType getType() const override { return PickType::Ray; }
+
PickRay getMathematicalPick() const override;
PickResultPointer getDefaultResult(const QVariantMap& pickVariant) const override { return std::make_shared(pickVariant); }
diff --git a/interface/src/raypick/RayPickScriptingInterface.cpp b/interface/src/raypick/RayPickScriptingInterface.cpp
index 247368df51..a837121e6a 100644
--- a/interface/src/raypick/RayPickScriptingInterface.cpp
+++ b/interface/src/raypick/RayPickScriptingInterface.cpp
@@ -17,7 +17,7 @@
#include
unsigned int RayPickScriptingInterface::createRayPick(const QVariant& properties) {
- return DependencyManager::get()->createRayPick(properties);
+ return DependencyManager::get()->createPick(PickQuery::PickType::Ray, properties);
}
void RayPickScriptingInterface::enableRayPick(unsigned int uid) {
diff --git a/interface/src/raypick/StylusPick.h b/interface/src/raypick/StylusPick.h
index e443fb1c6d..27514efefa 100644
--- a/interface/src/raypick/StylusPick.h
+++ b/interface/src/raypick/StylusPick.h
@@ -72,6 +72,7 @@ class StylusPick : public Pick {
public:
StylusPick(Side side, const PickFilter& filter, float maxDistance, bool enabled, const glm::vec3& tipOffset);
+ PickType getType() const override { return PickType::Stylus; }
StylusTip getMathematicalPick() const override;
PickResultPointer getDefaultResult(const QVariantMap& pickVariant) const override;
PickResultPointer getEntityIntersection(const StylusTip& pick) override;
diff --git a/interface/src/raypick/StylusPointer.cpp b/interface/src/raypick/StylusPointer.cpp
index 3cdcb9c3a5..48b61e9a2a 100644
--- a/interface/src/raypick/StylusPointer.cpp
+++ b/interface/src/raypick/StylusPointer.cpp
@@ -29,7 +29,7 @@ static const QString DEFAULT_STYLUS_MODEL_URL = PathUtils::resourcesUrl() + "/me
StylusPointer::StylusPointer(const QVariant& props, const QUuid& stylus, bool hover, bool enabled,
const glm::vec3& modelPositionOffset, const glm::quat& modelRotationOffset, const glm::vec3& modelDimensions) :
- Pointer(DependencyManager::get()->createStylusPick(props), enabled, hover),
+ Pointer(DependencyManager::get()->createPick(PickQuery::PickType::Stylus, props), enabled, hover),
_stylus(stylus),
_modelPositionOffset(modelPositionOffset),
_modelDimensions(modelDimensions),
@@ -43,6 +43,10 @@ StylusPointer::~StylusPointer() {
}
}
+PickQuery::PickType StylusPointer::getType() const {
+ return PickQuery::PickType::Stylus;
+}
+
QUuid StylusPointer::buildStylus(const QVariantMap& properties) {
// FIXME: we have to keep using the Overlays interface here, because existing scripts use overlay properties to define pointers
QVariantMap propertiesMap;
@@ -229,7 +233,7 @@ void StylusPointer::setRenderState(const std::string& state) {
}
QVariantMap StylusPointer::toVariantMap() const {
- return QVariantMap();
+ return Parent::toVariantMap();
}
glm::vec3 StylusPointer::findIntersection(const PickedObject& pickedObject, const glm::vec3& origin, const glm::vec3& direction) {
diff --git a/interface/src/raypick/StylusPointer.h b/interface/src/raypick/StylusPointer.h
index 7d43df2379..41ac17e598 100644
--- a/interface/src/raypick/StylusPointer.h
+++ b/interface/src/raypick/StylusPointer.h
@@ -23,6 +23,8 @@ public:
const glm::vec3& modelPositionOffset, const glm::quat& modelRotationOffset, const glm::vec3& modelDimensions);
~StylusPointer();
+ PickQuery::PickType getType() const override;
+
void updateVisuals(const PickResultPointer& pickResult) override;
// Styluses have three render states:
diff --git a/interface/src/scripting/Audio.h b/interface/src/scripting/Audio.h
index 5baeee4176..d3bc6b9449 100644
--- a/interface/src/scripting/Audio.h
+++ b/interface/src/scripting/Audio.h
@@ -66,15 +66,19 @@ class Audio : public AudioScriptingInterface, protected ReadWriteLockable {
* @property {boolean} pushToTalkHMD - true
if HMD push-to-talk is enabled, otherwise false
.
* @property {boolean} pushingToTalk - true
if the user is currently pushing-to-talk, otherwise
* false
.
- * @property {number} avatarGain - The gain (relative volume) that avatars' voices are played at. This gain is used at the server.
- * @property {number} localInjectorGain - The gain (relative volume) that local injectors (local environment sounds) are played at.
- * @property {number} serverInjectorGain - The gain (relative volume) that server injectors (server environment sounds) are played at. This gain is used at the server.
- * @property {number} systemInjectorGain - The gain (relative volume) that system sounds are played at.
- * @property {number} pushingToTalkOutputGainDesktop - The gain (relative volume) that all sounds are played at when the user is holding
- * the push-to-talk key in Desktop mode.
- * @property {boolean} acousticEchoCancellation - true
if audio-echo-cancellation is enabled, otherwise
- * false
. When enabled, sound from the audio output will be suppressed when it echos back to the
- * input audio signal.
+
+ * @property {number} avatarGain - The gain (relative volume in dB) that avatars' voices are played at. This gain is used
+ * at the server.
+ * @property {number} localInjectorGain - The gain (relative volume in dB) that local injectors (local environment sounds)
+ * are played at.
+ * @property {number} serverInjectorGain - The gain (relative volume in dB) that server injectors (server environment
+ * sounds) are played at. This gain is used at the server.
+ * @property {number} systemInjectorGain - The gain (relative volume in dB) that system sounds are played at.
+ * @property {number} pushingToTalkOutputGainDesktop - The gain (relative volume in dB) that all sounds are played at when
+ * the user is holding the push-to-talk key in desktop mode.
+ * @property {boolean} acousticEchoCancellation - true
if acoustic echo cancellation is enabled, otherwise
+ * false
. When enabled, sound from the audio output is suppressed when it echos back to the input audio
+ * signal.
*
* @comment The following properties are from AudioScriptingInterface.h.
* @property {boolean} isStereoInput - true
if the input audio is being used in stereo, otherwise
@@ -301,18 +305,18 @@ public:
Q_INVOKABLE bool getRecording();
/**jsdoc
- * Sets the output volume gain that will be used when the user is holding the Push to Talk key.
+ * Sets the output volume gain that will be used when the user is holding the push-to-talk key.
* Should be negative.
* @function Audio.setPushingToTalkOutputGainDesktop
- * @param {number} gain - The output volume gain (dB) while using PTT.
+ * @param {number} gain - The output volume gain (dB) while using push-to-talk.
*/
Q_INVOKABLE void setPushingToTalkOutputGainDesktop(float gain);
/**jsdoc
- * Gets the output volume gain that is used when the user is holding the Push to Talk key.
+ * Gets the output volume gain that is used when the user is holding the push-to-talk key.
* Should be negative.
* @function Audio.getPushingToTalkOutputGainDesktop
- * @returns {number} gain - The output volume gain (dB) while using PTT.
+ * @returns {number} gain - The output volume gain (dB) while using push-to-talk.
*/
Q_INVOKABLE float getPushingToTalkOutputGainDesktop();
@@ -457,7 +461,7 @@ signals:
/**jsdoc
* Triggered when the avatar gain changes.
* @function Audio.avatarGainChanged
- * @param {number} gain - The new avatar gain value.
+ * @param {number} gain - The new avatar gain value (dB).
* @returns {Signal}
*/
void avatarGainChanged(float gain);
@@ -465,7 +469,7 @@ signals:
/**jsdoc
* Triggered when the local injector gain changes.
* @function Audio.localInjectorGainChanged
- * @param {number} gain - The new local injector gain value.
+ * @param {number} gain - The new local injector gain value (dB).
* @returns {Signal}
*/
void localInjectorGainChanged(float gain);
@@ -473,7 +477,7 @@ signals:
/**jsdoc
* Triggered when the server injector gain changes.
* @function Audio.serverInjectorGainChanged
- * @param {number} gain - The new server injector gain value.
+ * @param {number} gain - The new server injector gain value (dB).
* @returns {Signal}
*/
void serverInjectorGainChanged(float gain);
@@ -481,7 +485,7 @@ signals:
/**jsdoc
* Triggered when the system injector gain changes.
* @function Audio.systemInjectorGainChanged
- * @param {number} gain - The new system injector gain value.
+ * @param {number} gain - The new system injector gain value (dB).
* @returns {Signal}
*/
void systemInjectorGainChanged(float gain);
@@ -489,7 +493,7 @@ signals:
/**jsdoc
* Triggered when the push to talk gain changes.
* @function Audio.pushingToTalkOutputGainDesktopChanged
- * @param {number} gain - The new output gain value.
+ * @param {number} gain - The new output gain value (dB).
* @returns {Signal}
*/
void pushingToTalkOutputGainDesktopChanged(float gain);
diff --git a/interface/src/scripting/PlatformInfoScriptingInterface.h b/interface/src/scripting/PlatformInfoScriptingInterface.h
index f59d476f0c..25cdc99577 100644
--- a/interface/src/scripting/PlatformInfoScriptingInterface.h
+++ b/interface/src/scripting/PlatformInfoScriptingInterface.h
@@ -15,7 +15,7 @@
class QScriptValue;
/**jsdoc
- * The PlatformInfo
API provides information about the computer and controllers being used.
+ * The PlatformInfo
API provides information about the hardware platform being used.
*
* @namespace PlatformInfo
*
@@ -31,6 +31,21 @@ public:
PlatformInfoScriptingInterface();
virtual ~PlatformInfoScriptingInterface();
+ /**jsdoc
+ * The platform tier of a computer is an indication of its rendering capability.
+ *
+ *
+ * Value | Name | Description |
+ *
+ *
+ * 0 | UNKNOWN | Unknown rendering capability. |
+ * 1 | LOW | Low-end PC, capable of rendering low-quality graphics. |
+ * 2 | MID | Business-class PC, capable of rendering medium-quality graphics. |
+ * 3 | HIGH | High-end PC, capable of rendering high-quality graphics. |
+ *
+ *
+ * @typedef {number} PlatformInfo.PlatformTier
+ */
// Platform tier enum type
enum PlatformTier {
UNKNOWN = platform::Profiler::Tier::UNKNOWN,
@@ -50,23 +65,18 @@ public slots:
/**jsdoc
* Gets the operating system type.
* @function PlatformInfo.getOperatingSystemType
- * @returns {string} "WINDOWS"
, "MACOS"
, or "UNKNOWN"
.
+ * @returns {string} The operating system type: "WINDOWS"
, "MACOS"
, or "UNKNOWN"
.
* @deprecated This function is deprecated and will be removed.
- * use getComputer()["OS"] instead
+ * Use JSON.parse({@link PlatformInfo.getComputer|PlatformInfo.getComputer()}).OS
instead.
*/
QString getOperatingSystemType();
/**jsdoc
- * Gets information on the CPU.
+ * Gets information on the CPU model.
* @function PlatformInfo.getCPUBrand
* @returns {string} Information on the CPU.
- * @example Report the CPU being used.
- * print("CPU: " + PlatformInfo.getCPUBrand());
- * // Example: Intel(R) Core(TM) i7-7820HK CPU @ 2.90GHz
* @deprecated This function is deprecated and will be removed.
- * use getNumCPUs() to know the number of CPUs in the hardware, at least one is expected
- * use getCPU(0)["vendor"] to get the brand of the vendor
- * use getCPU(0)["model"] to get the model name of the cpu
+ * Use JSON.parse({@link PlatformInfo.getCPU|PlatformInfo.getCPU(0)}).model
instead.
*/
QString getCPUBrand();
@@ -75,27 +85,27 @@ public slots:
* @function PlatformInfo.getNumLogicalCores
* @returns {number} The number of logical CPU cores.
* @deprecated This function is deprecated and will be removed.
- * use getCPU(0)["numCores"] instead
+ * Use JSON.parse({@link PlatformInfo.getCPU|PlatformInfo.getCPU(0)}).numCores
instead.
*/
unsigned int getNumLogicalCores();
/**jsdoc
- * Returns the total system memory in megabytes.
+ * Gets the total amount of usable physical memory, in MB.
* @function PlatformInfo.getTotalSystemMemoryMB
* @returns {number} The total system memory in megabytes.
* @deprecated This function is deprecated and will be removed.
- * use getMemory()["memTotal"] instead
+ * Use JSON.parse({@link PlatformInfo.getMemory|PlatformInfo.getMemory()}).memTotal
instead.
*/
int getTotalSystemMemoryMB();
/**jsdoc
- * Gets the graphics card type.
+ * Gets the model of the graphics card currently being used.
* @function PlatformInfo.getGraphicsCardType
- * @returns {string} The graphics card type.
+ * @returns {string} The model of the graphics card currently being used.
* @deprecated This function is deprecated and will be removed.
- * use getNumGPUs() to know the number of GPUs in the hardware, at least one is expected
- * use getGPU(getMasterGPU())["vendor"] to get the brand of the vendor
- * use getGPU(getMasterGPU())["model"] to get the model name of the gpu
+ * Use JSON.parse({@link PlatformInfo.getGPU|PlatformInfo.getGPU(}
+ * {@link PlatformInfo.getMasterGPU|PlatformInfo.getMasterGPU() )}).model
+ * instead.
*/
QString getGraphicsCardType();
@@ -117,139 +127,150 @@ public slots:
* Checks whether HTML on 3D surfaces (e.g., Web entities) is supported.
* @function PlatformInfo.has3DHTML
* @returns {boolean} true
if the current display supports HTML on 3D surfaces, false
if it
- * doesn't.
+ * doesn't.
*/
bool has3DHTML();
/**jsdoc
* Checks whether Interface is running on a stand-alone HMD device (CPU incorporated into the HMD display).
* @function PlatformInfo.isStandalone
- * @returns {boolean} true
if Interface is running on a stand-alone device, false
if it isn't.
+ * @returns {boolean} true
if Interface is running on a stand-alone HMD device, false
if it isn't.
*/
bool isStandalone();
/**jsdoc
- * Get the number of CPUs.
- * @function PlatformInfo.getNumCPUs
- * @returns {number} The number of CPUs detected on the hardware platform.
- */
+ * Gets the number of CPUs.
+ * @function PlatformInfo.getNumCPUs
+ * @returns {number} The number of CPUs.
+ */
int getNumCPUs();
/**jsdoc
- * Get the index of the master CPU.
- * @function PlatformInfo.getMasterCPU
- * @returns {number} The index of the master CPU detected on the hardware platform.
- */
+ * Gets the index number of the master CPU.
+ * @function PlatformInfo.getMasterCPU
+ * @returns {number} The index of the master CPU.
+ */
int getMasterCPU();
/**jsdoc
- * Get the description of the CPU at the index parameter
- * expected fields are:
- * - cpuVendor...
- * @param index The index of the CPU of the platform
- * @function PlatformInfo.getCPU
- * @returns {string} The CPU description json field
- */
+ * Gets the platform description of a CPU.
+ * @function PlatformInfo.getCPU
+ * @param {number} index - The index number of the CPU.
+ * @returns {string} The CPU's {@link PlatformInfo.CPUDescription|CPUDescription} information as a JSON string.
+ * @example Report details of the computer's CPUs.
+ * var numCPUs = PlatformInfo.getNumCPUs();
+ * print("Number of CPUs: " + numCPUs);
+ * for (var i = 0; i < numCPUs; i++) {
+ * var cpuDescription = PlatformInfo.getCPU(i);
+ * print("CPU " + i + ": " + cpuDescription);
+ * }
+ */
QString getCPU(int index);
/**jsdoc
- * Get the number of GPUs.
+ * Gets the number of GPUs.
* @function PlatformInfo.getNumGPUs
- * @returns {number} The number of GPUs detected on the hardware platform.
+ * @returns {number} The number of GPUs.
*/
int getNumGPUs();
/**jsdoc
- * Get the index of the master GPU.
- * @function PlatformInfo.getMasterGPU
- * @returns {number} The index of the master GPU detected on the hardware platform.
- */
+ * Gets the index number of the master GPU.
+ * @function PlatformInfo.getMasterGPU
+ * @returns {number} The index of the master GPU.
+ */
int getMasterGPU();
/**jsdoc
- * Get the description of the GPU at the index parameter
- * expected fields are:
- * - vendor, model...
- * @param index The index of the GPU of the platform
+ * Gets the platform description of a GPU.
+ * @param {number} index - The index number of the GPU.
* @function PlatformInfo.getGPU
- * @returns {string} The GPU description json field
+ * @returns {string} The GPU's {@link PlatformInfo.GPUDescription|GPUDescription} information as a JSON string.
+ * @example Report details of the computer's GPUs.
+ * var numGPUs = PlatformInfo.getNumGPUs();
+ * print("Number of GPUs: " + numGPUs);
+ * for (var i = 0; i < numGPUs; i++) {
+ * var gpuDescription = PlatformInfo.getGPU(i);
+ * print("GPU " + i + ": " + gpuDescription);
+ * }
*/
QString getGPU(int index);
/**jsdoc
- * Get the number of Displays.
- * @function PlatformInfo.getNumDisplays
- * @returns {number} The number of Displays detected on the hardware platform.
- */
+ * Gets the number of displays.
+ * @function PlatformInfo.getNumDisplays
+ * @returns {number} The number of displays.
+ */
int getNumDisplays();
/**jsdoc
- * Get the index of the master Display.
- * @function PlatformInfo.getMasterDisplay
- * @returns {number} The index of the master Display detected on the hardware platform.
- */
+ * Gets the index number of the master display.
+ * @function PlatformInfo.getMasterDisplay
+ * @returns {number} The index of the master display.
+ */
int getMasterDisplay();
/**jsdoc
- * Get the description of the Display at the index parameter
- * expected fields are:
- * - DisplayVendor...
- * @param index The index of the Display of the platform
- * @function PlatformInfo.getDisplay
- * @returns {string} The Display description json field
- */
+ * Gets the platform description of a display.
+ * @param {number} index - The index number of the display.
+ * @function PlatformInfo.getDisplay
+ * @returns {string} The display's {@link PlatformInfo.DisplayDescription|DisplayDescription} information as a JSON string.
+ * @example Report details of the systems's displays.
+ * var numDisplays = PlatformInfo.getNumDisplays();
+ * print("Number of displays: " + numDisplays);
+ * for (var i = 0; i < numDisplays; i++) {
+ * var displayDescription = PlatformInfo.getDisplay(i);
+ * print("Display " + i + ": " + displayDescription);
+ * }
+ */
QString getDisplay(int index);
/**jsdoc
- * Get the description of the Memory
- * expected fields are:
- * - MemoryVendor...
- * @function PlatformInfo.getMemory
- * @returns {string} The Memory description json field
- */
+ * Gets the platform description of computer memory.
+ * @function PlatformInfo.getMemory
+ * @returns {string} The computer's {@link PlatformInfo.MemoryDescription|MemoryDescription} information as a JSON string.
+ * @example Report details of the computer's memory.
+ * print("Memory: " + PlatformInfo.getMemory());
+ */
QString getMemory();
/**jsdoc
- * Get the description of the Computer
- * expected fields are:
- * - ComputerVendor...
- * @function PlatformInfo.getComputer
- * @returns {string} The Computer description json field
- */
+ * Gets the platform description of the computer.
+ * @function PlatformInfo.getComputer
+ * @returns {string} The {@link PlatformInfo.ComputerDescription|ComputerDescription} information as a JSON string.
+ */
QString getComputer();
/**jsdoc
- * Get the complete description of the Platform as an aggregated Json
- * The expected object description is:
- * { "computer": {...}, "memory": {...}, "cpus": [{...}, ...], "gpus": [{...}, ...], "displays": [{...}, ...] }
- * @function PlatformInfo.getPlatform
- * @returns {string} The Platform description json field
- */
+ * Gets the complete description of the computer as a whole.
+ * @function PlatformInfo.getPlatform
+ * @returns {string} The {@link PlatformInfo.PlatformDescription|PlatformDescription} information as a JSON string.
+ */
QString getPlatform();
/**jsdoc
- * Get the Platform TIer profiled on startup of the Computer
- * Platform Tier is an integer/enum value:
- * UNKNOWN = 0, LOW = 1, MID = 2, HIGH = 3
- * @function PlatformInfo.getTierProfiled
- * @returns {number} The Platform Tier profiled on startup.
- */
+ * Gets the platform tier of the computer, profiled at Interface start-up.
+ * @function PlatformInfo.getTierProfiled
+ * @returns {PlatformInfo.PlatformTier} The platform tier of the computer.
+ * @example Report the platform tier of the computer.
+ * var platformTier = PlatformInfo.getTierProfiled();
+ * var platformTierName = PlatformInfo.getPlatformTierNames()[platformTier];
+ * print("Platform tier: " + platformTier + ", " + platformTierName);
+ */
PlatformTier getTierProfiled();
/**jsdoc
- * Get the Platform Tier possible Names as an array of strings
- * Platform Tier names are:
- * [ "UNKNOWN", "LOW", "MID", "HIGH" ]
- * @function PlatformInfo.getPlatformTierNames
- * @returns {string} The array of names matching the number returned from PlatformInfo.getTierProfiled
- */
+ * Gets the names of the possible platform tiers, per {@link PlatformInfo.PlatformTier}.
+ * @function PlatformInfo.getPlatformTierNames
+ * @returns {string[]} The names of the possible platform tiers.
+ */
QStringList getPlatformTierNames();
/**jsdoc
- * Gets whether the current hardware can render using the Deferred method.
- * @function PlatformInfo.isRenderMethodDeferredCapable
- * @returns {bool} true
if the current hardware can render using the Deferred method; false
otherwise.
- */
+ * Gets whether the current hardware can use deferred rendering.
+ * @function PlatformInfo.isRenderMethodDeferredCapable
+ * @returns {boolean} true
if the current hardware can use deferred rendering, false
if it can't.
+ */
bool isRenderMethodDeferredCapable();
};
diff --git a/interface/src/scripting/RenderScriptingInterface.h b/interface/src/scripting/RenderScriptingInterface.h
index 9b96448c9d..1c2443144a 100644
--- a/interface/src/scripting/RenderScriptingInterface.h
+++ b/interface/src/scripting/RenderScriptingInterface.h
@@ -15,13 +15,20 @@
#include "RenderForward.h"
/**jsdoc
- * The Render
API allows you to configure the graphics engine
+ * The Render
API enables you to configure the graphics engine.
*
* @namespace Render
*
* @hifi-interface
* @hifi-client-entity
* @hifi-avatar
+ *
+ * @property {Render.RenderMethod} renderMethod - The render method being used.
+ * @property {boolean} shadowsEnabled - true
if shadows are enabled, false
if they're disabled.
+ * @property {boolean} ambientOcclusionEnabled - true
if ambient occlusion is enabled, false
if it's
+ * disabled.
+ * @property {boolean} antialiasingEnabled - true
if anti-aliasing is enabled, false
if it's disabled.
+ * @property {number} viewportResolutionScale - The view port resolution scale, > 0.0
.
*/
class RenderScriptingInterface : public QObject {
Q_OBJECT
@@ -36,6 +43,21 @@ public:
static RenderScriptingInterface* getInstance();
+ /**jsdoc
+ * The rendering method is specified by the following values:
+ *
+ *
+ * Value | Name | Description |
+ *
+ *
+ * 0 | DEFERRED | More complex rendering pipeline where lighting is applied to the
+ * scene as a whole after all objects have been rendered. |
+ * 1 | FORWARD | Simpler rendering pipeline where each object in the scene, in turn,
+ * is rendered and has lighting applied. |
+ *
+ *
+ * @typedef {number} Render.RenderMethod
+ */
// RenderMethod enum type
enum class RenderMethod {
DEFERRED = render::Args::RenderMethod::DEFERRED,
@@ -52,95 +74,114 @@ public:
public slots:
/**jsdoc
- * Get a config for a job by name
+ * Gets the configuration for a rendering job by name.
+ * Warning: For internal, debugging purposes. Subject to change.
* @function Render.getConfig
- * @param {string} name - Can be:
- * - : Search for the first job named job_name traversing the the sub graph of task and jobs (from this task as root)
- * - .[.]: Allows you to first look for the parent_name job (from this task as root) and then search from there for the
- * optional sub_parent_names and finally from there looking for the job_name (assuming every job in the path is found)
- * @returns {object} The sub job config.
+ * @param {string} name - The name of the rendering job.
+ * @returns {object} The configuration for the rendering job.
*/
QObject* getConfig(const QString& name) { return qApp->getRenderEngine()->getConfiguration()->getConfig(name); }
+
/**jsdoc
- * Gets the current render method
+ * Gets the render method being used.
* @function Render.getRenderMethod
- * @returns {number} "DEFERRED"
or "FORWARD"
+ * @returns {Render.RenderMethod} The render method being used.
+ * @example Report the current render method.
+ * var renderMethod = Render.getRenderMethod();
+ * print("Current render method: " + Render.getRenderMethodNames()[renderMethod]);
*/
RenderMethod getRenderMethod() const;
/**jsdoc
- * Sets the current render method
+ * Sets the render method to use.
* @function Render.setRenderMethod
- * @param {number} renderMethod - "DEFERRED"
or "FORWARD"
+ * @param {Render.RenderMethod} renderMethod - The render method to use.
*/
void setRenderMethod(RenderMethod renderMethod);
/**jsdoc
- * Gets the possible enum names of the RenderMethod type
- * @function Render.getRenderMethodNames
- * @returns [string] [ "DEFERRED"
, "FORWARD"
]
- */
+ * Gets the names of the possible render methods, per {@link Render.RenderMethod}.
+ * @function Render.getRenderMethodNames
+ * @returns {string[]} The names of the possible render methods.
+ * @example Report the names of the possible render methods.
+ * var renderMethods = Render.getRenderMethodNames();
+ * print("Render methods:");
+ * for (var i = 0; i < renderMethods.length; i++) {
+ * print("- " + renderMethods[i]);
+ * }
+ */
QStringList getRenderMethodNames() const;
/**jsdoc
- * Whether or not shadows are enabled
+ * Gets whether or not shadows are enabled.
* @function Render.getShadowsEnabled
- * @returns {bool} true
if shadows are enabled, otherwise false
+ * @returns {boolean} true
if shadows are enabled, false
if they're disabled.
*/
bool getShadowsEnabled() const;
/**jsdoc
- * Enables or disables shadows
+ * Sets whether or not shadows are enabled.
* @function Render.setShadowsEnabled
- * @param {bool} enabled - true
to enable shadows, false
to disable them
+ * @param {boolean} enabled - true
to enable shadows, false
to disable.
*/
void setShadowsEnabled(bool enabled);
/**jsdoc
- * Whether or not ambient occlusion is enabled
+ * Gets whether or not ambient occlusion is enabled.
* @function Render.getAmbientOcclusionEnabled
- * @returns {bool} true
if ambient occlusion is enabled, otherwise false
+ * @returns {boolean} true
if ambient occlusion is enabled, false
if it's disabled.
*/
bool getAmbientOcclusionEnabled() const;
/**jsdoc
- * Enables or disables ambient occlusion
+ * Sets whether or not ambient occlusion is enabled.
* @function Render.setAmbientOcclusionEnabled
- * @param {bool} enabled - true
to enable ambient occlusion, false
to disable it
+ * @param {boolean} enabled - true
to enable ambient occlusion, false
to disable.
*/
void setAmbientOcclusionEnabled(bool enabled);
/**jsdoc
- * Whether or not anti-aliasing is enabled
+ * Gets whether or not anti-aliasing is enabled.
* @function Render.getAntialiasingEnabled
- * @returns {bool} true
if anti-aliasing is enabled, otherwise false
+ * @returns {boolean} true
if anti-aliasing is enabled, false
if it's disabled.
*/
bool getAntialiasingEnabled() const;
/**jsdoc
- * Enables or disables anti-aliasing
+ * Sets whether or not anti-aliasing is enabled.
* @function Render.setAntialiasingEnabled
- * @param {bool} enabled - true
to enable anti-aliasing, false
to disable it
+ * @param {boolean} enabled - true
to enable anti-aliasing, false
to disable.
*/
void setAntialiasingEnabled(bool enabled);
/**jsdoc
- * Gets the current viewport resolution scale
+ * Gets the view port resolution scale.
* @function Render.getViewportResolutionScale
- * @returns {number}
+ * @returns {number} The view port resolution scale, > 0.0
.
*/
float getViewportResolutionScale() const;
/**jsdoc
- * Sets the current viewport resolution scale
+ * Sets the view port resolution scale.
* @function Render.setViewportResolutionScale
- * @param {number} resolutionScale - between epsilon and 1.0
+ * @param {number} resolutionScale - The view port resolution scale to set, > 0.0
.
*/
void setViewportResolutionScale(float resolutionScale);
signals:
+
+ /**jsdoc
+ * Triggered when one of the Render
API's properties changes.
+ * @function Render.settingsChanged
+ * @returns {Signal}
+ * @example Report when a render setting changes.
+ * Render.settingsChanged.connect(function () {
+ * print("Render setting changed");
+ * });
+ * // Toggle Developer > Render > Shadows or similar to trigger.
+ */
void settingsChanged();
private:
diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp
index be371c900b..100711d69b 100644
--- a/interface/src/ui/overlays/Overlays.cpp
+++ b/interface/src/ui/overlays/Overlays.cpp
@@ -1740,7 +1740,9 @@ QVector Overlays::findOverlays(const glm::vec3& center, float radius) {
* parented to if parentID
is set. Use 65535 or -1 to parent to the parent's position and orientation rather
* than a joint.
*
- * @property {string} url - The URL of the FBX or OBJ model used for the overlay.
+ * @property {string} url - The URL of the glTF, FBX, or OBJ model used for the overlay. glTF models may be in JSON or binary
+ * format (".gltf" or ".glb" URLs respectively). Baked models' URLs have ".baked" before the file type. Model files may
+ * also be compressed in GZ format, in which case the URL ends in ".gz".
* @property {number} loadPriority=0.0 - The priority for loading and displaying the overlay. Overlays with higher values load
* first. Currently not used.
* @property {Object.|string} textures - Texture name, URL pairs used when rendering the model in place of the
diff --git a/launchers/darwin/src/DownloadLauncher.m b/launchers/darwin/src/DownloadLauncher.m
index e7d293be43..1628d3db6c 100644
--- a/launchers/darwin/src/DownloadLauncher.m
+++ b/launchers/darwin/src/DownloadLauncher.m
@@ -47,7 +47,7 @@
return;
}
NSLog(@"extracting Launcher file");
- BOOL extractionSuccessful = [sharedLauncher extractZipFileAtDestination:[sharedLauncher getDownloadPathForContentAndScripts] :[[sharedLauncher getDownloadPathForContentAndScripts] stringByAppendingString:@"HQ Launcher.zip"]];
+ BOOL extractionSuccessful = [sharedLauncher extractZipFileAtDestination:[sharedLauncher getDownloadPathForContentAndScripts] :[[sharedLauncher getDownloadPathForContentAndScripts] stringByAppendingString:destinationFileName]];
if (!extractionSuccessful) {
[sharedLauncher displayErrorPage];
diff --git a/launchers/win32/LauncherApp.cpp b/launchers/win32/LauncherApp.cpp
index ff63841c5a..38bf7eebcc 100644
--- a/launchers/win32/LauncherApp.cpp
+++ b/launchers/win32/LauncherApp.cpp
@@ -72,9 +72,7 @@ BOOL CLauncherApp::InitInstance() {
} else {
_manager.init(!noUpdate, continueAction);
}
- if (!_manager.hasFailed() && !_manager.installLauncher()) {
- return FALSE;
- }
+ _manager.tryToInstallLauncher();
installFont(IDR_FONT_REGULAR);
installFont(IDR_FONT_BOLD);
CWinApp::InitInstance();
diff --git a/launchers/win32/LauncherDlg.cpp b/launchers/win32/LauncherDlg.cpp
index 928bf7010f..1fb6207c95 100644
--- a/launchers/win32/LauncherDlg.cpp
+++ b/launchers/win32/LauncherDlg.cpp
@@ -656,7 +656,6 @@ BOOL CLauncherDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
void CLauncherDlg::OnTimer(UINT_PTR nIDEvent) {
-
if (theApp._manager.hasFailed() && _drawStep != DrawStep::DrawError) {
theApp._manager.saveErrorLog();
prepareProcess(DrawStep::DrawError);
@@ -757,6 +756,9 @@ void CLauncherDlg::OnTimer(UINT_PTR nIDEvent) {
_applicationWND = theApp._manager.launchApplication();
}
}
+ if (theApp._manager.needsToSelfInstall()) {
+ theApp._manager.tryToInstallLauncher(TRUE);
+ }
}
void CLauncherDlg::setVerticalElement(CWnd* element, int verticalOffset, int heightOffset, bool fromMainWindowBottom) {
diff --git a/launchers/win32/LauncherManager.cpp b/launchers/win32/LauncherManager.cpp
index 49ae058ef5..5efcb38cf6 100644
--- a/launchers/win32/LauncherManager.cpp
+++ b/launchers/win32/LauncherManager.cpp
@@ -108,7 +108,7 @@ void LauncherManager::saveErrorLog() {
}
}
-BOOL LauncherManager::installLauncher() {
+void LauncherManager::tryToInstallLauncher(BOOL retry) {
CString appPath;
BOOL result = getAndCreatePaths(PathType::Running_Path, appPath);
if (!result) {
@@ -126,26 +126,49 @@ BOOL LauncherManager::installLauncher() {
if (!_shouldUninstall) {
// The installer is not running on the desired location and has to be installed
// Kill of running before self-copy
- addToLog(_T("Installing Launcher."));
+ addToLog(_T("Trying to install launcher."));
int launcherPID = -1;
if (LauncherUtils::isProcessRunning(LAUNCHER_EXE_FILENAME, launcherPID)) {
if (!LauncherUtils::shutdownProcess(launcherPID, 0)) {
addToLog(_T("Error shutting down the Launcher"));
}
}
- CopyFile(appPath, instalationPath, FALSE);
+ const int LAUNCHER_INSTALL_RETRYS = 10;
+ const int WAIT_BETWEEN_RETRYS_MS = 10;
+ int installTrys = retry ? LAUNCHER_INSTALL_RETRYS : 0;
+ for (int i = 0; i <= installTrys; i++) {
+ _retryLauncherInstall = !CopyFile(appPath, instalationPath, FALSE);
+ if (!_retryLauncherInstall) {
+ addToLog(_T("Launcher installed successfully."));
+ break;
+ } else if (i < installTrys) {
+ CString msg;
+ msg.Format(_T("Installing launcher try: %d"), i);
+ addToLog(msg);
+ Sleep(WAIT_BETWEEN_RETRYS_MS);
+ } else if (installTrys > 0) {
+ addToLog(_T("Error installing launcher."));
+ _retryLauncherInstall = false;
+ _hasFailed = true;
+ } else {
+ addToLog(_T("Old launcher is still running. Install could not be completed."));
+ }
+ }
}
} else if (_shouldUninstall) {
addToLog(_T("Launching Uninstall mode."));
CString tempPath;
if (getAndCreatePaths(PathType::Temp_Directory, tempPath)) {
tempPath += _T("\\HQ_uninstaller_tmp.exe");
- CopyFile(instalationPath, tempPath, false);
- LauncherUtils::launchApplication(tempPath, _T(" --uninstall"));
- exit(0);
+ if (!CopyFile(instalationPath, tempPath, false)) {
+ addToLog(_T("Error copying uninstaller to tmp directory."));
+ _hasFailed = true;
+ } else {
+ LauncherUtils::launchApplication(tempPath, _T(" --uninstall"));
+ exit(0);
+ }
}
}
- return TRUE;
}
BOOL LauncherManager::restartLauncher() {
diff --git a/launchers/win32/LauncherManager.h b/launchers/win32/LauncherManager.h
index 5169edfa75..18ac041b3b 100644
--- a/launchers/win32/LauncherManager.h
+++ b/launchers/win32/LauncherManager.h
@@ -92,7 +92,7 @@ public:
BOOL deleteShortcuts();
HWND launchApplication();
BOOL uninstallApplication();
- BOOL installLauncher();
+ void tryToInstallLauncher(BOOL retry = FALSE);
BOOL restartLauncher();
// getters
@@ -108,6 +108,7 @@ public:
BOOL needsInstall() const { return _shouldInstall; }
BOOL needsToWait() const { return _shouldWait; }
BOOL needsRestartNewLauncher() const { return _shouldRestartNewLauncher; }
+ BOOL needsToSelfInstall() const { return _retryLauncherInstall; }
BOOL willContinueUpdating() const { return _keepUpdating; }
ContinueActionOnStart getContinueAction() { return _continueAction; }
void setDisplayName(const CString& displayName) { _displayName = displayName; }
@@ -164,6 +165,7 @@ private:
BOOL _shouldRestartNewLauncher { FALSE };
BOOL _keepLoggingIn { FALSE };
BOOL _keepUpdating { FALSE };
+ BOOL _retryLauncherInstall { FALSE };
ContinueActionOnStart _continueAction;
float _progressOffset { 0.0f };
float _progress { 0.0f };
diff --git a/libraries/animation/src/AnimNodeLoader.cpp b/libraries/animation/src/AnimNodeLoader.cpp
index 4131009324..6828ed1c7e 100644
--- a/libraries/animation/src/AnimNodeLoader.cpp
+++ b/libraries/animation/src/AnimNodeLoader.cpp
@@ -29,6 +29,7 @@
#include "AnimTwoBoneIK.h"
#include "AnimSplineIK.h"
#include "AnimPoleVectorConstraint.h"
+#include "AnimUtil.h"
using NodeLoaderFunc = AnimNode::Pointer (*)(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl);
using NodeProcessFunc = bool (*)(AnimNode::Pointer node, const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl);
@@ -91,6 +92,8 @@ static AnimStateMachine::InterpType stringToInterpType(const QString& str) {
return AnimStateMachine::InterpType::SnapshotBoth;
} else if (str == "snapshotPrev") {
return AnimStateMachine::InterpType::SnapshotPrev;
+ } else if (str == "evaluateBoth") {
+ return AnimStateMachine::InterpType::EvaluateBoth;
} else {
return AnimStateMachine::InterpType::NumTypes;
}
@@ -101,11 +104,63 @@ static AnimRandomSwitch::InterpType stringToRandomInterpType(const QString& str)
return AnimRandomSwitch::InterpType::SnapshotBoth;
} else if (str == "snapshotPrev") {
return AnimRandomSwitch::InterpType::SnapshotPrev;
+ } else if (str == "evaluateBoth") {
+ return AnimRandomSwitch::InterpType::EvaluateBoth;
} else {
return AnimRandomSwitch::InterpType::NumTypes;
}
}
+static EasingType stringToEasingType(const QString& str) {
+ if (str == "linear") {
+ return EasingType_Linear;
+ } else if (str == "easeInSine") {
+ return EasingType_EaseInSine;
+ } else if (str == "easeOutSine") {
+ return EasingType_EaseOutSine;
+ } else if (str == "easeInOutSine") {
+ return EasingType_EaseInOutSine;
+ } else if (str == "easeInQuad") {
+ return EasingType_EaseInQuad;
+ } else if (str == "easeOutQuad") {
+ return EasingType_EaseOutQuad;
+ } else if (str == "easeInOutQuad") {
+ return EasingType_EaseInOutQuad;
+ } else if (str == "easeInCubic") {
+ return EasingType_EaseInCubic;
+ } else if (str == "easeOutCubic") {
+ return EasingType_EaseOutCubic;
+ } else if (str == "easeInOutCubic") {
+ return EasingType_EaseInOutCubic;
+ } else if (str == "easeInQuart") {
+ return EasingType_EaseInQuart;
+ } else if (str == "easeOutQuart") {
+ return EasingType_EaseOutQuart;
+ } else if (str == "easeInOutQuart") {
+ return EasingType_EaseInOutQuart;
+ } else if (str == "easeInQuint") {
+ return EasingType_EaseInQuint;
+ } else if (str == "easeOutQuint") {
+ return EasingType_EaseOutQuint;
+ } else if (str == "easeInOutQuint") {
+ return EasingType_EaseInOutQuint;
+ } else if (str == "easeInExpo") {
+ return EasingType_EaseInExpo;
+ } else if (str == "easeOutExpo") {
+ return EasingType_EaseOutExpo;
+ } else if (str == "easeInOutExpo") {
+ return EasingType_EaseInOutExpo;
+ } else if (str == "easeInCirc") {
+ return EasingType_EaseInCirc;
+ } else if (str == "easeOutCirc") {
+ return EasingType_EaseOutCirc;
+ } else if (str == "easeInOutCirc") {
+ return EasingType_EaseInOutCirc;
+ } else {
+ return EasingType_NumTypes;
+ }
+}
+
static const char* animManipulatorJointVarTypeToString(AnimManipulator::JointVar::Type type) {
switch (type) {
case AnimManipulator::JointVar::Type::Absolute: return "absolute";
@@ -723,6 +778,7 @@ bool processStateMachineNode(AnimNode::Pointer node, const QJsonObject& jsonObj,
READ_FLOAT(interpTarget, stateObj, nodeId, jsonUrl, false);
READ_FLOAT(interpDuration, stateObj, nodeId, jsonUrl, false);
READ_OPTIONAL_STRING(interpType, stateObj);
+ READ_OPTIONAL_STRING(easingType, stateObj);
READ_OPTIONAL_STRING(interpTargetVar, stateObj);
READ_OPTIONAL_STRING(interpDurationVar, stateObj);
@@ -743,7 +799,16 @@ bool processStateMachineNode(AnimNode::Pointer node, const QJsonObject& jsonObj,
}
}
- auto statePtr = std::make_shared(id, iter->second, interpTarget, interpDuration, interpTypeEnum);
+ EasingType easingTypeEnum = EasingType_Linear; // default value
+ if (!easingType.isEmpty()) {
+ easingTypeEnum = stringToEasingType(easingType);
+ if (easingTypeEnum == EasingType_NumTypes) {
+ qCCritical(animation) << "AnimNodeLoader, bad easingType on stateMachine state, nodeId = " << nodeId << "stateId =" << id;
+ return false;
+ }
+ }
+
+ auto statePtr = std::make_shared(id, iter->second, interpTarget, interpDuration, interpTypeEnum, easingTypeEnum);
assert(statePtr);
if (!interpTargetVar.isEmpty()) {
@@ -845,6 +910,7 @@ bool processRandomSwitchStateMachineNode(AnimNode::Pointer node, const QJsonObje
READ_FLOAT(interpTarget, stateObj, nodeId, jsonUrl, false);
READ_FLOAT(interpDuration, stateObj, nodeId, jsonUrl, false);
READ_OPTIONAL_STRING(interpType, stateObj);
+ READ_OPTIONAL_STRING(easingType, stateObj);
READ_FLOAT(priority, stateObj, nodeId, jsonUrl, false);
READ_BOOL(resume, stateObj, nodeId, jsonUrl, false);
@@ -867,7 +933,16 @@ bool processRandomSwitchStateMachineNode(AnimNode::Pointer node, const QJsonObje
}
}
- auto randomStatePtr = std::make_shared(id, iter->second, interpTarget, interpDuration, interpTypeEnum, priority, resume);
+ EasingType easingTypeEnum = EasingType_Linear; // default value
+ if (!easingType.isEmpty()) {
+ easingTypeEnum = stringToEasingType(easingType);
+ if (easingTypeEnum == EasingType_NumTypes) {
+ qCCritical(animation) << "AnimNodeLoader, bad easingType on randomSwitch state, nodeId = " << nodeId << "stateId =" << id;
+ return false;
+ }
+ }
+
+ auto randomStatePtr = std::make_shared(id, iter->second, interpTarget, interpDuration, interpTypeEnum, easingTypeEnum, priority, resume);
if (priority > 0.0f) {
smNode->addToPrioritySum(priority);
}
diff --git a/libraries/animation/src/AnimOverlay.cpp b/libraries/animation/src/AnimOverlay.cpp
index 910f9b37c0..9b6632e86f 100644
--- a/libraries/animation/src/AnimOverlay.cpp
+++ b/libraries/animation/src/AnimOverlay.cpp
@@ -54,15 +54,20 @@ const AnimPoseVec& AnimOverlay::evaluate(const AnimVariantMap& animVars, const A
if (_children.size() >= 2) {
auto& underPoses = _children[1]->evaluate(animVars, context, dt, triggersOut);
- auto& overPoses = _children[0]->overlay(animVars, context, dt, triggersOut, underPoses);
- if (underPoses.size() > 0 && underPoses.size() == overPoses.size()) {
- _poses.resize(underPoses.size());
- assert(_boneSetVec.size() == _poses.size());
+ if (_alpha == 0.0f) {
+ _poses = underPoses;
+ } else {
+ auto& overPoses = _children[0]->overlay(animVars, context, dt, triggersOut, underPoses);
- for (size_t i = 0; i < _poses.size(); i++) {
- float alpha = _boneSetVec[i] * _alpha;
- ::blend(1, &underPoses[i], &overPoses[i], alpha, &_poses[i]);
+ if (underPoses.size() > 0 && underPoses.size() == overPoses.size()) {
+ _poses.resize(underPoses.size());
+ assert(_boneSetVec.size() == _poses.size());
+
+ for (size_t i = 0; i < _poses.size(); i++) {
+ float alpha = _boneSetVec[i] * _alpha;
+ ::blend(1, &underPoses[i], &overPoses[i], alpha, &_poses[i]);
+ }
}
}
}
diff --git a/libraries/animation/src/AnimRandomSwitch.cpp b/libraries/animation/src/AnimRandomSwitch.cpp
index 2549a50062..edc8c8dd96 100644
--- a/libraries/animation/src/AnimRandomSwitch.cpp
+++ b/libraries/animation/src/AnimRandomSwitch.cpp
@@ -89,6 +89,7 @@ const AnimPoseVec& AnimRandomSwitch::evaluate(const AnimVariantMap& animVars, co
assert(_currentState);
auto currentStateNode = _children[_currentState->getChildIndex()];
+ auto previousStateNode = _children[_previousState->getChildIndex()];
assert(currentStateNode);
if (_duringInterp) {
@@ -97,6 +98,7 @@ const AnimPoseVec& AnimRandomSwitch::evaluate(const AnimVariantMap& animVars, co
AnimPoseVec* nextPoses = nullptr;
AnimPoseVec* prevPoses = nullptr;
AnimPoseVec localNextPoses;
+ AnimPoseVec localPrevPoses;
if (_interpType == InterpType::SnapshotBoth) {
// interp between both snapshots
prevPoses = &_prevPoses;
@@ -107,13 +109,18 @@ const AnimPoseVec& AnimRandomSwitch::evaluate(const AnimVariantMap& animVars, co
localNextPoses = currentStateNode->evaluate(animVars, context, dt, triggersOut);
prevPoses = &_prevPoses;
nextPoses = &localNextPoses;
+ } else if (_interpType == InterpType::EvaluateBoth) {
+ localPrevPoses = previousStateNode->evaluate(animVars, context, dt, triggersOut);
+ localNextPoses = currentStateNode->evaluate(animVars, context, dt, triggersOut);
+ prevPoses = &localPrevPoses;
+ nextPoses = &localNextPoses;
} else {
assert(false);
}
if (_poses.size() > 0 && nextPoses && prevPoses && nextPoses->size() > 0 && prevPoses->size() > 0) {
- ::blend(_poses.size(), &(prevPoses->at(0)), &(nextPoses->at(0)), _alpha, &_poses[0]);
+ ::blend(_poses.size(), &(prevPoses->at(0)), &(nextPoses->at(0)), easingFunc(_alpha, _easingType), &_poses[0]);
}
- context.setDebugAlpha(_currentState->getID(), _alpha * parentDebugAlpha, _children[_currentState->getChildIndex()]->getType());
+ context.setDebugAlpha(_currentState->getID(), easingFunc(_alpha, _easingType) * parentDebugAlpha, _children[_currentState->getChildIndex()]->getType());
} else {
_duringInterp = false;
_prevPoses.clear();
@@ -160,6 +167,7 @@ void AnimRandomSwitch::switchRandomState(const AnimVariantMap& animVars, const A
float duration = std::max(0.001f, animVars.lookup(desiredState->_interpDurationVar, desiredState->_interpDuration));
_alphaVel = FRAMES_PER_SECOND / duration;
_interpType = (InterpType)animVars.lookup(desiredState->_interpTypeVar, (int)desiredState->_interpType);
+ _easingType = desiredState->_easingType;
// because dt is 0, we should not encounter any triggers
const float dt = 0.0f;
diff --git a/libraries/animation/src/AnimRandomSwitch.h b/libraries/animation/src/AnimRandomSwitch.h
index 7a750cd89f..7c185dd7cb 100644
--- a/libraries/animation/src/AnimRandomSwitch.h
+++ b/libraries/animation/src/AnimRandomSwitch.h
@@ -14,6 +14,7 @@
#include
#include
#include "AnimNode.h"
+#include "AnimUtil.h"
// Random Switch State Machine for random transitioning between children AnimNodes
//
@@ -51,6 +52,7 @@ public:
enum class InterpType {
SnapshotBoth = 0,
SnapshotPrev,
+ EvaluateBoth,
NumTypes
};
@@ -73,12 +75,13 @@ protected:
RandomSwitchState::Pointer _randomSwitchState;
};
- RandomSwitchState(const QString& id, int childIndex, float interpTarget, float interpDuration, InterpType interpType, float priority, bool resume) :
+ RandomSwitchState(const QString& id, int childIndex, float interpTarget, float interpDuration, InterpType interpType, EasingType easingType, float priority, bool resume) :
_id(id),
_childIndex(childIndex),
_interpTarget(interpTarget),
_interpDuration(interpDuration),
_interpType(interpType),
+ _easingType(easingType),
_priority(priority),
_resume(resume){
}
@@ -106,6 +109,7 @@ protected:
float _interpTarget; // frames
float _interpDuration; // frames
InterpType _interpType;
+ EasingType _easingType;
float _priority {0.0f};
bool _resume {false};
@@ -154,7 +158,8 @@ protected:
int _randomSwitchEvaluationCount { 0 };
// interpolation state
bool _duringInterp = false;
- InterpType _interpType{ InterpType::SnapshotPrev };
+ InterpType _interpType { InterpType::SnapshotPrev };
+ EasingType _easingType { EasingType_Linear };
float _alphaVel = 0.0f;
float _alpha = 0.0f;
AnimPoseVec _prevPoses;
diff --git a/libraries/animation/src/AnimStateMachine.cpp b/libraries/animation/src/AnimStateMachine.cpp
index 2c5d4ad0f3..b2d993abb8 100644
--- a/libraries/animation/src/AnimStateMachine.cpp
+++ b/libraries/animation/src/AnimStateMachine.cpp
@@ -48,6 +48,7 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, co
assert(_currentState);
auto currentStateNode = _children[_currentState->getChildIndex()];
+ auto previousStateNode = _children[_previousState->getChildIndex()];
assert(currentStateNode);
if (_duringInterp) {
@@ -56,6 +57,8 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, co
AnimPoseVec* nextPoses = nullptr;
AnimPoseVec* prevPoses = nullptr;
AnimPoseVec localNextPoses;
+ AnimPoseVec localPrevPoses;
+
if (_interpType == InterpType::SnapshotBoth) {
// interp between both snapshots
prevPoses = &_prevPoses;
@@ -66,13 +69,18 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, co
localNextPoses = currentStateNode->evaluate(animVars, context, dt, triggersOut);
prevPoses = &_prevPoses;
nextPoses = &localNextPoses;
+ } else if (_interpType == InterpType::EvaluateBoth) {
+ localPrevPoses = previousStateNode->evaluate(animVars, context, dt, triggersOut);
+ localNextPoses = currentStateNode->evaluate(animVars, context, dt, triggersOut);
+ prevPoses = &localPrevPoses;
+ nextPoses = &localNextPoses;
} else {
assert(false);
}
if (_poses.size() > 0 && nextPoses && prevPoses && nextPoses->size() > 0 && prevPoses->size() > 0) {
- ::blend(_poses.size(), &(prevPoses->at(0)), &(nextPoses->at(0)), _alpha, &_poses[0]);
+ ::blend(_poses.size(), &(prevPoses->at(0)), &(nextPoses->at(0)), easingFunc(_alpha, _easingType), &_poses[0]);
}
- context.setDebugAlpha(_currentState->getID(), _alpha * parentDebugAlpha, _children[_currentState->getChildIndex()]->getType());
+ context.setDebugAlpha(_currentState->getID(), easingFunc(_alpha, _easingType) * parentDebugAlpha, _children[_currentState->getChildIndex()]->getType());
} else {
_duringInterp = false;
_prevPoses.clear();
@@ -95,6 +103,15 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, co
return _poses;
}
+const QString& AnimStateMachine::getCurrentStateID() const {
+ if (_currentState) {
+ return _currentState->getID();
+ } else {
+ static QString emptyString;
+ return emptyString;
+ }
+}
+
void AnimStateMachine::setCurrentState(State::Pointer state) {
_previousState = _currentState ? _currentState : state;
_currentState = state;
@@ -116,6 +133,7 @@ void AnimStateMachine::switchState(const AnimVariantMap& animVars, const AnimCon
float duration = std::max(0.001f, animVars.lookup(desiredState->_interpDurationVar, desiredState->_interpDuration));
_alphaVel = FRAMES_PER_SECOND / duration;
_interpType = (InterpType)animVars.lookup(desiredState->_interpTypeVar, (int)desiredState->_interpType);
+ _easingType = desiredState->_easingType;
// because dt is 0, we should not encounter any triggers
const float dt = 0.0f;
diff --git a/libraries/animation/src/AnimStateMachine.h b/libraries/animation/src/AnimStateMachine.h
index 713c659a1d..3998f7e9ef 100644
--- a/libraries/animation/src/AnimStateMachine.h
+++ b/libraries/animation/src/AnimStateMachine.h
@@ -14,6 +14,7 @@
#include
#include
#include "AnimNode.h"
+#include "AnimUtil.h"
// State Machine for transitioning between children AnimNodes
//
@@ -47,6 +48,7 @@ public:
enum class InterpType {
SnapshotBoth = 0,
SnapshotPrev,
+ EvaluateBoth,
NumTypes
};
@@ -69,12 +71,13 @@ protected:
State::Pointer _state;
};
- State(const QString& id, int childIndex, float interpTarget, float interpDuration, InterpType interpType) :
+ State(const QString& id, int childIndex, float interpTarget, float interpDuration, InterpType interpType, EasingType easingType) :
_id(id),
_childIndex(childIndex),
_interpTarget(interpTarget),
_interpDuration(interpDuration),
- _interpType(interpType) {}
+ _interpType(interpType),
+ _easingType(easingType) {}
void setInterpTargetVar(const QString& interpTargetVar) { _interpTargetVar = interpTargetVar; }
void setInterpDurationVar(const QString& interpDurationVar) { _interpDurationVar = interpDurationVar; }
@@ -95,6 +98,7 @@ protected:
float _interpTarget; // frames
float _interpDuration; // frames
InterpType _interpType;
+ EasingType _easingType;
QString _interpTargetVar;
QString _interpDurationVar;
@@ -116,6 +120,7 @@ public:
virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) override;
void setCurrentStateVar(QString& currentStateVar) { _currentStateVar = currentStateVar; }
+ const QString& getCurrentStateID() const;
protected:
@@ -134,6 +139,7 @@ protected:
// interpolation state
bool _duringInterp = false;
InterpType _interpType { InterpType::SnapshotPrev };
+ EasingType _easingType { EasingType_Linear };
float _alphaVel = 0.0f;
float _alpha = 0.0f;
AnimPoseVec _prevPoses;
diff --git a/libraries/animation/src/AnimUtil.cpp b/libraries/animation/src/AnimUtil.cpp
index 5fca2b4f88..f4f922d704 100644
--- a/libraries/animation/src/AnimUtil.cpp
+++ b/libraries/animation/src/AnimUtil.cpp
@@ -211,3 +211,86 @@ bool findPointKDopDisplacement(const glm::vec3& point, const AnimPose& shapePose
return true;
}
}
+
+// See https://easings.net/en# for a graphical visualiztion of easing types.
+float easingFunc(float alpha, EasingType type) {
+ switch (type) {
+ case EasingType_Linear:
+ return alpha;
+ case EasingType_EaseInSine:
+ return sinf((alpha - 1.0f) * PI_OVER_TWO) + 1.0f;
+ case EasingType_EaseOutSine:
+ return sinf(alpha * PI_OVER_TWO);
+ case EasingType_EaseInOutSine:
+ return 0.5f * (1.0f - cosf(alpha * PI));
+ case EasingType_EaseInQuad:
+ return alpha * alpha;
+ case EasingType_EaseOutQuad:
+ return -(alpha * (alpha - 2.0f));
+ case EasingType_EaseInOutQuad:
+ return (alpha < 0.5f) ? (2.0f * alpha * alpha) : ((-2.0f * alpha * alpha) + (4.0f * alpha) - 1.0f);
+ case EasingType_EaseInCubic:
+ return alpha * alpha * alpha;
+ case EasingType_EaseOutCubic: {
+ float temp = alpha - 1.0f;
+ return temp * temp * temp + 1.0f;
+ }
+ case EasingType_EaseInOutCubic:
+ if (alpha < 0.5f) {
+ return 4.0f * alpha * alpha * alpha;
+ } else {
+ float temp = ((2.0f * alpha) - 2.0f);
+ return 0.5f * temp * temp * temp + 1.0f;
+ }
+ case EasingType_EaseInQuart:
+ return alpha * alpha * alpha * alpha;
+ case EasingType_EaseOutQuart: {
+ float temp = alpha - 1.0f;
+ return temp * temp * temp * (1.0f - alpha) + 1.0f;
+ }
+ case EasingType_EaseInOutQuart:
+ if (alpha < 0.5f) {
+ return 8.0f * alpha * alpha * alpha * alpha;
+ } else {
+ float temp = alpha - 1.0f;
+ return -8.0f * temp * temp * temp * temp + 1.0f;
+ }
+ case EasingType_EaseInQuint:
+ return alpha * alpha * alpha * alpha * alpha;
+ case EasingType_EaseOutQuint: {
+ float temp = (alpha - 1.0f);
+ return temp * temp * temp * temp * temp + 1.0f;
+ }
+ case EasingType_EaseInOutQuint:
+ if (alpha < 0.5f) {
+ return 16.0f * alpha * alpha * alpha * alpha * alpha;
+ } else {
+ float temp = ((2.0f * alpha) - 2.0f);
+ return 0.5f * temp * temp * temp * temp * temp + 1.0f;
+ }
+ case EasingType_EaseInExpo:
+ return (alpha == 0.0f) ? alpha : powf(2.0f, 10.0f * (alpha - 1.0f));
+ case EasingType_EaseOutExpo:
+ return (alpha == 1.0f) ? alpha : 1.0f - powf(2.0f, -10.0f * alpha);
+ case EasingType_EaseInOutExpo:
+ if (alpha == 0.0f || alpha == 1.0f)
+ return alpha;
+ else if (alpha < 0.5f) {
+ return 0.5f * powf(2.0f, (20.0f * alpha) - 10.0f);
+ } else {
+ return -0.5f * powf(2.0f, (-20.0f * alpha) + 10.0f) + 1.0f;
+ }
+ case EasingType_EaseInCirc:
+ return 1.0f - sqrtf(1.0f - (alpha * alpha));
+ case EasingType_EaseOutCirc:
+ return sqrtf((2.0f - alpha) * alpha);
+ case EasingType_EaseInOutCirc:
+ if (alpha < 0.5f) {
+ return 0.5f * (1.0f - sqrtf(1.0f - 4.0f * (alpha * alpha)));
+ } else {
+ return 0.5f * (sqrtf(-((2.0f * alpha) - 3.0f) * ((2.0f * alpha) - 1.0f)) + 1.0f);
+ }
+ default:
+ return alpha;
+ }
+}
diff --git a/libraries/animation/src/AnimUtil.h b/libraries/animation/src/AnimUtil.h
index c2925e31e8..26dc19da06 100644
--- a/libraries/animation/src/AnimUtil.h
+++ b/libraries/animation/src/AnimUtil.h
@@ -128,10 +128,37 @@ protected:
bool _snapshotValid { false };
};
-
// returns true if the given point lies inside of the k-dop, specified by shapeInfo & shapePose.
// if the given point does lie within the k-dop, it also returns the amount of displacement necessary to push that point outward
// such that it lies on the surface of the kdop.
bool findPointKDopDisplacement(const glm::vec3& point, const AnimPose& shapePose, const HFMJointShapeInfo& shapeInfo, glm::vec3& displacementOut);
+enum EasingType {
+ EasingType_Linear,
+ EasingType_EaseInSine,
+ EasingType_EaseOutSine,
+ EasingType_EaseInOutSine,
+ EasingType_EaseInQuad,
+ EasingType_EaseOutQuad,
+ EasingType_EaseInOutQuad,
+ EasingType_EaseInCubic,
+ EasingType_EaseOutCubic,
+ EasingType_EaseInOutCubic,
+ EasingType_EaseInQuart,
+ EasingType_EaseOutQuart,
+ EasingType_EaseInOutQuart,
+ EasingType_EaseInQuint,
+ EasingType_EaseOutQuint,
+ EasingType_EaseInOutQuint,
+ EasingType_EaseInExpo,
+ EasingType_EaseOutExpo,
+ EasingType_EaseInOutExpo,
+ EasingType_EaseInCirc,
+ EasingType_EaseOutCirc,
+ EasingType_EaseInOutCirc,
+ EasingType_NumTypes
+};
+
+float easingFunc(float alpha, EasingType type);
+
#endif
diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp
index 5f4c49364e..f885f1113f 100644
--- a/libraries/animation/src/Rig.cpp
+++ b/libraries/animation/src/Rig.cpp
@@ -29,6 +29,7 @@
#include "AnimInverseKinematics.h"
#include "AnimOverlay.h"
#include "AnimSkeleton.h"
+#include "AnimStateMachine.h"
#include "AnimUtil.h"
#include "AvatarConstants.h"
#include "IKTarget.h"
@@ -1906,28 +1907,7 @@ void Rig::updateFeet(bool leftFootEnabled, bool rightFootEnabled, bool headEnabl
void Rig::updateReactions(const ControllerParameters& params) {
- // enable/disable animVars
- bool enabled = params.reactionEnabledFlags[AVATAR_REACTION_POSITIVE];
- _animVars.set("reactionPositiveEnabled", enabled);
- _animVars.set("reactionPositiveDisabled", !enabled);
-
- enabled = params.reactionEnabledFlags[AVATAR_REACTION_NEGATIVE];
- _animVars.set("reactionNegativeEnabled", enabled);
- _animVars.set("reactionNegativeDisabled", !enabled);
-
- enabled = params.reactionEnabledFlags[AVATAR_REACTION_RAISE_HAND];
- _animVars.set("reactionRaiseHandEnabled", enabled);
- _animVars.set("reactionRaiseHandDisabled", !enabled);
-
- enabled = params.reactionEnabledFlags[AVATAR_REACTION_APPLAUD];
- _animVars.set("reactionApplaudEnabled", enabled);
- _animVars.set("reactionApplaudDisabled", !enabled);
-
- enabled = params.reactionEnabledFlags[AVATAR_REACTION_POINT];
- _animVars.set("reactionPointEnabled", enabled);
- _animVars.set("reactionPointDisabled", !enabled);
-
- // trigger animVars
+ // trigger reactions
if (params.reactionTriggers[AVATAR_REACTION_POSITIVE]) {
_animVars.set("reactionPositiveTrigger", true);
} else {
@@ -1940,22 +1920,38 @@ void Rig::updateReactions(const ControllerParameters& params) {
_animVars.set("reactionNegativeTrigger", false);
}
- if (params.reactionTriggers[AVATAR_REACTION_RAISE_HAND]) {
- _animVars.set("reactionRaiseHandTrigger", true);
- } else {
- _animVars.set("reactionRaiseHandTrigger", false);
- }
+ // begin end reactions
+ bool enabled = params.reactionEnabledFlags[AVATAR_REACTION_RAISE_HAND];
+ _animVars.set("reactionRaiseHandEnabled", enabled);
+ _animVars.set("reactionRaiseHandDisabled", !enabled);
- if (params.reactionTriggers[AVATAR_REACTION_APPLAUD]) {
- _animVars.set("reactionApplaudTrigger", true);
- } else {
- _animVars.set("reactionApplaudTrigger", false);
- }
+ enabled = params.reactionEnabledFlags[AVATAR_REACTION_APPLAUD];
+ _animVars.set("reactionApplaudEnabled", enabled);
+ _animVars.set("reactionApplaudDisabled", !enabled);
- if (params.reactionTriggers[AVATAR_REACTION_POINT]) {
- _animVars.set("reactionPointTrigger", true);
- } else {
- _animVars.set("reactionPointTrigger", false);
+ enabled = params.reactionEnabledFlags[AVATAR_REACTION_POINT];
+ _animVars.set("reactionPointEnabled", enabled);
+ _animVars.set("reactionPointDisabled", !enabled);
+
+ // determine if we should ramp off IK
+ if (_enableInverseKinematics) {
+ bool reactionPlaying = false;
+ std::shared_ptr mainStateMachine = std::dynamic_pointer_cast(_animNode->findByName("mainStateMachine"));
+ std::shared_ptr idleStateMachine = std::dynamic_pointer_cast(_animNode->findByName("idle"));
+ if (mainStateMachine && mainStateMachine->getCurrentStateID() == "idle" && idleStateMachine) {
+ reactionPlaying = idleStateMachine->getCurrentStateID().startsWith("reaction");
+ }
+
+ bool isSeated = _state == RigRole::Seated;
+ bool hipsEnabled = params.primaryControllerFlags[PrimaryControllerType_Hips] & (uint8_t)ControllerFlags::Enabled;
+ bool hipsEstimated = params.primaryControllerFlags[PrimaryControllerType_Hips] & (uint8_t)ControllerFlags::Estimated;
+ bool hmdMode = hipsEnabled && !hipsEstimated;
+
+ if ((reactionPlaying || isSeated) && !hmdMode) {
+ // TODO: make this smooth.
+ // disable head IK while reaction is playing, but only in "desktop" mode.
+ _animVars.set("headType", (int)IKTarget::Type::Unknown);
+ }
}
}
@@ -2115,9 +2111,9 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo
_talkIdleInterpTime = 1.0f;
}
float easeOutInValue = _talkIdleInterpTime < 0.5f ? 4.0f * powf(_talkIdleInterpTime, 3.0f) : 4.0f * powf((_talkIdleInterpTime - 1.0f), 3.0f) + 1.0f;
- _animVars.set("idleOverlayAlpha", easeOutInValue);
+ _animVars.set("talkOverlayAlpha", easeOutInValue);
} else {
- _animVars.set("idleOverlayAlpha", 1.0f);
+ _animVars.set("talkOverlayAlpha", 1.0f);
}
} else {
if (_talkIdleInterpTime < 1.0f) {
@@ -2127,9 +2123,9 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo
}
float easeOutInValue = _talkIdleInterpTime < 0.5f ? 4.0f * powf(_talkIdleInterpTime, 3.0f) : 4.0f * powf((_talkIdleInterpTime - 1.0f), 3.0f) + 1.0f;
float talkAlpha = 1.0f - easeOutInValue;
- _animVars.set("idleOverlayAlpha", talkAlpha);
+ _animVars.set("talkOverlayAlpha", talkAlpha);
} else {
- _animVars.set("idleOverlayAlpha", 0.0f);
+ _animVars.set("talkOverlayAlpha", 0.0f);
}
}
diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h
index 7cf17ca391..99794fd0a7 100644
--- a/libraries/animation/src/Rig.h
+++ b/libraries/animation/src/Rig.h
@@ -88,8 +88,8 @@ public:
AnimPose secondaryControllerPoses[NumSecondaryControllerTypes]; // rig space
uint8_t secondaryControllerFlags[NumSecondaryControllerTypes];
bool isTalking;
- bool reactionEnabledFlags[NUM_AVATAR_REACTIONS];
- bool reactionTriggers[NUM_AVATAR_REACTIONS];
+ bool reactionEnabledFlags[NUM_AVATAR_BEGIN_END_REACTIONS];
+ bool reactionTriggers[NUM_AVATAR_TRIGGER_REACTIONS];
HFMJointShapeInfo hipsShapeInfo;
HFMJointShapeInfo spineShapeInfo;
HFMJointShapeInfo spine1ShapeInfo;
diff --git a/libraries/avatars-renderer/src/avatars-renderer/AvatarTransformNode.cpp b/libraries/avatars-renderer/src/avatars-renderer/AvatarTransformNode.cpp
index ca3d4a6062..5770e85e8d 100644
--- a/libraries/avatars-renderer/src/avatars-renderer/AvatarTransformNode.cpp
+++ b/libraries/avatars-renderer/src/avatars-renderer/AvatarTransformNode.cpp
@@ -1,5 +1,5 @@
//
-// Created by Sabrina Shanman 9/5/2018
+// Created by Sabrina Shanman 2018/09/05
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
@@ -10,4 +10,4 @@
template<>
glm::vec3 BaseNestableTransformNode::getActualScale(const std::shared_ptr& nestablePointer) const {
return nestablePointer->scaleForChildren();
-}
\ No newline at end of file
+}
diff --git a/libraries/avatars-renderer/src/avatars-renderer/AvatarTransformNode.h b/libraries/avatars-renderer/src/avatars-renderer/AvatarTransformNode.h
index 183e4ab05c..fcbe63d5ca 100644
--- a/libraries/avatars-renderer/src/avatars-renderer/AvatarTransformNode.h
+++ b/libraries/avatars-renderer/src/avatars-renderer/AvatarTransformNode.h
@@ -1,5 +1,5 @@
//
-// Created by Sabrina Shanman 9/5/2018
+// Created by Sabrina Shanman 2018/09/05
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
@@ -17,4 +17,4 @@ public:
AvatarTransformNode(std::weak_ptr spatiallyNestable, int jointIndex) : BaseNestableTransformNode(spatiallyNestable, jointIndex) {};
};
-#endif // hifi_AvatarTransformNode_h
\ No newline at end of file
+#endif // hifi_AvatarTransformNode_h
diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp
index 22b070464d..7d5f38db40 100755
--- a/libraries/avatars/src/AvatarData.cpp
+++ b/libraries/avatars/src/AvatarData.cpp
@@ -2860,7 +2860,8 @@ glm::vec3 AvatarData::getAbsoluteJointTranslationInObjectFrame(int index) const
/**jsdoc
* Information on an attachment worn by the avatar.
* @typedef {object} AttachmentData
- * @property {string} modelUrl - The URL of the model file. Models can be FBX or OBJ format.
+ * @property {string} modelUrl - The URL of the glTF, FBX, or OBJ model file. glTF models may be in JSON or binary format
+ * (".gltf" or ".glb" URLs respectively).
* @property {string} jointName - The name of the joint that the attachment is parented to.
* @property {Vec3} translation - The offset from the joint that the attachment is positioned at.
* @property {Vec3} rotation - The rotation applied to the model relative to the joint orientation.
diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h
index 3c8e2d6fcc..20c5b1900d 100755
--- a/libraries/avatars/src/AvatarData.h
+++ b/libraries/avatars/src/AvatarData.h
@@ -117,8 +117,7 @@ const int COLLIDE_WITH_OTHER_AVATARS = 11; // 12th bit
const int HAS_HERO_PRIORITY = 12; // 13th bit (be scared)
/**jsdoc
- * The pointing state of the hands is specified by the following values:
-
+ * The pointing state of the hands is specified by the following values:
*
*
* Value | Description |
@@ -1268,12 +1267,11 @@ public:
/**jsdoc
* Attaches a model to your avatar. For example, you can give your avatar a hat to wear, a guitar to hold, or a surfboard to
* stand on.
- * Note: Attached models are models only; they are not entities and can not be manipulated using the {@link Entities} API.
- * Nor can you use this function to attach an entity (such as a sphere or a box) to your avatar.
* @function Avatar.attach
- * @param {string} modelURL - The URL of the model to attach. Models can be .FBX or .OBJ format.
- * @param {string} [jointName=""] - The name of the avatar joint (see {@link MyAvatar.getJointNames} or {@link Avatar.getJointNames}) to attach the model
- * to.
+ * @param {string} modelURL - The URL of the glTF, FBX, or OBJ model to attach. glTF models may be in JSON or binary format
+ * (".gltf" or ".glb" URLs respectively).
+ * @param {string} [jointName=""] - The name of the avatar joint (see {@link MyAvatar.getJointNames} or
+ * {@link Avatar.getJointNames}) to attach the model to.
* @param {Vec3} [translation=Vec3.ZERO] - The offset to apply to the model relative to the joint position.
* @param {Quat} [rotation=Quat.IDENTITY] - The rotation to apply to the model relative to the joint orientation.
* @param {number} [scale=1.0] - The scale to apply to the model.
diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp
index 5cb7b89de5..305384361d 100644
--- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp
+++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp
@@ -1027,6 +1027,10 @@ void EntityTreeRenderer::addingEntity(const EntityItemID& entityID) {
void EntityTreeRenderer::entityScriptChanging(const EntityItemID& entityID, bool reload) {
checkAndCallPreload(entityID, reload, true);
+ // Force "re-checking" entities so that the logic inside `checkEnterLeaveEntities()` is run.
+ // This will ensure that the `enterEntity()` signal is emitted on clients whose avatars
+ // are inside an entity when the script is reloaded.
+ forceRecheckEntities();
}
void EntityTreeRenderer::checkAndCallPreload(const EntityItemID& entityID, bool reload, bool unloadFirst) {
diff --git a/libraries/entities/src/AnimationPropertyGroup.cpp b/libraries/entities/src/AnimationPropertyGroup.cpp
index 7f9225bd6c..38230b4f50 100644
--- a/libraries/entities/src/AnimationPropertyGroup.cpp
+++ b/libraries/entities/src/AnimationPropertyGroup.cpp
@@ -50,8 +50,10 @@ bool operator!=(const AnimationPropertyGroup& a, const AnimationPropertyGroup& b
/**jsdoc
* An animation is configured by the following properties:
* @typedef {object} Entities.AnimationProperties
- * @property {string} url="" - The URL of the FBX file that has the animation.
- * @property {boolean} allowTranslation=true - true
to enable translations contained in the animation to be
+ * @property {string} url="" - The URL of the glTF or FBX file that has the animation. glTF files may be in JSON or binary
+ * format (".gltf" or ".glb" URLs respectively).
+ * Warning: glTF animations currently do not always animate correctly.
+ * @property {boolean} allowTranslation=true - true
to enable translations contained in the animation to be
* played, false
to disable translations.
* @property {number} fps=30 - The speed in frames/s that the animation is played at.
* @property {number} firstFrame=0 - The first frame to play in the animation.
diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp
index 42ce276aca..c16839dc1a 100644
--- a/libraries/entities/src/EntityItemProperties.cpp
+++ b/libraries/entities/src/EntityItemProperties.cpp
@@ -980,8 +980,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
* value is specified then the model is automatically sized to its
* {@link Entities.EntityProperties|naturalDimensions}
.
* @property {string} modelURL="" - The URL of the glTF, FBX, or OBJ model. glTF models may be in JSON or binary format
- * (".gltf" or ".glb" URLs respectively). Baked FBX models' URLs end in ".baked.fbx". Model files may also be compressed in GZ
- * format, in which case the URL ends in ".gz".
+ * (".gltf" or ".glb" URLs respectively). Baked models' URLs have ".baked" before the file type. Model files may also be
+ * compressed in GZ format, in which case the URL ends in ".gz".
* @property {Vec3} modelScale - The scale factor applied to the model's dimensions.
* Deprecated: This property is deprecated and will be removed.
* @property {string} textures="" - A JSON string of texture name, URL pairs used when rendering the model in place of the
@@ -1307,11 +1307,11 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
* @property {number} rightMargin=0.0 - The right margin, in meters.
* @property {number} topMargin=0.0 - The top margin, in meters.
* @property {number} bottomMargin=0.0 - The bottom margin, in meters.
- * @property {boolean} unlit=false - true
if the entity should be unaffected by lighting. Otherwise, the text
- * is lit by the keylight and local lights.
- * @property {string} font="" - The text is rendered with this font. Can be one of the following: Courier
Inconsolata, Roboto
, Timeless
, or a path to a .sdff file.
- * @property {TextEffect} textEffect="none" - The effect that is applied to the text.
+ * @property {boolean} unlit=false - true
if the entity is unaffected by lighting, false
if it is lit
+ * by the key light and local lights.
+ * @property {string} font="" - The font to render the text with. It can be one of the following: "Courier"
"Inconsolata", "Roboto"
, "Timeless"
, or a path to a .sdff file.
+ * @property {Entities.TextEffect} textEffect="none" - The effect that is applied to the text.
* @property {Color} textEffectColor=255,255,255 - The color of the effect.
* @property {number} textEffectThickness=0.2 - The magnitude of the text effect, range 0.0
– 0.5
.
* @property {BillboardMode} billboardMode="none" - Whether the entity is billboarded to face the camera.
diff --git a/libraries/entities/src/EntityTypes.h b/libraries/entities/src/EntityTypes.h
index 8fdc752cac..4106eb8054 100644
--- a/libraries/entities/src/EntityTypes.h
+++ b/libraries/entities/src/EntityTypes.h
@@ -59,7 +59,7 @@ public:
* "Sphere"
. If an entity of type Box
or Shape
has its shape
set
* to "Sphere"
then its type
will be reported as "Sphere"
.
* {@link Entities.EntityProperties-Sphere|EntityProperties-Sphere} |
- * "Model" | A mesh model from a glTf, FBX, or OBJ file. |
+ *
"Model" | A mesh model from a glTF, FBX, or OBJ file. |
* {@link Entities.EntityProperties-Model|EntityProperties-Model} |
* "Text" | A pane of text oriented in space. |
* {@link Entities.EntityProperties-Text|EntityProperties-Text} |
diff --git a/libraries/entities/src/KeyLightPropertyGroup.h b/libraries/entities/src/KeyLightPropertyGroup.h
index facbf88f3c..6441c30d50 100644
--- a/libraries/entities/src/KeyLightPropertyGroup.h
+++ b/libraries/entities/src/KeyLightPropertyGroup.h
@@ -37,10 +37,10 @@ class ReadBitstreamToTreeParams;
* are cast by avatars, plus {@link Entities.EntityProperties-Model|Model} and
* {@link Entities.EntityProperties-Shape|Shape} entities that have their
* {@link Entities.EntityProperties|canCastShadow}
property set to true
.
- * @property {number} shadowBias=0.5 - The bias of the shadows cast by the light. Use this to fine-tune your shadows to your scene
- * to prevent shadow acne and peter panning. In the range 0.0
– 1.0
.
- * @property {number} shadowMaxDistance=40.0 - The max distance from your view at which shadows will be computed. Higher values will
- * cover more of your scene, but with less precision. In the range 1.0
– 250.0
.
+ * @property {number} shadowBias=0.5 - The bias of the shadows cast by the light, range 0.0
–
+ * 1.0
. This fine-tunes shadows cast by the light, to prevent shadow acne and peter panning.
+ * @property {number} shadowMaxDistance=40.0 - The maximum distance from the camera position at which shadows will be computed,
+ * range 1.0
– 250.0
. Higher values cover more of the scene but with less precision.
*/
class KeyLightPropertyGroup : public PropertyGroup {
public:
diff --git a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp
index 404e2d3ac6..45f8461a1a 100644
--- a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp
+++ b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp
@@ -297,10 +297,6 @@ MeshPointer GraphicsScriptingInterface::getMeshPointer(scriptable::ScriptableMes
namespace {
QVector metaTypeIds{
- qRegisterMetaType("uint32"),
- qRegisterMetaType("glm::uint32"),
- qRegisterMetaType>(),
- qRegisterMetaType>("QVector"),
qRegisterMetaType(),
qRegisterMetaType("ScriptableMeshes"),
qRegisterMetaType("scriptable::ScriptableMeshes"),
@@ -532,7 +528,6 @@ namespace scriptable {
}
void GraphicsScriptingInterface::registerMetaTypes(QScriptEngine* engine) {
- qScriptRegisterSequenceMetaType>(engine);
qScriptRegisterSequenceMetaType>(engine);
scriptable::registerQPointerMetaType(engine);
diff --git a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.h b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.h
index 267ba01041..808d3f221f 100644
--- a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.h
+++ b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.h
@@ -19,6 +19,7 @@
#include "ScriptableMesh.h"
#include
+#include "RegisteredMetaTypes.h"
/**jsdoc
@@ -107,8 +108,6 @@ namespace scriptable {
QScriptValue scriptableMaterialToScriptValue(QScriptEngine* engine, const scriptable::ScriptableMaterial &material);
};
-Q_DECLARE_METATYPE(glm::uint32)
-Q_DECLARE_METATYPE(QVector)
Q_DECLARE_METATYPE(NestableType)
#endif // hifi_GraphicsScriptingInterface_h
diff --git a/libraries/material-networking/src/material-networking/MaterialCache.cpp b/libraries/material-networking/src/material-networking/MaterialCache.cpp
index fd218fe074..087e1ca049 100644
--- a/libraries/material-networking/src/material-networking/MaterialCache.cpp
+++ b/libraries/material-networking/src/material-networking/MaterialCache.cpp
@@ -120,7 +120,8 @@ NetworkMaterialResource::ParsedMaterials NetworkMaterialResource::parseJSONMater
* Set to "fallthrough"
to fall through to the material below. "hifi_pbr"
model only.
* @property {number|string} opacity=1.0 - The opacity, range 0.0
– 1.0
.
* Set to "fallthrough"
to fall through to the material below. "hifi_pbr"
model only.
- * @property {boolean|string} unlit=false - true
if the material is not lit, false
if it is.
+ * @property {boolean|string} unlit=false - true
if the material is unaffected by lighting, false
if
+ * it is lit by the key light and local lights.
* Set to "fallthrough"
to fall through to the material below. "hifi_pbr"
model only.
* @property {ColorFloat|RGBS|string} albedo - The albedo color. A {@link ColorFloat} value is treated as sRGB and must have
* component values in the range 0.0
– 1.0
. A {@link RGBS} value can be either RGB or sRGB.
diff --git a/libraries/networking/src/udt/Packet.h b/libraries/networking/src/udt/Packet.h
index cad5cccb0e..36098235f9 100644
--- a/libraries/networking/src/udt/Packet.h
+++ b/libraries/networking/src/udt/Packet.h
@@ -83,6 +83,7 @@ public:
bool isPartOfMessage() const { return _isPartOfMessage; }
bool isReliable() const { return _isReliable; }
+ void setReliable(bool reliable) { _isReliable = reliable; }
ObfuscationLevel getObfuscationLevel() const { return _obfuscationLevel; }
SequenceNumber getSequenceNumber() const { return _sequenceNumber; }
diff --git a/libraries/octree/src/OctreeQueryNode.cpp b/libraries/octree/src/OctreeQueryNode.cpp
index 0c1c108f68..5bce547a34 100644
--- a/libraries/octree/src/OctreeQueryNode.cpp
+++ b/libraries/octree/src/OctreeQueryNode.cpp
@@ -82,7 +82,7 @@ bool OctreeQueryNode::shouldSuppressDuplicatePacket() {
void OctreeQueryNode::init() {
_myPacketType = getMyPacketType();
- _octreePacket = NLPacket::create(getMyPacketType());
+ _octreePacket = NLPacket::create(getMyPacketType(), -1, true);
resetOctreePacket(); // don't bump sequence
}
diff --git a/libraries/octree/src/OctreeSceneStats.h b/libraries/octree/src/OctreeSceneStats.h
index e1228609a6..f78e51081b 100644
--- a/libraries/octree/src/OctreeSceneStats.h
+++ b/libraries/octree/src/OctreeSceneStats.h
@@ -169,7 +169,7 @@ private:
bool _isReadyToSend;
- std::unique_ptr _statsPacket = NLPacket::create(PacketType::OctreeStats);
+ std::unique_ptr _statsPacket = NLPacket::create(PacketType::OctreeStats, -1, true);
// scene timing data in usecs
bool _isStarted;
diff --git a/libraries/platform/src/platform/backend/Platform.cpp b/libraries/platform/src/platform/backend/Platform.cpp
index c3abcce5f1..8b52b9cc29 100644
--- a/libraries/platform/src/platform/backend/Platform.cpp
+++ b/libraries/platform/src/platform/backend/Platform.cpp
@@ -10,19 +10,52 @@
#include "../Platform.h"
#include "../PlatformKeys.h"
+/**jsdoc
+ * Information on the computer platform as a whole.
+ * @typedef {object} PlatformInfo.PlatformDescription
+ * @property {PlatformInfo.ComputerDescription} computer - Information on the computer.
+ * @property {PlatformInfo.CPUDescription[]} cpus - Information on the computer's CPUs.
+ * @property {PlatformInfo.DisplayDescription[]} displays - Information on the computer's displays.
+ * @property {PlatformInfo.GPUDescription[]} gpus - Information on the computer's GPUs.
+ * @property {PlatformInfo.GraphicsAPIDescription[]} graphicsAPIs - Information on the computer's graphics APIs.
+ * @property {PlatformInfo.MemoryDescription} memory - Information on the computer's memory.
+ * @property {PlatformInfo.NICDescription} nics - Information on the computer's network cards.
+ */
namespace platform { namespace keys {
const char* UNKNOWN = "UNKNOWN";
+ /**jsdoc
+ * Information on a CPU.
+ * @typedef {object} PlatformInfo.CPUDescription
+ * @property {string} vendor - The CPU vendor (e.g., "Intel"
or "AMD"
).
+ * @property {string} model - The CPU model.
+ * @property {number} numCores - The number of logical cores.
+ * @property {boolean} isMaster - true
if the CPU is the "master" or primary CPU, false
or
+ * undefined
if it isn't.
+ */
namespace cpu {
const char* vendor = "vendor";
const char* vendor_Intel = "Intel";
const char* vendor_AMD = "AMD";
const char* model = "model";
- const char* clockSpeed = "clockSpeed";
+ const char* clockSpeed = "clockSpeed"; // FIXME: Not used.
const char* numCores = "numCores";
const char* isMaster = "isMaster";
}
+
+ /**jsdoc
+ * Information on a GPU.
+ * @typedef {object} PlatformInfo.GPUDescription
+ * @property {string} vendor - The GPU vendor (e.g., "NVIDIA"
, "AMD"
, or "Intel"
).
+ * @property {string} model - The GPU model.
+ * @property {string} driver - The GPU driver version.
+ * @property {number} videoMemory - The size of the GPU's video memory, in MB.
+ * @property {number[]} displays - The index numbers of the displays currently being driven by the GPU. An empty array if
+ * the GPU is currently not driving any displays.
+ * @property {boolean} isMaster - true
if the GPU is the "master" or primary GPU, false
or
+ * undefined
if it isn't.
+ */
namespace gpu {
const char* vendor = "vendor";
const char* vendor_NVIDIA = "NVIDIA";
@@ -35,6 +68,45 @@ namespace platform { namespace keys {
const char* displays = "displays";
const char* isMaster = "isMaster";
}
+
+ /**jsdoc
+ * Information on a graphics API.
+ * @typedef {object} PlatformInfo.GraphicsAPIDescription
+ * @property {string} name - The name of the graphics API.
+ * @property {string} version - The version of the graphics API.
+ *
+ * @property {string} [renderer] - If an OpenGL API, then the graphics card that performs the rendering.
+ * @property {string} [vendor] - If an OpenGL API, then the OpenGL vendor.
+ * @property {string} [shadingLanguageVersion] - If an OpenGL API, then the shading language version.
+ * @property {string[]} [extensions] - If an OpenGL API, then the list of OpenGL extensions supported.
+ *
+ * @property {PlatformInfo.VulkanAPIDescription[]} [devices] - If a Vulkan API, then the devices provided in the API.
+ */
+ /**jsdoc
+ * Information on a Vulkan graphics API.
+ * @typedef {object} PlatformInfo.VulkanAPIDescription
+ * @property {string}
+ * @property {string} driverVersion - The driver version.
+ * @property {string} apiVersion - The API version.
+ * @property {string} deviceType - The device type.
+ * @property {string} vendor - The device vendor.
+ * @property {string} name - The device name.
+ * @property {string[]} extensions - The list of Vulkan extensions supported.
+ * @property {PlatformInfo.VulkanQueueDescription[]} queues - The Vulkan queues available.
+ * @property {PlatformInfo.VulkanHeapDescription[]} heaps - The Vulkan heaps available.
+ */
+ /**jsdoc
+ * Information on a Vulkan queue.
+ * @typedef {object} PlatformInfo.VulkanQueueDescription
+ * @property {string} flags - The Vulkan queue flags.
+ * @property {number} count - The queue count.
+ */
+ /**jsdoc
+ * Information on a Vulkan heap.
+ * @typedef {object} PlatformInfo.VulkanHeapDescription
+ * @property {string} flags - The Vulkan heap flags.
+ * @property {number} size - The heap size.
+ */
namespace graphicsAPI {
const char* name = "name";
const char* version = "version";
@@ -74,10 +146,38 @@ namespace platform { namespace keys {
}
}
}
+
+ /**jsdoc
+ * Information on a network card.
+ * @typedef {object} PlatformInfo.NICDescription
+ * @property {string} name - The name of the network card.
+ * @property {string} mac - The MAC address of the network card.
+ */
namespace nic {
const char* mac = "mac";
const char* name = "name";
}
+
+ /**jsdoc
+ * Information on a display.
+ * @typedef {object} PlatformInfo.DisplayDescription
+ * @property {string} description - The display's description.
+ * @property {string} deviceName - The display's device name.
+ * @property {number} boundsLeft - The pixel coordinate of the left edge of the display (e.g., 0
).
+ * @property {number} boundsRight - The pixel coordinate of the right edge of the display (e.g., 1920
).
+ * @property {number} boundsTop - The pixel coordinate of the top edge of the display (e.g., 0
).
+ * @property {number} boundsBottom - The pixel coordinate of the bottom edge of the display (e.g., 1080
).
+ * @property {number} gpu - The index number of the GPU that's driving the display.
+ * @property {number} ppi - The physical dots per inch of the display.
+ * @property {number} ppiDesktop - The logical dots per inch of the desktop as used by the operating system.
+ * @property {number} physicalWidth - The physical width of the display, in inches.
+ * @property {number} physicalHeight - The physical height of the display, in inches.
+ * @property {number} modeRefreshrate - The refresh rate of the current display mode, in Hz.
+ * @property {number} modeWidth - The width of the current display mode, in pixels.
+ * @property {number} modeHeight - The height of the current display mode, in pixels.
+ * @property {boolean} isMaster - true
if the GPU is the "master" or primary display, false
or
+ * undefined
if it isn't.
+ */
namespace display {
const char* description = "description";
const char* name = "deviceName";
@@ -95,9 +195,40 @@ namespace platform { namespace keys {
const char* modeHeight = "modeHeight";
const char* isMaster = "isMaster";
}
+
+ /**jsdoc
+ * Information on the computer's memory.
+ * @typedef {object} PlatformInfo.MemoryDescription
+ * @property {number} memTotal - The total amount of usable physical memory, in MB.
+ */
namespace memory {
const char* memTotal = "memTotal";
}
+
+ /**jsdoc
+ * Information on the computer.
+ * @typedef {object} PlatformInfo.ComputerDescription
+ * @property {PlatformInfo.ComputerOS} OS - The operating system.
+ * @property {string} OSversion - The operating system version.
+ * @property {string} vendor - The computer vendor.
+ * @property {string} model - The computer model.
+ * @property {PlatformInfo.PlatformTier} profileTier - The platform tier of the computer, profiled at Interface start-up.
+ */
+ /**jsdoc
+ * The computer operating system.
+ *
+ *
+ * Value | Description |
+ *
+ *
+ * "WINDOWS" | Windows. |
+ * "MACOS" | Mac OS. |
+ * "LINUX" | Linux. |
+ * "ANDROID" | Android. |
+ *
+ *
+ * @typedef {string} PlatformInfo.ComputerOS
+ */
namespace computer {
const char* OS = "OS";
const char* OS_WINDOWS = "WINDOWS";
diff --git a/libraries/pointers/src/Pick.cpp b/libraries/pointers/src/Pick.cpp
index e95721c04b..f6877d40ef 100644
--- a/libraries/pointers/src/Pick.cpp
+++ b/libraries/pointers/src/Pick.cpp
@@ -56,6 +56,14 @@ QVector PickQuery::getIgnoreItems() const {
});
}
+void PickQuery::setScriptParameters(const QVariantMap& parameters) {
+ _scriptParameters = parameters;
+}
+
+QVariantMap PickQuery::getScriptParameters() const {
+ return _scriptParameters;
+}
+
QVector PickQuery::getIncludeItems() const {
return resultWithReadLock>([&] {
return _includeItems;
diff --git a/libraries/pointers/src/Pick.h b/libraries/pointers/src/Pick.h
index 4adb571a5a..e4257140fd 100644
--- a/libraries/pointers/src/Pick.h
+++ b/libraries/pointers/src/Pick.h
@@ -117,7 +117,8 @@ public:
Stylus,
Parabola,
Collision,
- NUM_PICK_TYPES
+ NUM_PICK_TYPES,
+ INVALID_PICK_TYPE = -1
};
Q_ENUM(PickType)
@@ -134,6 +135,7 @@ public:
PickFilter getFilter() const;
float getMaxDistance() const;
bool isEnabled() const;
+ virtual PickType getType() const = 0;
void setPrecisionPicking(bool precisionPicking);
@@ -168,6 +170,27 @@ public:
void setIgnoreItems(const QVector& items);
void setIncludeItems(const QVector& items);
+ virtual QVariantMap toVariantMap() const {
+ QVariantMap properties;
+
+ properties["pickType"] = (int)getType();
+ properties["enabled"] = isEnabled();
+ properties["filter"] = (unsigned int)getFilter()._flags.to_ulong();
+ properties["maxDistance"] = getMaxDistance();
+
+ if (parentTransform) {
+ auto transformNodeProperties = parentTransform->toVariantMap();
+ for (auto it = transformNodeProperties.cbegin(); it != transformNodeProperties.cend(); ++it) {
+ properties[it.key()] = it.value();
+ }
+ }
+
+ return properties;
+ }
+
+ void setScriptParameters(const QVariantMap& parameters);
+ QVariantMap getScriptParameters() const;
+
virtual bool isLeftHand() const { return _jointState == JOINT_STATE_LEFT_HAND; }
virtual bool isRightHand() const { return _jointState == JOINT_STATE_RIGHT_HAND; }
virtual bool isMouse() const { return _jointState == JOINT_STATE_MOUSE; }
@@ -187,6 +210,9 @@ private:
QVector _ignoreItems;
QVector _includeItems;
+ // The parameters used to create this pick when created through a script
+ QVariantMap _scriptParameters;
+
JointState _jointState { JOINT_STATE_NONE };
};
Q_DECLARE_METATYPE(PickQuery::PickType)
@@ -202,6 +228,17 @@ public:
virtual PickResultPointer getAvatarIntersection(const T& pick) = 0;
virtual PickResultPointer getHUDIntersection(const T& pick) = 0;
+ QVariantMap toVariantMap() const override {
+ QVariantMap properties = PickQuery::toVariantMap();
+
+ const QVariantMap mathPickProperties = _mathPick.toVariantMap();
+ for (auto it = mathPickProperties.cbegin(); it != mathPickProperties.cend(); ++it) {
+ properties[it.key()] = it.value();
+ }
+
+ return properties;
+ }
+
protected:
T _mathPick;
};
diff --git a/libraries/pointers/src/PickManager.cpp b/libraries/pointers/src/PickManager.cpp
index aadfbc41a0..cad44b1864 100644
--- a/libraries/pointers/src/PickManager.cpp
+++ b/libraries/pointers/src/PickManager.cpp
@@ -49,6 +49,35 @@ void PickManager::removePick(unsigned int uid) {
});
}
+QVariantMap PickManager::getPickProperties(unsigned int uid) const {
+ auto pick = findPick(uid);
+ if (pick) {
+ return pick->toVariantMap();
+ }
+ return QVariantMap();
+}
+
+QVariantMap PickManager::getPickScriptParameters(unsigned int uid) const {
+ auto pick = findPick(uid);
+ if (pick) {
+ return pick->getScriptParameters();
+ }
+ return QVariantMap();
+}
+
+QVector PickManager::getPicks() const {
+ QVector picks;
+ withReadLock([&] {
+ for (auto typeIt = _picks.cbegin(); typeIt != _picks.cend(); ++typeIt) {
+ auto& picksForType = typeIt->second;
+ for (auto pickIt = picksForType.cbegin(); pickIt != picksForType.cend(); ++pickIt) {
+ picks.push_back(pickIt->first);
+ }
+ }
+ });
+ return picks;
+}
+
PickResultPointer PickManager::getPrevPickResult(unsigned int uid) const {
auto pick = findPick(uid);
if (pick) {
@@ -71,6 +100,14 @@ void PickManager::disablePick(unsigned int uid) const {
}
}
+bool PickManager::isPickEnabled(unsigned int uid) const {
+ auto pick = findPick(uid);
+ if (pick) {
+ return pick->isEnabled();
+ }
+ return false;
+}
+
void PickManager::setPrecisionPicking(unsigned int uid, bool precisionPicking) const {
auto pick = findPick(uid);
if (pick) {
diff --git a/libraries/pointers/src/PickManager.h b/libraries/pointers/src/PickManager.h
index 8f5aa5caf8..79ab6ca2c8 100644
--- a/libraries/pointers/src/PickManager.h
+++ b/libraries/pointers/src/PickManager.h
@@ -31,8 +31,14 @@ public:
void removePick(unsigned int uid);
void enablePick(unsigned int uid) const;
void disablePick(unsigned int uid) const;
+ bool isPickEnabled(unsigned int uid) const;
+ QVector getPicks() const;
PickResultPointer getPrevPickResult(unsigned int uid) const;
+ // The actual current properties of the pick
+ QVariantMap getPickProperties(unsigned int uid) const;
+ // The properties that were passed in to create the pick (may be empty if the pick was created by invoking the constructor)
+ QVariantMap getPickScriptParameters(unsigned int uid) const;
template
std::shared_ptr getPrevPickResultTyped(unsigned int uid) const {
diff --git a/libraries/pointers/src/PickTransformNode.cpp b/libraries/pointers/src/PickTransformNode.cpp
index fe011b7fcd..badc9dccec 100644
--- a/libraries/pointers/src/PickTransformNode.cpp
+++ b/libraries/pointers/src/PickTransformNode.cpp
@@ -1,5 +1,5 @@
//
-// Created by Sabrina Shanman 8/22/2018
+// Created by Sabrina Shanman 2018/08/22
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
@@ -23,4 +23,10 @@ Transform PickTransformNode::getTransform() {
}
return pickManager->getResultTransform(_uid);
-}
\ No newline at end of file
+}
+
+QVariantMap PickTransformNode::toVariantMap() const {
+ QVariantMap map;
+ map["parentID"] = _uid;
+ return map;
+}
diff --git a/libraries/pointers/src/PickTransformNode.h b/libraries/pointers/src/PickTransformNode.h
index b4c92f3ba7..fb8161757b 100644
--- a/libraries/pointers/src/PickTransformNode.h
+++ b/libraries/pointers/src/PickTransformNode.h
@@ -1,5 +1,5 @@
//
-// Created by Sabrina Shanman 8/22/2018
+// Created by Sabrina Shanman 2018/08/22
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
@@ -15,9 +15,10 @@ class PickTransformNode : public TransformNode {
public:
PickTransformNode(unsigned int uid);
Transform getTransform() override;
+ QVariantMap toVariantMap() const override;
protected:
unsigned int _uid;
};
-#endif // hifi_PickTransformNode_h
\ No newline at end of file
+#endif // hifi_PickTransformNode_h
diff --git a/libraries/pointers/src/Pointer.cpp b/libraries/pointers/src/Pointer.cpp
index c08a3c2be6..f435482865 100644
--- a/libraries/pointers/src/Pointer.cpp
+++ b/libraries/pointers/src/Pointer.cpp
@@ -36,10 +36,32 @@ void Pointer::disable() {
DependencyManager::get()->disablePick(_pickUID);
}
+bool Pointer::isEnabled() {
+ return _enabled;
+}
+
PickResultPointer Pointer::getPrevPickResult() {
return DependencyManager::get()->getPrevPickResult(_pickUID);
}
+QVariantMap Pointer::toVariantMap() const {
+ QVariantMap qVariantMap = DependencyManager::get()->getPickProperties(_pickUID);
+
+ qVariantMap["pointerType"] = getType();
+ qVariantMap["pickID"] = _pickUID;
+ qVariantMap["hover"] = _hover;
+
+ return qVariantMap;
+}
+
+void Pointer::setScriptParameters(const QVariantMap& scriptParameters) {
+ _scriptParameters = scriptParameters;
+}
+
+QVariantMap Pointer::getScriptParameters() const {
+ return _scriptParameters;
+}
+
void Pointer::setPrecisionPicking(bool precisionPicking) {
DependencyManager::get()->setPrecisionPicking(_pickUID, precisionPicking);
}
diff --git a/libraries/pointers/src/Pointer.h b/libraries/pointers/src/Pointer.h
index 28d7e42e8f..7a7c51477a 100644
--- a/libraries/pointers/src/Pointer.h
+++ b/libraries/pointers/src/Pointer.h
@@ -45,12 +45,16 @@ public:
virtual void enable();
virtual void disable();
+ virtual bool isEnabled();
+ virtual PickQuery::PickType getType() const = 0;
virtual PickResultPointer getPrevPickResult();
virtual void setRenderState(const std::string& state) = 0;
virtual void editRenderState(const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) = 0;
- virtual QVariantMap toVariantMap() const = 0;
+ virtual QVariantMap toVariantMap() const;
+ virtual void setScriptParameters(const QVariantMap& scriptParameters);
+ virtual QVariantMap getScriptParameters() const;
virtual void setPrecisionPicking(bool precisionPicking);
virtual void setIgnoreItems(const QVector& ignoreItems) const;
@@ -84,6 +88,9 @@ protected:
bool _enabled;
bool _hover;
+ // The parameters used to create this pointer when created through a script
+ QVariantMap _scriptParameters;
+
virtual PointerEvent buildPointerEvent(const PickedObject& target, const PickResultPointer& pickResult, const std::string& button = "", bool hover = true) = 0;
virtual PickedObject getHoveredObject(const PickResultPointer& pickResult) = 0;
diff --git a/libraries/pointers/src/PointerManager.cpp b/libraries/pointers/src/PointerManager.cpp
index ca8dfb3f26..de403a46e8 100644
--- a/libraries/pointers/src/PointerManager.cpp
+++ b/libraries/pointers/src/PointerManager.cpp
@@ -54,6 +54,24 @@ void PointerManager::disablePointer(unsigned int uid) const {
}
}
+bool PointerManager::isPointerEnabled(unsigned int uid) const {
+ auto pointer = find(uid);
+ if (pointer) {
+ return pointer->isEnabled();
+ }
+ return false;
+}
+
+QVector PointerManager::getPointers() const {
+ QVector pointers;
+ withReadLock([&] {
+ for (auto it = _pointers.cbegin(); it != _pointers.cend(); ++it) {
+ pointers.push_back(it->first);
+ }
+ });
+ return pointers;
+}
+
void PointerManager::setRenderState(unsigned int uid, const std::string& renderState) const {
auto pointer = find(uid);
if (pointer) {
@@ -86,6 +104,14 @@ QVariantMap PointerManager::getPointerProperties(unsigned int uid) const {
}
}
+QVariantMap PointerManager::getPointerScriptParameters(unsigned int uid) const {
+ auto pointer = find(uid);
+ if (pointer) {
+ return pointer->getScriptParameters();
+ }
+ return QVariantMap();
+}
+
void PointerManager::update() {
auto cachedPointers = resultWithReadLock>>([&] {
return _pointers;
diff --git a/libraries/pointers/src/PointerManager.h b/libraries/pointers/src/PointerManager.h
index 6c1581b09b..609f944101 100644
--- a/libraries/pointers/src/PointerManager.h
+++ b/libraries/pointers/src/PointerManager.h
@@ -27,10 +27,17 @@ public:
void removePointer(unsigned int uid);
void enablePointer(unsigned int uid) const;
void disablePointer(unsigned int uid) const;
+ bool isPointerEnabled(unsigned int uid) const;
+ QVector getPointers() const;
+
void setRenderState(unsigned int uid, const std::string& renderState) const;
void editRenderState(unsigned int uid, const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) const;
+
PickResultPointer getPrevPickResult(unsigned int uid) const;
+ // The actual current properties of the pointer
QVariantMap getPointerProperties(unsigned int uid) const;
+ // The properties that were passed in to create the pointer (may be empty if the pointer was created by invoking the constructor)
+ QVariantMap getPointerScriptParameters(unsigned int uid) const;
void setPrecisionPicking(unsigned int uid, bool precisionPicking) const;
void setIgnoreItems(unsigned int uid, const QVector& ignoreEntities) const;
diff --git a/libraries/shared/src/AvatarConstants.h b/libraries/shared/src/AvatarConstants.h
index c4a8b91ed5..a955e0f0c3 100644
--- a/libraries/shared/src/AvatarConstants.h
+++ b/libraries/shared/src/AvatarConstants.h
@@ -106,13 +106,17 @@ static const float AVATAR_WALK_SPEED_SCALAR = 1.0f;
static const float AVATAR_DESKTOP_SPRINT_SPEED_SCALAR = 3.0f;
static const float AVATAR_HMD_SPRINT_SPEED_SCALAR = 2.0f;
-enum AvatarReaction {
+enum AvatarTriggerReaction {
AVATAR_REACTION_POSITIVE = 0,
AVATAR_REACTION_NEGATIVE,
+ NUM_AVATAR_TRIGGER_REACTIONS
+};
+
+enum AvatarBeginEndReaction {
AVATAR_REACTION_RAISE_HAND,
AVATAR_REACTION_APPLAUD,
AVATAR_REACTION_POINT,
- NUM_AVATAR_REACTIONS
+ NUM_AVATAR_BEGIN_END_REACTIONS
};
#endif // hifi_AvatarConstants_h
diff --git a/libraries/shared/src/DebugDraw.h b/libraries/shared/src/DebugDraw.h
index 785e549c03..9e3140ca9b 100644
--- a/libraries/shared/src/DebugDraw.h
+++ b/libraries/shared/src/DebugDraw.h
@@ -22,8 +22,9 @@
#include
/**jsdoc
- * Helper functions to render ephemeral debug markers and lines.
- * DebugDraw markers and lines are only visible locally, they are not visible by other users.
+ * The DebugDraw
API renders debug markers and lines. These markers are only visible locally; they are not visible
+ * to other users.
+ *
* @namespace DebugDraw
*
* @hifi-interface
@@ -41,57 +42,107 @@ public:
~DebugDraw();
/**jsdoc
- * Draws a line in world space, but it will only be visible for a single frame.
+ * Draws a line in world space, visible for a single frame. To make the line visually persist, you need to repeatedly draw
+ * it.
* @function DebugDraw.drawRay
- * @param {Vec3} start - start position of line in world space.
- * @param {Vec3} end - end position of line in world space.
- * @param {Vec4} color - color of line, each component should be in the zero to one range. x = red, y = blue, z = green, w = alpha.
+ * @param {Vec3} start - The start position of the line, in world coordinates.
+ * @param {Vec3} end - The end position of the line, in world coordinates.
+ * @param {Vec4} color - The color of the line. Each component should be in the range 0.0
–
+ * 1.0
, with x
= red, y
= green, z
= blue, and w
= alpha.
+ * @example Draw a red ray from your initial avatar position to 10m in front of it.
+ * var start = MyAvatar.position;
+ * var end = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -10 }));
+ * var color = { x: 1.0, y: 0.0, z: 0.0, w: 1.0 };
+ *
+ * Script.update.connect(function () {
+ * DebugDraw.drawRay(start, end, color);
+ * });
*/
Q_INVOKABLE void drawRay(const glm::vec3& start, const glm::vec3& end, const glm::vec4& color);
/**jsdoc
- * Draws a line in world space, but it will only be visible for a single frame.
- * @function DebugDraw.drawRay
- * @param {Vec3} start - start position of line in world space.
- * @param {Vec3} end - end position of line in world space.
- * @param {Vec4} color - color of line, each component should be in the zero to one range. x = red, y = blue, z = green, w = alpha.
- */
+ * Draws lines in world space, visible for a single frame. To make the lines visually persist, you need to repeatedly draw
+ * them.
+ * Note: Currently doesn't work.
+ * @function DebugDraw.drawRays
+ * @param {Vec3Pair[]} lines - The start and end points of the lines to draw.
+ * @param {Vec4} color - The color of the lines. Each component should be in the range 0.0
–
+ * 1.0
, with x
= red, y
= green, z
= blue, and w
= alpha.
+ * @param {Vec3} [translation=0,0,0] - A translation applied to each line.
+ * @param {Quat} [rotation=Quat.IDENTITY] - A rotation applied to each line.
+ * @example
Draw a red "V" in front of your initial avatar position.
+ * var lines = [
+ * [{ x: -1, y: 0.5, z: 0 }, { x: 0, y: 0, z: 0 }],
+ * [{ x: 0, y: 0, z: 0 }, { x: 1, y: 0.5, z: 0 }]
+ * ];
+ * var color = { x: 1, y: 0, z: 0, w: 1 };
+ * var translation = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0.75, z: -5 }));
+ * var rotation = MyAvatar.orientation;
+ *
+ * Script.update.connect(function () {
+ * DebugDraw.drawRays(lines, color, translation, rotation);
+ * });
+ */
Q_INVOKABLE void drawRays(const std::vector>& lines, const glm::vec4& color,
const glm::vec3& translation = glm::vec3(0.0f, 0.0f, 0.0f), const glm::quat& rotation = glm::quat(1.0f, 0.0f, 0.0f, 0.0f));
/**jsdoc
- * Adds a debug marker to the world. This marker will be drawn every frame until it is removed with DebugDraw.removeMarker.
- * This can be called repeatedly to change the position of the marker.
+ * Adds or updates a debug marker in world coordinates. This marker is drawn every frame until it is removed using
+ * {@link DebugDraw.removeMarker|removeMarker}. If a world coordinates debug marker of the specified name
+ * already exists, its parameters are updated.
* @function DebugDraw.addMarker
- * @param {string} key - name to uniquely identify this marker, later used for DebugDraw.removeMarker.
- * @param {Quat} rotation - start position of line in world space.
- * @param {Vec3} position - position of the marker in world space.
- * @param {Vec4} color - color of the marker.
+ * @param {string} key - A name that uniquely identifies the marker.
+ * @param {Quat} rotation - The orientation of the marker in world coordinates.
+ * @param {Vec3} position - The position of the market in world coordinates.
+ * @param {Vec4} color - The color of the marker.
+ * @example Briefly draw a debug marker in front of your avatar, in world coordinates.
+ * var MARKER_NAME = "my marker";
+ * DebugDraw.addMarker(
+ * MARKER_NAME,
+ * Quat.ZERO,
+ * Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5})),
+ * { red: 255, green: 0, blue: 0 }
+ * );
+ * Script.setTimeout(function () {
+ * DebugDraw.removeMarker(MARKER_NAME);
+ * }, 5000);
*/
Q_INVOKABLE void addMarker(const QString& key, const glm::quat& rotation, const glm::vec3& position, const glm::vec4& color);
/**jsdoc
- * Removes debug marker from the world. Once a marker is removed, it will no longer be visible.
+ * Removes a debug marker that was added in world coordinates.
* @function DebugDraw.removeMarker
- * @param {string} key - name of marker to remove.
+ * @param {string} key - The name of the world coordinates debug marker to remove.
*/
Q_INVOKABLE void removeMarker(const QString& key);
/**jsdoc
- * Adds a debug marker to the world, this marker will be drawn every frame until it is removed with DebugDraw.removeMyAvatarMarker.
- * This can be called repeatedly to change the position of the marker.
+ * Adds or updates a debug marker to the world in avatar coordinates. This marker is drawn every frame until it is removed
+ * using {@link DebugDraw.removeMyAvatarMarker|removeMyAvatarMarker}. If an avatar coordinates debug marker of the
+ * specified name
already exists, its parameters are updated. The debug marker moves with your avatar.
* @function DebugDraw.addMyAvatarMarker
- * @param {string} key - name to uniquely identify this marker, later used for DebugDraw.removeMyAvatarMarker.
- * @param {Quat} rotation - start position of line in avatar space.
- * @param {Vec3} position - position of the marker in avatar space.
+ * @param {string} key - A name that uniquely identifies the marker.
+ * @param {Quat} rotation - The orientation of the marker in avatar coordinates.
+ * @param {Vec3} position - The position of the market in avatar coordinates.
* @param {Vec4} color - color of the marker.
+ * @example Briefly draw a debug marker in front of your avatar, in avatar coordinates.
+ * var MARKER_NAME = "My avatar marker";
+ * DebugDraw.addMyAvatarMarker(
+ * MARKER_NAME,
+ * Quat.ZERO,
+ * { x: 0, y: 0, z: -5 },
+ * { red: 255, green: 0, blue: 0 }
+ * );
+ * Script.setTimeout(function () {
+ * DebugDraw.removeMyAvatarMarker(MARKER_NAME);
+ * }, 5000);
*/
Q_INVOKABLE void addMyAvatarMarker(const QString& key, const glm::quat& rotation, const glm::vec3& position, const glm::vec4& color);
/**jsdoc
- * Removes debug marker from the world. Once a marker is removed, it will no longer be visible
+ * Removes a debug marker that was added in avatar coordinates.
* @function DebugDraw.removeMyAvatarMarker
- * @param {string} key - name of marker to remove.
+ * @param {string} key - The name of the avatar coordinates debug marker to remove.
*/
Q_INVOKABLE void removeMyAvatarMarker(const QString& key);
diff --git a/libraries/shared/src/NestableTransformNode.cpp b/libraries/shared/src/NestableTransformNode.cpp
index 9723f388f6..464037dbe5 100644
--- a/libraries/shared/src/NestableTransformNode.cpp
+++ b/libraries/shared/src/NestableTransformNode.cpp
@@ -1,5 +1,5 @@
//
-// Created by Sabrina Shanman 8/14/2018
+// Created by Sabrina Shanman 2018/08/14
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
@@ -11,4 +11,4 @@
template<>
glm::vec3 BaseNestableTransformNode::getActualScale(const std::shared_ptr& nestablePointer) const {
return nestablePointer->getAbsoluteJointScaleInObjectFrame(_jointIndex);
-}
\ No newline at end of file
+}
diff --git a/libraries/shared/src/NestableTransformNode.h b/libraries/shared/src/NestableTransformNode.h
index f70d158c91..4267ca5541 100644
--- a/libraries/shared/src/NestableTransformNode.h
+++ b/libraries/shared/src/NestableTransformNode.h
@@ -1,5 +1,5 @@
//
-// Created by Sabrina Shanman 8/14/2018
+// Created by Sabrina Shanman 2018/08/14
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
@@ -12,6 +12,8 @@
#include "SpatiallyNestable.h"
+#include "RegisteredMetaTypes.h"
+
template
class BaseNestableTransformNode : public TransformNode {
public:
@@ -45,6 +47,19 @@ public:
return jointWorldTransform;
}
+ QVariantMap toVariantMap() const override {
+ QVariantMap map;
+
+ auto nestable = _spatiallyNestable.lock();
+ if (nestable) {
+ map["parentID"] = nestable->getID();
+ map["parentJointIndex"] = _jointIndex;
+ map["baseParentScale"] = vec3toVariant(_baseScale);
+ }
+
+ return map;
+ }
+
glm::vec3 getActualScale(const std::shared_ptr& nestablePointer) const;
protected:
diff --git a/libraries/shared/src/RegisteredMetaTypes.cpp b/libraries/shared/src/RegisteredMetaTypes.cpp
index e23064c8a0..87cd269c97 100644
--- a/libraries/shared/src/RegisteredMetaTypes.cpp
+++ b/libraries/shared/src/RegisteredMetaTypes.cpp
@@ -26,6 +26,8 @@
#include
#include
+int uint32MetaTypeId = qRegisterMetaType("uint32");
+int glmUint32MetaTypeId = qRegisterMetaType("glm::uint32");
int vec2MetaTypeId = qRegisterMetaType();
int u8vec3MetaTypeId = qRegisterMetaType();
int vec3MetaTypeId = qRegisterMetaType();
@@ -33,6 +35,7 @@ int vec4MetaTypeId = qRegisterMetaType();
int qVectorVec3MetaTypeId = qRegisterMetaType>();
int qVectorQuatMetaTypeId = qRegisterMetaType>();
int qVectorBoolMetaTypeId = qRegisterMetaType>();
+int qVectorGLMUint32MetaTypeId = qRegisterMetaType>("QVector");
int quatMetaTypeId = qRegisterMetaType();
int pickRayMetaTypeId = qRegisterMetaType();
int collisionMetaTypeId = qRegisterMetaType();
@@ -67,6 +70,8 @@ void registerMetaTypes(QScriptEngine* engine) {
qScriptRegisterMetaType(engine, aaCubeToScriptValue, aaCubeFromScriptValue);
qScriptRegisterMetaType(engine, stencilMaskModeToScriptValue, stencilMaskModeFromScriptValue);
+
+ qScriptRegisterSequenceMetaType>(engine);
}
QScriptValue vec2ToScriptValue(QScriptEngine* engine, const glm::vec2& vec2) {
@@ -1229,8 +1234,10 @@ AnimationDetails::AnimationDetails(QString role, QUrl url, float fps, float prio
* The details of an animation that is playing.
* @typedef {object} Avatar.AnimationDetails
* @property {string} role - Not used.
- * @property {string} url - The URL to the animation file. Animation files need to be in .FBX format but only need to contain
-* the avatar skeleton and animation data.
+ * @property {string} url - The URL to the animation file. Animation files need to be in glTF or FBX format but only need to
+ * contain the avatar skeleton and animation data. glTF models may be in JSON or binary format (".gltf" or ".glb" URLs
+ * respectively).
+ * Warning: glTF animations currently do not always animate correctly.
* @property {number} fps - The frames per second(FPS) rate for the animation playback. 30 FPS is normal speed.
* @property {number} priority - Not used.
* @property {boolean} loop - true
if the animation should loop, false
if it shouldn't.
diff --git a/libraries/shared/src/RegisteredMetaTypes.h b/libraries/shared/src/RegisteredMetaTypes.h
index 5b8aa34fd9..3b47bb70c6 100644
--- a/libraries/shared/src/RegisteredMetaTypes.h
+++ b/libraries/shared/src/RegisteredMetaTypes.h
@@ -37,6 +37,8 @@ Q_DECLARE_METATYPE(glm::vec4)
Q_DECLARE_METATYPE(glm::quat)
Q_DECLARE_METATYPE(glm::mat4)
Q_DECLARE_METATYPE(QVector)
+Q_DECLARE_METATYPE(unsigned int)
+Q_DECLARE_METATYPE(QVector)
Q_DECLARE_METATYPE(AACube)
Q_DECLARE_METATYPE(std::function);
Q_DECLARE_METATYPE(std::function);
diff --git a/libraries/shared/src/TransformNode.h b/libraries/shared/src/TransformNode.h
index c9340bddf0..530218db98 100644
--- a/libraries/shared/src/TransformNode.h
+++ b/libraries/shared/src/TransformNode.h
@@ -1,5 +1,5 @@
//
-// Created by Sabrina Shanman 8/14/2018
+// Created by Sabrina Shanman 2018/08/14
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
@@ -8,6 +8,8 @@
#ifndef hifi_TransformNode_h
#define hifi_TransformNode_h
+#include
+
#include "Transform.h"
class TransformNode {
@@ -15,6 +17,7 @@ public:
virtual ~TransformNode() = default;
virtual Transform getTransform() = 0;
+ virtual QVariantMap toVariantMap() const = 0;
};
#endif // hifi_TransformNode_h
diff --git a/libraries/task/src/task/Config.h b/libraries/task/src/task/Config.h
index 8c674da31c..ba17c7418c 100644
--- a/libraries/task/src/task/Config.h
+++ b/libraries/task/src/task/Config.h
@@ -121,14 +121,14 @@ public:
virtual void setPresetList(const QJsonObject& object);
/**jsdoc
- * @function Render.toJSON
+ * @function Workload.toJSON
* @returns {string}
*/
// This must be named toJSON to integrate with the global scripting JSON object
Q_INVOKABLE QString toJSON() { return QJsonDocument(toJsonValue(*this).toObject()).toJson(QJsonDocument::Compact); }
/**jsdoc
- * @function Render.load
+ * @function Workload.load
* @param {object} map
*/
Q_INVOKABLE void load(const QVariantMap& map) { qObjectFromJsonValue(QJsonObject::fromVariantMap(map), *this); emit loaded(); }
@@ -181,25 +181,25 @@ public:
// Describe the node graph data connections of the associated Job/Task
/**jsdoc
- * @function Render.isTask
+ * @function Workload.isTask
* @returns {boolean}
*/
//Q_INVOKABLE virtual bool isTask() const { return false; }
/**jsdoc
- * @function Render.getSubConfigs
+ * @function Workload.getSubConfigs
* @returns {object[]}
*/
// Q_INVOKABLE virtual QObjectList getSubConfigs() const { return QObjectList(); }
/**jsdoc
- * @function Render.getNumSubs
+ * @function Workload.getNumSubs
* @returns {number}
*/
// Q_INVOKABLE virtual int getNumSubs() const { return 0; }
/**jsdoc
- * @function Render.getSubConfig
+ * @function Workload.getSubConfig
* @param {number} index
* @returns {object}
*/
@@ -216,32 +216,32 @@ public:
public slots:
/**jsdoc
- * @function Render.load
+ * @function Workload.load
* @param {object} map
*/
void load(const QJsonObject& val) { qObjectFromJsonValue(val, *this); emit loaded(); }
/**jsdoc
- * @function Render.refresh
+ * @function Workload.refresh
*/
void refresh();
signals:
/**jsdoc
- * @function Render.loaded
+ * @function Workload.loaded
* @returns {Signal}
*/
void loaded();
/**jsdoc
- * @function Render.newStats
+ * @function Workload.newStats
* @returns {Signal}
*/
void newStats();
/**jsdoc
- * @function Render.dirtyEnabled
+ * @function Workload.dirtyEnabled
* @returns {Signal}
*/
void dirtyEnabled();
@@ -253,7 +253,7 @@ using QConfigPointer = std::shared_ptr;
#ifdef SPECIALIZE_CONFIG
/**jsdoc
- * @namespace Render
+ * @namespace Workload
*
* @hifi-interface
* @hifi-client-entity
@@ -272,7 +272,7 @@ public:
TaskConfig(bool enabled) : JobConfig(enabled) {}
/**jsdoc
- * @function Render.getConfig
+ * @function Workload.getConfig
* @param {string} name
* @returns {object}
*/
diff --git a/tools/jsdoc/plugins/hifi.js b/tools/jsdoc/plugins/hifi.js
index a7c62cfc6d..67dafe5a16 100644
--- a/tools/jsdoc/plugins/hifi.js
+++ b/tools/jsdoc/plugins/hifi.js
@@ -56,6 +56,7 @@ exports.handlers = {
'../../libraries/networking/src',
'../../libraries/octree/src',
'../../libraries/physics/src',
+ '../../libraries/platform/src/platform/backend',
'../../libraries/plugins/src/plugins',
'../../libraries/pointers/src',
'../../libraries/render-utils/src',