diff --git a/interface/src/SpeechRecognizer.h b/interface/src/SpeechRecognizer.h index 9d18f14e3a..d5f9031cfc 100644 --- a/interface/src/SpeechRecognizer.h +++ b/interface/src/SpeechRecognizer.h @@ -22,6 +22,9 @@ #include +/**jsdoc + * @namespace SpeechRecognizer + */ class SpeechRecognizer : public QObject, public Dependency { Q_OBJECT SINGLETON_DEPENDENCY @@ -31,12 +34,39 @@ public: bool getEnabled() const { return _enabled; } public slots: + + /**jsdoc + * @function SpeechRecognizer.setEnabled + * @param {boolean} enabled + */ void setEnabled(bool enabled); + + /**jsdoc + * @function SpeechRecognizer.addCommand + * @param {string} command + */ void addCommand(const QString& command); + + /**jsdoc + * @function SpeechRecognizer.removeCommand + * @param {string} command + */ void removeCommand(const QString& command); signals: + + /**jsdoc + * @function SpeechRecognizer.commandRecognized + * @param {string} command + * @returns {Signal} + */ void commandRecognized(const QString& command); + + /**jsdoc + * @function SpeechRecognizer.enabledUpdated + * @param {boolean} enabled + * @returns {Signal} + */ void enabledUpdated(bool enabled); protected: diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 6f82c7dfb9..a6d637d184 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -55,68 +55,115 @@ 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 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 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. - * @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. - */ + * @property {Vec3} qmlPosition - A synonym for position for use by QML. + * @property {boolean} shouldRenderLocally=true - If true then your avatar is rendered for you in Interface, + * otherwise it is not rendered for you (but it is still rendered for other users). + * @property {Vec3} motorVelocity=Vec3.ZERO - The target velocity of your avatar to be achieved by a scripted motor. + * @property {number} motorTimescale=1000000 - The timescale for the scripted motor to achieve the target + * motorVelocity avatar velocity. Smaller values result in higher acceleration. + * @property {string} motorReferenceFrame="camera" - Reference frame of the motorVelocity. Must be one of the + * following: "camera", "avatar", and "world". + * @property {string} motorMode="simple" - The Type of scripted motor behavior: "simple" to use the + * motorTimescale time scale; "dynamic" to use character controller timescales. + * @property {string} collisionSoundURL="Body_Hits_Impact.wav" - The sound that's played when the avatar experiences a + * collision. It can be a mono or stereo 16-bit WAV file running at either 24kHz or 48kHz. The latter is down-sampled + * by the audio mixer, so all audio effectively plays back at a 24khz. 48kHz RAW files are also supported. + * @property {number} audioListenerMode=0 - Specifies the listening position when hearing spatialized audio. Must be one + * of the following property values:
+ * audioListenerModeHead
+ * audioListenerModeCamera
+ * audioListenerModeCustom + * @property {number} audioListenerModeHead=0 - The audio listening position is at the avatar's head. Read-only. + * @property {number} audioListenerModeCamera=1 - The audio listening position is at the camera. Read-only. + * @property {number} audioListenerModeCustom=2 - The audio listening position is at a the position specified by set by the + * customListenPosition and customListenOrientation property values. Read-only. + * @property {Vec3} customListenPosition=Vec3.ZERO - The listening position used when the audioListenerMode + * property value is audioListenerModeCustom. + * @property {Quat} customListenOrientation=Quat.IDENTITY - The listening orientation used when the + * audioListenerMode property value is audioListenerModeCustom. + * @property {Vec3} leftHandPosition - The position of the left hand in avatar coordinates if it's being positioned by + * controllers, otherwise {@link Vec3(0)|Vec3.ZERO}. Read-only. + * @property {Vec3} rightHandPosition - The position of the right hand in avatar coordinates if it's being positioned by + * controllers, otherwise {@link Vec3(0)|Vec3.ZERO}. Read-only. + * @property {Vec3} leftHandTipPosition - The position 30cm offset from the left hand in avatar coordinates if it's being + * positioned by controllers, otherwise {@link Vec3(0)|Vec3.ZERO}. Read-only. + * @property {Vec3} rightHandTipPosition - The position 30cm offset from the right hand in avatar coordinates if it's being + * positioned by controllers, otherwise {@link Vec3(0)|Vec3.ZERO}. Read-only. + * @property {Pose} leftHandPose - The pose of the left hand as determined by the hand controllers. Read-only. + * @property {Pose} rightHandPose - The pose right hand position as determined by the hand controllers. Read-only. + * @property {Pose} leftHandTipPose - The pose of the left hand as determined by the hand controllers, with the position + * by 30cm. Read-only. + * @property {Pose} rightHandTipPose - The pose of the right hand as determined by the hand controllers, with the position + * by 30cm. Read-only. + * @property {boolean} hmdLeanRecenterEnabled=true - If true then the avatar is re-centered to be under the + * head's position. In room-scale VR, this behavior is what causes your avatar to follow your HMD as you walk around + * the room. Setting the value false is useful if you want to pin the avatar to a fixed position. + * @property {boolean} collisionsEnabled - Set to true to enable collisions for the avatar, false + * to disable collisions. May return true even though the value was set false because the + * zone may disallow collisionless avatars. + * @property {boolean} characterControllerEnabled - Synonym of collisionsEnabled. + * Deprecated: Use collisionsEnabled instead. + * @property {boolean} useAdvancedMovementControls - Returns the value of the Interface setting, Settings > Advanced + * Movement for Hand Controller. Note: Setting the value has no effect unless Interface is restarted. + * @property {number} yawSpeed=75 + * @property {number} pitchSpeed=50 + * @property {boolean} hmdRollControlEnabled=true - If true, the roll angle of your HMD turns your avatar + * while flying. + * @property {number} hmdRollControlDeadZone=8 - The amount of HMD roll, in degrees, required before your avatar turns if + * hmdRollControlEnabled is enabled. + * @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 {number} userHeight=1.75 - The height of the user in sensor space. + * @property {number} userEyeHeight=1.65 - The estimated height of the user's eyes in sensor space. Read-only. + * @property {Uuid} SELF_ID - 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 {number} walkSpeed + * + * @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); } @@ -200,6 +247,9 @@ public: void reset(bool andRecenter = false, bool andReload = true, bool andHead = true); + /**jsdoc + * @function MyAvatar.resetSensorsAndBody + */ Q_INVOKABLE void resetSensorsAndBody(); /**jsdoc @@ -224,7 +274,16 @@ public: const glm::vec3& getHMDSensorPosition() const { return _hmdSensorPosition; } const glm::quat& getHMDSensorOrientation() const { return _hmdSensorOrientation; } + /**jsdoc + * @function MyAvatar.setOrientationVar + * @param {object} newOrientationVar + */ Q_INVOKABLE void setOrientationVar(const QVariant& newOrientationVar); + + /**jsdoc + * @function MyAvatar.getOrientationVar + * @returns {object} + */ Q_INVOKABLE QVariant getOrientationVar() const; // A method intended to be overriden by MyAvatar for polling orientation for network transmission. @@ -246,12 +305,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 +322,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 set of specified animations. To end these animations 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 + * Avatar Standards.

* @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 +342,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 +367,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 +382,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 animations 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 + * Avatar Standards. * @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 +420,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); @@ -360,18 +434,58 @@ public: // a handler must not remove properties from animStateDictionaryIn, nor change property values that it does not intend to change. // It is not specified in what order multiple handlers are called. Q_INVOKABLE QScriptValue addAnimationStateHandler(QScriptValue handler, QScriptValue propertiesList) { return _skeletonModel->getRig().addAnimationStateHandler(handler, propertiesList); } + + /**jsdoc + * @function MyAvatar.removeAnimationStateHandler + * @param {number} handler + */ // Removes a handler previously added by addAnimationStateHandler. Q_INVOKABLE void removeAnimationStateHandler(QScriptValue handler) { _skeletonModel->getRig().removeAnimationStateHandler(handler); } + + /**jsdoc + * @function MyAvatar.getSnapTurn + * @returns {boolean} + */ Q_INVOKABLE bool getSnapTurn() const { return _useSnapTurn; } + /**jsdoc + * @function MyAvatar.setSnapTurn + * @param {boolean} on + */ Q_INVOKABLE void setSnapTurn(bool on) { _useSnapTurn = on; } + /**jsdoc + * @function MyAvatar.getClearOverlayWhenMoving + * @returns {boolean} + */ Q_INVOKABLE bool getClearOverlayWhenMoving() const { return _clearOverlayWhenMoving; } + /**jsdoc + * @function MyAvatar.setClearOverlayWhenMoving + * @returns {boolean} + */ Q_INVOKABLE void setClearOverlayWhenMoving(bool on) { _clearOverlayWhenMoving = on; } + + /**jsdoc + * @function MyAvatar.setDominantHand + * @param {string} hand + */ Q_INVOKABLE void setDominantHand(const QString& hand); + /**jsdoc + * @function MyAvatar.getDominantHand + * @returns {string} + */ Q_INVOKABLE QString getDominantHand() const { return _dominantHand; } + + /**jsdoc + * @function MyAvatar.setHMDLeanRecenterEnabled + * @param {boolean} enabled + */ Q_INVOKABLE void setHMDLeanRecenterEnabled(bool value) { _hmdLeanRecenterEnabled = value; } + /**jsdoc + * @function MyAvatar.getHMDLeanRecenterEnabled + * @returns {boolean} + */ Q_INVOKABLE bool getHMDLeanRecenterEnabled() const { return _hmdLeanRecenterEnabled; } bool useAdvancedMovementControls() const { return _useAdvancedMovementControls.get(); } @@ -397,70 +511,241 @@ public: void setDriveKey(DriveKeys key, float val); void setSprintMode(bool sprint); float getDriveKey(DriveKeys key) const; + + /**jsdoc + * @function MyAvatar.getRawDriveKey + * @param {DriveKeys} key + * @returns {number} + */ Q_INVOKABLE float getRawDriveKey(DriveKeys key) const; + void relayDriveKeysToCharacterController(); + /**jsdoc + * @function MyAvatar.disableDriveKey + * @param {DriveKeys} key + */ Q_INVOKABLE void disableDriveKey(DriveKeys key); + + /**jsdoc + * @function MyAvatar.enableDriveKey + * @param {DriveKeys} key + */ Q_INVOKABLE void enableDriveKey(DriveKeys key); + /**jsdoc + * @function MyAvatar.isDriveKeyDisabled + * @param {DriveKeys} key + * @returns {boolean} + */ Q_INVOKABLE bool isDriveKeyDisabled(DriveKeys key) const; - /**jsdoc - *The triggerVerticalRecenter function activates one time the recentering - *behaviour in the vertical direction. This call is only takes effect when the property - *MyAvatar.hmdLeanRecenterEnabled is set to false. - *@function MyAvatar.triggerVerticalRecenter - * - */ /**jsdoc - *The triggerHorizontalRecenter function activates one time the recentering behaviour - *in the horizontal direction. This call is only takes effect when the property - *MyAvatar.hmdLeanRecenterEnabled is set to false. - *@function MyAvatar.triggerHorizontalRecenter - */ - - /**jsdoc - *The triggerRotationRecenter function activates one time the recentering behaviour - *in the rotation of the root of the avatar. This call is only takes effect when the property - *MyAvatar.hmdLeanRecenterEnabled is set to false. - *@function MyAvatar.triggerRotationRecenter - */ - + * Recenter the avatar in the vertical direction, if {@link MyAvatar|MyAvatar.hmdLeanRecenterEnabled} is + * false. + * @function MyAvatar.triggerVerticalRecenter + */ Q_INVOKABLE void triggerVerticalRecenter(); + + /**jsdoc + * Recenter the avatar in the horizontal direction, if {@link MyAvatar|MyAvatar.hmdLeanRecenterEnabled} is + * false. + * @ function MyAvatar.triggerHorizontalRecenter + */ Q_INVOKABLE void triggerHorizontalRecenter(); + + /**jsdoc + * Recenter the avatar's rotation, if {@link MyAvatar|MyAvatar.hmdLeanRecenterEnabled} is false. + * @function MyAvatar.triggerRotationRecenter + */ 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(); } + + /**jsdoc + * @function MyAvatar.getHeadFinalYaw + * @returns {number} + */ Q_INVOKABLE float getHeadFinalYaw() const { return getHead()->getFinalYaw(); } + + /**jsdoc + * @function MyAvatar.getHeadFinalRoll + * @returns {number} + */ Q_INVOKABLE float getHeadFinalRoll() const { return getHead()->getFinalRoll(); } + + /**jsdoc + * @function MyAvatar.getHeadFinalPitch + * @returns {number} + */ Q_INVOKABLE float getHeadFinalPitch() const { return getHead()->getFinalPitch(); } + + /**jsdoc + * @function MyAvatar.getHeadDeltaPitch + * @returns {number} + */ 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; } + + /**jsdoc + * @function MyAvatar.getTargetAvatar + * @returns {AvatarData} + */ Q_INVOKABLE ScriptAvatarData* getTargetAvatar() const; + + /**jsdoc + * Get the position of the avatar's left hand as positioned 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.)

+ * @function MyAvatar.getLeftHandPosition + * @returns {Vec3} The position of the left hand in avatar coordinates if positioned by a hand controller, otherwise + * {@link Vec3(0)|Vec3.ZERO}. + * @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 positioned 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.)

+ * @function MyAvatar.getRightHandPosition + * @returns {Vec3} The position of the right hand in avatar coordinates if positioned by a hand controller, otherwise + * {@link Vec3(0)|Vec3.ZERO}. + * @example Report the position of your right hand relative to your avatar. + * print(JSON.stringify(MyAvatar.getLeftHandPosition())); + */ Q_INVOKABLE glm::vec3 getRightHandPosition() const; + + /**jsdoc + * @function MyAvatar.getLeftHandTipPosition + * @returns {Vec3} + */ Q_INVOKABLE glm::vec3 getLeftHandTipPosition() const; + + /**jsdoc + * @function MyAvatar.getRightHandTipPosition + * @returns {Vec3} + */ Q_INVOKABLE glm::vec3 getRightHandTipPosition() const; + + /**jsdoc + * Get the pose (position, rotation, velocity, and angular velocity) of the avatar's left hand as positioned 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 positioned 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; + + /**jsdoc + * @function MyAvatar.getLeftHandTipPose + * @returns {Pose} + */ Q_INVOKABLE controller::Pose getLeftHandTipPose() const; + + /**jsdoc + * @function MyAvatar.getRightHandTipPose + * @returns {Pose} + */ Q_INVOKABLE controller::Pose getRightHandTipPose() const; // world-space to avatar-space rigconversion functions + /**jsdoc + * @function MyAvatar.worldToJointPoint + * @param {Vec3} position + * @param {number} [jointIndex=-1] + * @returns {Vec3} + */ Q_INVOKABLE glm::vec3 worldToJointPoint(const glm::vec3& position, const int jointIndex = -1) const; + + /**jsdoc + * @function MyAvatar.worldToJointDirection + * @param {Vec3} direction + * @param {number} [jointIndex=-1] + * @returns {Vec3} + */ Q_INVOKABLE glm::vec3 worldToJointDirection(const glm::vec3& direction, const int jointIndex = -1) const; + + /**jsdoc + * @function MyAvatar.worldToJointRotation + * @param {Quat} rotation + * @param {number} [jointIndex=-1] + * @returns {Quat} + */ Q_INVOKABLE glm::quat worldToJointRotation(const glm::quat& rotation, const int jointIndex = -1) const; + + /**jsdoc + * @function MyAvatar.jointToWorldPoint + * @param {vec3} position + * @param {number} [jointIndex=-1] + * @returns {Vec3} + */ Q_INVOKABLE glm::vec3 jointToWorldPoint(const glm::vec3& position, const int jointIndex = -1) const; + + /**jsdoc + * @function MyAvatar.jointToWorldDirection + * @param {Vec3} direction + * @param {number} [jointIndex=-1] + * @returns {Vec3} + */ Q_INVOKABLE glm::vec3 jointToWorldDirection(const glm::vec3& direction, const int jointIndex = -1) const; + + /**jsdoc + * @function MyAvatar.jointToWorldRotation + * @param {Quat} rotation + * @param {number} [jointIndex=-1] + * @returns {Quat} + */ Q_INVOKABLE glm::quat jointToWorldRotation(const glm::quat& rotation, const int jointIndex = -1) const; AvatarWeakPointer getLookAtTargetAvatar() const { return _lookAtTargetAvatar; } @@ -479,15 +764,55 @@ public: virtual void clearJointData(const QString& name) override; virtual void clearJointsData() override; + /**jsdoc + * @function MyAvatar.pinJoint + * @param {number} index + * @param {Vec3} position + * @param {Quat} orientation + * @returns {boolean} + */ Q_INVOKABLE bool pinJoint(int index, const glm::vec3& position, const glm::quat& orientation); + bool isJointPinned(int index); + + /**jsdoc + * @function MyAvatar.clearPinOnJoint + * @param {number} index + * @returns {boolean} + */ Q_INVOKABLE bool clearPinOnJoint(int index); + /**jsdoc + * @function MyAvatar.getIKErrorOnLastSolve + * @returns {number} + */ Q_INVOKABLE float getIKErrorOnLastSolve() const; + /**jsdoc + * @function MyAvatar.useFullAvatarURL + * @param {string} fullAvatarURL + * @param {string} [modelName=""] + */ 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()); + */ Q_INVOKABLE QString getFullAvatarModelName() const { return _fullAvatarModelName; } + void resetFullAvatarURL(); virtual void setAttachmentData(const QVector& attachmentData) override; @@ -544,17 +869,68 @@ public: QVariantList getAvatarEntitiesVariant(); void removeAvatarEntities(); + /**jsdoc + * @function MyAvatar.isFlying + * @returns {boolean} + */ Q_INVOKABLE bool isFlying(); + + /**jsdoc + * @function MyAvatar.isInAir + * @returns {boolean} + */ Q_INVOKABLE bool isInAir(); + + /**jsdoc + * @function MyAvatar.setFlyingEnabled + * @param {boolean} enabled + */ Q_INVOKABLE void setFlyingEnabled(bool enabled); + + /**jsdoc + * @function MyAvatar.getFlyingEnabled + * @returns {boolean} + */ Q_INVOKABLE bool getFlyingEnabled(); + + /**jsdoc + * @function MyAvatar.getAvatarScale + * @returns {number} + */ Q_INVOKABLE float getAvatarScale(); + + /**jsdoc + * @function MyAvatar.setAvatarScale + * @param {number} scale + */ Q_INVOKABLE void setAvatarScale(float scale); + + /**jsdoc + * @function MyAvatar.setCollisionsEnabled + * @param {boolean} enabled + */ Q_INVOKABLE void setCollisionsEnabled(bool enabled); + + /**jsdoc + * @function MyAvatar.getCollisionsEnabled + * @returns {boolean} + */ Q_INVOKABLE bool getCollisionsEnabled(); + + /**jsdoc + * @function MyAvatar.setCharacterControllerEnabled + * @param {boolean} enabled + * @deprecated + */ Q_INVOKABLE void setCharacterControllerEnabled(bool enabled); // deprecated + + /**jsdoc + * @function MyAvatar.getCharacterControllerEnabled + * @returns {boolean} + * @deprecated + */ Q_INVOKABLE bool getCharacterControllerEnabled(); // deprecated virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override; @@ -580,7 +956,18 @@ public: // results are in HMD frame glm::mat4 deriveBodyFromHMDSensor() const; + /**jsdoc + * @function MyAvatar.isUp + * @param {Vec3} direction + * @returns {boolean} + */ Q_INVOKABLE bool isUp(const glm::vec3& direction) { return glm::dot(direction, _worldUpDirection) > 0.0f; }; // true iff direction points up wrt avatar's definition of up. + + /**jsdoc + * @function MyAvatar.isDown + * @param {Vec3} direction + * @returns {boolean} + */ Q_INVOKABLE bool isDown(const glm::vec3& direction) { return glm::dot(direction, _worldUpDirection) < 0.0f; }; void setUserHeight(float value); @@ -595,69 +982,337 @@ 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(); + + /**jsdoc + * @function MyAvatar.animGraphLoaded + */ void animGraphLoaded(); + /**jsdoc + * @function MyAvatar.setGravity + * @param {number} gravity + */ void setGravity(float gravity); + + /**jsdoc + * @function MyAvatar.getGravity + * @returns {number} + */ 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); + + /**jsdoc + * @function MyAvatar.goToLocationAndEnableCollisions + * @param {Vec3} position + */ void goToLocationAndEnableCollisions(const glm::vec3& newPosition); + + /**jsdoc + * @function MyAvatar.safeLanding + * @param {Vec3} position + * @returns {boolean} + */ bool safeLanding(const glm::vec3& position); + + /**jsdoc + * @function MyAvatar.restrictScaleFromDomainSettings + * @param {objecct} domainSettingsObject + */ void restrictScaleFromDomainSettings(const QJsonObject& domainSettingsObject); + + /**jsdoc + * @function MyAvatar.clearScaleRestriction + */ void clearScaleRestriction(); + + /**jsdoc + * @function MyAvatar.addThrust + * @param {Vec3} thrust + */ // Set/Get update the thrust that will move the avatar around void addThrust(glm::vec3 newThrust) { _thrust += newThrust; }; + + /**jsdoc + * @function MyAvatar.getThrust + * @returns {vec3} + */ glm::vec3 getThrust() { return _thrust; }; + + /**jsdoc + * @function MyAvatar.setThrust + * @param {Vec3} thrust + */ void setThrust(glm::vec3 newThrust) { _thrust = newThrust; } + + /**jsdoc + * @function MyAvatar.updateMotionBehaviorFromMenu + */ Q_INVOKABLE void updateMotionBehaviorFromMenu(); + + /**jsdoc + * @function MyAvatar.setEnableDebugDrawDefaultPose + * @param {boolean} enabled + */ void setEnableDebugDrawDefaultPose(bool isEnabled); + /**jsdoc + * @function MyAvatar.setEnableDebugDrawAnimPose + * @param {boolean} enabled + */ void setEnableDebugDrawAnimPose(bool isEnabled); + /**jsdoc + * @function MyAvatar.setEnableDebugDrawPosition + * @param {boolean} enabled + */ void setEnableDebugDrawPosition(bool isEnabled); + /**jsdoc + * @function MyAvatar.setEnableDebugDrawHandControllers + * @param {boolean} enabled + */ void setEnableDebugDrawHandControllers(bool isEnabled); + /**jsdoc + * @function MyAvatar.setEnableDebugDrawSensorToWorldMatrix + * @param {boolean} enabled + */ void setEnableDebugDrawSensorToWorldMatrix(bool isEnabled); + /**jsdoc + * @function MyAvatar.setEnableDebugDrawIKTargets + * @param {boolean} enabled + */ void setEnableDebugDrawIKTargets(bool isEnabled); + /**jsdoc + * @function MyAvatar.setEnableDebugDrawIKConstraints + * @param {boolean} enabled + */ void setEnableDebugDrawIKConstraints(bool isEnabled); + /**jsdoc + * @function MyAvatar.setEnableDebugDrawIKChains + * @param {boolean} enabled + */ void setEnableDebugDrawIKChains(bool isEnabled); + /**jsdoc + * @function MyAvatar.setEnableDebugDrawDetailedCollision + * @param {boolean} enabled + */ 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); + + /**jsdoc + * @function MyAvatar.setEnableInverseKinematics + * @param {boolean} enabled + */ void setEnableInverseKinematics(bool isEnabled); + + /**jsdoc + * @function MyAvatar.getAnimGraphOverrideUrl + * @returns {string} + */ QUrl getAnimGraphOverrideUrl() const; // thread-safe + + /**jsdoc + * @function MyAvatar.setAnimGraphOverrideUrl + * @param {string} url + */ void setAnimGraphOverrideUrl(QUrl value); // thread-safe + + /**jsdoc + * @function MyAvatar.getAnimGraphUrl + * @returns {string} + */ QUrl getAnimGraphUrl() const; // thread-safe + + /**jsdoc + * @function MyAvatar.setAnimGraphUrl + * @param {string} url + */ void setAnimGraphUrl(const QUrl& url); // thread-safe + + /**jsdoc + * @function MyAvatar.getPositionForAudio + * @returns {Vec3} + */ glm::vec3 getPositionForAudio(); + + /**jsdoc + * @function MyAvatar.getOrientationForAudio + * @returns {Quat} + */ glm::quat getOrientationForAudio(); + + /**jsdoc + * @function MyAvatar.setModelScale + * @param {number} scale + */ virtual void setModelScale(float scale) override; signals: + + /**jsdoc + * @function MyAvatar.audioListenerModeChanged + * @returns {Signal} + */ void audioListenerModeChanged(); + + /**jsdoc + * @function MyAvatar.transformChanged + * @returns {Signal} + */ void transformChanged(); + + /**jsdoc + * @function MyAvatar.newCollisionSoundURL + * @param {string} url + * @returns {Signal} + */ 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 avatar collides with an entity. + * MyAvatar.collisionWithEntity.connect(function (collision) { + * print("Your avatar collided with an entity."); + * }); + */ void collisionWithEntity(const Collision& collision); + + /**jsdoc + * @function MyAvatar.energyChanged + * @param {number} energy + * @returns {Signal} + */ void energyChanged(float newEnergy); + + /**jsdoc + * @function MyAvatar.positionGoneTo + * @returns {Signal} + */ + // FIXME: Better name would be goneToLocation(). void positionGoneTo(); + + /**jsdoc + * @function MyAvatar.onLoadComplete + * @returns {Signal} + */ void onLoadComplete(); + + /**jsdoc + * @function MyAvatar.wentAway + * @returns {Signal} + */ void wentAway(); + + /**jsdoc + * @function MyAvatar.wentActive + * @returns {Signal} + */ void wentActive(); + + /**jsdoc + * @function MyAvatar.skeletonChanged + * @returns {Signal} + */ void skeletonChanged(); + + /**jsdoc + * @function MyAvatar.dominantHandChanged + * @param {string} hand + * @returns {Signal} + */ void dominantHandChanged(const QString& hand); + + /**jsdoc + * @function MyAvatar.sensorToWorldScaleChanged + * @param {number} scale + * @returns {Signal} + */ void sensorToWorldScaleChanged(float sensorToWorldScale); + + /**jsdoc + * @function MyAvatar.attachmentsChanged + * @returns {Signal} + */ void attachmentsChanged(); + + /**jsdoc + * @function MyAvatar.scaleChanged + * @returns {Signal} + */ void scaleChanged(); private slots: diff --git a/interface/src/scripting/SelectionScriptingInterface.cpp b/interface/src/scripting/SelectionScriptingInterface.cpp index 5f762ab511..9716b7e665 100644 --- a/interface/src/scripting/SelectionScriptingInterface.cpp +++ b/interface/src/scripting/SelectionScriptingInterface.cpp @@ -56,6 +56,19 @@ bool GameplayObjects::removeFromGameplayObjects(const OverlayID& overlayID) { SelectionScriptingInterface::SelectionScriptingInterface() { } +/**jsdoc + * + * + * + * + * + * + * + * + * + *
ValueDescription
"avatar"
"entity"
"overlay"
+ * @typedef {string} Selection.ItemType + */ bool SelectionScriptingInterface::addToSelectedItemsList(const QString& listName, const QString& itemType, const QUuid& id) { if (itemType == "avatar") { return addToGameplayObjects(listName, (QUuid)id); @@ -255,6 +268,12 @@ void SelectionScriptingInterface::printList(const QString& listName) { } } +/**jsdoc + * @typedef {object} Selection.SelectedItemsList + * @property {Uuid[]} avatars - The IDs of the avatars in the selection. + * @property {Uuid[]} entities - The IDs of the entities in the selection. + * @property {Uuid[]} overlays - The IDs of the overlays in the selection. + */ QVariantMap SelectionScriptingInterface::getSelectedItemsList(const QString& listName) const { QReadLocker lock(&_selectionListsLock); QVariantMap list; @@ -461,6 +480,20 @@ bool SelectionHighlightStyle::fromVariantMap(const QVariantMap& properties) { return true; } +/**jsdoc + * @typedef {object} Selection.HighlightStyle + * @property {Color} outlineUnoccludedColor - Color of the specified highlight region. + * @property {Color} outlineOccludedColor - "" + * @property {Color} fillUnoccludedColor- "" + * @property {Color} fillOccludedColor- "" + * @property {number} outlineUnoccludedAlpha - Alpha value ranging from 0.0 (not visible) to 1.0 + * (fully opaque) for the specified highlight region. + * @property {number} outlineOccludedAlpha - "" + * @property {number} fillUnoccludedAlpha - "" + * @property {number} fillOccludedAlpha - "" + * @property {number} outlineWidth - Width of the outline, in pixels. + * @property {boolean} isOutlineSmooth - true to enable outline smooth fall-off. + */ QVariantMap SelectionHighlightStyle::toVariantMap() const { QVariantMap properties; diff --git a/interface/src/scripting/SelectionScriptingInterface.h b/interface/src/scripting/SelectionScriptingInterface.h index ed6efb39c6..71ff41248a 100644 --- a/interface/src/scripting/SelectionScriptingInterface.h +++ b/interface/src/scripting/SelectionScriptingInterface.h @@ -82,6 +82,46 @@ protected: render::HighlightStyle _style; }; +/**jsdoc + * The Selection API provides a means of grouping together avatars, entities, and overlays in named lists. + * @namespace Selection + * + * @example Outline an entity when it is grabbed by a controller. + * // Create a box and copy the following text into the entity's "Script URL" field. + * (function () { + * print("Starting highlight script..............."); + * var _this = this; + * var prevID = 0; + * var listName = "contextOverlayHighlightList"; + * var listType = "entity"; + * + * _this.startNearGrab = function(entityID){ + * if (prevID !== entityID) { + * Selection.addToSelectedItemsList(listName, listType, entityID); + * prevID = entityID; + * } + * }; + * + * _this.releaseGrab = function(entityID){ + * if (prevID !== 0) { + * Selection.removeFromSelectedItemsList("contextOverlayHighlightList", listType, prevID); + * prevID = 0; + * } + * }; + * + * var cleanup = function(){ + * Entities.findEntities(MyAvatar.position, 1000).forEach(function(entity) { + * try { + * Selection.removeListFromMap(listName); + * } catch (e) { + * print("Error cleaning up."); + * } + * }); + * }; + * + * Script.scriptEnding.connect(cleanup); + * }); + */ class SelectionScriptingInterface : public QObject, public Dependency { Q_OBJECT @@ -89,138 +129,120 @@ public: SelectionScriptingInterface(); /**jsdoc - * Query the names of all the selection lists + * Get the names of all the selection lists. * @function Selection.getListNames - * @return An array of names of all the selection lists + * @return {list[]} An array of names of all the selection lists. */ Q_INVOKABLE QStringList getListNames() const; /**jsdoc - * Removes a named selection from the list of selections. + * Delete a named selection list. * @function Selection.removeListFromMap - * @param listName {string} name of the selection - * @returns {bool} true if the selection existed and was successfully removed. + * @param {string} listName - The name of the selection list. + * @returns {boolean} true if the selection existed and was successfully removed, otherwise false. */ Q_INVOKABLE bool removeListFromMap(const QString& listName); /**jsdoc - * Add an item in a selection. + * Add an item to a selection list. * @function Selection.addToSelectedItemsList - * @param listName {string} name of the selection - * @param itemType {string} the type of the item (one of "avatar", "entity" or "overlay") - * @param id {EntityID} the Id of the item to add to the selection - * @returns {bool} true if the item was successfully added. + * @param {string} listName - The name of the selection list to add the item to. + * @param {Selection.ItemType} itemType - The type of the item being added. + * @param {Uuid} id - The ID of the item to add to the selection. + * @returns {boolean} true if the item was successfully added, otherwise false. */ Q_INVOKABLE bool addToSelectedItemsList(const QString& listName, const QString& itemType, const QUuid& id); /**jsdoc - * Remove an item from a selection. + * Remove an item from a selection list. * @function Selection.removeFromSelectedItemsList - * @param listName {string} name of the selection - * @param itemType {string} the type of the item (one of "avatar", "entity" or "overlay") - * @param id {EntityID} the Id of the item to remove - * @returns {bool} true if the item was successfully removed. + * @param {string} listName - The name of the selection list to remove the item from. + * @param {Selection.ItemType} itemType - The type of the item being removed. + * @param {Uuid} id - The ID of the item to remove. + * @returns {boolean} true if the item was successfully removed, otherwise false. + * is returned if the list doesn't contain any data. */ Q_INVOKABLE bool removeFromSelectedItemsList(const QString& listName, const QString& itemType, const QUuid& id); /**jsdoc * Remove all items from a selection. * @function Selection.clearSelectedItemsList - * @param listName {string} name of the selection - * @returns {bool} true if the item was successfully cleared. + * @param {string} listName - The name of the selection list. + * @returns {boolean} true if the item was successfully cleared, otherwise false. */ Q_INVOKABLE bool clearSelectedItemsList(const QString& listName); /**jsdoc - * Prints out the list of avatars, entities and overlays stored in a particular selection. + * Print out the list of avatars, entities, and overlays in a selection to the debug log (not the script log). * @function Selection.printList - * @param listName {string} name of the selection + * @param {string} listName - The name of the selection list. */ Q_INVOKABLE void printList(const QString& listName); /**jsdoc - * Query the list of avatars, entities and overlays stored in a particular selection. + * Get the list of avatars, entities, and overlays stored in a selection list. * @function Selection.getList - * @param listName {string} name of the selection - * @return a js object describing the content of a selection list with the following properties: - * - "entities": [ and array of the entityID of the entities in the selection] - * - "avatars": [ and array of the avatarID of the avatars in the selection] - * - "overlays": [ and array of the overlayID of the overlays in the selection] - * If the list name doesn't exist, the function returns an empty js object with no properties. + * @param {string} listName - The name of the selection list. + * @return {Selection.SelectedItemsList} The content of a selection list. If the list name doesn't exist, the function + * returns an empty object with no properties. */ Q_INVOKABLE QVariantMap getSelectedItemsList(const QString& listName) const; /**jsdoc - * Query the names of the highlighted selection lists + * Get the names of the highlighted selection lists. * @function Selection.getHighlightedListNames - * @return An array of names of the selection list currently highlight enabled + * @return {string[]} An array of names of the selection list currently highlight enabled. */ Q_INVOKABLE QStringList getHighlightedListNames() const; /**jsdoc - * Enable highlighting for the named selection. - * If the Selection doesn't exist, it will be created. - * All objects in the list will be displayed with the highlight effect as specified from the highlightStyle. - * The function can be called several times with different values in the style to modify it. - * + * Enable highlighting for a selection list. + * If the selection list doesn't exist, it will be created. + * All objects in the list will be displayed with the highlight effect specified. + * The function can be called several times with different values in the style to modify it.
+ * Note: This function implicitly calls {@link Selection.enableListToScene}. * @function Selection.enableListHighlight - * @param listName {string} name of the selection - * @param highlightStyle {jsObject} highlight style fields (see Selection.getListHighlightStyle for a detailed description of the highlightStyle). - * @returns {bool} true if the selection was successfully enabled for highlight. - * - * Note: This function will implicitly call Selection.enableListToScene + * @param {string} listName - The name of the selection list. + * @param {Selection.HighlightStyle} highlightStyle - The highlight style. + * @returns {boolean} true if the selection was successfully enabled for highlight. */ Q_INVOKABLE bool enableListHighlight(const QString& listName, const QVariantMap& highlightStyle); /**jsdoc - * Disable highlighting for the named selection. - * If the Selection doesn't exist or wasn't enabled for highliting then nothing happens simply returning false. - * + * Disable highlighting for the selection list. + * If the selection list doesn't exist or wasn't enabled for highlighting then nothing happens and false is + * returned.
+ * Note: This function implicitly calls {@link Selection.disableListToScene}. * @function Selection.disableListHighlight - * @param listName {string} name of the selection - * @returns {bool} true if the selection was successfully disabled for highlight, false otherwise. - * - * Note: This function will implicitly call Selection.disableListToScene + * @param {string} listName - The name of the selection list. + * @returns {boolean} true if the selection was successfully disabled for highlight, otherwise + * false. */ Q_INVOKABLE bool disableListHighlight(const QString& listName); /**jsdoc - * Enable scene selection for the named selection. + * Enable scene selection for the selection list. * If the Selection doesn't exist, it will be created. * All objects in the list will be sent to a scene selection. - * * @function Selection.enableListToScene - * @param listName {string} name of the selection - * @returns {bool} true if the selection was successfully enabled on the scene. + * @param {string} listName - The name of the selection list. + * @returns {boolean} true if the selection was successfully enabled on the scene, otherwise false. */ Q_INVOKABLE bool enableListToScene(const QString& listName); + /**jsdoc * Disable scene selection for the named selection. - * If the Selection doesn't exist or wasn't enabled on the scene then nothing happens simply returning false. - * + * If the selection list doesn't exist or wasn't enabled on the scene then nothing happens and false is + * returned. * @function Selection.disableListToScene - * @param listName {string} name of the selection - * @returns {bool} true if the selection was successfully disabled on the scene, false otherwise. + * @param {string} listName - The name of the selection list. + * @returns {boolean} true if the selection was successfully disabled on the scene, false otherwise. */ Q_INVOKABLE bool disableListToScene(const QString& listName); /**jsdoc - * Query the highlight style values for the named selection. - * If the Selection doesn't exist or hasn't been highlight enabled yet, it will return an empty object. - * Otherwise, the jsObject describes the highlight style properties: - * - outlineUnoccludedColor: {xColor} Color of the specified highlight region - * - outlineOccludedColor: {xColor} " - * - fillUnoccludedColor: {xColor} " - * - fillOccludedColor: {xColor} " - * - * - outlineUnoccludedAlpha: {float} Alpha value ranging from 0.0 (not visible) to 1.0 (fully opaque) for the specified highlight region - * - outlineOccludedAlpha: {float} " - * - fillUnoccludedAlpha: {float} " - * - fillOccludedAlpha: {float} " - * - * - outlineWidth: {float} width of the outline expressed in pixels - * - isOutlineSmooth: {bool} true to enable oultine smooth falloff - * + * Get the highlight style values for the a selection list. + * If the selection doesn't exist or hasn't been highlight enabled yet, an empty object is returned. * @function Selection.getListHighlightStyle - * @param listName {string} name of the selection - * @returns {jsObject} highlight style as described above + * @param {string} listName - The name of the selection list. + * @returns {Selection.HighlightStyle} highlight style */ Q_INVOKABLE QVariantMap getListHighlightStyle(const QString& listName) const; @@ -232,6 +254,12 @@ public: void onSelectedItemsListChanged(const QString& listName); signals: + /**jsoc + * Triggered when a list's content changes. + * @function Selection.selectedItemsListChanged + * @param {string} listName - The name of the selection list that changed. + * @returns {Signal} + */ void selectedItemsListChanged(const QString& listName); private: diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index bf0adc5c05..01114b5f6d 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 MyAvatar.h. Q_PROPERTY(glm::vec3 skeletonOffset READ getSkeletonOffset WRITE setSkeletonOffset) public: @@ -128,14 +120,25 @@ public: virtual int getJointIndex(const QString& name) const override; virtual QStringList getJointNames() const override; + /**jsdoc + * @function MyAvatar.getDefaultJointRotation + * @param {number} index + * @returns {Quat} + */ Q_INVOKABLE virtual glm::quat getDefaultJointRotation(int index) const; + + /**jsdoc + * @function MyAvatar.getDefaultJointTranslation + * @param {number} index + * @returns {Vec3} + */ Q_INVOKABLE virtual glm::vec3 getDefaultJointTranslation(int index) const; /**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 +147,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,14 +173,65 @@ 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; + /**jsdoc + * @function MyAvatar.getAcceleration + * @returns {Vec3} + */ Q_INVOKABLE glm::vec3 getAcceleration() const { return _acceleration; } /// Scales a world space position vector relative to the avatar position and scale @@ -201,24 +255,47 @@ public: void setPositionViaScript(const glm::vec3& position) override; void setOrientationViaScript(const glm::quat& orientation) override; - // these call through to the SpatiallyNestable versions, but they are here to expose these to javascript. + + /**jsdoc + * @function MyAvatar.getParentID + * @returns {Uuid} + */ + // This calls through to the SpatiallyNestable versions, but is here to expose these to JavaScript. Q_INVOKABLE virtual const QUuid getParentID() const override { return SpatiallyNestable::getParentID(); } + + /**jsdoc + * @function MyAvatar.setParentID + * @param {Uuid} parentID + */ + // This calls through to the SpatiallyNestable versions, but is here to expose these to JavaScript. Q_INVOKABLE virtual void setParentID(const QUuid& parentID) override; + + /**jsdoc + * @function MyAvatar.getParentJointIndex + * @returns {number} + */ + // This calls through to the SpatiallyNestable versions, but is here to expose these to JavaScript. Q_INVOKABLE virtual quint16 getParentJointIndex() const override { return SpatiallyNestable::getParentJointIndex(); } + + /**jsdoc + * @function MyAvatar.setParentJointIndex + * @param {number} parentJointIndex + */ + // This calls through to the SpatiallyNestable versions, but is here to expose these to JavaScript. 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) - */ /**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. + * 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 + * 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(); @@ -235,6 +312,11 @@ public: void setTargetScale(float targetScale) override; float getTargetScale() const { return _targetScale; } + /**jsdoc + * @function MyAvatar.getSimulationRate + * @param {string} [rateName=""] + * @returns {number} + */ Q_INVOKABLE float getSimulationRate(const QString& rateName = QString("")) const; bool hasNewJointData() const { return _hasNewJointData; } @@ -256,6 +338,7 @@ public: bool isFading() const { return _isFading; } void updateFadingStatus(render::ScenePointer scene); + // JSDoc is in AvatarData.h. Q_INVOKABLE virtual float getEyeHeight() const override; // returns eye height of avatar in meters, ignoring avatar scale. @@ -282,16 +365,57 @@ 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 void setModelURLFinished(bool success); - // hooked up to Model::rigReady & rigReset signals + /**jsdoc + * @function MyAvatar.rigReady + * @returns {Signal} + */ + // Hooked up to Model::rigReady signal void rigReady(); + + /**jsdoc + * @function MyAvatar.rigReset + * @returns {Signal} + */ + // Jooked up to Model::rigReset signal void rigReset(); protected: 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..888c3bfb24 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; @@ -547,49 +548,372 @@ public: void setDomainMinimumHeight(float domainMinimumHeight); void setDomainMaximumHeight(float domainMaximumHeight); - // Hand State + /**jsdoc + * @function MyAvatar.setHandState + * @param {string} state + */ Q_INVOKABLE void setHandState(char s) { _handState = s; } + + /**jsdoc + * @function MyAvatar.getHandState + * @returns {string} + */ Q_INVOKABLE char getHandState() const { return _handState; } const QVector& getRawJointData() const { return _jointData; } + + /**jsdoc + * @function MyAvatar.setRawJointData + * @param {JointData[]} data + */ 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.
+ * Avatar in T-pose + * + * // 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); + + /**jsdoc + * @function MyAvatar.isJointDataValid + * @param {number} index + * @returns {boolean} + */ 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.
+ * Avatar in T-pose with arm rotated + * // 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.
+ * Avatar with 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); + + /**jsdoc + * @function MyAvatar.isJointDataValid + * @param {string} name + * @returns {boolean} + */ 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; + + /**jsdoc + * @function MyAvatar.getJointTranslations + * @returns {Vec3[]} + */ 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.
+ * Avatar in T-pose + * + * // 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); + + /**jsdoc + * @function MyAvatar.setJointTranslations + * @param {Vec3[]} translations + */ 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; + + /**jsdoc + * @function MyAvatar.setBlendshape + * @param {string} name + * @param {number} value + */ Q_INVOKABLE void setBlendshape(QString name, float val) { _headData->setBlendshape(name, val); } + + /**jsdoc + * @function MyAvatar.getAttachmentsVariant + * @returns {object} + */ + // FIXME: Can this name be improved? Can it be deprecated? Q_INVOKABLE QVariantList getAttachmentsVariant() const; + + /**jsdoc + * @function MyAvatar.setAttachmentsVariant + * @param {object} variant + */ + // FIXME: Can this name be improved? Can it be deprecated? Q_INVOKABLE void setAttachmentsVariant(const QVariantList& variant); + + /**jsdoc + * @function MyAvatar.updateAvatarEntity + * @param {Uuid} entityID + * @param {string} entityData + */ Q_INVOKABLE void updateAvatarEntity(const QUuid& entityID, const QByteArray& entityData); + /**jsdoc + * @function MyAvatar.clearAvatarEntity + * @param {Uuid} entityID + */ Q_INVOKABLE void clearAvatarEntity(const QUuid& entityID); + + /**jsdoc + * @function MyAvatar.setForceFaceTrackerConnected + * @param {boolean} connected + */ Q_INVOKABLE void setForceFaceTrackerConnected(bool connected) { _forceFaceTrackerConnected = connected; } // key state @@ -627,15 +951,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(); } @@ -657,19 +1062,63 @@ public: glm::vec3 getClientGlobalPosition() const { return _globalPosition; } glm::vec3 getGlobalBoundingBoxCorner() const { return _globalPosition + _globalBoundingBoxOffset - _globalBoundingBoxDimensions; } + /**jsdoc + * @function MyAvatar.getAvatarEntityData + * @returns {object} + */ Q_INVOKABLE AvatarEntityMap getAvatarEntityData() const; + + /**jsdoc + * @function MyAvatar.setAvatarEntityData + * @param {object} avatarEntityData + */ Q_INVOKABLE void setAvatarEntityData(const AvatarEntityMap& avatarEntityData); + virtual void setAvatarEntityDataChanged(bool value) { _avatarEntityDataChanged = value; } void insertDetachedEntityID(const QUuid entityID); AvatarEntityIDs getAndClearRecentlyDetachedIDs(); + /**jsdoc + * @function MyAvatar.getSensorToWorldMatrix + * @returns {Mat4} + */ // thread safe Q_INVOKABLE glm::mat4 getSensorToWorldMatrix() const; + + /**jsdoc + * @function MyAvatar.getSensorToWorldScale + * @returns {number} + */ + // thread safe Q_INVOKABLE float getSensorToWorldScale() const; + + /**jsdoc + * @function MyAvatar.getControllerLeftHandMatrix + * @returns {Mat4} + */ + // thread safe Q_INVOKABLE glm::mat4 getControllerLeftHandMatrix() const; + + /**jsdoc + * @function MyAvatar.getControllerRightHandMatrix + * @returns {Mat4} + */ + // thread safe Q_INVOKABLE glm::mat4 getControllerRightHandMatrix() const; + + /**jsdoc + * @function MyAvatar.getDataRate + * @param {string} [rateName=""] + * @returns {number} + */ Q_INVOKABLE float getDataRate(const QString& rateName = QString("")) const; + + /**jsdoc + * @function MyAvatar.getUpdateRate + * @param {string} [rateName=""] + * @returns {number} + */ Q_INVOKABLE float getUpdateRate(const QString& rateName = QString("")) const; int getJointCount() const { return _jointData.size(); } @@ -705,17 +1154,60 @@ public: virtual void removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName) {} signals: + + /**jsdoc + * @function MyAvatar.displayNameChanged + * @returns {Signal} + */ void displayNameChanged(); + + /**jsdoc + * @function MyAvatar.sessionDisplayNameChanged + * @returns {Signal} + */ void sessionDisplayNameChanged(); + + /**jsdoc + * @function MyAvatar.skeletonModelURLChanged + * @returns {Signal} + */ void skeletonModelURLChanged(); + + /**jsdoc + * @function MyAvatar.lookAtSnappingChanged + * @param {boolean} enabled + * @returns {Signal} + */ void lookAtSnappingChanged(bool enabled); + + /**jsdoc + * @function MyAvatar.sessionUUIDChanged + * @returns {Signal} + */ void sessionUUIDChanged(); public slots: + +/**jsdoc + * @function MyAvatar.sendAvatarDataPacket + * @param {boolean} [sendAll=false] + */ void sendAvatarDataPacket(bool sendAll = false); + + /**jsdoc + * @function MyAvatar.sendIdentityPacket + */ void sendIdentityPacket(); + /**jsdoc + * @function MyAvatar.setJointMappingsFromNetworkReply + */ void setJointMappingsFromNetworkReply(); + + /**jsdoc + * @function MyAvatar.setSessionUUID + * @param {Uuid} sessionUUID + */ virtual void setSessionUUID(const QUuid& sessionUUID) { if (sessionUUID != getID()) { if (sessionUUID == QUuid()) { @@ -727,13 +1219,45 @@ public slots: } } + /**jsdoc + * @function MyAvatar.getAbsoluteJointRotationInObjectFrame + * @param {number} index + * @returns {Quat} + */ virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override; + + /**jsdoc + * @function MyAvatar.getAbsoluteJointTranslationInObjectFrame + * @param {number} index + * @returns {Vec3} + */ virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const override; + + /**jsdoc + * @function MyAvatar.setAbsoluteJointRotationInObjectFrame + * @param {number} index + * @param {Quat} rotation + * @returns {boolean} + */ virtual bool setAbsoluteJointRotationInObjectFrame(int index, const glm::quat& rotation) override { return false; } + + /**jsdoc + * @function MyAvatar.setAbsoluteJointTranslationInObjectFrame + * @param {number} index + * @param {Vec3} translation + * @returns {boolean} + */ virtual bool setAbsoluteJointTranslationInObjectFrame(int index, const glm::vec3& translation) override { return false; } + /**jsdoc + * @function MyAvatar.getTargetScale + * @returns {number} + */ float getTargetScale() const { return _targetScale; } // why is this a slot? + /**jsdoc + * @function MyAvatar.resetLastSent + */ void resetLastSent() { _lastToByteArray = 0; } protected: diff --git a/libraries/display-plugins/src/display-plugins/CompositorHelper.h b/libraries/display-plugins/src/display-plugins/CompositorHelper.h index de115b0554..bc6ed63363 100644 --- a/libraries/display-plugins/src/display-plugins/CompositorHelper.h +++ b/libraries/display-plugins/src/display-plugins/CompositorHelper.h @@ -172,6 +172,17 @@ private: ReticleInterface* _reticleInterface { nullptr }; }; +/**jsdoc + * @namespace Reticle + * @property {boolean} allowMouseCapture + * @property {number} depth + * @property {Vec2} maximumPosition + * @property {boolean} mouseCaptured + * @property {boolean} pointingAtSystemOverlay + * @property {Vec2} position + * @property {number} scale + * @property {boolean} visible + */ // Scripting interface available to control the Reticle class ReticleInterface : public QObject { Q_OBJECT @@ -187,25 +198,82 @@ class ReticleInterface : public QObject { public: ReticleInterface(CompositorHelper* outer) : QObject(outer), _compositor(outer) {} + /**jsdoc + * @function Reticle.isMouseCaptured + * @returns {boolean} + */ Q_INVOKABLE bool isMouseCaptured() { return _compositor->shouldCaptureMouse(); } + /**jsdoc + * @function Reticle.getAllowMouseCapture + * @returns {boolean} + */ Q_INVOKABLE bool getAllowMouseCapture() { return _compositor->getAllowMouseCapture(); } + + /**jsdoc + * @function Reticle.setAllowMouseCapture + * @param {boolean} allowMouseCaptured + */ Q_INVOKABLE void setAllowMouseCapture(bool value) { return _compositor->setAllowMouseCapture(value); } + /**jsdoc + * @function Reticle.isPointingAtSystemOverlay + * @returns {boolean} + */ Q_INVOKABLE bool isPointingAtSystemOverlay() { return !_compositor->getReticleOverDesktop(); } + /**jsdoc + * @function Reticle.getVisible + * @returns {boolean} + */ Q_INVOKABLE bool getVisible() { return _compositor->getReticleVisible(); } + + /**jsdoc + * @function Reticle.setVisible + * @param {boolean} visible + */ Q_INVOKABLE void setVisible(bool visible) { _compositor->setReticleVisible(visible); } + /**jsdoc + * @function Reticle.getDepth + * @returns {number} + */ Q_INVOKABLE float getDepth() { return _compositor->getReticleDepth(); } + + /**jsdoc + * @function Reticle.setDepth + * @param {number} depth + */ Q_INVOKABLE void setDepth(float depth) { _compositor->setReticleDepth(depth); } + /**jsdoc + * @function Reticle.getScale + * @returns {number} + */ Q_INVOKABLE float getScale() const; + + /**jsdoc + * @function Reticle.setScale + * @param {number} scale + */ Q_INVOKABLE void setScale(float scale); + /**jsdoc + * @function Reticle.getPosition + * @returns {Vec2} + */ Q_INVOKABLE QVariant getPosition() const; + + /**jsdoc + * @function Reticle.setPosition + * @param {Vec2} position + */ Q_INVOKABLE void setPosition(QVariant position); + /**jsdoc + * @function Reticle.getMaximumPosition + * @returns {Vec2} + */ Q_INVOKABLE glm::vec2 getMaximumPosition() { return _compositor->getReticleMaximumPosition(); } private: diff --git a/libraries/script-engine/src/RecordingScriptingInterface.h b/libraries/script-engine/src/RecordingScriptingInterface.h index 22e4d30830..0e4f90b928 100644 --- a/libraries/script-engine/src/RecordingScriptingInterface.h +++ b/libraries/script-engine/src/RecordingScriptingInterface.h @@ -23,6 +23,9 @@ class QScriptEngine; class QScriptValue; +/**jsdoc + * @namespace Recording + */ class RecordingScriptingInterface : public QObject, public Dependency { Q_OBJECT @@ -32,43 +35,196 @@ public: void setScriptEngine(QSharedPointer scriptEngine) { _scriptEngine = scriptEngine; } public slots: + + /**jsdoc + * @function Recording.loadRecording + * @param {string} url + * @param {Recording~loadRecordingCallback} [callback=null] + */ + /**jsdoc + * Called when {@link Recording.loadRecording} is complete. + * @callback Recording~loadRecordingCallback + * @param {boolean} success + * @param {string} url + */ void loadRecording(const QString& url, QScriptValue callback = QScriptValue()); + + /**jsdoc + * @function Recording.startPlaying + */ void startPlaying(); + + /**jsdoc + * @function Recording.pausePlayer + */ void pausePlayer(); + + /**jsdoc + * @function Recording.stopPlaying + */ void stopPlaying(); + + /**jsdoc + * @function Recording.isPlaying + * @returns {boolean} + */ bool isPlaying() const; + + /**jsdoc + * @function Recording.isPaused + * @returns {boolean} + */ bool isPaused() const; + + /**jsdoc + * @function Recording.playerElapsed + * @returns {number} + */ float playerElapsed() const; + + /**jsdoc + * @function Recording.playerLength + * @returns {number} + */ float playerLength() const; + + /**jsdoc + * @function Recording.setPlayerVolume + * @param {number} volume + */ void setPlayerVolume(float volume); + + /**jsdoc + * @function Recording.setPlayerAudioOffset + * @param {number} audioOffset + */ void setPlayerAudioOffset(float audioOffset); + + /**jsdoc + * @function Recording.setPlayerTime + * @param {number} time + */ void setPlayerTime(float time); + + /**jsdoc + * @function Recording.setPlayerLoop + * @param {boolean} loop + */ void setPlayerLoop(bool loop); + + /**jsdoc + * @function Recording.setPlayerUseDisplayName + * @param {boolean} useDisplayName + */ void setPlayerUseDisplayName(bool useDisplayName); + + /**jsdoc + * @function Recording.setPlayerUseAttachments + * @param {boolean} useAttachments + */ void setPlayerUseAttachments(bool useAttachments); + + /**jsdoc + * @function Recording.setPlayerUseHeadModel + * @param {boolean} useHeadModel + * @todo Note: This function currently has no effect. + */ void setPlayerUseHeadModel(bool useHeadModel); + + /**jsdoc + * @function Recording.setPlayerUseSkeletonModel + * @param {boolean} useSkeletonModel + * @todo Note: This function currently doesn't work. + */ void setPlayerUseSkeletonModel(bool useSkeletonModel); + + /**jsdoc + * @function Recording.setPlayFromCurrentLocation + * @param {boolean} playFromCurrentLocation + */ void setPlayFromCurrentLocation(bool playFromCurrentLocation); + + /**jsdoc + * @function Recording.getPlayerUseDisplayName + * @returns {boolean} + */ bool getPlayerUseDisplayName() { return _useDisplayName; } + + /**jsdoc + * @function Recording.getPlayerUseAttachments + * @returns {boolean} + */ bool getPlayerUseAttachments() { return _useAttachments; } + + /**jsdoc + * @function Recording.getPlayerUseHeadModel + * @returns {boolean} + */ bool getPlayerUseHeadModel() { return _useHeadModel; } + + /**jsdoc + * @function Recording.getPlayerUseSkeletonModel + * @returns {boolean} + */ bool getPlayerUseSkeletonModel() { return _useSkeletonModel; } + + /**jsdoc + * @function Recording.getPlayFromCurrentLocation + * @returns {boolean} + */ bool getPlayFromCurrentLocation() { return _playFromCurrentLocation; } + + /**jsdoc + * @function Recording.startRecording + */ void startRecording(); + + /**jsdoc + * @function Recording.stopRecording + */ void stopRecording(); + + /**jsdoc + * @function Recording.isRecording + * @returns {boolean} + */ bool isRecording() const; + + /**jsdoc + * @function Recording.recorderElapsed + * @returns {number} + */ float recorderElapsed() const; + + /**jsdoc + * @function Recording.getDefaultRecordingSaveDirectory + * @returns {string} + */ QString getDefaultRecordingSaveDirectory(); + + /**jsdoc + * @function Recording.saveRecording + * @param {string} filename + */ void saveRecording(const QString& filename); + + /**jsdoc + * @function Recording.saveRecordingToAsset + * @param {function} getClipAtpUrl + */ bool saveRecordingToAsset(QScriptValue getClipAtpUrl); + + /**jsdoc + * @function Recording.loadLastRecording + */ void loadLastRecording(); protected: diff --git a/libraries/script-engine/src/SceneScriptingInterface.h b/libraries/script-engine/src/SceneScriptingInterface.h index 07b8c22ca6..c69cd7090d 100644 --- a/libraries/script-engine/src/SceneScriptingInterface.h +++ b/libraries/script-engine/src/SceneScriptingInterface.h @@ -19,6 +19,13 @@ // TODO: if QT moc ever supports nested classes, subclass these to the interface instead of namespacing namespace SceneScripting { + + /**jsdoc + * @typedef Scene.Stage.Location + * @property {number} longitude + * @property {number} latitude + * @property {number} altitude + */ class Location : public QObject { Q_OBJECT @@ -41,6 +48,11 @@ namespace SceneScripting { }; using LocationPointer = std::unique_ptr; + /**jsdoc + * @typedef Scene.Stage.Time + * @property {number} hour + * @property {number} day + */ class Time : public QObject { Q_OBJECT @@ -60,6 +72,13 @@ namespace SceneScripting { }; using TimePointer = std::unique_ptr