diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h
index 6f82c7dfb9..c74670bbed 100644
--- a/interface/src/avatar/MyAvatar.h
+++ b/interface/src/avatar/MyAvatar.h
@@ -55,68 +55,108 @@ class MyAvatar : public Avatar {
Q_OBJECT
/**jsdoc
- * Your avatar is your in-world representation of you. The MyAvatar API is used to manipulate the avatar.
- * For example, using the MyAvatar API you can customize the avatar's appearance, run custom avatar animations,
+ * Your avatar is your in-world representation of you. The MyAvatar
API is used to manipulate the avatar.
+ * For example, you can customize the avatar's appearance, run custom avatar animations,
* change the avatar's position within the domain, or manage the avatar's collisions with other objects.
- * NOTE: MyAvatar extends Avatar and AvatarData, see those namespace for more properties/methods.
*
* @namespace MyAvatar
- * @augments Avatar
- * @property qmlPosition {Vec3} Used as a stopgap for position access by QML, as glm::vec3 is unavailable outside of scripts
- * @property shouldRenderLocally {bool} Set it to true if you would like to see MyAvatar in your local interface,
- * and false if you would not like to see MyAvatar in your local interface.
+ * @property qmlPosition {Vec3} Used as a stopgap for position access by QML, as Vec3 is unavailable outside of scripts.
+ * @property shouldRenderLocally {boolean} Set it to true if you would like to see MyAvatar in your local interface,
+ * and false if you would not like to see MyAvatar in your local interface.
* @property motorVelocity {Vec3} Can be used to move the avatar with this velocity.
- * @property motorTimescale {float} Specifies how quickly the avatar should accelerate to meet the motorVelocity,
- * smaller values will result in higher acceleration.
- * @property motorReferenceFrame {string} Reference frame of the motorVelocity, must be one of the following: "avatar", "camera", "world"
- * @property motorMode {string} Type of scripted motor behavior, "simple" = use motorTimescale property (default mode) and "dynamic" = use action motor's timescales
+ * @property motorTimescale {number} Specifies how quickly the avatar should accelerate to meet the motorVelocity,
+ * smaller values will result in higher acceleration.
+ * @property motorReferenceFrame {string} Reference frame of the motorVelocity, must be one of the following: "avatar",
+ * "camera", "world".
+ * @property motorMode {string} Type of scripted motor behavior, "simple" = use motorTimescale property (default mode) and
+ * "dynamic" = use action motor's timescales.
* @property collisionSoundURL {string} Specifies the sound to play when the avatar experiences a collision.
- * You can provide a mono or stereo 16-bit WAV file running at either 24 Khz or 48 Khz.
- * The latter is downsampled by the audio mixer, so all audio effectively plays back at a 24 Khz sample rate.
- * 48 Khz RAW files are also supported.
+ * You can provide a mono or stereo 16-bit WAV file running at either 24 Khz or 48 Khz.
+ * The latter is downsampled by the audio mixer, so all audio effectively plays back at a 24 Khz sample rate.
+ * 48 Khz RAW files are also supported.
* @property audioListenerMode {number} When hearing spatialized audio this determines where the listener placed.
- * Should be one of the following values:
- * MyAvatar.audioListenerModeHead - the listener located at the avatar's head.
- * MyAvatar.audioListenerModeCamera - the listener is relative to the camera.
- * MyAvatar.audioListenerModeCustom - the listener is at a custom location specified by the MyAvatar.customListenPosition
- * and MyAvatar.customListenOrientation properties.
- * @property customListenPosition {Vec3} If MyAvatar.audioListenerMode == MyAvatar.audioListenerModeHead, then this determines the position
- * of audio spatialization listener.
- * @property customListenOrientation {Quat} If MyAvatar.audioListenerMode == MyAvatar.audioListenerModeHead, then this determines the orientation
- * of the audio spatialization listener.
- * @property audioListenerModeHead {number} READ-ONLY. When passed to MyAvatar.audioListenerMode, it will set the audio listener
- * around the avatar's head.
- * @property audioListenerModeCamera {number} READ-ONLY. When passed to MyAvatar.audioListenerMode, it will set the audio listener
- * around the camera.
- * @property audioListenerModeCustom {number} READ-ONLY. When passed to MyAvatar.audioListenerMode, it will set the audio listener
- * around the value specified by MyAvatar.customListenPosition and MyAvatar.customListenOrientation.
- * @property leftHandPosition {Vec3} READ-ONLY. The desired position of the left wrist in avatar space, determined by the hand controllers.
- * Note: only valid if hand controllers are in use.
- * @property rightHandPosition {Vec3} READ-ONLY. The desired position of the right wrist in avatar space, determined by the hand controllers.
- * Note: only valid if hand controllers are in use.
- * @property leftHandTipPosition {Vec3} READ-ONLY. A position 30 cm offset from MyAvatar.leftHandPosition
- * @property rightHandTipPosition {Vec3} READ-ONLY. A position 30 cm offset from MyAvatar.rightHandPosition
- * @property leftHandPose {Pose} READ-ONLY. Returns full pose (translation, orientation, velocity & angularVelocity) of the desired
- * wrist position, determined by the hand controllers.
- * @property rightHandPose {Pose} READ-ONLY. Returns full pose (translation, orientation, velocity & angularVelocity) of the desired
- * wrist position, determined by the hand controllers.
- * @property leftHandTipPose {Pose} READ-ONLY. Returns a pose offset 30 cm from MyAvatar.leftHandPose
- * @property rightHandTipPose {Pose} READ-ONLY. Returns a pose offset 30 cm from MyAvatar.rightHandPose
- * @property hmdLeanRecenterEnabled {bool} This can be used disable the hmd lean recenter behavior. This behavior is what causes your avatar
- * to follow your HMD as you walk around the room, in room scale VR. Disabling this is useful if you desire to pin the avatar to a fixed location.
- * @property collisionsEnabled {bool} This can be used to disable collisions between the avatar and the world.
- * @property useAdvancedMovementControls {bool} Stores the user preference only, does not change user mappings, this is done in the defaultScript
- * "scripts/system/controllers/toggleAdvancedMovementForHandControllers.js".
- * @property userHeight {number} The height of the user in sensor space. (meters).
- * @property userEyeHeight {number} Estimated height of the users eyes in sensor space. (meters)
- * @property SELF_ID {string} READ-ONLY. UUID representing "my avatar". Only use for local-only entities and overlays in situations where MyAvatar.sessionUUID is not available (e.g., if not connected to a domain).
- * Note: Likely to be deprecated.
- * @property hmdRollControlEnabled {bool} When enabled the roll angle of your HMD will turn your avatar while flying.
- * @property hmdRollControlDeadZone {number} If hmdRollControlEnabled is true, this value can be used to tune what roll angle is required to begin turning.
- * This angle is specified in degrees.
- * @property hmdRollControlRate {number} If hmdRollControlEnabled is true, this value determines the maximum turn rate of your avatar when rolling your HMD in degrees per second.
+ * Should be one of the following values:
+ * MyAvatar.audioListenerModeHead - the listener located at the avatar's head.
+ * MyAvatar.audioListenerModeCamera - the listener is relative to the camera.
+ * MyAvatar.audioListenerModeCustom - the listener is at a custom location specified by the
+ * MyAvatar.customListenPosition and MyAvatar.customListenOrientation properties.
+ * @property customListenPosition {Vec3} If MyAvatar.audioListenerMode == MyAvatar.audioListenerModeHead, then this
+ * determines the position of audio spatialization listener.
+ * @property customListenOrientation {Quat} If MyAvatar.audioListenerMode == MyAvatar.audioListenerModeHead, then this
+ * determines the orientation of the audio spatialization listener.
+ * @property audioListenerModeHead {number} When passed to MyAvatar.audioListenerMode, it will set the audio listener
+ * around the avatar's head. Read-only.
+ * @property audioListenerModeCamera {number} When passed to MyAvatar.audioListenerMode, it will set the audio listener
+ * around the camera. Read-only.
+ * @property audioListenerModeCustom {number} When passed to MyAvatar.audioListenerMode, it will set the audio listener
+ * around the value specified by MyAvatar.customListenPosition and MyAvatar.customListenOrientation. Read-only.
+ * @property leftHandPosition {Vec3} The desired position of the left wrist in avatar space, determined by the hand
+ * controllers. Note: only valid if hand controllers are in use. Read-only.
+ * @property rightHandPosition {Vec3} The desired position of the right wrist in avatar space, determined by the hand
+ * controllers. Note: only valid if hand controllers are in use. Read-only.
+ * F@property leftHandTipPosition {Vec3} A position 30 cm offset from MyAvatar.leftHandPosition. Read-only.
+ * @property rightHandTipPosition {Vec3} A position 30 cm offset from MyAvatar.rightHandPosition. Read-only.
+ * @property leftHandPose {Pose} Returns full pose (translation, orientation, velocity & angularVelocity) of the desired
+ * wrist position, determined by the hand controllers. Read-only.
+ * @property rightHandPose {Pose} Returns full pose (translation, orientation, velocity & angularVelocity) of the desired
+ * wrist position, determined by the hand controllers. Read-only.
+ * @property leftHandTipPose {Pose} Returns a pose offset 30 cm from MyAvatar.leftHandPose. Read-only.
+ * @property rightHandTipPose {Pose} Returns a pose offset 30 cm from MyAvatar.rightHandPose. Read-only.
+ * @property hmdLeanRecenterEnabled {boolean} This can be used disable the hmd lean recenter behavior. This behavior is
+ * what causes your avatar to follow your HMD as you walk around the room, in room scale VR. Disabling this is useful
+ * if you desire to pin the avatar to a fixed location.
+ * @property collisionsEnabled {boolean} This can be used to disable collisions between the avatar and the world.
+ * @property useAdvancedMovementControls {boolean} Stores the user preference only, does not change user mappings, this is
+ * done in the default script, "toggleAdvancedMovementForHandControllers.js".
+ * @property userHeight {number} The height of the user in sensor space.
+ * @property userEyeHeight {number} Estimated height of the users eyes in sensor space.
+ * @property SELF_ID {string} UUID representing "my avatar". Only use for local-only entities and overlays in situations
+ * where MyAvatar.sessionUUID is not available (e.g., if not connected to a domain). Note: Likely to be deprecated.
+ * Read-only.
+ * @property hmdRollControlEnabled {boolean} When enabled the roll angle of your HMD will turn your avatar while flying.
+ * @property hmdRollControlDeadZone {number} If hmdRollControlEnabled is true, this value can be used to tune what roll
+ * angle is required to begin turning. This angle is specified in degrees.
+ * @property hmdRollControlRate {number} If hmdRollControlEnabled is true, this value determines the maximum turn rate of
+ * your avatar when rolling your HMD in degrees per second.
+ *
+ * @property {Vec3} skeletonOffset - Can be used to apply a translation offset between the avatar's position and the
+ * registration point of the 3D model.
+ *
+ * @property {Vec3} position
+ * @property {number} scale
+ * @property {number} density Read-only.
+ * @property {Vec3} handPosition
+ * @property {number} bodyYaw - The rotation left or right about an axis running from the head to the feet of MyAvatar. Yaw
+ * is sometimes called "heading".
+ * @property {number} bodyPitch - The rotation about an axis running from shoulder to shoulder of MyAvatar. Pitch is
+ * sometimes called "elevation".
+ * @property {number} bodyRoll - The rotation about an axis running from the chest to the back of the avatar. Roll is
+ * sometimes called "bank".
+ * @property {Quat} orientation
+ * @property {Quat} headOrientation - The orientation of the avatar's head.
+ * @property {number} headPitch - The rotation about an axis running from ear to ear of the avatar's head. Pitch is
+ * sometimes called "elevation".
+ * @property {number} headYaw - The rotation left or right about an axis running from the base to the crown of the avatar's
+ * head. Yaw is sometimes called "heading".
+ * @property {number} headRoll - The rotation about an axis running from the nose to the back of the avatar's head. Roll is
+ * sometimes called "bank".
+ * @property {Vec3} velocity
+ * @property {Vec3} angularVelocity
+ * @property {number} audioLoudness
+ * @property {number} audioAverageLoudness
+ * @property {string} displayName
+ * @property {string} sessionDisplayName - Sanitized, defaulted version displayName that is defined by the AvatarMixer
+ * rather than by Interface clients. The result is unique among all avatars present at the time.
+ * @property {boolean} lookAtSnappingEnabled
+ * @property {string} skeletonModelURL
+ * @property {AttachmentData[]} attachmentData
+ * @property {string[]} jointNames - The list of joints in the current avatar model. Read-only.
+ * @property {Uuid} sessionUUID Read-only.
+ * @property {Mat4} sensorToWorldMatrix Read-only.
+ * @property {Mat4} controllerLeftHandMatrix Read-only.
+ * @property {Mat4} controllerRightHandMatrix Read-only.
+ * @property {number} sensorToWorldScale Read-only.
*/
-
// FIXME: `glm::vec3 position` is not accessible from QML, so this exposes position in a QML-native type
Q_PROPERTY(QVector3D qmlPosition READ getQmlPosition)
QVector3D getQmlPosition() { auto p = getWorldPosition(); return QVector3D(p.x, p.y, p.z); }
@@ -246,12 +286,14 @@ public:
void setRealWorldFieldOfView(float realWorldFov) { _realWorldFieldOfView.set(realWorldFov); }
/**jsdoc
- * The default position in world coordinates of the point directly between the avatar's eyes
+ * Get the position in world coordinates of the point directly between your avatar's eyes assuming your avatar was in its
+ * default pose. This is a reference position; it does not change as your avatar's head moves relative to the avatar
+ * position.
* @function MyAvatar.getDefaultEyePosition
- * @example
This example gets the default eye position and prints it to the debug log.
+ * @returns {Vec3} Default position between your avatar's eyes in world coordinates.
+ * @example Report your avatar's default eye position.
* var defaultEyePosition = MyAvatar.getDefaultEyePosition();
- * print (JSON.stringify(defaultEyePosition));
- * @returns {Vec3} Position between the avatar's eyes.
+ * print(JSON.stringify(defaultEyePosition));
*/
Q_INVOKABLE glm::vec3 getDefaultEyePosition() const;
@@ -261,8 +303,19 @@ public:
* The avatar animation system includes a set of default animations along with rules for how those animations are blended
* together with procedural data (such as look at vectors, hand sensors etc.). overrideAnimation() is used to completely
* override all motion from the default animation system (including inverse kinematics for hand and head controllers) and
- * play a specified animation. To end this animation and restore the default animations, use MyAvatar.restoreAnimation.
+ * play a specified animation. To end this animation and restore the default animations, use
+ * {@link MyAvatar.restoreAnimation}.
+ * 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 the
+ * General Rigging Concepts section in Creating Avatars.
* @function MyAvatar.overrideAnimation
+ * @param url {string} 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 fps {number} The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
+ * @param loop {boolean} Set to true if the animation should loop.
+ * @param firstFrame {number} The frame the animation should start at.
+ * @param lastFrame {number} The frame the animation should end at.
* @example Play a clapping animation on your avatar for three seconds.
* // Clap your hands for 3 seconds then restore animation back to the avatar.
* var ANIM_URL = "https://s3.amazonaws.com/hifi-public/animations/ClapAnimations/ClapHands_Standing.fbx";
@@ -270,11 +323,6 @@ public:
* Script.setTimeout(function () {
* MyAvatar.restoreAnimation();
* }, 3000);
- * @param url {string} 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 fps {number} The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
- * @param loop {bool} Set to true if the animation should loop.
- * @param firstFrame {number} The frame the animation should start at.
- * @param lastFrame {number} The frame the animation should end at.
*/
Q_INVOKABLE void overrideAnimation(const QString& url, float fps, bool loop, float firstFrame, float lastFrame);
@@ -300,13 +348,13 @@ public:
* Animation roles map to easily understandable actions that the avatar can perform, such as "idleStand", "idleTalk", or "walkFwd."
* getAnimationRoles() is used get the list of animation roles defined in the avatar-animation.json.
* @function MyAvatar.getAnimationRoles
- * @example This example prints the list of animation roles defined in the avatar's avatar-animation.json file to the debug log.
+ * @returns {string[]} Array of role strings.
+ * @example Print the list of animation roles defined in the avatar's avatar-animation.json file to the debug log.
* var roles = MyAvatar.getAnimationRoles();
* print("Animation Roles:");
* for (var i = 0; i < roles.length; i++) {
* print(roles[i]);
* }
- * @returns {string[]} Array of role strings
*/
Q_INVOKABLE QStringList getAnimationRoles();
@@ -315,25 +363,32 @@ public:
* that the avatar can perform, such as "idleStand", "idleTalk", or "walkFwd". To get the full list of roles, use 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.
- * Note: Hand roles only affect the hand. Other 'main' roles, like 'idleStand', 'idleTalk', 'takeoffStand' are full body.
+ * overrideRoleAnimation() is used to change the animation clip (.FBX) associated with a specified animation role. To end
+ * the animation and restore the default animations, use {@link MyAvatar.restoreRoleAnimation}.
+ * Note: Hand roles only affect the hand. Other 'main' roles, like 'idleStand', 'idleTalk', '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 the
+ * General Rigging Concepts section in Creating Avatars.
* @function MyAvatar.overrideRoleAnimation
+ * @param role {string} The animation role to override
+ * @param url {string} 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 fps {number} The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
+ * @param loop {boolean} Set to true if the animation should loop
+ * @param firstFrame {number} The frame the animation should start at
+ * @param lastFrame {number} The frame the animation should end at
* @example The default avatar-animation.json defines an "idleStand" animation role. This role specifies that when the avatar is not moving,
* an animation clip of the avatar idling with hands hanging at its side will be used. It also specifies that when the avatar moves, the animation
* will smoothly blend to the walking animation used by the "walkFwd" animation role.
* In this example, the "idleStand" role animation clip has been replaced with a clapping animation clip. Now instead of standing with its arms
* hanging at its sides when it is not moving, the avatar will stand and clap its hands. Note that just as it did before, as soon as the avatar
* starts to move, the animation will smoothly blend into the walk animation used by the "walkFwd" animation role.
- * // An animation of the avatar clapping its hands while standing
+ * // An animation of the avatar clapping its hands while standing. Restore default after 30s.
* var ANIM_URL = "https://s3.amazonaws.com/hifi-public/animations/ClapAnimations/ClapHands_Standing.fbx";
* MyAvatar.overrideRoleAnimation("idleStand", ANIM_URL, 30, true, 0, 53);
- * // To restore the default animation, use MyAvatar.restoreRoleAnimation().
- * @param role {string} The animation role to override
- * @param url {string} 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 fps {number} The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
- * @param loop {bool} Set to true if the animation should loop
- * @param firstFrame {number} The frame the animation should start at
- * @param lastFrame {number} The frame the animation should end at
+ * Script.setTimeout(function () {
+ * MyAvatar.restoreRoleAnimation();
+ * }, 30000);
*/
Q_INVOKABLE void overrideRoleAnimation(const QString& role, const QString& url, float fps, bool loop, float firstFrame, float lastFrame);
@@ -346,7 +401,7 @@ public:
* 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 will have no effect.
* @function MyAvatar.restoreRoleAnimation
- * @param role {string} The animation role clip to restore
+ * @param role {string} The animation role clip to restore.
*/
Q_INVOKABLE void restoreRoleAnimation(const QString& role);
@@ -409,8 +464,8 @@ public:
*behaviour in the vertical direction. This call is only takes effect when the property
*MyAvatar.hmdLeanRecenterEnabled is set to false.
*@function MyAvatar.triggerVerticalRecenter
- *
*/
+ Q_INVOKABLE void triggerVerticalRecenter();
/**jsdoc
*The triggerHorizontalRecenter function activates one time the recentering behaviour
@@ -418,6 +473,7 @@ public:
*MyAvatar.hmdLeanRecenterEnabled is set to false.
*@function MyAvatar.triggerHorizontalRecenter
*/
+ Q_INVOKABLE void triggerHorizontalRecenter();
/**jsdoc
*The triggerRotationRecenter function activates one time the recentering behaviour
@@ -425,31 +481,96 @@ public:
*MyAvatar.hmdLeanRecenterEnabled is set to false.
*@function MyAvatar.triggerRotationRecenter
*/
-
- Q_INVOKABLE void triggerVerticalRecenter();
- Q_INVOKABLE void triggerHorizontalRecenter();
Q_INVOKABLE void triggerRotationRecenter();
eyeContactTarget getEyeContactTarget();
const MyHead* getMyHead() const;
+
+ /**jsdoc
+ * Get the current position of the avatar's "Head" joint.
+ * @function MyAvatar.getHeadPosition
+ * @returns {Vec3} The current position of the avatar's "Head" joint.
+ * @example Report the current position of your avatar's head.
+ * print(JSON.stringify(MyAvatar.getHeadPosition()));
+ */
Q_INVOKABLE glm::vec3 getHeadPosition() const { return getHead()->getPosition(); }
Q_INVOKABLE float getHeadFinalYaw() const { return getHead()->getFinalYaw(); }
Q_INVOKABLE float getHeadFinalRoll() const { return getHead()->getFinalRoll(); }
Q_INVOKABLE float getHeadFinalPitch() const { return getHead()->getFinalPitch(); }
Q_INVOKABLE float getHeadDeltaPitch() const { return getHead()->getDeltaPitch(); }
+ /**jsdoc
+ * Get the current position of the point directly between the avatar's eyes.
+ * @function MyAvatar.getEyePosition
+ * @returns {Vec3} The current position of the point directly between the avatar's eyes.
+ * @example Report your avatar's current eye position.
+ * var eyePosition = MyAvatar.getEyePosition();
+ * print(JSON.stringify(eyePosition));
+ */
Q_INVOKABLE glm::vec3 getEyePosition() const { return getHead()->getEyePosition(); }
+ /**jsdoc
+ * @function MyAvatar.getTargetAvatarPosition
+ * @returns {Vec3} The position of the avatar you're currently looking at.
+ * @example Report the position of the avatar you're currently looking at.
+ * print(JSON.stringify(MyAvatar.getTargetAvatarPosition()));
+ */
Q_INVOKABLE glm::vec3 getTargetAvatarPosition() const { return _targetAvatarPosition; }
Q_INVOKABLE ScriptAvatarData* getTargetAvatar() const;
+
+ /**jsdoc
+ * Get the position of the avatar's left hand as it is controlled by a hand controller (e.g., Oculus Touch or Vive).
+ * Note: The Leap Motion isn't part of the hand controller input system. (Instead, it manipulates the avatar's joints
+ * for hand animation.) If you are using the Leap Motion, the return value's valid
property will be
+ * false
and any pose values returned will not be meaningful.
+ * @function MyAvatar.getLeftHandPosition
+ * @returns {Vec3} The position of the left hand in avatar coordinates.
+ * @example Report the position of your left hand relative to your avatar.
+ * print(JSON.stringify(MyAvatar.getLeftHandPosition()));
+ */
Q_INVOKABLE glm::vec3 getLeftHandPosition() const;
+
+ /**jsdoc
+ * Get the position of the avatar's right hand as it is controlled by a hand controller (e.g., Oculus Touch or Vive).
+ * Note: The Leap Motion isn't part of the hand controller input system. (Instead, it manipulates the avatar's joints
+ * for hand animation.) If you are using the Leap Motion, the return value's valid
property will be
+ * false
and any pose values returned will not be meaningful.
+ * @function MyAvatar.getRightHandPosition
+ * @returns {Vec3} The position of the right hand in avatar coordinates.
+ * @example Report the position of your right hand relative to your avatar.
+ * print(JSON.stringify(MyAvatar.getLeftHandPosition()));
+ */
Q_INVOKABLE glm::vec3 getRightHandPosition() const;
Q_INVOKABLE glm::vec3 getLeftHandTipPosition() const;
Q_INVOKABLE glm::vec3 getRightHandTipPosition() const;
+
+ /**jsdoc
+ * Get the pose (position, rotation, velocity, and angular velocity) of the avatar's left hand as it is controlled by a
+ * hand controller (e.g., Oculus Touch or Vive).
+ * Note: The Leap Motion isn't part of the hand controller input system. (Instead, it manipulates the avatar's joints
+ * for hand animation.) If you are using the Leap Motion, the return value's valid
property will be
+ * false
and any pose values returned will not be meaningful.
+ * @function MyAvatar.getLeftHandPose
+ * @returns {Pose}
+ * @example Report the pose of your avatar's left hand.
+ * print(JSON.stringify(MyAvatar.getLeftHandPose()));
+ */
Q_INVOKABLE controller::Pose getLeftHandPose() const;
+
+ /**jsdoc
+ * Get the pose (position, rotation, velocity, and angular velocity) of the avatar's left hand as it is controlled by a
+ * hand controller (e.g., Oculus Touch or Vive).
+ * Note: The Leap Motion isn't part of the hand controller input system. (Instead, it manipulates the avatar's joints
+ * for hand animation.) If you are using the Leap Motion, the return value's valid
property will be
+ * false
and any pose values returned will not be meaningful.
+ * @function MyAvatar.getRightHandPose
+ * @returns {Pose}
+ * @example Report the pose of your avatar's right hand.
+ * print(JSON.stringify(MyAvatar.getRightHandPose()));
+ */
Q_INVOKABLE controller::Pose getRightHandPose() const;
Q_INVOKABLE controller::Pose getLeftHandTipPose() const;
Q_INVOKABLE controller::Pose getRightHandTipPose() const;
@@ -486,8 +607,26 @@ public:
Q_INVOKABLE float getIKErrorOnLastSolve() const;
Q_INVOKABLE void useFullAvatarURL(const QUrl& fullAvatarURL, const QString& modelName = QString());
+
+ /**jsdoc
+ * Get the complete URL for the current avatar.
+ * @function MyAvatar.getFullAvatarURLFromPreferences
+ * @returns {string} The full avatar model name.
+ * @example Report the URL for the current avatar.
+ * print(MyAvatar.getFullAvatarURLFromPreferences());
+ */
Q_INVOKABLE QUrl getFullAvatarURLFromPreferences() const { return _fullAvatarURLFromPreferences; }
+
+ /**jsdoc
+ * Get the full avatar model name for the current avatar.
+ * @function MyAvatar.getFullAvatarModelName
+ * @returns {string} The full avatar model name.
+ * @example Report the current full avatar model name.
+ * print(MyAvatar.getFullAvatarModelName());
+ * // For example: being_of_light
+ */
Q_INVOKABLE QString getFullAvatarModelName() const { return _fullAvatarModelName; }
+
void resetFullAvatarURL();
virtual void setAttachmentData(const QVector& attachmentData) override;
@@ -595,17 +734,60 @@ public:
float getWalkSpeed() const;
public slots:
+
+ /**jsdoc
+ * Increase the avatar's scale by five percent, up to a minimum scale of 1000
.
+ * @function MyAvatar.increaseSize
+ * @example Reset your avatar's size to default then grow it 5 times.
+ * MyAvatar.resetSize();
+ *
+ * for (var i = 0; i < 5; i++){
+ * print ("Growing by 5 percent");
+ * MyAvatar.increaseSize();
+ * }
+ */
void increaseSize();
+
+ /**jsdoc
+ * Decrease the avatar's scale by five percent, down to a minimum scale of 0.25
.
+ * @function MyAvatar.decreaseSize
+ * @example Reset your avatar's size to default then shrink it 5 times.
+ * MyAvatar.resetSize();
+ *
+ * for (var i = 0; i < 5; i++){
+ * print ("Shrinking by 5 percent");
+ * MyAvatar.decreaseSize();
+ * }
+ */
void decreaseSize();
+
+ /**jsdoc
+ * Reset the avatar's scale back to the default scale of 1.0
.
+ * @function MyAvatar.resetSize
+ */
void resetSize();
+
void animGraphLoaded();
void setGravity(float gravity);
float getGravity();
+ /**jsdoc
+ * Move the avatar to a new position and/or orientation in the domain.
+ * @function MyAvatar.goToLocation
+ * @param {Vec3} position - The new position for the avatar, in world coordinates.
+ * @param {boolean} [hasOrientation=false] - Set to true
to set the orientation of the avatar.
+ * @param {Quat} [orientation=Quat.IDENTITY] - The new orientation for the avatar.
+ * @param {boolean} [shouldFaceLocation=false] - Set to true
to position the avatar a short distance away from
+ * the new position and orientate the avatar to face the position.
+ */
void goToLocation(const glm::vec3& newPosition,
bool hasOrientation = false, const glm::quat& newOrientation = glm::quat(),
bool shouldFaceLocation = false);
+ /**jsdoc
+ * @function MyAvatar.goToLocation
+ * @param {object} properties
+ */
void goToLocation(const QVariant& properties);
void goToLocationAndEnableCollisions(const glm::vec3& newPosition);
bool safeLanding(const glm::vec3& position);
@@ -630,7 +812,23 @@ public slots:
void setEnableDebugDrawIKChains(bool isEnabled);
void setEnableDebugDrawDetailedCollision(bool isEnabled);
+ /**jsdoc
+ * Get whether or not your avatar mesh is visible.
+ * @function MyAvatar.getEnableMeshVisible
+ * @returns {boolean} true
if your avatar's mesh is visible, otherwise false
.
+ */
bool getEnableMeshVisible() const { return _skeletonModel->isVisible(); }
+
+ /**jsdoc
+ * Set whether or not your avatar mesh is visible.
+ * @function MyAvatar.setEnableMeshVisible
+ * @param {boolean} visible - true
to set your avatar mesh visible; false
to set it invisible.
+ * @example Make your avatar invisible for 10s.
+ * MyAvatar.setEnableMeshVisible(false);
+ * Script.setTimeout(function () {
+ * MyAvatar.setEnableMeshVisible(true);
+ * }, 10000);
+ */
void setEnableMeshVisible(bool isEnabled);
void setEnableInverseKinematics(bool isEnabled);
@@ -648,6 +846,17 @@ signals:
void audioListenerModeChanged();
void transformChanged();
void newCollisionSoundURL(const QUrl& url);
+
+ /**jsdoc
+ * Triggered when the avatar collides with an entity.
+ * @function MyAvatar.collisionWithEntity
+ * @param {Collision} collision
+ * @returns {Signal}
+ * @example Report each time your aatar collides with an entity.
+ * MyAvatar.collisionWithEntity.connect(function (collision) {
+ * print("Your avatar collided with an entity.");
+ * });
+ */
void collisionWithEntity(const Collision& collision);
void energyChanged(float newEnergy);
void positionGoneTo();
diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h
index bf0adc5c05..38f72609d1 100644
--- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h
+++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h
@@ -57,15 +57,7 @@ using AvatarPhysicsCallback = std::function;
class Avatar : public AvatarData, public scriptable::ModelProvider {
Q_OBJECT
- /**jsdoc
- * An avatar is representation of yourself or another user. The Avatar API can be used to query or manipulate the avatar of a user.
- * NOTE: Avatar extends AvatarData, see those namespace for more properties/methods.
- *
- * @namespace Avatar
- * @augments AvatarData
- *
- * @property skeletonOffset {Vec3} can be used to apply a translation offset between the avatar's position and the registration point of the 3d model.
- */
+ // This property has JSDoc in MyAvatart.h.
Q_PROPERTY(glm::vec3 skeletonOffset READ getSkeletonOffset WRITE setSkeletonOffset)
public:
@@ -134,8 +126,8 @@ public:
/**jsdoc
* Provides read only access to the default joint rotations in avatar coordinates.
* The default pose of the avatar is defined by the position and orientation of all bones
- * in the avatar's model file. Typically this is a t-pose.
- * @function Avatar.getAbsoluteDefaultJointRotationInObjectFrame
+ * in the avatar's model file. Typically this is a T-pose.
+ * @function MyAvatar.getAbsoluteDefaultJointRotationInObjectFrame
* @param index {number} index number
* @returns {Quat} The rotation of this joint in avatar coordinates.
*/
@@ -144,8 +136,8 @@ public:
/**jsdoc
* Provides read only access to the default joint translations in avatar coordinates.
* The default pose of the avatar is defined by the position and orientation of all bones
- * in the avatar's model file. Typically this is a t-pose.
- * @function Avatar.getAbsoluteDefaultJointTranslationInObjectFrame
+ * in the avatar's model file. Typically this is a T-pose.
+ * @function MyAvatar.getAbsoluteDefaultJointTranslationInObjectFrame
* @param index {number} index number
* @returns {Vec3} The position of this joint in avatar coordinates.
*/
@@ -170,12 +162,59 @@ public:
virtual void applyCollision(const glm::vec3& contactPoint, const glm::vec3& penetration) { }
+ /**jsdoc
+ * Set the offset applied to the current avatar. The offset adjusts the position that the avatar is rendered. For example,
+ * with an offset of { x: 0, y: 0.1, z: 0 }
, your avatar will appear to be raised off the ground slightly.
+ * @function MyAvatar.setSkeletonOffset
+ * @param {Vec3} offset - The skeleton offset to set.
+ * @example Raise your avatar off the ground a little.
+ * // Raise your avatar off the ground a little.
+ * MyAvatar.setSkeletonOffset({ x: 0, y: 0.1: z: 0 });
+ *
+ * // Restore its offset after 5s.
+ * Script.setTimeout(function () {
+ * MyAvatar.setSkeletonOffset(Vec3.ZERO);
+ * }, 5000);
+ */
Q_INVOKABLE void setSkeletonOffset(const glm::vec3& offset);
+
+ /**jsdoc
+ * Get the offset applied to the current avatar. The offset adjusts the position that the avatar is rendered. For example,
+ * with an offset of { x: 0, y: 0.1, z: 0 }
, your avatar will appear to be raised off the ground slightly.
+ * @function MyAvatar.getSkeletonOffset
+ * @returns {Vec3} The current skeleton offset.
+ * @example Report your avatar's current skeleton offset.
+ * print(JSON.stringify(MyAvatar.getSkeletonOffset());
+ */
Q_INVOKABLE glm::vec3 getSkeletonOffset() { return _skeletonOffset; }
+
virtual glm::vec3 getSkeletonPosition() const;
+ /**jsdoc
+ * Get the position of a joint in the current avatar.
+ * @function MyAvatar.getJointPosition
+ * @param {number} index - The index of the joint.
+ * @returns {Vec3} The position of the joint in world coordinates.
+ */
Q_INVOKABLE glm::vec3 getJointPosition(int index) const;
+
+ /**jsdoc
+ * Get the position of a joint in the current avatar.
+ * @function MyAvatar.getJointPosition
+ * @param {string} name - The name of the joint.
+ * @returns {Vec3} The position of the joint in world coordinates.
+ * @example Report the position of your avatar's hips.
+ * print(JSON.stringify(MyAvatar.getJointPosition("Hips")));
+ */
Q_INVOKABLE glm::vec3 getJointPosition(const QString& name) const;
+
+ /**jsdoc
+ * Get the position of the current avatar's neck in world coordinates.
+ * @function MyAvatar.getNeckPosition
+ * @returns {Vec3} The position of the neck in world coordinates.
+ * @example Report the position of your avatar's neck.
+ * print(JSON.stringify(MyAvatar.getNeckPosition()));
+ */
Q_INVOKABLE glm::vec3 getNeckPosition() const;
Q_INVOKABLE glm::vec3 getAcceleration() const { return _acceleration; }
@@ -208,17 +247,16 @@ public:
Q_INVOKABLE virtual void setParentJointIndex(quint16 parentJointIndex) override;
/**jsdoc
- * Information about a single joint in an Avatar's skeleton hierarchy.
- * @typedef Avatar.SkeletonJoint
- * @property {string} name - name of joint
- * @property {number} index - joint index
- * @property {number} parentIndex - index of this joint's parent (-1 if no parent)
+ * Returns an array of joints, where each joint is an object containing name, index, and parentIndex fields.
+ * @function MyAvatar.getSkeleton
+ * @returns {MyAvatar.SkeletonJoint[]} A list of information about each joint in this avatar's skeleton.
*/
-
/**jsdoc
- * Returns an array of joints, where each joint is an object containing name, index and parentIndex fields.
- * @function Avatar.getSkeleton
- * @returns {Avatar.SkeletonJoint[]} returns a list of information about each joint in this avatar's skeleton.
+ * Information about a single joint in an Avatar's skeleton hierarchy.
+ * @typedef MyAvatar.SkeletonJoint
+ * @property {string} name - Joint name.
+ * @property {number} index - Joint index.
+ * @property {number} parentIndex - Index of this joint's parent (-1 if no parent).
*/
Q_INVOKABLE QList getSkeleton();
@@ -282,9 +320,40 @@ public slots:
// FIXME - these should be migrated to use Pose data instead
// thread safe, will return last valid palm from cache
+
+ /**jsdoc
+ * Get the position of the left palm in world coordinates.
+ * @function MyAvatar.getLeftPalmPosition
+ * @returns {Vec3} The position of the left palm in world coordinates.
+ * @example Report the position of your avatar's left palm.
+ * print(JSON.stringify(MyAvatar.getLeftPalmPosition()));
+ */
glm::vec3 getLeftPalmPosition() const;
+
+ /**jsdoc
+ * Get the rotation of the left palm in world coordinates.
+ * @function MyAvatar.getLeftPalmRotation
+ * @returns {Vec3} The rotation of the left palm in world coordinates.
+ * @example Report the rotation of your avatar's left palm.
+ * print(JSON.stringify(MyAvatar.getLeftPalmRotation()));
+ */
glm::quat getLeftPalmRotation() const;
+ /**jsdoc
+ * Get the position of the right palm in world coordinates.
+ * @function MyAvatar.getRightPalmPosition
+ * @returns {Vec3} The position of the right palm in world coordinates.
+ * @example Report the position of your avatar's right palm.
+ * print(JSON.stringify(MyAvatar.getRightPalmPosition()));
+ */
glm::vec3 getRightPalmPosition() const;
+
+ /**jsdoc
+ * Get the rotation of the right palm in world coordinates.
+ * @function MyAvatar.getRightPalmRotation
+ * @returns {Vec3} The rotation of the right palm in world coordinates.
+ * @example Report the rotation of your avatar's right palm.
+ * print(JSON.stringify(MyAvatar.getRightPalmRotation()));
+ */
glm::quat getRightPalmRotation() const;
// hooked up to Model::setURLFinished signal
diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp
index 6b974ac9ae..db38999481 100644
--- a/libraries/avatars/src/AvatarData.cpp
+++ b/libraries/avatars/src/AvatarData.cpp
@@ -2362,6 +2362,15 @@ glm::vec3 AvatarData::getAbsoluteJointTranslationInObjectFrame(int index) const
return glm::vec3();
}
+/**jsdoc
+ * @typedef MyAvatar.AttachmentData
+ * @property {string} modelUrl
+ * @property {string} jointName
+ * @property {Vec3} translation
+ * @property {Vec3} rotation
+ * @property {number} scale
+ * @property {boolean} soft
+ */
QVariant AttachmentData::toVariant() const {
QVariantMap result;
result["modelUrl"] = modelURL;
diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h
index 7c188019db..cc34d560b5 100644
--- a/libraries/avatars/src/AvatarData.h
+++ b/libraries/avatars/src/AvatarData.h
@@ -353,6 +353,7 @@ public:
class AvatarData : public QObject, public SpatiallyNestable {
Q_OBJECT
+ // The following properties have JSDoc in MyAvatar.h.
Q_PROPERTY(glm::vec3 position READ getWorldPosition WRITE setPositionViaScript)
Q_PROPERTY(float scale READ getTargetScale WRITE setTargetScale)
Q_PROPERTY(float density READ getDensity)
@@ -505,7 +506,7 @@ public:
/**jsdoc
* returns the minimum scale allowed for this avatar in the current domain.
* This value can change as the user changes avatars or when changing domains.
- * @function AvatarData.getDomainMinScale
+ * @function MyAvatar.getDomainMinScale
* @returns {number} minimum scale allowed for this avatar in the current domain.
*/
Q_INVOKABLE float getDomainMinScale() const;
@@ -513,7 +514,7 @@ public:
/**jsdoc
* returns the maximum scale allowed for this avatar in the current domain.
* This value can change as the user changes avatars or when changing domains.
- * @function AvatarData.getDomainMaxScale
+ * @function MyAvatar.getDomainMaxScale
* @returns {number} maximum scale allowed for this avatar in the current domain.
*/
Q_INVOKABLE float getDomainMaxScale() const;
@@ -529,16 +530,16 @@ public:
/**jsdoc
* Provides read only access to the current eye height of the avatar.
* This height is only an estimate and might be incorrect for avatars that are missing standard joints.
- * @function AvatarData.getEyeHeight
- * @returns {number} eye height of avatar in meters
+ * @function MyAvatar.getEyeHeight
+ * @returns {number} Eye height of avatar in meters.
*/
Q_INVOKABLE virtual float getEyeHeight() const { return _targetScale * getUnscaledEyeHeight(); }
/**jsdoc
* Provides read only access to the current height of the avatar.
* This height is only an estimate and might be incorrect for avatars that are missing standard joints.
- * @function AvatarData.getHeight
- * @returns {number} height of avatar in meters
+ * @function MyAvatar.getHeight
+ * @returns {number} Height of avatar in meters.
*/
Q_INVOKABLE virtual float getHeight() const;
@@ -554,32 +555,287 @@ public:
const QVector& getRawJointData() const { return _jointData; }
Q_INVOKABLE void setRawJointData(QVector data);
+ /**jsdoc
+ * Set a specific joint's rotation and position relative to its parent.
+ * Setting joint data completely overrides/replaces all motion from the default animation system including inverse
+ * kinematics, but just for the specified joint. So for example, if you were to procedurally manipulate the finger joints,
+ * the avatar's hand and head would still do inverse kinematics properly. However, as soon as you start to manipulate
+ * joints in the inverse kinematics chain, the inverse kinematics might not function as you expect. For example, if you set
+ * the rotation of the elbow, the hand inverse kinematics position won't end up in the right place.
+ * @function MyAvatar.setJointData
+ * @param {number} index - The index of the joint.
+ * @param {Quat} rotation - The rotation of the joint relative to its parent.
+ * @param {Vec3} translation - The translation of the joint relative to its parent.
+ * @example Set your avatar to it's default T-pose for a while.
+ *
+ *
+ * // Set all joint translations and rotations to defaults.
+ * var i, length, rotation, translation;
+ * for (i = 0, length = MyAvatar.getJointNames().length; i < length; i++) {
+ * rotation = MyAvatar.getDefaultJointRotation(i);
+ * translation = MyAvatar.getDefaultJointTranslation(i);
+ * MyAvatar.setJointData(i, rotation, translation);
+ * }
+ *
+ * // Restore your avatar's motion after 5s.
+ * Script.setTimeout(function () {
+ * MyAvatar.clearJointsData();
+ * }, 5000);
+ */
Q_INVOKABLE virtual void setJointData(int index, const glm::quat& rotation, const glm::vec3& translation);
+
+ /**jsdoc
+ * Set a specific joint's rotation relative to its parent.
+ * Setting joint data completely overrides/replaces all motion from the default animation system including inverse
+ * kinematics, but just for the specified joint. So for example, if you were to procedurally manipulate the finger joints,
+ * the avatar's hand and head would still do inverse kinematics properly. However, as soon as you start to manipulate
+ * joints in the inverse kinematics chain, the inverse kinematics might not function as you expect. For example, if you set
+ * the rotation of the elbow, the hand inverse kinematics position won't end up in the right place.
+ * @function MyAvatar.setJointRotation
+ * @param {number} index - The index of the joint.
+ * @param {Quat} rotation - The rotation of the joint relative to its parent.
+ */
Q_INVOKABLE virtual void setJointRotation(int index, const glm::quat& rotation);
+
+ /**jsdoc
+ * Set a specific joint's translation relative to its parent.
+ * Setting joint data completely overrides/replaces all motion from the default animation system including inverse
+ * kinematics, but just for the specified joint. So for example, if you were to procedurally manipulate the finger joints,
+ * the avatar's hand and head would still do inverse kinematics properly. However, as soon as you start to manipulate
+ * joints in the inverse kinematics chain, the inverse kinematics might not function as you expect. For example, if you set
+ * the rotation of the elbow, the hand inverse kinematics position won't end up in the right place.
+ * @function MyAvatar.setJointTranslation
+ * @param {number} index - The index of the joint.
+ * @param {Vec3} translation - The translation of the joint relative to its parent.
+ */
Q_INVOKABLE virtual void setJointTranslation(int index, const glm::vec3& translation);
+
+ /**jsdoc
+ * Clear joint translations and rotations set by script for a specific joint. This restores all motion from the default
+ * animation system including inverse kinematics for that joint.
+ * Note: This is slightly faster than the function variation that specifies the joint name.
+ * @function MyAvatar.clearJointData
+ * @param {number} index - The index of the joint.
+ */
Q_INVOKABLE virtual void clearJointData(int index);
Q_INVOKABLE bool isJointDataValid(int index) const;
+
+ /**jsdoc
+ * Get the rotation of a joint relative to its parent. For information on the joint hierarchy used, see
+ * avatar standards.
+ * @function MyAvatar.getJointRotation
+ * @param {number} index - The index of the joint.
+ * @returns {Quat} The rotation of the joint relative to its parent.
+ */
Q_INVOKABLE virtual glm::quat getJointRotation(int index) const;
+
+ /**jsdoc
+ * Get the translation of a joint relative to its parent. For information on the joint hierarchy used, see
+ * avatar standards.
+ * @function MyAvatar.getJointTranslation
+ * @param {number} index - The index of the joint.
+ * @returns {Vec3} The translation of the joint relative to its parent.
+ */
Q_INVOKABLE virtual glm::vec3 getJointTranslation(int index) const;
+ /**jsdoc
+ * Set a specific joint's rotation and position relative to its parent.
+ * Setting joint data completely overrides/replaces all motion from the default animation system including inverse
+ * kinematics, but just for the specified joint. So for example, if you were to procedurally manipulate the finger joints,
+ * the avatar's hand and head would still do inverse kinematics properly. However, as soon as you start to manipulate
+ * joints in the inverse kinematics chain, the inverse kinematics might not function as you expect. For example, if you set
+ * the rotation of the elbow, the hand inverse kinematics position won't end up in the right place.
+ * @function MyAvatar.setJointData
+ * @param {string} name - The name of the joint.
+ * @param {Quat} rotation - The rotation of the joint relative to its parent.
+ * @param {Vec3} translation - The translation of the joint relative to its parent.
+ */
Q_INVOKABLE virtual void setJointData(const QString& name, const glm::quat& rotation, const glm::vec3& translation);
+
+ /**jsdoc
+ * Set a specific joint's rotation relative to its parent.
+ * Setting joint data completely overrides/replaces all motion from the default animation system including inverse
+ * kinematics, but just for the specified joint. So for example, if you were to procedurally manipulate the finger joints,
+ * the avatar's hand and head would still do inverse kinematics properly. However, as soon as you start to manipulate
+ * joints in the inverse kinematics chain, the inverse kinematics might not function as you expect. For example, if you set
+ * the rotation of the elbow, the hand inverse kinematics position won't end up in the right place.
+ * @function MyAvatar.setJointRotation
+ * @param {string} name - The name of the joint.
+ * @param {Quat} rotation - The rotation of the joint relative to its parent.
+ * @example Set your avatar to its default T-pose then rotate its right arm.
+ *
+ * // Set all joint translations and rotations to defaults.
+ * var i, length, rotation, translation;
+ * for (i = 0, length = MyAvatar.getJointNames().length; i < length; i++) {
+ * rotation = MyAvatar.getDefaultJointRotation(i);
+ * translation = MyAvatar.getDefaultJointTranslation(i);
+ * MyAvatar.setJointData(i, rotation, translation);
+ * }
+ *
+ * // Rotate the right arm.
+ * var newArmRotation = { x: 0.47, y: 0.22, z: -0.02, w: 0.87 };
+ * MyAvatar.setJointRotation("RightArm", newArmRotation);
+ *
+ * // Restore your avatar's motion after 5s.
+ * Script.setTimeout(function () {
+ * MyAvatar.clearJointsData();
+ * }, 5000);
+ */
Q_INVOKABLE virtual void setJointRotation(const QString& name, const glm::quat& rotation);
+
+ /**jsdoc
+ * Set a specific joint's translation relative to its parent.
+ * Setting joint data completely overrides/replaces all motion from the default animation system including inverse
+ * kinematics, but just for the specified joint. So for example, if you were to procedurally manipulate the finger joints,
+ * the avatar's hand and head would still do inverse kinematics properly. However, as soon as you start to manipulate
+ * joints in the inverse kinematics chain, the inverse kinematics might not function as you expect. For example, if you set
+ * the rotation of the elbow, the hand inverse kinematics position won't end up in the right place.
+ * @function MyAvatar.setJointTranslation
+ * @param {string} name - The name of the joint.
+ * @param {Vec3} translation - The translation of the joint relative to its parent.
+ * @example Stretch your avatar's neck. Depending on the avatar you are using, you will either see a gap between
+ * the head and body or you will see the neck stretched.
+ *
+ * // Stretch your avatar's neck.
+ * MyAvatar.setJointTranslation("Neck", { x: 0, y: 25, z: 0 });
+ *
+ * // Restore your avatar's neck after 5s.
+ * Script.setTimeout(function () {
+ * MyAvatar.clearJointData("Neck");
+ * }, 5000);
+ */
Q_INVOKABLE virtual void setJointTranslation(const QString& name, const glm::vec3& translation);
+
+ /**jsdoc
+ * Clear joint translations and rotations set by script for a specific joint. This restores all motion from the default
+ * animation system including inverse kinematics for that joint.
+ * Note: This is slightly slower than the function variation that specifies the joint index.
+ * @function MyAvatar.clearJointData
+ * @param {string} name - The name of the joint.
+ * @example Offset and restore the position of your avatar's head.
+ * // Move your avatar's head up by 25cm from where it should be.
+ * MyAvatar.setJointTranslation("Neck", { x: 0, y: 0.25, z: 0 });
+ *
+ * // Restore your avatar's head to its default position after 5s.
+ * Script.setTimeout(function () {
+ * MyAvatar.clearJointData("Neck");
+ * }, 5000);
+ */
Q_INVOKABLE virtual void clearJointData(const QString& name);
Q_INVOKABLE virtual bool isJointDataValid(const QString& name) const;
+
+ /**jsdoc
+ * Get the rotation of a joint relative to its parent. For information on the joint hierarchy used, see
+ * avatar standards.
+ * @function MyAvatar.getJointRotation
+ * @param {string} name - The name of the joint.
+ * @returns {Quat} The rotation of the joint relative to its parent.
+ * @example Report the rotation of your avatar's hips joint.
+ * print(JSON.stringify(MyAvatar.getJointRotation("Hips")));
+ */
Q_INVOKABLE virtual glm::quat getJointRotation(const QString& name) const;
+
+ /**jsdoc
+ * Get the translation of a joint relative to its parent. For information on the joint hierarchy used, see
+ * avatar standards.
+ * @function MyAvatar.getJointTranslation
+ * @param {number} name - The name of the joint.
+ * @returns {Vec3} The translation of the joint relative to its parent.
+ * @example Report the translation of your avatar's hips joint.
+ * print(JSON.stringify(MyAvatar.getJointRotation("Hips")));
+ */
Q_INVOKABLE virtual glm::vec3 getJointTranslation(const QString& name) const;
+ /**jsdoc
+ * Get the rotations of all joints in the current avatar. Each joint's rotation is relative to its parent joint.
+ * @function MyAvatar.getJointRotations
+ * @returns {Quat[]} The rotations of all joints relative to each's parent. The values are in the same order as the array
+ * returned by {@link MyAvatar.getJointNames}.
+ * @example Report the rotations of all your avatar's joints.
+ * print(JSON.stringify(MyAvatar.getJointRotations()));
+ */
Q_INVOKABLE virtual QVector getJointRotations() const;
Q_INVOKABLE virtual QVector getJointTranslations() const;
+
+ /**jsdoc
+ * Set the rotations of all joints in the current avatar. Each joint's rotation is relative to its parent joint.
+ * Setting joint data completely overrides/replaces all motion from the default animation system including inverse
+ * kinematics, but just for the specified joint. So for example, if you were to procedurally manipulate the finger joints,
+ * the avatar's hand and head would still do inverse kinematics properly. However, as soon as you start to manipulate
+ * joints in the inverse kinematics chain, the inverse kinematics might not function as you expect. For example, if you set
+ * the rotation of the elbow, the hand inverse kinematics position won't end up in the right place.
+ * @function MyAvatar.setJointRotations
+ * @param {Quat[]} jointRotations - The rotations for all joints in the avatar. The values are in the same order as the
+ * array returned by {@link MyAvatar.getJointNames}.
+ * @example Set your avatar to its default T-pose then rotate its right arm.
+ *
+ *
+ * // Set all joint translations and rotations to defaults.
+ * var i, length, rotation, translation;
+ * for (i = 0, length = MyAvatar.getJointNames().length; i < length; i++) {
+ * rotation = MyAvatar.getDefaultJointRotation(i);
+ * translation = MyAvatar.getDefaultJointTranslation(i);
+ * MyAvatar.setJointData(i, rotation, translation);
+ * }
+ *
+ * // Get all join rotations.
+ * var jointRotations = MyAvatar.getJointRotations();
+ *
+ * // Update the rotation of the right arm in the array.
+ * jointRotations[MyAvatar.getJointIndex("RightArm")] = { x: 0.47, y: 0.22, z: -0.02, w: 0.87 };
+ *
+ * // Update all joint rotations.
+ * MyAvatar.setJointRotations(jointRotations);
+ *
+ * // Restore your avatar's motion after 5s.
+ * Script.setTimeout(function () {
+ * MyAvatar.clearJointsData();
+ * }, 5000);
+ */
Q_INVOKABLE virtual void setJointRotations(const QVector& jointRotations);
Q_INVOKABLE virtual void setJointTranslations(const QVector& jointTranslations);
+ /**jsdoc
+ * Clear all joint translations and rotations that have been set by script. This restores all motion from the default
+ * animation system including inverse kinematics for all joints.
+ * @function MyAvatar.clearJointsData
+ * @example Set your avatar to it's default T-pose for a while.
+ * // Set all joint translations and rotations to defaults.
+ * var i, length, rotation, translation;
+ * for (i = 0, length = MyAvatar.getJointNames().length; i < length; i++) {
+ * rotation = MyAvatar.getDefaultJointRotation(i);
+ * translation = MyAvatar.getDefaultJointTranslation(i);
+ * MyAvatar.setJointData(i, rotation, translation);
+ * }
+ *
+ * // Restore your avatar's motion after 5s.
+ * Script.setTimeout(function () {
+ * MyAvatar.clearJointsData();
+ * }, 5000);
+ */
Q_INVOKABLE virtual void clearJointsData();
+ /**jsdoc
+ * Get the joint index for a named joint. The joint index value is the position of the joint in the array returned by
+ * {@link MyAvatar.getJointNames}.
+ * @function MyAvatar.getJointIndex
+ * @param {string} name - The name of the joint.
+ * @returns {number} The index of the joint.
+ * @example Report the index of your avatar's left arm joint.
+ * print(JSON.stringify(MyAvatar.getJointIndex("LeftArm"));
+ */
/// Returns the index of the joint with the specified name, or -1 if not found/unknown.
Q_INVOKABLE virtual int getJointIndex(const QString& name) const;
+ /**jsdoc
+ * Get the names of all the joints in the current avatar.
+ * @function MyAvatar.getJointNames
+ * @returns {string[]} The joint names.
+ * @example Report the names of all the joints in your current avatar.
+ * print(JSON.stringify(MyAvatar.getJointNames()));
+ */
Q_INVOKABLE virtual QStringList getJointNames() const;
Q_INVOKABLE void setBlendshape(QString name, float val) { _headData->setBlendshape(name, val); }
@@ -627,15 +883,96 @@ public:
markIdentityDataChanged();
}
+ /**jsdoc
+ * Get information about all models currently attached to your avatar.
+ * @function MyAvatar.getAttachmentData
+ * @returns {MyAvatar.AttachmentData[]} Information about all models attached to your avatar.
+ * @example Report the URLs of all current attachments.
+ * var attachments = MyAvatar.getaAttachmentData();
+ * for (var i = 0; i < attachments.length; i++) {
+ * print (attachments[i].modelURL);
+ * }
+ */
Q_INVOKABLE QVector getAttachmentData() const;
+
+ /**jsdoc
+ * Set all models currently attached to your avatar. For example, if you retrieve attachment data using
+ * {@link MyAvatar.getAttachmentData}, make changes to it, and then want to update your avatar's attachments per the
+ * changed data. You can also remove all attachments by using setting attachmentData
to null
.
+ * @function MyAvatar.setAttachmentData
+ * @param {MyAvatar.AttachmentData[]} attachmentData - The attachment data defining the models to have attached to your avatar. Use
+ * null
to remove all attachments.
+ * @example Remove a hat attachment if your avatar is wearing it.
+ * var hatURL = "https://s3.amazonaws.com/hifi-public/tony/cowboy-hat.fbx";
+ * var attachments = MyAvatar.getAttachmentData();
+ *
+ * for (var i = 0; i < attachments.length; i++) {
+ * if (attachments[i].modelURL === hatURL) {
+ * attachments.splice(i, 1);
+ * MyAvatar.setAttachmentData(attachments);
+ * break;
+ * }
+ * }
+ */
Q_INVOKABLE virtual void setAttachmentData(const QVector& attachmentData);
+ /**jsdoc
+ * Attach 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 MyAvatar.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}) 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.
+ * @param {boolean} [isSoft=false] - If the model has a skeleton, set this to true
so that the bones of the
+ * attached model's skeleton are be rotated to fit the avatar's current pose. isSoft
is used, for example,
+ * to have clothing that moves with the avatar.
+ * If true
, the translation
, rotation
, and scale
parameters are
+ * ignored.
+ * @param {boolean} [allowDuplicates=false]
+ * @param {boolean} [useSaved=true]
+ * @example Attach a cowboy hat to your avatar's head.
+ * var attachment = {
+ * modelURL: "https://s3.amazonaws.com/hifi-public/tony/cowboy-hat.fbx",
+ * jointName: "Head",
+ * translation: {"x": 0, "y": 0.25, "z": 0},
+ * rotation: {"x": 0, "y": 0, "z": 0, "w": 1},
+ * scale: 1,
+ * isSoft: false
+ * };
+ *
+ * MyAvatar.attach(attachment.modelURL,
+ * attachment.jointName,
+ * attachment.translation,
+ * attachment.rotation,
+ * attachment.scale,
+ * attachment.isSoft);
+ */
Q_INVOKABLE virtual void attach(const QString& modelURL, const QString& jointName = QString(),
const glm::vec3& translation = glm::vec3(), const glm::quat& rotation = glm::quat(),
float scale = 1.0f, bool isSoft = false,
bool allowDuplicates = false, bool useSaved = true);
+ /**jsdoc
+ * Detach the most recently attached instance of a particular model from either a specific joint or any joint.
+ * @function MyAvatar.detachOne
+ * @param {string} modelURL - The URL of the model to detach.
+ * @param {string} [jointName=""] - The name of the joint to detach the model from. If ""
, then the most
+ * recently attached model is removed from which ever joint it was attached to.
+ */
Q_INVOKABLE void detachOne(const QString& modelURL, const QString& jointName = QString());
+
+ /**jsdoc
+ * Detach all instances of a particular model from either a specific joint or all joints.
+ * @function MyAvatar.detachAll
+ * @param {string} modelURL - The URL of the model to detach.
+ * @param {string} [jointName=""] - The name of the joint to detach the model from. If ""
, then the model is
+ * detached from all joints.
+ */
Q_INVOKABLE void detachAll(const QString& modelURL, const QString& jointName = QString());
QString getSkeletonModelURLFromScript() const { return _skeletonModelURL.toString(); }
diff --git a/tools/jsdoc/plugins/hifi.js b/tools/jsdoc/plugins/hifi.js
index 807e31f098..d49736d7e0 100644
--- a/tools/jsdoc/plugins/hifi.js
+++ b/tools/jsdoc/plugins/hifi.js
@@ -23,6 +23,7 @@ exports.handlers = {
'../../interface/src/raypick',
'../../libraries/animation/src',
'../../libraries/avatars/src',
+ '../../libraries/avatars-renderer/src/avatars-renderer',
'../../libraries/controllers/src/controllers/',
'../../libraries/controllers/src/controllers/impl/',
'../../libraries/display-plugins/src/display-plugins/',