// // MyAvatar.h // interface/src/avatar // // Created by Mark Peng on 8/16/13. // Copyright 2012 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #ifndef hifi_MyAvatar_h #define hifi_MyAvatar_h #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "AtRestDetector.h" #include "MyCharacterController.h" #include "RingBufferHistory.h" #include "devices/DdeFaceTracker.h" class AvatarActionHold; class ModelItemID; class MyHead; class DetailedMotionState; /**jsdoc *

Locomotion control types.

* * * * * * * * * *
ValueNameDescription
0DefaultYour walking speed is constant; it doesn't change depending on how far * forward you push your controller's joystick. Fully pushing your joystick forward makes your avatar run.
1AnalogYour walking speed changes in steps based on how far forward you push your * controller's joystick. Fully pushing your joystick forward makes your avatar run.
2AnalogPlusYour walking speed changes proportionally to how far forward you push * your controller's joystick. Fully pushing your joystick forward makes your avatar run.
* @typedef {number} MyAvatar.LocomotionControlsMode */ enum LocomotionControlsMode { CONTROLS_DEFAULT = 0, CONTROLS_ANALOG, CONTROLS_ANALOG_PLUS }; enum LocomotionRelativeMovementMode { MOVEMENT_HMD_RELATIVE = 0, MOVEMENT_HAND_RELATIVE, MOVEMENT_HAND_RELATIVE_LEVELED }; enum eyeContactTarget { LEFT_EYE, RIGHT_EYE, MOUTH }; enum AudioListenerMode { FROM_HEAD = 0, FROM_CAMERA, CUSTOM }; Q_DECLARE_METATYPE(AudioListenerMode); class MyAvatar : public Avatar { Q_OBJECT friend class AnimStats; /**jsdoc * 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 the environment and other avatars. * *

For assignment client scripts, see {@link Avatar}.

* * @namespace MyAvatar * * @hifi-interface * @hifi-client-entity * @hifi-avatar * * @comment IMPORTANT: This group of properties is copied from AvatarData.h; they should NOT be edited here. * @property {Vec3} position - The position of the avatar. * @property {number} scale=1.0 - The scale of the avatar. The value can be set to anything between 0.005 and * 1000.0. When the scale value is fetched, it may temporarily be further limited by the domain's settings. * @property {number} density - The density of the avatar in kg/m3. The density is used to work out its mass in * the application of physics. Read-only. * @property {Vec3} handPosition - A user-defined hand position, in world coordinates. The position moves with the avatar * but is otherwise not used or changed by Interface. * @property {number} bodyYaw - The left or right rotation about an axis running from the head to the feet of the avatar. * Yaw is sometimes called "heading". * @property {number} bodyPitch - The rotation about an axis running from shoulder to shoulder of the avatar. 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 - The orientation of the avatar. * @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 - The current velocity of the avatar. * @property {Vec3} angularVelocity - The current angular velocity of the avatar. * @property {number} audioLoudness - The instantaneous loudness of the audio input that the avatar is injecting into the * domain. * @property {number} audioAverageLoudness - The rolling average loudness of the audio input that the avatar is injecting * into the domain. * @property {string} displayName - The avatar's display name. * @property {string} sessionDisplayName - displayName's sanitized and default version defined by the avatar * mixer rather than Interface clients. The result is unique among all avatars present in the domain at the time. * @property {boolean} lookAtSnappingEnabled=true - true if the avatar's eyes snap to look at another avatar's * eyes when the other avatar is in the line of sight and also has lookAtSnappingEnabled == true. * @property {string} skeletonModelURL - The avatar's FST file. * @property {AttachmentData[]} attachmentData - Information on the avatar's attachments. *

Deprecated: This property is deprecated and will be removed. Use avatar entities instead.

* @property {string[]} jointNames - The list of joints in the current avatar model. Read-only. * @property {Uuid} sessionUUID - Unique ID of the avatar in the domain. Read-only. * @property {Mat4} sensorToWorldMatrix - The scale, rotation, and translation transform from the user's real world to the * avatar's size, orientation, and position in the virtual world. Read-only. * @property {Mat4} controllerLeftHandMatrix - The rotation and translation of the left hand controller relative to the * avatar. Read-only. * @property {Mat4} controllerRightHandMatrix - The rotation and translation of the right hand controller relative to the * avatar. Read-only. * @property {number} sensorToWorldScale - The scale that transforms dimensions in the user's real world to the avatar's * size in the virtual world. Read-only. * @property {boolean} hasPriority - true if the avatar is in a "hero" zone, false if it isn't. * Read-only. * * @comment IMPORTANT: This group of properties is copied from Avatar.h; they should NOT be edited here. * @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} qmlPosition - A synonym for position for use by QML. * * @property {Vec3} feetPosition - The position of the avatar's feet. * @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:
* Myavatar.audioListenerModeHead
* Myavatar.audioListenerModeCamera
* Myavatar.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 {boolean} hasScriptedBlendshapes=false - true to transmit blendshapes over the network.
* Note: Currently doesn't work. Use {@link MyAvatar.setForceFaceTrackerConnected} instead. * @property {boolean} hasProceduralBlinkFaceMovement=true - true if procedural blinking is turned on. * @property {boolean} hasProceduralEyeFaceMovement=true - true if procedural eye movement is turned on. * @property {boolean} hasAudioEnabledFaceMovement=true - true to move the mouth blendshapes with voice audio * when MyAvatar.hasScriptedBlendshapes is enabled. * @property {number} rotationRecenterFilterLength - Configures how quickly the avatar root rotates to recenter its facing * direction to match that of the user's torso based on head and hands orientation. A smaller value makes the * recentering happen more quickly. The minimum value is 0.01. * @property {number} rotationThreshold - The angle in radians that the user's torso facing direction (based on head and * hands orientation) can differ from that of the avatar before the avatar's root is rotated to match the user's torso. * @property {boolean} enableStepResetRotation - If true then after the user's avatar takes a step, the * avatar's root immediately rotates to recenter its facing direction to match that of the user's torso based on head * and hands orientation. * @property {boolean} enableDrawAverageFacing - If true, debug graphics are drawn that show the average * facing direction of the user's torso (based on head and hands orientation). This can be useful if you want to try * out different filter lengths and thresholds. * * @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 0.3m in front of the left hand's position, in the direction along the * palm, in avatar coordinates. If the hand isn't being positioned by a controller, the value is * {@link Vec3(0)|Vec3.ZERO}. Read-only. * @property {Vec3} rightHandTipPosition - The position 0.3m in front of the right hand's position, in the direction along * the palm, in avatar coordinates. If the hand isn't being positioned by a controller, the value is * {@link Vec3(0)|Vec3.ZERO}. Read-only. * * @property {Pose} leftHandPose - The left hand's pose as determined by the hand controllers, relative to the avatar. * Read-only. * @property {Pose} rightHandPose - The right hand's pose as determined by the hand controllers, relative to the avatar. * Read-only. * @property {Pose} leftHandTipPose - The left hand's pose as determined by the hand controllers, relative to the avatar, * with the position adjusted by 0.3m along the direction of the palm. Read-only. * @property {Pose} rightHandTipPose - The right hand's pose as determined by the hand controllers, relative to the avatar, * with the position adjusted by 0.3m along the direction of the palm. Read-only. * * @property {number} energy - Deprecated: This property will be removed. * @property {boolean} isAway - true if your avatar is away (i.e., inactive), false if it is * active. * * @property {boolean} centerOfGravityModelEnabled=true - true if the avatar hips are placed according to * the center of gravity model that balances the center of gravity over the base of support of the feet. Set the * value to false for default behavior where the hips are positioned under the head. * @property {boolean} hmdLeanRecenterEnabled=true - true IF 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 the avatar to collide with the environment, * false to disable collisions with the environment. May return true even though the value * was set false because the zone may disallow collisionless avatars. * @property {boolean} otherAvatarsCollisionsEnabled - Set to true to enable the avatar to collide with other * avatars, false to disable collisions with other avatars. * @property {boolean} characterControllerEnabled - Synonym of collisionsEnabled. *

Deprecated: This property is deprecated and will be removed. Use collisionsEnabled * instead.

* @property {boolean} useAdvancedMovementControls - Returns and sets the value of the Interface setting, Settings > * Controls > Walking. Note: Setting the value has no effect unless Interface is restarted. * @property {boolean} showPlayArea - Returns and sets the value of the Interface setting, Settings > Controls > Show room * boundaries while teleporting.
* Note: Setting the value has no effect unless Interface is restarted. * * @property {number} yawSpeed=75 - The mouse X sensitivity value in Settings > General. Read-only. * @property {number} pitchSpeed=50 - The mouse Y sensitivity value in Settings > General. Read-only. * * @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 {number} hmdRollControlRate If MyAvatar.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 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 - The walk speed of your avatar for the current control scheme (see * {@link MyAvatar.getControlScheme|getControlScheme}). * @property {number} walkBackwardSpeed - The walk backward speed of your avatar for the current control scheme (see * {@link MyAvatar.getControlScheme|getControlScheme}). * @property {number} sprintSpeed - The sprint (run) speed of your avatar for the current control scheme (see * {@link MyAvatar.getControlScheme|getControlScheme}). * @property {number} analogPlusWalkSpeed - The walk speed of your avatar for the "AnalogPlus" control scheme. *

Warning: Setting this value also sets the value of analogPlusSprintSpeed to twice * the value.

* @property {number} analogPlusSprintSpeed - The sprint (run) speed of your avatar for the "AnalogPlus" control scheme. * @property {MyAvatar.SitStandModelType} userRecenterModel - Controls avatar leaning and recentering behavior. * @property {number} isInSittingState - true if your avatar is sitting (avatar leaning is disabled, * recenntering is enabled), false if it is standing (avatar leaning is enabled, and avatar recenters if it * leans too far). If userRecenterModel == 2 (i.e., auto) the property value automatically updates as the * user sits or stands, unless isSitStandStateLocked == true. Setting the property value overrides the * current siting / standing state, which is updated when the user next sits or stands unless * isSitStandStateLocked == true. * @property {boolean} isSitStandStateLocked - true to lock the avatar sitting/standing state, i.e., use this * to disable automatically changing state. * @property {boolean} allowTeleporting - true if teleporting is enabled in the Interface settings, * false if it isn't. Read-only. * * @borrows Avatar.getDomainMinScale as getDomainMinScale * @borrows Avatar.getDomainMaxScale as getDomainMaxScale * @borrows Avatar.getEyeHeight as getEyeHeight * @borrows Avatar.getHeight as getHeight * @borrows Avatar.setHandState as setHandState * @borrows Avatar.getHandState as getHandState * @borrows Avatar.setRawJointData as setRawJointData * @borrows Avatar.setJointData as setJointData * @borrows Avatar.setJointRotation as setJointRotation * @borrows Avatar.setJointTranslation as setJointTranslation * @borrows Avatar.clearJointData as clearJointData * @borrows Avatar.isJointDataValid as isJointDataValid * @borrows Avatar.getJointRotation as getJointRotation * @borrows Avatar.getJointTranslation as getJointTranslation * @borrows Avatar.getJointRotations as getJointRotations * @borrows Avatar.getJointTranslations as getJointTranslations * @borrows Avatar.setJointRotations as setJointRotations * @borrows Avatar.setJointTranslations as setJointTranslations * @borrows Avatar.clearJointsData as clearJointsData * @borrows Avatar.getJointIndex as getJointIndex * @borrows Avatar.getJointNames as getJointNames * @borrows Avatar.setBlendshape as setBlendshape * @borrows Avatar.getAttachmentsVariant as getAttachmentsVariant * @borrows Avatar.setAttachmentsVariant as setAttachmentsVariant * @borrows Avatar.updateAvatarEntity as updateAvatarEntity * @borrows Avatar.clearAvatarEntity as clearAvatarEntity * @borrows Avatar.setForceFaceTrackerConnected as setForceFaceTrackerConnected * @borrows Avatar.setSkeletonModelURL as setSkeletonModelURL * @borrows Avatar.getAttachmentData as getAttachmentData * @borrows Avatar.setAttachmentData as setAttachmentData * @borrows Avatar.attach as attach * @borrows Avatar.detachOne as detachOne * @borrows Avatar.detachAll as detachAll * @comment Avatar.getAvatarEntityData as getAvatarEntityData - Don't borrow because implementation is different. * @comment Avatar.setAvatarEntityData as setAvatarEntityData - Don't borrow because implementation is different. * @borrows Avatar.getSensorToWorldMatrix as getSensorToWorldMatrix * @borrows Avatar.getSensorToWorldScale as getSensorToWorldScale * @borrows Avatar.getControllerLeftHandMatrix as getControllerLeftHandMatrix * @borrows Avatar.getControllerRightHandMatrix as getControllerRightHandMatrix * @borrows Avatar.getDataRate as getDataRate * @borrows Avatar.getUpdateRate as getUpdateRate * @borrows Avatar.displayNameChanged as displayNameChanged * @borrows Avatar.sessionDisplayNameChanged as sessionDisplayNameChanged * @borrows Avatar.skeletonModelURLChanged as skeletonModelURLChanged * @borrows Avatar.lookAtSnappingChanged as lookAtSnappingChanged * @borrows Avatar.sessionUUIDChanged as sessionUUIDChanged * @borrows Avatar.sendAvatarDataPacket as sendAvatarDataPacket * @borrows Avatar.sendIdentityPacket as sendIdentityPacket * @borrows Avatar.setSessionUUID as setSessionUUID * @comment Avatar.getAbsoluteJointRotationInObjectFrame as getAbsoluteJointRotationInObjectFrame - Don't borrow because implementation is different. * @comment Avatar.getAbsoluteJointTranslationInObjectFrame as getAbsoluteJointTranslationInObjectFrame - Don't borrow because implementation is different. * @comment Avatar.setAbsoluteJointRotationInObjectFrame as setAbsoluteJointRotationInObjectFrame - Don't borrow because implementation is different. * @comment Avatar.setAbsoluteJointTranslationInObjectFrame as setAbsoluteJointTranslationInObjectFrame - Don't borrow because implementation is different. * @borrows Avatar.getTargetScale as getTargetScale * @borrows Avatar.resetLastSent as resetLastSent */ // 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); } Q_PROPERTY(glm::vec3 feetPosition READ getWorldFeetPosition WRITE goToFeetLocation) Q_PROPERTY(bool shouldRenderLocally READ getShouldRenderLocally WRITE setShouldRenderLocally) Q_PROPERTY(glm::vec3 motorVelocity READ getScriptedMotorVelocity WRITE setScriptedMotorVelocity) Q_PROPERTY(float motorTimescale READ getScriptedMotorTimescale WRITE setScriptedMotorTimescale) Q_PROPERTY(QString motorReferenceFrame READ getScriptedMotorFrame WRITE setScriptedMotorFrame) Q_PROPERTY(QString motorMode READ getScriptedMotorMode WRITE setScriptedMotorMode) Q_PROPERTY(QString collisionSoundURL READ getCollisionSoundURL WRITE setCollisionSoundURL) Q_PROPERTY(AudioListenerMode audioListenerMode READ getAudioListenerMode WRITE setAudioListenerMode) Q_PROPERTY(AudioListenerMode audioListenerModeHead READ getAudioListenerModeHead) Q_PROPERTY(AudioListenerMode audioListenerModeCamera READ getAudioListenerModeCamera) Q_PROPERTY(AudioListenerMode audioListenerModeCustom READ getAudioListenerModeCustom) Q_PROPERTY(glm::vec3 customListenPosition READ getCustomListenPosition WRITE setCustomListenPosition) Q_PROPERTY(glm::quat customListenOrientation READ getCustomListenOrientation WRITE setCustomListenOrientation) Q_PROPERTY(bool hasScriptedBlendshapes READ getHasScriptedBlendshapes WRITE setHasScriptedBlendshapes) Q_PROPERTY(bool hasProceduralBlinkFaceMovement READ getHasProceduralBlinkFaceMovement WRITE setHasProceduralBlinkFaceMovement) Q_PROPERTY(bool hasProceduralEyeFaceMovement READ getHasProceduralEyeFaceMovement WRITE setHasProceduralEyeFaceMovement) Q_PROPERTY(bool hasAudioEnabledFaceMovement READ getHasAudioEnabledFaceMovement WRITE setHasAudioEnabledFaceMovement) Q_PROPERTY(float rotationRecenterFilterLength READ getRotationRecenterFilterLength WRITE setRotationRecenterFilterLength) Q_PROPERTY(float rotationThreshold READ getRotationThreshold WRITE setRotationThreshold) Q_PROPERTY(bool enableStepResetRotation READ getEnableStepResetRotation WRITE setEnableStepResetRotation) Q_PROPERTY(bool enableDrawAverageFacing READ getEnableDrawAverageFacing WRITE setEnableDrawAverageFacing) //TODO: make gravity feature work Q_PROPERTY(glm::vec3 gravity READ getGravity WRITE setGravity) Q_PROPERTY(glm::vec3 leftHandPosition READ getLeftHandPosition) Q_PROPERTY(glm::vec3 rightHandPosition READ getRightHandPosition) Q_PROPERTY(glm::vec3 leftHandTipPosition READ getLeftHandTipPosition) Q_PROPERTY(glm::vec3 rightHandTipPosition READ getRightHandTipPosition) Q_PROPERTY(controller::Pose leftHandPose READ getLeftHandPose) Q_PROPERTY(controller::Pose rightHandPose READ getRightHandPose) Q_PROPERTY(controller::Pose leftHandTipPose READ getLeftHandTipPose) Q_PROPERTY(controller::Pose rightHandTipPose READ getRightHandTipPose) Q_PROPERTY(float energy READ getEnergy WRITE setEnergy) Q_PROPERTY(bool isAway READ getIsAway WRITE setAway) Q_PROPERTY(bool centerOfGravityModelEnabled READ getCenterOfGravityModelEnabled WRITE setCenterOfGravityModelEnabled) Q_PROPERTY(bool hmdLeanRecenterEnabled READ getHMDLeanRecenterEnabled WRITE setHMDLeanRecenterEnabled) Q_PROPERTY(bool collisionsEnabled READ getCollisionsEnabled WRITE setCollisionsEnabled) Q_PROPERTY(bool otherAvatarsCollisionsEnabled READ getOtherAvatarsCollisionsEnabled WRITE setOtherAvatarsCollisionsEnabled) Q_PROPERTY(bool characterControllerEnabled READ getCharacterControllerEnabled WRITE setCharacterControllerEnabled) Q_PROPERTY(bool useAdvancedMovementControls READ useAdvancedMovementControls WRITE setUseAdvancedMovementControls) Q_PROPERTY(bool showPlayArea READ getShowPlayArea WRITE setShowPlayArea) Q_PROPERTY(float yawSpeed MEMBER _yawSpeed) Q_PROPERTY(float pitchSpeed MEMBER _pitchSpeed) Q_PROPERTY(bool hmdRollControlEnabled READ getHMDRollControlEnabled WRITE setHMDRollControlEnabled) Q_PROPERTY(float hmdRollControlDeadZone READ getHMDRollControlDeadZone WRITE setHMDRollControlDeadZone) Q_PROPERTY(float hmdRollControlRate READ getHMDRollControlRate WRITE setHMDRollControlRate) Q_PROPERTY(float userHeight READ getUserHeight WRITE setUserHeight) Q_PROPERTY(float userEyeHeight READ getUserEyeHeight) Q_PROPERTY(QUuid SELF_ID READ getSelfID CONSTANT) Q_PROPERTY(float walkSpeed READ getWalkSpeed WRITE setWalkSpeed); Q_PROPERTY(float analogPlusWalkSpeed READ getAnalogPlusWalkSpeed WRITE setAnalogPlusWalkSpeed NOTIFY analogPlusWalkSpeedChanged); Q_PROPERTY(float analogPlusSprintSpeed READ getAnalogPlusSprintSpeed WRITE setAnalogPlusSprintSpeed NOTIFY analogPlusSprintSpeedChanged); Q_PROPERTY(float walkBackwardSpeed READ getWalkBackwardSpeed WRITE setWalkBackwardSpeed NOTIFY walkBackwardSpeedChanged); Q_PROPERTY(float sprintSpeed READ getSprintSpeed WRITE setSprintSpeed NOTIFY sprintSpeedChanged); Q_PROPERTY(bool isInSittingState READ getIsInSittingState WRITE setIsInSittingState); Q_PROPERTY(MyAvatar::SitStandModelType userRecenterModel READ getUserRecenterModel WRITE setUserRecenterModel); Q_PROPERTY(bool isSitStandStateLocked READ getIsSitStandStateLocked WRITE setIsSitStandStateLocked); Q_PROPERTY(bool allowTeleporting READ getAllowTeleporting) const QString DOMINANT_LEFT_HAND = "left"; const QString DOMINANT_RIGHT_HAND = "right"; const QString DEFAULT_HMD_AVATAR_ALIGNMENT_TYPE = "head"; using Clock = std::chrono::system_clock; using TimePoint = Clock::time_point; const float DEFAULT_GEAR_1 = 0.2f; const float DEFAULT_GEAR_2 = 0.4f; const float DEFAULT_GEAR_3 = 0.8f; const float DEFAULT_GEAR_4 = 0.9f; const float DEFAULT_GEAR_5 = 1.0f; const bool DEFAULT_STRAFE_ENABLED = true; public: /**jsdoc *

Logical keys that drive your avatar and camera.

* * * * * * * * * * * * * * * * * * *
ValueNameDescription
0TRANSLATE_XMove the user's avatar in the direction of its x-axis, if the * camera isn't in independent or mirror modes.
1TRANSLATE_YMove the user's avatar in the direction of its y-axis, if the * camera isn't in independent or mirror modes.
2TRANSLATE_ZMove the user's avatar in the direction of its z-axis, if the * camera isn't in independent or mirror modes
3YAWRotate the user's avatar about its y-axis at a rate proportional to the * control value, if the camera isn't in independent or mirror modes.
4STEP_TRANSLATE_XNo action.
5STEP_TRANSLATE_YNo action.
6STEP_TRANSLATE_ZNo action.
7STEP_YAWRotate the user's avatar about its y-axis in a step increment, if * the camera isn't in independent or mirror modes.
8PITCHRotate the user's avatar head and attached camera about its negative * x-axis (i.e., positive values pitch down) at a rate proportional to the control value, if the camera isn't in HMD, * independent, or mirror modes.
9ZOOMZoom the camera in or out.
10DELTA_YAWRotate the user's avatar about its y-axis by an amount proportional * to the control value, if the camera isn't in independent or mirror modes.
11DELTA_PITCHRotate the user's avatar head and attached camera about its * negative x-axis (i.e., positive values pitch down) by an amount proportional to the control value, if the camera * isn't in HMD, independent, or mirror modes.
* @typedef {number} MyAvatar.DriveKeys */ enum DriveKeys { TRANSLATE_X = 0, TRANSLATE_Y, TRANSLATE_Z, YAW, STEP_TRANSLATE_X, STEP_TRANSLATE_Y, STEP_TRANSLATE_Z, STEP_YAW, PITCH, ZOOM, DELTA_YAW, DELTA_PITCH, MAX_DRIVE_KEYS }; Q_ENUM(DriveKeys) /**jsdoc *

Specifies different avatar leaning and recentering behaviors.

* * * * * * * * * * *
ValueNameDescription
0ForceSitAssumes the user is seated in the real world. Disables avatar * leaning regardless of what the avatar is doing in the virtual world (i.e., avatar always recenters).
1ForceStandAssumes the user is standing in the real world. Enables avatar * leaning regardless of what the avatar is doing in the virtual world (i.e. avatar leans, then if leans too far it * recenters).
2AutoInterface detects when the user is standing or seated in the real world. * Avatar leaning is disabled when the user is sitting (i.e., avatar always recenters), and avatar leaning is enabled * when the user is standing (i.e., avatar leans, then if leans too far it recenters).
3DisableHMDLeanBoth avatar leaning and recentering are disabled regardless of * what the user is doing in the real world and no matter what their avatar is doing in the virtual world. Enables * the avatar to sit on the floor when the user sits on the floor.
Note: Experimental.
* @typedef {number} MyAvatar.SitStandModelType */ enum SitStandModelType { ForceSit = 0, ForceStand, Auto, DisableHMDLean, NumSitStandTypes }; Q_ENUM(SitStandModelType) explicit MyAvatar(QThread* thread); virtual ~MyAvatar(); void instantiableAvatar() override {}; void registerMetaTypes(ScriptEnginePointer engine); virtual void simulateAttachments(float deltaTime) override; AudioListenerMode getAudioListenerModeHead() const { return FROM_HEAD; } AudioListenerMode getAudioListenerModeCamera() const { return FROM_CAMERA; } AudioListenerMode getAudioListenerModeCustom() const { return CUSTOM; } void reset(bool andRecenter = false, bool andReload = true, bool andHead = true); void setCollisionWithOtherAvatarsFlags() override; /**jsdoc * Resets the sensor positioning of your HMD (if in use) and recenters your avatar body and head. * @function MyAvatar.resetSensorsAndBody */ Q_INVOKABLE void resetSensorsAndBody(); /**jsdoc * Moves and orients the avatar, such that it is directly underneath the HMD, with toes pointed forward in the direction of * the HMD. * @function MyAvatar.centerBody */ Q_INVOKABLE void centerBody(); // thread-safe /**jsdoc * Clears inverse kinematics joint limit history. *

The internal inverse-kinematics system maintains a record of which joints are "locked". Sometimes it is useful to * forget this history to prevent contorted joints, e.g., after finishing with an override animation.

* @function MyAvatar.clearIKJointLimitHistory */ Q_INVOKABLE void clearIKJointLimitHistory(); // thread-safe void update(float deltaTime); virtual void postUpdate(float deltaTime, const render::ScenePointer& scene) override; void preDisplaySide(const RenderArgs* renderArgs); const glm::mat4& getHMDSensorMatrix() const { return _hmdSensorMatrix; } const glm::vec3& getHMDSensorPosition() const { return _hmdSensorPosition; } const glm::quat& getHMDSensorOrientation() const { return _hmdSensorOrientation; } /**jsdoc * Gets the avatar orientation. Suitable for use in QML. * @function MyAvatar.setOrientationVar * @param {object} newOrientationVar - The avatar's orientation. */ Q_INVOKABLE void setOrientationVar(const QVariant& newOrientationVar); /**jsdoc * Gets the avatar orientation. Suitable for use in QML. * @function MyAvatar.getOrientationVar * @returns {object} The avatar's orientation. */ Q_INVOKABLE QVariant getOrientationVar() const; // A method intended to be overriden by MyAvatar for polling orientation for network transmission. glm::quat getOrientationOutbound() const override; // Pass a recent sample of the HMD to the avatar. // This can also update the avatar's position to follow the HMD // as it moves through the world. void updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix); // compute the hip to hand average azimuth. glm::vec2 computeHandAzimuth() const; // read the location of a hand controller and save the transform void updateJointFromController(controller::Action poseKey, ThreadSafeValueCache& matrixCache); // best called at end of main loop, just before rendering. // update sensor to world matrix from current body position and hmd sensor. // This is so the correct camera can be used for rendering. void updateSensorToWorldMatrix(); void setRealWorldFieldOfView(float realWorldFov) { _realWorldFieldOfView.set(realWorldFov); } /**jsdoc * Gets 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 * @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)); */ Q_INVOKABLE glm::vec3 getDefaultEyePosition() const; float getRealWorldFieldOfView() { return _realWorldFieldOfView.get(); } /**jsdoc * Overrides the default avatar animations. *

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 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 {string} url - The URL to the animation file. Animation files may be in glTF or FBX format, but only need to * contain the avatar skeleton and animation data. glTF models may be in JSON or binary format (".gltf" or ".glb" URLs * respectively). *

Warning: glTF animations currently do not always animate correctly.

* @param {number} fps - The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed. * @param {boolean} loop - true if the animation should loop, false if it shouldn't. * @param {number} firstFrame - The frame to start the animation at. * @param {number} lastFrame - The frame to end the animation at. * @example Play a clapping animation on your avatar for three seconds. * var ANIM_URL = "https://s3.amazonaws.com/hifi-public/animations/ClapAnimations/ClapHands_Standing.fbx"; * MyAvatar.overrideAnimation(ANIM_URL, 30, true, 0, 53); * Script.setTimeout(function () { * MyAvatar.restoreAnimation(); * MyAvatar.clearIKJointLimitHistory(); * }, 3000); */ Q_INVOKABLE void overrideAnimation(const QString& url, float fps, bool loop, float firstFrame, float lastFrame); /**jsdoc * Overrides the default hand poses that are triggered with controller buttons. * Use {@link MyAvatar.restoreHandAnimation} to restore the default poses. * @function MyAvatar.overrideHandAnimation * @param isLeft {boolean} true to override the left hand, false to override the right hand. * @param {string} url - The URL of the animation file. Animation files need to be in glTF or FBX format, but only need to * contain the avatar skeleton and animation data. glTF models may be in JSON or binary format (".gltf" or ".glb" URLs * respectively). *

Warning: glTF animations currently do not always animate correctly.

* @param {number} fps - The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed. * @param {boolean} loop - true if the animation should loop, false if it shouldn't. * @param {number} firstFrame - The frame to start the animation at. * @param {number} lastFrame - The frame to end the animation at. * @example Override left hand animation for three seconds. * var ANIM_URL = "https://s3.amazonaws.com/hifi-public/animations/ClapAnimations/ClapHands_Standing.fbx"; * MyAvatar.overrideHandAnimation(isLeft, ANIM_URL, 30, true, 0, 53); * Script.setTimeout(function () { * MyAvatar.restoreHandAnimation(); * }, 3000); */ Q_INVOKABLE void overrideHandAnimation(bool isLeft, const QString& url, float fps, bool loop, float firstFrame, float lastFrame); /**jsdoc * Restores the default animations. *

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.). Playing your own custom animations will * override the default animations. restoreAnimation() is used to restore all motion from the default * animation system including inverse kinematics for hand and head controllers. If you aren't currently playing an override * animation, this function has no effect.

* @function MyAvatar.restoreAnimation * @example Play a clapping animation on your avatar for three seconds. * var ANIM_URL = "https://s3.amazonaws.com/hifi-public/animations/ClapAnimations/ClapHands_Standing.fbx"; * MyAvatar.overrideAnimation(ANIM_URL, 30, true, 0, 53); * Script.setTimeout(function () { * MyAvatar.restoreAnimation(); * }, 3000); */ Q_INVOKABLE void restoreAnimation(); /**jsdoc * Restores the default hand animation state machine that is driven by the state machine in the avatar-animation JSON. *

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.). Playing your own custom animations will * override the default animations. restoreHandAnimation() is used to restore the default hand poses. * If you aren't currently playing an override hand animation, this function has no effect.

* @function MyAvatar.restoreHandAnimation * @param isLeft {boolean} Set to true if using the left hand * @example Override left hand animation for three seconds. * var ANIM_URL = "https://s3.amazonaws.com/hifi-public/animations/ClapAnimations/ClapHands_Standing.fbx"; * MyAvatar.overrideHandAnimation(isLeft, ANIM_URL, 30, true, 0, 53); * Script.setTimeout(function () { * MyAvatar.restoreHandAnimation(); * }, 3000); */ Q_INVOKABLE void restoreHandAnimation(bool isLeft); /**jsdoc * Gets the current animation roles. *

Each avatar has an avatar-animation.json file that defines which animations are used and how they are blended together * with procedural data (such as look at vectors, hand sensors etc.). Each animation specified in the avatar-animation.json * file is known as an animation role. 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 * @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]); * } */ Q_INVOKABLE QStringList getAnimationRoles(); /**jsdoc * Overrides a specific animation role. *

Each avatar has an avatar-animation.json file that defines a set of animation roles. Animation roles map to easily * understandable actions that the avatar can perform, such as "idleStand", "idleTalk", or * "walkFwd". To get the full list of roles, use {@ link MyAvatar.getAnimationRoles}. * For each role, the avatar-animation.json defines when the animation is used, the animation clip (glTF or FBX) used, and * how animations are blended together with procedural data (such as look at vectors, hand sensors etc.). * overrideRoleAnimation() is used to change the animation clip (glTF or FBX) associated with a specified * animation role. To end the role animation and restore the default, use {@link MyAvatar.restoreRoleAnimation}.

*

Note: Hand roles only affect the hand. Other "main" roles, like "idleStand", "idleTalk", and "takeoffStand", are full * body.

*

Note: When using pre-built animation data, it's critical that the joint orientation of the source animation and target * rig are equivalent, since the animation data applies absolute values onto the joints. If the orientations are different, * the avatar will move in unpredictable ways. For more information about avatar joint orientation standards, see * Avatar Standards. * @function MyAvatar.overrideRoleAnimation * @param {string} role - The animation role to override * @param {string} url - The URL to the animation file. Animation files need to be in glTF or FBX format, but only need to * contain the avatar skeleton and animation data. glTF models may be in JSON or binary format (".gltf" or ".glb" URLs * respectively). *

Warning: glTF animations currently do not always animate correctly.

* @param {number} fps - The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed. * @param {boolean} loop - true if the animation should loop, false if it shouldn't. * @param {number} firstFrame - The frame the animation should start at. * @param {number} lastFrame - 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. 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); * Script.setTimeout(function () { * MyAvatar.restoreRoleAnimation(); * }, 30000); */ Q_INVOKABLE void overrideRoleAnimation(const QString& role, const QString& url, float fps, bool loop, float firstFrame, float lastFrame); /**jsdoc * Restores a default role animation. *

Each avatar has an avatar-animation.json file that defines a set of animation roles. Animation roles map to easily * understandable actions that the avatar can perform, such as "idleStand", "idleTalk", or * "walkFwd". To get the full list of roles, use {@link MyAvatar.getAnimationRoles}. For each role, * the avatar-animation.json defines when the animation is used, the animation clip (glTF or FBX) used, and how animations * are blended together with procedural data (such as look-at vectors, hand sensors etc.). You can change the animation * clip (glTF or FBX) associated with a specified animation role using {@link MyAvatar.overrideRoleAnimation}. * restoreRoleAnimation() is used to restore a specified animation role's default animation clip. If you have * not specified an override animation for the specified role, this function has no effect. * @function MyAvatar.restoreRoleAnimation * @param role {string} The animation role clip to restore. */ Q_INVOKABLE void restoreRoleAnimation(const QString& role); // Adds handler(animStateDictionaryIn) => animStateDictionaryOut, which will be invoked just before each animGraph state update. // The handler will be called with an animStateDictionaryIn that has all those properties specified by the (possibly empty) // propertiesList argument. However for debugging, if the properties argument is null, all internal animGraph state is provided. // The animStateDictionaryOut can be a different object than animStateDictionaryIn. Any properties set in animStateDictionaryOut // will override those of the internal animation machinery. // The animStateDictionaryIn may be shared among multiple handlers, and thus may contain additional properties specified when // adding one of the other handlers. While any handler may change a value in animStateDictionaryIn (or supply different values in animStateDictionaryOut) // 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. /**jsdoc * Adds an animation state handler function that is invoked just before each animation graph update. More than one * animation state handler function may be added by calling addAnimationStateHandler multiple times. It is not * specified in what order multiple handlers are called. *

The animation state handler function is called with an {@link MyAvatar.AnimStateDictionary|AnimStateDictionary} * "animStateDictionaryIn" parameter and is expected to return an * {@link MyAvatar.AnimStateDictionary|AnimStateDictionary} "animStateDictionaryOut" object. The * animStateDictionaryOut object can be the same object as animStateDictionaryIn, or it can be a * different object. The animStateDictionaryIn may be shared among multiple handlers and thus may contain * additional properties specified when adding the different handlers.

*

A handler may change a value from animStateDictionaryIn or add different values in the * animStateDictionaryOut returned. Any property values set in animStateDictionaryOut will * override those of the internal animation machinery.|null} propertiesList - The list of {@link MyAvatar.AnimStateDictionary|AnimStateDictionary} * properties that should be included in the parameter that the handler function is called with. If null * then all properties are included in the call parameter. * @returns {number} The ID of the animation state handler function if successfully added, undefined if not. * @example Log all the animation state dictionary parameters for a short while. * function animStateHandler(dictionary) { * print("Anim state dictionary: " + JSON.stringify(dictionary)); * } * * var handler = MyAvatar.addAnimationStateHandler(animStateHandler, null); * * Script.setTimeout(function () { * MyAvatar.removeAnimationStateHandler(handler); * }, 100); */ Q_INVOKABLE QScriptValue addAnimationStateHandler(QScriptValue handler, QScriptValue propertiesList) { return _skeletonModel->getRig().addAnimationStateHandler(handler, propertiesList); } /**jsdoc * Removes an animation state handler function. * @function MyAvatar.removeAnimationStateHandler * @param {number} handler - The ID of the animation state handler function to remove. */ // Removes a handler previously added by addAnimationStateHandler. Q_INVOKABLE void removeAnimationStateHandler(QScriptValue handler) { _skeletonModel->getRig().removeAnimationStateHandler(handler); } /**jsdoc * Gets whether you do snap turns in HMD mode. * @function MyAvatar.getSnapTurn * @returns {boolean} true if you do snap turns in HMD mode; false if you do smooth turns in HMD * mode. */ Q_INVOKABLE bool getSnapTurn() const { return _useSnapTurn; } /**jsdoc * Sets whether you do snap turns or smooth turns in HMD mode. * @function MyAvatar.setSnapTurn * @param {boolean} on - true to do snap turns in HMD mode; false to do smooth turns in HMD mode. */ Q_INVOKABLE void setSnapTurn(bool on) { _useSnapTurn = on; } /**jsdoc * Gets the control scheme that is in use. * @function MyAvatar.getControlScheme * @returns {MyAvatar.LocomotionControlsMode} The control scheme that is in use. */ Q_INVOKABLE int getControlScheme() const { return _controlSchemeIndex; } /**jsdoc * Sets the control scheme to use. * @function MyAvatar.setControlScheme * @param {MyAvatar.LocomotionControlsMode} controlScheme - The control scheme to use. */ Q_INVOKABLE void setControlScheme(int index) { _controlSchemeIndex = (index >= 0 && index <= 2) ? index : 0; } /**jsdoc * Gets whether your avatar hovers when its feet are not on the ground. * @function MyAvatar.hoverWhenUnsupported * @returns {boolean} true if your avatar hovers when its feet are not on the ground, false if it * falls. */ // FIXME: Should be named, getHoverWhenUnsupported(). Q_INVOKABLE bool hoverWhenUnsupported() const { return _hoverWhenUnsupported; } /**jsdoc * Sets whether your avatar hovers when its feet are not on the ground. * @function MyAvatar.setHoverWhenUnsupported * @param {boolean} hover - true if your avatar hovers when its feet are not on the ground, false * if it falls. */ Q_INVOKABLE void setHoverWhenUnsupported(bool on) { _hoverWhenUnsupported = on; } /**jsdoc * Sets the avatar's dominant hand. * @function MyAvatar.setDominantHand * @param {string} hand - The dominant hand: "left" for the left hand or "right" for the right * hand. Any other value has no effect. */ Q_INVOKABLE void setDominantHand(const QString& hand); /**jsdoc * Gets the avatar's dominant hand. * @function MyAvatar.getDominantHand * @returns {string} "left" for the left hand, "right" for the right hand. */ Q_INVOKABLE QString getDominantHand() const; /**jsdoc * Sets whether strafing is enabled. * @function MyAvatar.setStrafeEnabled * @param {boolean} enabled - true if strafing is enabled, false if it isn't. */ Q_INVOKABLE void setStrafeEnabled(bool enabled); /**jsdoc * Gets whether strafing is enabled. * @function MyAvatar.getStrafeEnabled * @returns {boolean} true if strafing is enabled, false if it isn't. */ Q_INVOKABLE bool getStrafeEnabled() const; /**jsdoc * Sets the HMD alignment relative to your avatar. * @function MyAvatar.setHmdAvatarAlignmentType * @param {string} type - "head" to align your head and your avatar's head, "eyes" to align your * eyes and your avatar's eyes. */ Q_INVOKABLE void setHmdAvatarAlignmentType(const QString& type); /**jsdoc * Gets the HMD alignment relative to your avatar. * @function MyAvatar.getHmdAvatarAlignmentType * @returns {string} "head" if aligning your head and your avatar's head, "eyes" if aligning your * eyes and your avatar's eyes. */ Q_INVOKABLE QString getHmdAvatarAlignmentType() const; /**jsdoc * Sets whether the avatar's hips are balanced over the feet or positioned under the head. * @function MyAvatar.setCenterOfGravityModelEnabled * @param {boolean} enabled - true to balance the hips over the feet, false to position the hips * under the head. */ Q_INVOKABLE void setCenterOfGravityModelEnabled(bool value) { _centerOfGravityModelEnabled = value; } /**jsdoc * Gets whether the avatar hips are being balanced over the feet or placed under the head. * @function MyAvatar.getCenterOfGravityModelEnabled * @returns {boolean} true if the hips are being balanced over the feet, false if the hips are * being positioned under the head. */ Q_INVOKABLE bool getCenterOfGravityModelEnabled() const { return _centerOfGravityModelEnabled; } /**jsdoc * Sets whether the avatar's position updates to recenter the avatar under the head. In room-scale VR, recentering * causes your avatar to follow your HMD as you walk around the room. Disabling recentering is useful if you want to pin * the avatar to a fixed position. * @function MyAvatar.setHMDLeanRecenterEnabled * @param {boolean} enabled - true to recenter the avatar under the head as it moves, false to * disable recentering. */ Q_INVOKABLE void setHMDLeanRecenterEnabled(bool value) { _hmdLeanRecenterEnabled = value; } /**jsdoc * Gets whether the avatar's position updates to recenter the avatar under the head. In room-scale VR, recentering * causes your avatar to follow your HMD as you walk around the room. * @function MyAvatar.getHMDLeanRecenterEnabled * @returns {boolean} true if recentering is enabled, false if not. */ Q_INVOKABLE bool getHMDLeanRecenterEnabled() const { return _hmdLeanRecenterEnabled; } /**jsdoc * Requests that the hand touch effect is disabled for your avatar. Any resulting change in the status of the hand touch * effect will be signaled by {@link MyAvatar.shouldDisableHandTouchChanged}. *

The hand touch effect makes the avatar's fingers adapt to the shape of any object grabbed, creating the effect that * it is really touching that object.

* @function MyAvatar.requestEnableHandTouch */ Q_INVOKABLE void requestEnableHandTouch(); /**jsdoc * Requests that the hand touch effect is enabled for your avatar. Any resulting change in the status of the hand touch * effect will be signaled by {@link MyAvatar.shouldDisableHandTouchChanged}. *

The hand touch effect makes the avatar's fingers adapt to the shape of any object grabbed, creating the effect that * it is really touching that object.

* @function MyAvatar.requestDisableHandTouch */ Q_INVOKABLE void requestDisableHandTouch(); /**jsdoc * Disables the hand touch effect on a specific entity. *

The hand touch effect makes the avatar's fingers adapt to the shape of any object grabbed, creating the effect that * it is really touching that object.

* @function MyAvatar.disableHandTouchForID * @param {Uuid} entityID - The entity that the hand touch effect will be disabled for. */ Q_INVOKABLE void disableHandTouchForID(const QUuid& entityID); /**jsdoc * Enables the hand touch effect on a specific entity. *

The hand touch effect makes the avatar's fingers adapt to the shape of any object grabbed, creating the effect that * it is really touching that object.

* @function MyAvatar.enableHandTouchForID * @param {Uuid} entityID - The entity that the hand touch effect will be enabled for. */ Q_INVOKABLE void enableHandTouchForID(const QUuid& entityID); bool useAdvancedMovementControls() const { return _useAdvancedMovementControls.get(); } void setUseAdvancedMovementControls(bool useAdvancedMovementControls) { _useAdvancedMovementControls.set(useAdvancedMovementControls); } bool getAllowTeleporting() { return _allowTeleportingSetting.get(); } void setAllowTeleporting(bool allowTeleporting) { _allowTeleportingSetting.set(allowTeleporting); } bool getShowPlayArea() const { return _showPlayArea.get(); } void setShowPlayArea(bool showPlayArea) { _showPlayArea.set(showPlayArea); } void setHMDRollControlEnabled(bool value) { _hmdRollControlEnabled = value; } bool getHMDRollControlEnabled() const { return _hmdRollControlEnabled; } void setHMDRollControlDeadZone(float value) { _hmdRollControlDeadZone = value; } float getHMDRollControlDeadZone() const { return _hmdRollControlDeadZone; } void setHMDRollControlRate(float value) { _hmdRollControlRate = value; } float getHMDRollControlRate() const { return _hmdRollControlRate; } // get/set avatar data void resizeAvatarEntitySettingHandles(uint32_t maxIndex); void saveData(); void saveAvatarEntityDataToSettings(); void loadData(); void loadAvatarEntityDataFromSettings(); void saveAttachmentData(const AttachmentData& attachment) const; AttachmentData loadAttachmentData(const QUrl& modelURL, const QString& jointName = QString()) const; // Set what driving keys are being pressed to control thrust levels void clearDriveKeys(); void setDriveKey(DriveKeys key, float val); void setSprintMode(bool sprint); float getDriveKey(DriveKeys key) const; /**jsdoc * Gets the value of a drive key, regardless of whether it is disabled. * @function MyAvatar.getRawDriveKey * @param {MyAvatar.DriveKeys} key - The drive key. * @returns {number} The value of the drive key. */ Q_INVOKABLE float getRawDriveKey(DriveKeys key) const; void relayDriveKeysToCharacterController(); /**jsdoc * Disables the action associated with a drive key. * @function MyAvatar.disableDriveKey * @param {MyAvatar.DriveKeys} key - The drive key to disable. * @example Disable rotating your avatar using the keyboard for a couple of seconds. * var YAW = 3; * print("Disable"); * MyAvatar.disableDriveKey(YAW); * Script.setTimeout(function () { * print("Enable"); * MyAvatar.enableDriveKey(YAW); * }, 5000); */ Q_INVOKABLE void disableDriveKey(DriveKeys key); /**jsdoc * Enables the action associated with a drive key. The action may have been disabled with * {@link MyAvatar.disableDriveKey|disableDriveKey}. * @function MyAvatar.enableDriveKey * @param {MyAvatar.DriveKeys} key - The drive key to enable. */ Q_INVOKABLE void enableDriveKey(DriveKeys key); /**jsdoc * Checks whether a drive key is disabled. * @function MyAvatar.isDriveKeyDisabled * @param {DriveKeys} key - The drive key to check. * @returns {boolean} true if the drive key is disabled, false if it isn't. */ Q_INVOKABLE bool isDriveKeyDisabled(DriveKeys key) const; /**jsdoc * 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(); /**jsdoc * Gets whether the avatar is configured to keep its center of gravity under its head. * @function MyAvatar.isRecenteringHorizontally * @returns {boolean} true if the avatar is keeping its center of gravity under its head position, * false if not. */ Q_INVOKABLE bool isRecenteringHorizontally() const; eyeContactTarget getEyeContactTarget(); const MyHead* getMyHead() const; /**jsdoc * Gets 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 * Gets the yaw of the avatar's head relative to its body. * @function MyAvatar.getHeadFinalYaw * @returns {number} The yaw of the avatar's head, in degrees. */ Q_INVOKABLE float getHeadFinalYaw() const { return getHead()->getFinalYaw(); } /**jsdoc * Gets the roll of the avatar's head relative to its body. * @function MyAvatar.getHeadFinalRoll * @returns {number} The roll of the avatar's head, in degrees. */ Q_INVOKABLE float getHeadFinalRoll() const { return getHead()->getFinalRoll(); } /**jsdoc * Gets the pitch of the avatar's head relative to its body. * @function MyAvatar.getHeadFinalPitch * @returns {number} The pitch of the avatar's head, in degrees. */ Q_INVOKABLE float getHeadFinalPitch() const { return getHead()->getFinalPitch(); } /**jsdoc * If a face tracker is connected and being used, gets the estimated pitch of the user's head scaled. This is scale such * that the avatar looks at the edge of the view frustum when the user looks at the edge of their screen. * @function MyAvatar.getHeadDeltaPitch * @returns {number} The pitch that the avatar's head should be if a face tracker is connected and being used, otherwise * 0, in degrees. */ Q_INVOKABLE float getHeadDeltaPitch() const { return getHead()->getDeltaPitch(); } /**jsdoc * Gets 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 * Gets the position of the avatar your avatar is currently looking at. * @function MyAvatar.getTargetAvatarPosition * @returns {Vec3} The position of the avatar beeing looked at. * @example Report the position of the avatar you're currently looking at. * print(JSON.stringify(MyAvatar.getTargetAvatarPosition())); */ // FIXME: If not looking at an avatar, the most recently looked-at position is returned. This should be fixed to return // undefined or {NaN, NaN, NaN} or similar. Q_INVOKABLE glm::vec3 getTargetAvatarPosition() const { return _targetAvatarPosition; } /**jsdoc * Gets information on the avatar your avatar is currently looking at. * @function MyAvatar.getTargetAvatar * @returns {AvatarData} Information on the avatar being looked at. */ // FIXME: The return type doesn't have a conversion to a script value so the function always returns undefined in // JavaScript. Note: When fixed, JSDoc is needed for the return type. Q_INVOKABLE ScriptAvatarData* getTargetAvatar() const; /**jsdoc * Gets the position of the avatar's left hand, relative to the avatar, 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 * Gets the position of the avatar's right hand, relative to the avatar, 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 * Gets the position 0.3m in front of the left hand's position in the direction along the palm, in avatar coordinates, as * positioned by a hand controller. * @function MyAvatar.getLeftHandTipPosition * @returns {Vec3} The position 0.3m in front of the left hand's position in the direction along the palm, in avatar * coordinates. If the hand isn't being positioned by a controller, {@link Vec3(0)|Vec3.ZERO} is returned. */ Q_INVOKABLE glm::vec3 getLeftHandTipPosition() const; /**jsdoc * Gets the position 0.3m in front of the right hand's position in the direction along the palm, in avatar coordinates, as * positioned by a hand controller. * @function MyAvatar.getRightHandTipPosition * @returns {Vec3} The position 0.3m in front of the right hand's position in the direction along the palm, in avatar * coordinates. If the hand isn't being positioned by a controller, {@link Vec3(0)|Vec3.ZERO} is returned. */ Q_INVOKABLE glm::vec3 getRightHandTipPosition() const; /**jsdoc * Gets 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} The pose of the avatar's left hand, relative to the avatar, as positioned by a hand controller. * @example Report the pose of your avatar's left hand. * print(JSON.stringify(MyAvatar.getLeftHandPose())); */ Q_INVOKABLE controller::Pose getLeftHandPose() const; /**jsdoc * Gets 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} The pose of the avatar's right hand, relative to the avatar, as positioned by a hand controller. * @example Report the pose of your avatar's right hand. * print(JSON.stringify(MyAvatar.getRightHandPose())); */ Q_INVOKABLE controller::Pose getRightHandPose() const; /**jsdoc * Gets the pose (position, rotation, velocity, and angular velocity) of the avatar's left hand, relative to the avatar, as * positioned by a hand controller (e.g., Oculus Touch or Vive), and translated 0.3m along the palm. *

Note: 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 Leap Motion, the return value's valid property will be * false and any pose values returned will not be meaningful.

* @function MyAvatar.getLeftHandTipPose * @returns {Pose} The pose of the avatar's left hand, relative to the avatar, as positioned by a hand controller, and * translated 0.3m along the palm. */ Q_INVOKABLE controller::Pose getLeftHandTipPose() const; /**jsdoc * Gets the pose (position, rotation, velocity, and angular velocity) of the avatar's right hand, relative to the avatar, as * positioned by a hand controller (e.g., Oculus Touch or Vive), and translated 0.3m along the palm. *

Note: 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 Leap Motion, the return value's valid property will be * false and any pose values returned will not be meaningful.

* @function MyAvatar.getRightHandTipPose * @returns {Pose} The pose of the avatar's right hand, relative to the avatar, as positioned by a hand controller, and * translated 0.3m along the palm. */ Q_INVOKABLE controller::Pose getRightHandTipPose() const; AvatarWeakPointer getLookAtTargetAvatar() const { return _lookAtTargetAvatar; } void updateLookAtTargetAvatar(); void computeMyLookAtTarget(const AvatarHash& hash); void snapOtherAvatarLookAtTargetsToMe(const AvatarHash& hash); void clearLookAtTargetAvatar(); virtual void setJointRotations(const QVector& jointRotations) override; virtual void setJointData(int index, const glm::quat& rotation, const glm::vec3& translation) override; virtual void setJointRotation(int index, const glm::quat& rotation) override; virtual void setJointTranslation(int index, const glm::vec3& translation) override; virtual void clearJointData(int index) override; virtual void setJointData(const QString& name, const glm::quat& rotation, const glm::vec3& translation) override; virtual void setJointRotation(const QString& name, const glm::quat& rotation) override; virtual void setJointTranslation(const QString& name, const glm::vec3& translation) override; virtual void clearJointData(const QString& name) override; virtual void clearJointsData() override; /**jsdoc * Sets and locks a joint's position and orientation. *

Note: Only works on the hips joint.

* @function MyAvatar.pinJoint * @param {number} index - The index of the joint. * @param {Vec3} position - The position of the joint in world coordinates. * @param {Quat} orientation - The orientation of the joint in world coordinates. * @returns {boolean} true if the joint was pinned, false if it wasn't. */ Q_INVOKABLE bool pinJoint(int index, const glm::vec3& position, const glm::quat& orientation); bool isJointPinned(int index); /**jsdoc * Clears a lock on a joint's position and orientation, as set by {@link MyAvatar.pinJoint|pinJoint}. *

Note: Only works on the hips joint.

* @function MyAvatar.clearPinOnJoint * @param {number} index - The index of the joint. * @returns {boolean} true if the joint was unpinned, false if it wasn't. */ Q_INVOKABLE bool clearPinOnJoint(int index); /**jsdoc * Gets the maximum error distance from the most recent inverse kinematics (IK) solution. * @function MyAvatar.getIKErrorOnLastSolve * @returns {number} The maximum IK error distance. */ Q_INVOKABLE float getIKErrorOnLastSolve() const; /**jsdoc * Changes the user's avatar and associated descriptive name. * @function MyAvatar.useFullAvatarURL * @param {string} fullAvatarURL - The URL of the avatar's .fst file. * @param {string} [modelName=""] - Descriptive name of the avatar. */ Q_INVOKABLE void useFullAvatarURL(const QUrl& fullAvatarURL, const QString& modelName = QString()); /**jsdoc * Gets 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 * Gets 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(); MyCharacterController* getCharacterController() { return &_characterController; } const MyCharacterController* getCharacterController() const { return &_characterController; } void updateMotors(); void prepareForPhysicsSimulation(); void nextAttitude(glm::vec3 position, glm::quat orientation); // Can be safely called at any time. void harvestResultsFromPhysicsSimulation(float deltaTime); const QString& getCollisionSoundURL() { return _collisionSoundURL; } void setCollisionSoundURL(const QString& url); SharedSoundPointer getCollisionSound(); void setCollisionSound(SharedSoundPointer sound) { _collisionSound = sound; } void clearScriptableSettings(); float getBoomLength() const { return _boomLength; } void setBoomLength(float boomLength) { _boomLength = boomLength; } float getPitchSpeed() const { return _pitchSpeed; } void setPitchSpeed(float speed) { _pitchSpeed = speed; } float getYawSpeed() const { return _yawSpeed; } void setYawSpeed(float speed) { _yawSpeed = speed; } static const float ZOOM_MIN; static const float ZOOM_MAX; static const float ZOOM_DEFAULT; void destroyAnimGraph(); AudioListenerMode getAudioListenerMode() { return _audioListenerMode; } void setAudioListenerMode(AudioListenerMode audioListenerMode); glm::vec3 getCustomListenPosition() { return _customListenPosition; } void setCustomListenPosition(glm::vec3 customListenPosition) { _customListenPosition = customListenPosition; } glm::quat getCustomListenOrientation() { return _customListenOrientation; } void setCustomListenOrientation(glm::quat customListenOrientation) { _customListenOrientation = customListenOrientation; } virtual void rebuildCollisionShape() override; const glm::vec2& getHipToHandController() const { return _hipToHandController; } void setHipToHandController(glm::vec2 currentHipToHandController) { _hipToHandController = currentHipToHandController; } const glm::vec2& getHeadControllerFacing() const { return _headControllerFacing; } void setHeadControllerFacing(glm::vec2 currentHeadControllerFacing) { _headControllerFacing = currentHeadControllerFacing; } const glm::vec2& getHeadControllerFacingMovingAverage() const { return _headControllerFacingMovingAverage; } void setHeadControllerFacingMovingAverage(glm::vec2 currentHeadControllerFacing) { _headControllerFacingMovingAverage = currentHeadControllerFacing; } float getCurrentStandingHeight() const { return _currentStandingHeight; } void setCurrentStandingHeight(float newMode) { _currentStandingHeight = newMode; } const glm::quat getAverageHeadRotation() const { return _averageHeadRotation; } void setAverageHeadRotation(glm::quat rotation) { _averageHeadRotation = rotation; } bool getResetMode() const { return _resetMode; } void setResetMode(bool hasBeenReset) { _resetMode = hasBeenReset; } void setControllerPoseInSensorFrame(controller::Action action, const controller::Pose& pose); controller::Pose getControllerPoseInSensorFrame(controller::Action action) const; controller::Pose getControllerPoseInWorldFrame(controller::Action action) const; controller::Pose getControllerPoseInAvatarFrame(controller::Action action) const; glm::quat getOffHandRotation() const; bool hasDriveInput() const; /**jsdoc * Gets the current avatar entity IDs and their properties. * @function MyAvatar.getAvatarEntitiesVariant * @returns {MyAvatar.AvatarEntityData[]} The current avatar entity IDs and their properties. */ Q_INVOKABLE QVariantList getAvatarEntitiesVariant(); void removeWornAvatarEntity(const EntityItemID& entityID); void clearWornAvatarEntities(); /**jsdoc * Checks whether your avatar is flying. * @function MyAvatar.isFlying * @returns {boolean} true if your avatar is flying and not taking off or falling, false if not. */ Q_INVOKABLE bool isFlying(); /**jsdoc * Checks whether your avatar is in the air. * @function MyAvatar.isInAir * @returns {boolean} true if your avatar is taking off, flying, or falling, otherwise false * because your avatar is on the ground. */ Q_INVOKABLE bool isInAir(); /**jsdoc * Sets your preference for flying in your current desktop or HMD display mode. Note that your ability to fly also depends * on whether the domain you're in allows you to fly. * @function MyAvatar.setFlyingEnabled * @param {boolean} enabled - Set true if you want to enable flying in your current desktop or HMD display * mode, otherwise set false. */ Q_INVOKABLE void setFlyingEnabled(bool enabled); /**jsdoc * Gets your preference for flying in your current desktop or HMD display mode. Note that your ability to fly also depends * on whether the domain you're in allows you to fly. * @function MyAvatar.getFlyingEnabled * @returns {boolean} true if your preference is to enable flying in your current desktop or HMD display mode, * otherwise false. */ Q_INVOKABLE bool getFlyingEnabled(); /**jsdoc * Sets your preference for flying in desktop display mode. Note that your ability to fly also depends on whether the domain * you're in allows you to fly. * @function MyAvatar.setFlyingDesktopPref * @param {boolean} enabled - Set true if you want to enable flying in desktop display mode, otherwise set * false. */ Q_INVOKABLE void setFlyingDesktopPref(bool enabled); /**jsdoc * Gets your preference for flying in desktop display mode. Note that your ability to fly also depends on whether the domain * you're in allows you to fly. * @function MyAvatar.getFlyingDesktopPref * @returns {boolean} true if your preference is to enable flying in desktop display mode, otherwise * false. */ Q_INVOKABLE bool getFlyingDesktopPref(); /**jsdoc * Sets your preference for flying in HMD display mode. Note that your ability to fly also depends on whether the domain * you're in allows you to fly. * @function MyAvatar.setFlyingHMDPref * @param {boolean} enabled - Set true if you want to enable flying in HMD display mode, otherwise set * false. */ Q_INVOKABLE void setFlyingHMDPref(bool enabled); /**jsdoc * Gets your preference for flying in HMD display mode. Note that your ability to fly also depends on whether the domain * you're in allows you to fly. * @function MyAvatar.getFlyingHMDPref * @returns {boolean} true if your preference is to enable flying in HMD display mode, otherwise * false. */ Q_INVOKABLE bool getFlyingHMDPref(); /**jsdoc * Set your preference for hand-relative movement. * @function MyAvatar.setHandRelativeMovement * @param {number} enabled - Set true if you want to enable hand-relative movement, otherwise set to false. * */ Q_INVOKABLE void setMovementReference(int enabled); /**jsdoc * Get your preference for hand-relative movement. * @function MyAvatar.getHandRelativeMovement * @returns {number} true if your preference is for user locomotion to be relative to the direction your * controller is pointing, otherwise false. */ Q_INVOKABLE int getMovementReference(); /**jsdoc * Set the first 'shifting point' for acceleration step function. * @function MyAvatar.setDriveGear1 * @param {number} shiftPoint - Set the first shift point for analog movement acceleration step function, between [0.0, 1.0]. Must be less than or equal to Gear 2. */ Q_INVOKABLE void setDriveGear1(float shiftPoint); /**jsdoc * Get the first 'shifting point' for acceleration step function. * @function MyAvatar.getDriveGear1 * @returns {number} Value between [0.0, 1.0]. */ Q_INVOKABLE float getDriveGear1(); /**jsdoc * Set the second 'shifting point' for acceleration step function. * @function MyAvatar.setDriveGear2 * @param {number} shiftPoint - Defines the second shift point for analog movement acceleration step function, between [0, 1]. Must be greater than or equal to Gear 1 and less than or equal to Gear 2. */ Q_INVOKABLE void setDriveGear2(float shiftPoint); /**jsdoc * Get the second 'shifting point' for acceleration step function. * @function MyAvatar.getDriveGear2 * @returns {number} Value between [0.0, 1.0]. */ Q_INVOKABLE float getDriveGear2(); /**jsdoc * Set the third 'shifting point' for acceleration step function. * @function MyAvatar.setDriveGear3 * @param {number} shiftPoint - Defines the third shift point for analog movement acceleration step function, between [0, 1]. Must be greater than or equal to Gear 2 and less than or equal to Gear 4. */ Q_INVOKABLE void setDriveGear3(float shiftPoint); /**jsdoc * Get the third 'shifting point' for acceleration step function. * @function MyAvatar.getDriveGear3 * @returns {number} Value between [0.0, 1.0]. */ Q_INVOKABLE float getDriveGear3(); /**jsdoc * Set the fourth 'shifting point' for acceleration step function. * @function MyAvatar.setDriveGear4 * @param {number} shiftPoint - Defines the fourth shift point for analog movement acceleration step function, between [0, 1]. Must be greater than Gear 3 and less than Gear 5. */ Q_INVOKABLE void setDriveGear4(float shiftPoint); /**jsdoc * Get the fourth 'shifting point' for acceleration step function. * @function MyAvatar.getDriveGear4 * @returns {number} Value between [0.0, 1.0]. */ Q_INVOKABLE float getDriveGear4(); /**jsdoc * Set the fifth 'shifting point' for acceleration step function. * @function MyAvatar.setDriveGear5 * @param {number} shiftPoint - Defines the fifth shift point for analog movement acceleration step function, between [0, 1]. Must be greater than or equal to Gear 4. */ Q_INVOKABLE void setDriveGear5(float shiftPoint); /**jsdoc * Get the fifth 'shifting point' for acceleration step function. * @function MyAvatar.getDriveGear5 * @returns {number} Value between [0.0, 1.0]. */ Q_INVOKABLE float getDriveGear5(); void setControlSchemeIndex(int index); int getControlSchemeIndex(); /**jsdoc * Gets the target scale of the avatar. The target scale is the desired scale of the avatar without any restrictions on * permissible scale values imposed by the domain. * @function MyAvatar.getAvatarScale * @returns {number} The target scale for the avatar, range 0.0051000.0. */ Q_INVOKABLE float getAvatarScale(); /**jsdoc * Sets the target scale of the avatar. The target scale is the desired scale of the avatar without any restrictions on * permissible scale values imposed by the domain. * @function MyAvatar.setAvatarScale * @param {number} scale - The target scale for the avatar, range 0.0051000.0. */ Q_INVOKABLE void setAvatarScale(float scale); /**jsdoc * Sets whether the avatar should collide with entities. *

Note: A false value won't disable collisions if the avatar is in a zone that disallows * collisionless avatars. However, the false value will be set so that collisions are disabled as soon as the * avatar moves to a position where collisionless avatars are allowed. * @function MyAvatar.setCollisionsEnabled * @param {boolean} enabled - true to enable the avatar to collide with entities, false to * disable. */ Q_INVOKABLE void setCollisionsEnabled(bool enabled); /**jsdoc * Gets whether the avatar will currently collide with entities. *

Note: The avatar will always collide with entities if in a zone that disallows collisionless avatars. * @function MyAvatar.getCollisionsEnabled * @returns {boolean} true if the avatar will currently collide with entities, false if it won't. */ Q_INVOKABLE bool getCollisionsEnabled(); /**jsdoc * Sets whether the avatar should collide with other avatars. * @function MyAvatar.setOtherAvatarsCollisionsEnabled * @param {boolean} enabled - true to enable the avatar to collide with other avatars, false * to disable. */ Q_INVOKABLE void setOtherAvatarsCollisionsEnabled(bool enabled); /**jsdoc * Gets whether the avatar will collide with other avatars. * @function MyAvatar.getOtherAvatarsCollisionsEnabled * @returns {boolean} true if the avatar will collide with other avatars, false if it won't. */ Q_INVOKABLE bool getOtherAvatarsCollisionsEnabled(); /**jsdoc * Gets the avatar's collision capsule: a cylinder with hemispherical ends that approximates the extents or the avatar. *

Warning: The values returned are in world coordinates but aren't necessarily up to date with the * avatar's current position.

* @function MyAvatar.getCollisionCapsule * @returns {MyAvatar.CollisionCapsule} The avatar's collision capsule. */ Q_INVOKABLE QVariantMap getCollisionCapsule() const; /**jsdoc * @function MyAvatar.setCharacterControllerEnabled * @param {boolean} enabled - true to enable the avatar to collide with entities, false to * disable. * @deprecated This function is deprecated and will be removed. Use {@link MyAvatar.setCollisionsEnabled} instead. */ Q_INVOKABLE void setCharacterControllerEnabled(bool enabled); // deprecated /**jsdoc * @function MyAvatar.getCharacterControllerEnabled * @returns {boolean} true if the avatar will currently collide with entities, false if it won't. * @deprecated This function is deprecated and will be removed. Use {@link MyAvatar.getCollisionsEnabled} instead. */ Q_INVOKABLE bool getCharacterControllerEnabled(); // deprecated /**jsdoc * Gets the rotation of a joint relative to the avatar. * @comment Different behavior to the Avatar version of this method. * @function MyAvatar.getAbsoluteJointRotationInObjectFrame * @param {number} index - The index of the joint. * @returns {Quat} The rotation of the joint relative to the avatar. * @example Report the rotation of your avatar's head joint relative to your avatar. * var headIndex = MyAvatar.getJointIndex("Head"); * var headRotation = MyAvatar.getAbsoluteJointRotationInObjectFrame(headIndex); * print("Head rotation: " + JSON.stringify(Quat.safeEulerAngles(headRotation))); // Degrees */ virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override; /**jsdoc * Gets the translation of a joint relative to the avatar. * @comment Different behavior to the Avatar version of this method. * @function MyAvatar.getAbsoluteJointTranslationInObjectFrame * @param {number} index - The index of the joint. * @returns {Vec3} The translation of the joint relative to the avatar. * @example Report the translation of your avatar's head joint relative to your avatar. * var headIndex = MyAvatar.getJointIndex("Head"); * var headTranslation = MyAvatar.getAbsoluteJointTranslationInObjectFrame(headIndex); * print("Head translation: " + JSON.stringify(headTranslation)); */ virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const override; // all calibration matrices are in absolute sensor space. glm::mat4 getCenterEyeCalibrationMat() const; glm::mat4 getHeadCalibrationMat() const; glm::mat4 getSpine2CalibrationMat() const; glm::mat4 getHipsCalibrationMat() const; glm::mat4 getLeftFootCalibrationMat() const; glm::mat4 getRightFootCalibrationMat() const; glm::mat4 getRightArmCalibrationMat() const; glm::mat4 getLeftArmCalibrationMat() const; glm::mat4 getLeftHandCalibrationMat() const; glm::mat4 getRightHandCalibrationMat() const; void addHoldAction(AvatarActionHold* holdAction); // thread-safe void removeHoldAction(AvatarActionHold* holdAction); // thread-safe void updateHoldActions(const AnimPose& prePhysicsPose, const AnimPose& postUpdatePose); // derive avatar body position and orientation from the current HMD Sensor location. // results are in sensor frame (-z forward) glm::mat4 deriveBodyFromHMDSensor() const; glm::mat4 getSpine2RotationRigSpace() const; glm::vec3 computeCounterBalance(); // derive avatar body position and orientation from using the current HMD Sensor location in relation to the previous // location of the base of support of the avatar. // results are in sensor frame (-z foward) glm::mat4 deriveBodyUsingCgModel(); /**jsdoc * Tests whether a vector is pointing in the general direction of the avatar's "up" direction (i.e., dot product of vectors * is > 0). * @function MyAvatar.isUp * @param {Vec3} direction - The vector to test. * @returns {boolean} true if the direction vector is pointing generally in the direction of the avatar's "up" * direction. */ 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 * Tests whether a vector is pointing in the general direction of the avatar's "down" direction (i.e., dot product of * vectors is < 0). * @function MyAvatar.isDown * @param {Vec3} direction - The vector to test. * @returns {boolean} true if the direction vector is pointing generally in the direction of the avatar's * "down" direction. */ Q_INVOKABLE bool isDown(const glm::vec3& direction) { return glm::dot(direction, _worldUpDirection) < 0.0f; }; void setUserHeight(float value); float getUserHeight() const; float getUserEyeHeight() const; virtual SpatialParentTree* getParentTree() const override; virtual glm::vec3 scaleForChildren() const override { return glm::vec3(getSensorToWorldScale()); } const QUuid& getSelfID() const { return AVATAR_SELF_ID; } void setIsInWalkingState(bool isWalking); bool getIsInWalkingState() const; void setIsInSittingState(bool isSitting); bool getIsInSittingState() const; void setUserRecenterModel(MyAvatar::SitStandModelType modelName); MyAvatar::SitStandModelType getUserRecenterModel() const; void setIsSitStandStateLocked(bool isLocked); bool getIsSitStandStateLocked() const; void setWalkSpeed(float value); float getWalkSpeed() const; void setWalkBackwardSpeed(float value); float getWalkBackwardSpeed() const; void setSprintSpeed(float value); float getSprintSpeed() const; void setAnalogWalkSpeed(float value); float getAnalogWalkSpeed() const; void setAnalogSprintSpeed(float value); float getAnalogSprintSpeed() const; void setAnalogPlusWalkSpeed(float value); float getAnalogPlusWalkSpeed() const; void setAnalogPlusSprintSpeed(float value); float getAnalogPlusSprintSpeed() const; void setSitStandStateChange(bool stateChanged); float getSitStandStateChange() const; void updateSitStandState(float newHeightReading, float dt); QVector getScriptUrls(); bool isReadyForPhysics() const; float computeStandingHeightMode(const controller::Pose& head); glm::quat computeAverageHeadRotation(const controller::Pose& head); virtual void setAttachmentData(const QVector& attachmentData) override; virtual QVector getAttachmentData() const override; virtual QVariantList getAttachmentsVariant() const override; virtual void setAttachmentsVariant(const QVariantList& variant) override; glm::vec3 getNextPosition() { return _goToPending ? _goToPosition : getWorldPosition(); } void prepareAvatarEntityDataForReload(); /**jsdoc * Turn the avatar's head until it faces the target point within the 90/-90 degree range. * Once this method is called, API calls will have full control of the head for a limited time. * If this method is not called for two seconds, the engine will regain control of the head. * @function MyAvatar.setHeadLookAt * @param {Vec3} lookAtTarget - The target point in world coordinates. */ Q_INVOKABLE void setHeadLookAt(const glm::vec3& lookAtTarget); /**jsdoc * Returns the current head look at target point in world coordinates. * @function MyAvatar.getHeadLookAt * @returns {Vec3} Default position between your avatar's eyes in world coordinates. */ Q_INVOKABLE glm::vec3 getHeadLookAt() { return _lookAtCameraTarget; } glm::quat getLookAtRotation() { return _lookAtYaw * _lookAtPitch; } /**jsdoc * Creates a new grab that grabs an entity. * @function MyAvatar.grab * @param {Uuid} targetID - The ID of the entity to grab. * @param {number} parentJointIndex - The avatar joint to use to grab the entity. * @param {Vec3} offset - The target's local position relative to the joint. * @param {Quat} rotationalOffset - The target's local rotation relative to the joint. * @returns {Uuid} The ID of the new grab. * @example Create and grab an entity for a short while. * var entityPosition = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })); * var entityRotation = MyAvatar.orientation; * var entityID = Entities.addEntity({ * type: "Box", * position: entityPosition, * rotation: entityRotation, * dimensions: { x: 0.5, y: 0.5, z: 0.5 } * }); * var rightHandJoint = MyAvatar.getJointIndex("RightHand"); * var relativePosition = Entities.worldToLocalPosition(entityPosition, MyAvatar.SELF_ID, rightHandJoint); * var relativeRotation = Entities.worldToLocalRotation(entityRotation, MyAvatar.SELF_ID, rightHandJoint); * var grabID = MyAvatar.grab(entityID, rightHandJoint, relativePosition, relativeRotation); * * Script.setTimeout(function () { * MyAvatar.releaseGrab(grabID); * Entities.deleteEntity(entityID); * }, 10000); */ Q_INVOKABLE const QUuid grab(const QUuid& targetID, int parentJointIndex, glm::vec3 positionalOffset, glm::quat rotationalOffset); /**jsdoc * Releases (deletes) a grab to stop grabbing an entity. * @function MyAvatar.releaseGrab * @param {Uuid} grabID - The ID of the grab to release. */ Q_INVOKABLE void releaseGrab(const QUuid& grabID); /**jsdoc * Gets details of all avatar entities. * @function MyAvatar.getAvatarEntityData * @returns {AvatarEntityMap} Details of the avatar entities. * @example Report the current avatar entities. * var avatarEntityData = MyAvatar.getAvatarEntityData(); * print("Avatar entities: " + JSON.stringify(avatarEntityData)); */ AvatarEntityMap getAvatarEntityData() const override; /**jsdoc * Sets all avatar entities from an object. * @function MyAvatar.setAvatarEntityData * @param {AvatarEntityMap} avatarEntityData - Details of the avatar entities. */ void setAvatarEntityData(const AvatarEntityMap& avatarEntityData) override; /**jsdoc * @comment Uses the base class's JSDoc. */ void updateAvatarEntity(const QUuid& entityID, const QByteArray& entityData) override; void avatarEntityDataToJson(QJsonObject& root) const override; /**jsdoc * @comment Uses the base class's JSDoc. */ int sendAvatarDataPacket(bool sendAll = false) override; void addAvatarHandsToFlow(const std::shared_ptr& otherAvatar); /**jsdoc * Enables and disables flow simulation of physics on the avatar's hair, clothes, and body parts. See * {@link https://docs.highfidelity.com/create/avatars/add-flow.html|Add Flow to Your Avatar} for more * information. * @function MyAvatar.useFlow * @param {boolean} isActive - true if flow simulation is enabled on the joint, false if it isn't. * @param {boolean} isCollidable - true to enable collisions in the flow simulation, false to * disable. * @param {Object} [physicsConfig>] - Physics configurations for particular entity * and avatar joints. * @param {Object} [collisionsConfig] - Collision configurations for particular * entity and avatar joints. */ Q_INVOKABLE void useFlow(bool isActive, bool isCollidable, const QVariantMap& physicsConfig = QVariantMap(), const QVariantMap& collisionsConfig = QVariantMap()); /**jsdoc * Gets the current flow configuration. * @function MyAvatar.getFlowData * @returns {MyAvatar.FlowData} */ Q_INVOKABLE QVariantMap getFlowData(); /**jsdoc * Gets the indexes of currently colliding flow joints. * @function MyAvatar.getCollidingFlowJoints * @returns {number[]} The indexes of currently colliding flow joints. */ Q_INVOKABLE QVariantList getCollidingFlowJoints(); /**jsdoc * Starts a sitting action for the avatar * @function MyAvatar.beginSit * @param {Vec3} position - The point in space where the avatar will sit. * @param {Quat} rotation - Initial absolute orientation of the avatar once is seated. */ Q_INVOKABLE void beginSit(const glm::vec3& position, const glm::quat& rotation); /**jsdoc * Ends a sitting action for the avatar * @function MyAvatar.endSit * @param {Vec3} position - The position of the avatar when standing up. * @param {Quat} rotation - The absolute rotation of the avatar once the sitting action ends. */ Q_INVOKABLE void endSit(const glm::vec3& position, const glm::quat& rotation); int getOverrideJointCount() const; bool getFlowActive() const; bool getNetworkGraphActive() const; void updateLookAtPosition(FaceTracker* faceTracker, Camera& myCamera); // sets the reaction enabled and triggered parameters of the passed in params // also clears internal reaction triggers void updateRigControllerParameters(Rig::ControllerParameters& params); // Don't substitute verify-fail: virtual const QUrl& getSkeletonModelURL() const override { return _skeletonModelURL; } void debugDrawPose(controller::Action action, const char* channelName, float size); bool getIsJointOverridden(int jointIndex) const; public slots: /**jsdoc * @comment Uses the base class's JSDoc. */ virtual void setSessionUUID(const QUuid& sessionUUID) override; /**jsdoc * Increases 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 * Decreases 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 * Resets the avatar's scale back to the default scale of 1.0. * @function MyAvatar.resetSize */ void resetSize(); /**jsdoc * @function MyAvatar.animGraphLoaded * @deprecated This function is deprecated and will be removed. */ void animGraphLoaded(); /**jsdoc * Sets the amount of gravity applied to the avatar in the y-axis direction. (Negative values are downward.) * @function MyAvatar.setGravity * @param {number} gravity - The amount of gravity to be applied to the avatar, in m/s2. */ void setGravity(float gravity); /**jsdoc * Sets the amount of gravity applied to the avatar in the y-axis direction. (Negative values are downward.) The default * value is -5 m/s2. * @function MyAvatar.getGravity * @returns {number} The amount of gravity currently applied to the avatar, in m/s2. */ float getGravity(); /**jsdoc * Moves the avatar to a new position and/or orientation in the domain, while taking into account Avatar leg-length. * @function MyAvatar.goToFeetLocation * @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 goToFeetLocation(const glm::vec3& newPosition, bool hasOrientation = false, const glm::quat& newOrientation = glm::quat(), bool shouldFaceLocation = false); /**jsdoc * Moves 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 * @param {boolean} [withSafeLanding=true] - Set to false MyAvatar::safeLanding will not be called (used when teleporting). * 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, bool withSafeLanding = true); /**jsdoc * Moves the avatar to a new position and (optional) orientation in the domain. * @function MyAvatar.goToLocation * @param {MyAvatar.GoToProperties} target - The goto target. */ void goToLocation(const QVariant& properties); /**jsdoc * Moves the avatar to a new position and then enables collisions. * @function MyAvatar.goToLocationAndEnableCollisions * @param {Vec3} position - The new position for the avatar, in world coordinates. */ void goToLocationAndEnableCollisions(const glm::vec3& newPosition); /**jsdoc * @function MyAvatar.safeLanding * @param {Vec3} position -The new position for the avatar, in world coordinates. * @returns {boolean} true if the avatar was moved, false if it wasn't. * @deprecated This function is deprecated and will be removed. */ bool safeLanding(const glm::vec3& position); /**jsdoc * @function MyAvatar.restrictScaleFromDomainSettings * @param {object} domainSettings - Domain settings. * @deprecated This function is deprecated and will be removed. */ void restrictScaleFromDomainSettings(const QJsonObject& domainSettingsObject); /**jsdoc * @function MyAvatar.clearScaleRestriction * @deprecated This function is deprecated and will be removed. */ void clearScaleRestriction(); /**jsdoc * Adds a thrust to your avatar's current thrust to be applied for a short while. * @function MyAvatar.addThrust * @param {Vec3} thrust - The thrust direction and magnitude. * @deprecated This function is deprecated and will be removed. Use {@link MyAvatar|MyAvatar.motorVelocity} and related * properties instead. */ // Set/Get update the thrust that will move the avatar around void addThrust(glm::vec3 newThrust) { _thrust += newThrust; }; /**jsdoc * Gets the thrust currently being applied to your avatar. * @function MyAvatar.getThrust * @returns {Vec3} The thrust currently being applied to your avatar. * @deprecated This function is deprecated and will be removed. Use {@link MyAvatar|MyAvatar.motorVelocity} and related * properties instead. */ glm::vec3 getThrust() { return _thrust; }; /**jsdoc * Sets the thrust to be applied to your avatar for a short while. * @function MyAvatar.setThrust * @param {Vec3} thrust - The thrust direction and magnitude. * @deprecated This function is deprecated and will be removed. Use {@link MyAvatar|MyAvatar.motorVelocity} and related * properties instead. */ void setThrust(glm::vec3 newThrust) { _thrust = newThrust; } /**jsdoc * Updates avatar motion behavior from the Developer > Avatar > Enable Default Motor Control and Enable Scripted * Motor Control menu items. * @function MyAvatar.updateMotionBehaviorFromMenu */ Q_INVOKABLE void updateMotionBehaviorFromMenu(); /**jsdoc * @function MyAvatar.setToggleHips * @param {boolean} enabled - Enabled. * @deprecated This function is deprecated and will be removed. */ void setToggleHips(bool followHead); /**jsdoc * Displays the base of support area debug graphics if in HMD mode. If your head goes outside this area your avatar's hips * are moved to counterbalance your avatar, and if your head moves too far then your avatar's position is moved (i.e., a * step happens). * @function MyAvatar.setEnableDebugDrawBaseOfSupport * @param {boolean} enabled - true to show the debug graphics, false to hide. */ void setEnableDebugDrawBaseOfSupport(bool isEnabled); /**jsdoc * Displays default pose debug graphics. * @function MyAvatar.setEnableDebugDrawDefaultPose * @param {boolean} enabled - true to show the debug graphics, false to hide. */ void setEnableDebugDrawDefaultPose(bool isEnabled); /**jsdoc * Displays animation debug graphics. By default, the animation poses used for rendering are displayed. However, * {@link MyAvatar.setDebugDrawAnimPoseName} can be used to set a specific animation node to display. * @function MyAvatar.setEnableDebugDrawAnimPose * @param {boolean} enabled - true to show the debug graphics, false to hide. */ void setEnableDebugDrawAnimPose(bool isEnabled); /**jsdoc * Sets the animation node to display when animation debug graphics are enabled with * {@link MyAvatar.setEnableDebugDrawAnimPose}. * @function MyAvatar.setDebugDrawAnimPoseName * @param {string} poseName - The name of the animation node to display debug graphics for. Use "" to reset to * default. */ void setDebugDrawAnimPoseName(QString poseName); /**jsdoc * Displays position debug graphics. * @function MyAvatar.setEnableDebugDrawPosition * @param {boolean} enabled - true to show the debug graphics, false to hide. */ void setEnableDebugDrawPosition(bool isEnabled); /**jsdoc * Displays controller hand target debug graphics. * @function MyAvatar.setEnableDebugDrawHandControllers * @param {boolean} enabled - true to show the debug graphics, false to hide. */ void setEnableDebugDrawHandControllers(bool isEnabled); /**jsdoc * Displays sensor-to-world matrix debug graphics. * @function MyAvatar.setEnableDebugDrawSensorToWorldMatrix * @param {boolean} enable - true to show the debug graphics, false to hide. */ void setEnableDebugDrawSensorToWorldMatrix(bool isEnabled); /**jsdoc * Displays inverse kinematics targets debug graphics. * @function MyAvatar.setEnableDebugDrawIKTargets * @param {boolean} enabled - true to show the debug graphics, false to hide. */ void setEnableDebugDrawIKTargets(bool isEnabled); /**jsdoc * Displays inverse kinematics constraints debug graphics. * @function MyAvatar.setEnableDebugDrawIKConstraints * @param {boolean} enabled - true to show the debug graphics, false to hide. */ void setEnableDebugDrawIKConstraints(bool isEnabled); /**jsdoc * Displays inverse kinematics chains debug graphics. * @function MyAvatar.setEnableDebugDrawIKChains * @param {boolean} enabled - true to show the debug graphics, false to hide. */ void setEnableDebugDrawIKChains(bool isEnabled); /**jsdoc * Displays detailed collision debug graphics. * @function MyAvatar.setEnableDebugDrawDetailedCollision * @param {boolean} enabled - true to show the debug graphics, false to hide. */ void setEnableDebugDrawDetailedCollision(bool isEnabled); /**jsdoc * Gets whether your avatar mesh is visible. * @function MyAvatar.getEnableMeshVisible * @returns {boolean} true if your avatar's mesh is visible, otherwise false. */ bool getEnableMeshVisible() const override; /**jsdoc * @function MyAvatar.storeAvatarEntityDataPayload * @deprecated This function is deprecated and will be removed. */ void storeAvatarEntityDataPayload(const QUuid& entityID, const QByteArray& payload) override; /**jsdoc * @comment Uses the base class's JSDoc. */ void clearAvatarEntity(const QUuid& entityID, bool requiresRemovalFromTree = true) override; /**jsdoc * @function MyAvatar.sanitizeAvatarEntityProperties * @param {EntityItemProperties} properties - Properties. * @deprecated This function is deprecated and will be removed. */ void sanitizeAvatarEntityProperties(EntityItemProperties& properties) const; /**jsdoc * Sets whether your avatar mesh is visible to you. * @function MyAvatar.setEnableMeshVisible * @param {boolean} enabled - true to show your avatar mesh, false to hide. * @example Make your avatar invisible for 10s. * MyAvatar.setEnableMeshVisible(false); * Script.setTimeout(function () { * MyAvatar.setEnableMeshVisible(true); * }, 10000); */ virtual void setEnableMeshVisible(bool isEnabled) override; /**jsdoc * Sets whether inverse kinematics (IK) is enabled for your avatar. * @function MyAvatar.setEnableInverseKinematics * @param {boolean} enabled - true to enable IK, false to disable. */ void setEnableInverseKinematics(bool isEnabled); /**jsdoc * Gets the URL of the override animation graph. *

See {@link https://docs.highfidelity.com/create/avatars/custom-animations.html|Custom Avatar Animations} for * information on animation graphs.

* @function MyAvatar.getAnimGraphOverrideUrl * @returns {string} The URL of the override animation graph JSON file. "" if there is no override animation * graph. */ QUrl getAnimGraphOverrideUrl() const; // thread-safe /**jsdoc * Sets the animation graph to use in preference to the default animation graph. *

See {@link https://docs.highfidelity.com/create/avatars/custom-animations.html|Custom Avatar Animations} for * information on animation graphs.

* @function MyAvatar.setAnimGraphOverrideUrl * @param {string} url - The URL of the animation graph JSON file to use. Set to "" to clear an override. */ void setAnimGraphOverrideUrl(QUrl value); // thread-safe /**jsdoc * Gets the URL of animation graph (i.e., the avatar animation JSON) that's currently being used for avatar animations. *

See {@link https://docs.highfidelity.com/create/avatars/custom-animations.html|Custom Avatar Animations} for * information on animation graphs.

* @function MyAvatar.getAnimGraphUrl * @returns {string} The URL of the current animation graph JSON file. * @Example Report the current avatar animation JSON being used. * print(MyAvatar.getAnimGraphUrl()); */ QUrl getAnimGraphUrl() const; // thread-safe /**jsdoc * Sets the current animation graph (i.e., the avatar animation JSON) to use for avatar animations and makes it the default. *

See {@link https://docs.highfidelity.com/create/avatars/custom-animations.html|Custom Avatar Animations} for * information on animation graphs.

* @function MyAvatar.setAnimGraphUrl * @param {string} url - The URL of the animation graph JSON file to use. */ void setAnimGraphUrl(const QUrl& url); // thread-safe /**jsdoc * Gets your listening position for spatialized audio. The position depends on the value of the * {@link Myavatar|audioListenerMode} property. * @function MyAvatar.getPositionForAudio * @returns {Vec3} Your listening position. */ glm::vec3 getPositionForAudio(); /**jsdoc * Gets the orientation of your listening position for spatialized audio. The orientation depends on the value of the * {@link Myavatar|audioListenerMode} property. * @function MyAvatar.getOrientationForAudio * @returns {Quat} The orientation of your listening position. */ glm::quat getOrientationForAudio(); /**jsdoc * @function MyAvatar.setModelScale * @param {number} scale - The scale. * @deprecated This function is deprecated and will be removed. */ virtual void setModelScale(float scale) override; /**jsdoc * MyAvatar.getTriggerReactions * Returns a list of reactions names that can be triggered using MyAvatar.triggerReaction(). * @returns {string[]} Array of reaction names. */ QStringList getTriggerReactions() const; /**jsdoc * MyAvatar.getBeginReactions * Returns a list of reactions names that can be enabled using MyAvatar.beginReaction() and MyAvatar.endReaction(). * @returns {string[]} Array of reaction names. */ QStringList getBeginEndReactions() const; /**jsdoc * MyAvatar.triggerReaction * Plays the given reaction on the avatar, once the reaction is complete it will automatically complete. Only reaction names returned from MyAvatar.getTriggerReactions() are available. * @param {string} reactionName - reaction name * @returns {bool} false if the given reaction is not supported. */ bool triggerReaction(QString reactionName); /**jsdoc * MyAvatar.beginReaction * Plays the given reaction on the avatar. The avatar will continue to play the reaction until stopped via the MyAvatar.endReaction() call or superseeded by another reaction. * Only reaction names returned from MyAvatar.getBeginEndReactions() are available. * NOTE: the caller is responsible for calling the corresponding MyAvatar.endReaction(), otherwise the avatar might become stuck in the reaction forever. * @param {string} reactionName - reaction name * @returns {bool} false if the given reaction is not supported. */ bool beginReaction(QString reactionName); /**jsdoc * MyAvatar.endReaction * Used to stop a given reaction that was started via MyAvatar.beginReaction(). * @param {string} reactionName - reaction name * @returns {bool} false if the given reaction is not supported. */ bool endReaction(QString reactionName); signals: /**jsdoc * Triggered when the {@link MyAvatar|audioListenerMode} property value changes. * @function MyAvatar.audioListenerModeChanged * @returns {Signal} */ void audioListenerModeChanged(); /**jsdoc * Triggered when the walk speed set for the "AnalogPlus" control scheme changes. * @function MyAvatar.analogPlusWalkSpeedChanged * @param {number} speed - The new walk speed set for the "AnalogPlus" control scheme. * @returns {Signal} */ void analogPlusWalkSpeedChanged(float value); /**jsdoc * Triggered when the sprint (run) speed set for the "AnalogPlus" control scheme changes. * @function MyAvatar.analogPlusSprintSpeedChanged * @param {number} speed - The new sprint speed set for the "AnalogPlus" control scheme. * @returns {Signal} */ void analogPlusSprintSpeedChanged(float value); /**jsdoc * Triggered when the sprint (run) speed set for the current control scheme (see * {@link MyAvatar.getControlScheme|getControlScheme}) changes. * @function MyAvatar.sprintSpeedChanged * @param {number} speed -The new sprint speed set for the current control scheme. * @returns {Signal} */ void sprintSpeedChanged(float value); /**jsdoc * Triggered when the walk backward speed set for the current control scheme (see * {@link MyAvatar.getControlScheme|getControlScheme}) changes. * @function MyAvatar.walkBackwardSpeedChanged * @param {number} speed - The new walk backward speed set for the current control scheme. * @returns {Signal} */ void walkBackwardSpeedChanged(float value); /**jsdoc * @function MyAvatar.transformChanged * @returns {Signal} * @deprecated This signal is deprecated and will be removed. */ void transformChanged(); /**jsdoc * Triggered when the {@link MyAvatar|collisionSoundURL} property value changes. * @function MyAvatar.newCollisionSoundURL * @param {string} url - The URL of the new collision sound. * @returns {Signal} */ void newCollisionSoundURL(const QUrl& url); /**jsdoc * Triggered when the avatar collides with an entity. * @function MyAvatar.collisionWithEntity * @param {Collision} collision - Details of the 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 * Triggered when collisions with the environment are enabled or disabled. * @function MyAvatar.collisionsEnabledChanged * @param {boolean} enabled - true if collisions with the environment are enabled, false if * they're not. * @returns {Signal} */ void collisionsEnabledChanged(bool enabled); /**jsdoc * Triggered when collisions with other avatars are enabled or disabled. * @function MyAvatar.otherAvatarsCollisionsEnabledChanged * @param {boolean} enabled - true if collisions with other avatars are enabled, false if they're * not. * @returns {Signal} */ void otherAvatarsCollisionsEnabledChanged(bool enabled); /**jsdoc * Triggered when the avatar's animation graph being used changes. * @function MyAvatar.animGraphUrlChanged * @param {string} url - The URL of the new animation graph JSON file. * @returns {Signal} * @example Report when the current avatar animation JSON being used changes. * MyAvatar.animGraphUrlChanged.connect(function (url) { * print("Avatar animation JSON changed to: " + url); * }); */ void animGraphUrlChanged(const QUrl& url); /**jsdoc * @function MyAvatar.energyChanged * @param {number} energy - Avatar energy. * @returns {Signal} * @deprecated This signal is deprecated and will be removed. */ void energyChanged(float newEnergy); /**jsdoc * Triggered when the avatar has been moved to a new position by one of the MyAvatar "goTo" functions. * @function MyAvatar.positionGoneTo * @returns {Signal} */ // FIXME: Better name would be goneToLocation(). void positionGoneTo(); /**jsdoc * Triggered when the avatar's model finishes loading. * @function MyAvatar.onLoadComplete * @returns {Signal} */ void onLoadComplete(); /**jsdoc * Triggered when your avatar changes from being active to being away. * @function MyAvatar.wentAway * @returns {Signal} * @example Report when your avatar goes away. * MyAvatar.wentAway.connect(function () { * print("My avatar went away"); * }); * // In desktop mode, pres the Esc key to go away. */ void wentAway(); /**jsdoc * Triggered when your avatar changes from being away to being active. * @function MyAvatar.wentActive * @returns {Signal} */ void wentActive(); /**jsdoc * Triggered when the avatar's model (i.e., {@link MyAvatar|skeletonModelURL} property value) is changed. *

Synonym of {@link MyAvatar.skeletonModelURLChanged|skeletonModelURLChanged}.

* @function MyAvatar.skeletonChanged * @returns {Signal} */ void skeletonChanged(); /**jsdoc * Triggered when the avatar's dominant hand changes. * @function MyAvatar.dominantHandChanged * @param {string} hand - The dominant hand: "left" for the left hand, "right" for the right hand. * @returns {Signal} */ void dominantHandChanged(const QString& hand); /**jsdoc * Triggered when the HMD alignment for your avatar changes. * @function MyAvatar.hmdAvatarAlignmentTypeChanged * @param {string} type - "head" if aligning your head and your avatar's head, "eyes" if aligning * your eyes and your avatar's eyes. * @returns {Signal} */ void hmdAvatarAlignmentTypeChanged(const QString& type); /**jsdoc * Triggered when the avatar's sensorToWorldScale property value changes. * @function MyAvatar.sensorToWorldScaleChanged * @param {number} scale - The scale that transforms dimensions in the user's real world to the avatar's size in the virtual * world. * @returns {Signal} */ void sensorToWorldScaleChanged(float sensorToWorldScale); /**jsdoc * Triggered when the a model is attached to or detached from one of the avatar's joints using one of * {@link MyAvatar.attach|attach}, {@link MyAvatar.detachOne|detachOne}, {@link MyAvatar.detachAll|detachAll}, or * {@link MyAvatar.setAttachmentData|setAttachmentData}. * @function MyAvatar.attachmentsChanged * @returns {Signal} * @deprecated This signal is deprecated and will be removed. Use avatar entities instead. */ void attachmentsChanged(); /**jsdoc * Triggered when the avatar's size changes. This can be due to the user changing the size of their avatar or the domain * limiting the size of their avatar. * @function MyAvatar.scaleChanged * @returns {Signal} */ void scaleChanged(); /**jsdoc * Triggered when the hand touch effect is enabled or disabled for the avatar. *

The hand touch effect makes the avatar's fingers adapt to the shape of any object grabbed, creating the effect that * it is really touching that object.

* @function MyAvatar.shouldDisableHandTouchChanged * @param {boolean} disabled - true if the hand touch effect is disabled for the avatar, * false if it isn't disabled. * @returns {Signal} */ void shouldDisableHandTouchChanged(bool shouldDisable); /**jsdoc * Triggered when the hand touch is enabled or disabled on a specific entity. *

The hand touch effect makes the avatar's fingers adapt to the shape of any object grabbed, creating the effect that * it is really touching that object.

* @function MyAvatar.disableHandTouchForIDChanged * @param {Uuid} entityID - The entity that the hand touch effect has been enabled or disabled for. * @param {boolean} disabled - true if the hand touch effect is disabled for the entity, * false if it isn't disabled. * @returns {Signal} */ void disableHandTouchForIDChanged(const QUuid& entityID, bool disable); private slots: void leaveDomain(); void updateCollisionCapsuleCache(); protected: void handleChangedAvatarEntityData(); virtual void beParentOfChild(SpatiallyNestablePointer newChild) const override; virtual void forgetChild(SpatiallyNestablePointer newChild) const override; virtual void recalculateChildCauterization() const override; private: bool updateStaleAvatarEntityBlobs() const; bool requiresSafeLanding(const glm::vec3& positionIn, glm::vec3& positionOut); virtual QByteArray toByteArrayStateful(AvatarDataDetail dataDetail, bool dropFaceTracking) override; void simulate(float deltaTime, bool inView) override; void updateFromTrackers(float deltaTime); void saveAvatarUrl(); virtual void render(RenderArgs* renderArgs) override; virtual bool shouldRenderHead(const RenderArgs* renderArgs) const override; void setShouldRenderLocally(bool shouldRender) { _shouldRender = shouldRender; setEnableMeshVisible(shouldRender); } bool getShouldRenderLocally() const { return _shouldRender; } void setHasScriptedBlendshapes(bool hasScriptedBlendshapes); bool getHasScriptedBlendshapes() const override { return _hasScriptedBlendShapes; } void setHasProceduralBlinkFaceMovement(bool hasProceduralBlinkFaceMovement); bool getHasProceduralBlinkFaceMovement() const override { return _headData->getHasProceduralBlinkFaceMovement(); } void setHasProceduralEyeFaceMovement(bool hasProceduralEyeFaceMovement); bool getHasProceduralEyeFaceMovement() const override { return _headData->getHasProceduralEyeFaceMovement(); } void setHasAudioEnabledFaceMovement(bool hasAudioEnabledFaceMovement); bool getHasAudioEnabledFaceMovement() const override { return _headData->getHasAudioEnabledFaceMovement(); } void setRotationRecenterFilterLength(float length); float getRotationRecenterFilterLength() const { return _rotationRecenterFilterLength; } void setRotationThreshold(float angleRadians); float getRotationThreshold() const { return _rotationThreshold; } void setEnableStepResetRotation(bool stepReset) { _stepResetRotationEnabled = stepReset; } bool getEnableStepResetRotation() const { return _stepResetRotationEnabled; } void setEnableDrawAverageFacing(bool drawAverage) { _drawAverageFacingEnabled = drawAverage; } bool getEnableDrawAverageFacing() const { return _drawAverageFacingEnabled; } virtual bool isMyAvatar() const override { return true; } virtual int parseDataFromBuffer(const QByteArray& buffer) override; virtual glm::vec3 getSkeletonPosition() const override; int _skeletonModelChangeCount { 0 }; void saveAvatarScale(); glm::vec3 getScriptedMotorVelocity() const { return _scriptedMotorVelocity; } float getScriptedMotorTimescale() const { return _scriptedMotorTimescale; } QString getScriptedMotorFrame() const; QString getScriptedMotorMode() const; void setScriptedMotorVelocity(const glm::vec3& velocity); void setScriptedMotorTimescale(float timescale); void setScriptedMotorFrame(QString frame); void setScriptedMotorMode(QString mode); // Attachments 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) override; virtual void detachOne(const QString& modelURL, const QString& jointName = QString()) override; virtual void detachAll(const QString& modelURL, const QString& jointName = QString()) override; // Attachments/Avatar Entity void attachmentDataToEntityProperties(const AttachmentData& data, EntityItemProperties& properties); AttachmentData entityPropertiesToAttachmentData(const EntityItemProperties& properties) const; bool findAvatarEntity(const QString& modelURL, const QString& jointName, QUuid& entityID); bool cameraInsideHead(const glm::vec3& cameraPosition) const; void updateEyeContactTarget(float deltaTime); // These are made private for MyAvatar so that you will use the "use" methods instead /**jsdoc * @comment Borrows the base class's JSDoc. */ Q_INVOKABLE virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) override; virtual void updatePalms() override {} void lateUpdatePalms(); void setSitDriveKeysStatus(bool enabled); void clampTargetScaleToDomainLimits(); void clampScaleChangeToDomainLimits(float desiredScale); glm::mat4 computeCameraRelativeHandControllerMatrix(const glm::mat4& controllerSensorMatrix) const; std::array _driveKeys; std::bitset _disabledDriveKeys; bool _enableFlying { false }; bool _flyingPrefDesktop { true }; bool _flyingPrefHMD { false }; bool _wasPushing { false }; bool _isPushing { false }; bool _isBeingPushed { false }; bool _isBraking { false }; bool _isAway { false }; float _boomLength { ZOOM_DEFAULT }; float _yawSpeed; // degrees/sec float _pitchSpeed; // degrees/sec float _driveGear1 { DEFAULT_GEAR_1 }; float _driveGear2 { DEFAULT_GEAR_2 }; float _driveGear3 { DEFAULT_GEAR_3 }; float _driveGear4 { DEFAULT_GEAR_4 }; float _driveGear5 { DEFAULT_GEAR_5 }; int _controlSchemeIndex { CONTROLS_DEFAULT }; int _movementReference{ 0 }; glm::vec3 _thrust { 0.0f }; // impulse accumulator for outside sources glm::vec3 _actionMotorVelocity; // target local-frame velocity of avatar (default controller actions) glm::vec3 _scriptedMotorVelocity; // target local-frame velocity of avatar (analog script) float _scriptedMotorTimescale; // timescale for avatar to achieve its target velocity int _scriptedMotorFrame; int _scriptedMotorMode; quint32 _motionBehaviors; QString _collisionSoundURL; SharedSoundPointer _collisionSound; MyCharacterController _characterController; int32_t _previousCollisionMask { BULLET_COLLISION_MASK_MY_AVATAR }; AvatarWeakPointer _lookAtTargetAvatar; glm::vec3 _targetAvatarPosition; bool _shouldRender { true }; float _oculusYawOffset; eyeContactTarget _eyeContactTarget; float _eyeContactTargetTimer { 0.0f }; glm::vec3 _trackedHeadPosition; const float MAX_LOOK_AT_TIME_SCRIPT_CONTROL = 2.0f; glm::quat _lookAtPitch; glm::quat _lookAtYaw; glm::vec3 _lookAtCameraTarget; glm::vec3 _lookAtScriptTarget; bool _headLookAtActive { false }; bool _shouldTurnToFaceCamera { false }; bool _scriptControlsHeadLookAt { false }; float _scriptHeadControlTimer { 0.0f }; Setting::Handle _realWorldFieldOfView; Setting::Handle _useAdvancedMovementControls; Setting::Handle _showPlayArea; // Smoothing. const float SMOOTH_TIME_ORIENTATION = 0.5f; // Smoothing data for blending from one position/orientation to another on remote agents. float _smoothOrientationTimer; glm::quat _smoothOrientationInitial; glm::quat _smoothOrientationTarget; // private methods void updateOrientation(float deltaTime); glm::vec3 calculateScaledDirection(); float calculateGearedSpeed(const float driveKey); glm::vec3 scaleMotorSpeed(const glm::vec3 forward, const glm::vec3 right); void updateActionMotor(float deltaTime); void updatePosition(float deltaTime); void updateViewBoom(); void updateCollisionSound(const glm::vec3& penetration, float deltaTime, float frequency); void initHeadBones(); void initAnimGraph(); void initFlowFromFST(); void updateHeadLookAt(float deltaTime); void resetHeadLookAt(); void resetLookAtRotation(const glm::vec3& avatarPosition, const glm::quat& avatarOrientation); // Avatar Preferences QUrl _fullAvatarURLFromPreferences; QString _fullAvatarModelName; ThreadSafeValueCache _currentAnimGraphUrl; ThreadSafeValueCache _prefOverrideAnimGraphUrl; QUrl _fstAnimGraphOverrideUrl; bool _useSnapTurn { true }; bool _hoverWhenUnsupported{ true }; ThreadSafeValueCache _dominantHand { DOMINANT_RIGHT_HAND }; ThreadSafeValueCache _hmdAvatarAlignmentType { DEFAULT_HMD_AVATAR_ALIGNMENT_TYPE }; ThreadSafeValueCache _strafeEnabled{ DEFAULT_STRAFE_ENABLED }; const float ROLL_CONTROL_DEAD_ZONE_DEFAULT = 8.0f; // degrees const float ROLL_CONTROL_RATE_DEFAULT = 114.0f; // degrees / sec bool _hmdRollControlEnabled { true }; float _hmdRollControlDeadZone { ROLL_CONTROL_DEAD_ZONE_DEFAULT }; float _hmdRollControlRate { ROLL_CONTROL_RATE_DEFAULT }; std::atomic _hasScriptedBlendShapes { false }; std::atomic _rotationRecenterFilterLength { 4.0f }; std::atomic _rotationThreshold { 0.5235f }; // 30 degrees in radians std::atomic _stepResetRotationEnabled { true }; std::atomic _drawAverageFacingEnabled { false }; // working copy -- see AvatarData for thread-safe _sensorToWorldMatrixCache, used for outward facing access glm::mat4 _sensorToWorldMatrix { glm::mat4() }; // cache of the current HMD sensor position and orientation in sensor space. glm::mat4 _hmdSensorMatrix; glm::quat _hmdSensorOrientation; glm::vec3 _hmdSensorPosition; // cache head controller pose in sensor space glm::vec2 _headControllerFacing; // facing vector in xz plane (sensor space) glm::vec2 _headControllerFacingMovingAverage { 0.0f, 0.0f }; // facing vector in xz plane (sensor space) glm::quat _averageHeadRotation { 0.0f, 0.0f, 0.0f, 1.0f }; glm::vec2 _hipToHandController { 0.0f, 1.0f }; // spine2 facing vector in xz plane (spine2 space) float _currentStandingHeight { 0.0f }; bool _resetMode { true }; RingBufferHistory _recentModeReadings; // cache of the current body position and orientation of the avatar's body, // in sensor space. glm::mat4 _bodySensorMatrix; struct FollowHelper { FollowHelper(); enum FollowType { Rotation = 0, Horizontal, Vertical, NumFollowTypes }; float _timeRemaining[NumFollowTypes]; void deactivate(); void deactivate(FollowType type); void activate(); void activate(FollowType type); bool isActive() const; bool isActive(FollowType followType) const; float getMaxTimeRemaining() const; void decrementTimeRemaining(float dt); bool shouldActivateRotation(const MyAvatar& myAvatar, const glm::mat4& desiredBodyMatrix, const glm::mat4& currentBodyMatrix) const; bool shouldActivateVertical(const MyAvatar& myAvatar, const glm::mat4& desiredBodyMatrix, const glm::mat4& currentBodyMatrix) const; bool shouldActivateHorizontal(const MyAvatar& myAvatar, const glm::mat4& desiredBodyMatrix, const glm::mat4& currentBodyMatrix) const; bool shouldActivateHorizontalCG(MyAvatar& myAvatar) const; void prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat4& bodySensorMatrix, const glm::mat4& currentBodyMatrix, bool hasDriveInput); glm::mat4 postPhysicsUpdate(MyAvatar& myAvatar, const glm::mat4& currentBodyMatrix); bool getForceActivateRotation() const; void setForceActivateRotation(bool val); bool getForceActivateVertical() const; void setForceActivateVertical(bool val); bool getForceActivateHorizontal() const; void setForceActivateHorizontal(bool val); bool getToggleHipsFollowing() const; void setToggleHipsFollowing(bool followHead); bool _squatDetected { false }; std::atomic _forceActivateRotation { false }; std::atomic _forceActivateVertical { false }; std::atomic _forceActivateHorizontal { false }; std::atomic _toggleHipsFollowing { true }; }; FollowHelper _follow; bool isFollowActive(FollowHelper::FollowType followType) const; bool _goToPending { false }; bool _physicsSafetyPending { false }; bool _goToSafe { true }; bool _goToFeetAjustment { false }; glm::vec3 _goToPosition; glm::quat _goToOrientation; std::unordered_set _headBoneSet; std::unordered_set _cauterizedChildrenOfHead; bool _prevShouldDrawHead; bool _rigEnabled { true }; bool _enableDebugDrawBaseOfSupport { false }; bool _enableDebugDrawDefaultPose { false }; bool _enableDebugDrawAnimPose { false }; bool _enableDebugDrawHandControllers { false }; bool _enableDebugDrawSensorToWorldMatrix { false }; bool _enableDebugDrawIKTargets { false }; bool _enableDebugDrawIKConstraints { false }; bool _enableDebugDrawIKChains { false }; bool _enableDebugDrawDetailedCollision { false }; ThreadSafeValueCache _debugDrawAnimPoseName; mutable bool _cauterizationNeedsUpdate { false }; // do we need to scan children and update their "cauterized" state? AudioListenerMode _audioListenerMode; glm::vec3 _customListenPosition; glm::quat _customListenOrientation; AtRestDetector _leftHandAtRestDetector; AtRestDetector _rightHandAtRestDetector; // all poses are in sensor-frame std::map _controllerPoseMap; mutable std::mutex _controllerPoseMapMutex; mutable std::mutex _disableHandTouchMutex; bool _centerOfGravityModelEnabled { true }; bool _hmdLeanRecenterEnabled { true }; bool _sprint { false }; AnimPose _prePhysicsRoomPose; std::mutex _holdActionsMutex; std::vector _holdActions; float AVATAR_MOVEMENT_ENERGY_CONSTANT { 0.001f }; float AUDIO_ENERGY_CONSTANT { 0.000001f }; float MAX_AVATAR_MOVEMENT_PER_FRAME { 30.0f }; float currentEnergy { 0.0f }; float energyChargeRate { 0.003f }; glm::vec3 priorVelocity; glm::vec3 lastPosition; float getAudioEnergy(); float getAccelerationEnergy(); float getEnergy(); void setEnergy(float value); bool didTeleport(); bool getIsAway() const { return _isAway; } void setAway(bool value); void sendPacket(const QUuid& entityID) const override; std::mutex _pinnedJointsMutex; std::vector _pinnedJoints; void updateChildCauterization(SpatiallyNestablePointer object, bool cauterize); // height of user in sensor space, when standing erect. ThreadSafeValueCache _userHeight { DEFAULT_AVATAR_HEIGHT }; float _averageUserHeightSensorSpace { _userHeight.get() }; bool _sitStandStateChange { false }; ThreadSafeValueCache _lockSitStandState { false }; // max unscaled forward movement speed ThreadSafeValueCache _defaultWalkSpeed { DEFAULT_AVATAR_MAX_WALKING_SPEED }; ThreadSafeValueCache _defaultWalkBackwardSpeed { DEFAULT_AVATAR_MAX_WALKING_BACKWARD_SPEED }; ThreadSafeValueCache _defaultSprintSpeed { DEFAULT_AVATAR_MAX_SPRINT_SPEED }; ThreadSafeValueCache _analogWalkSpeed { ANALOG_AVATAR_MAX_WALKING_SPEED }; ThreadSafeValueCache _analogWalkBackwardSpeed { ANALOG_AVATAR_MAX_WALKING_BACKWARD_SPEED }; ThreadSafeValueCache _analogSprintSpeed { ANALOG_AVATAR_MAX_SPRINT_SPEED }; ThreadSafeValueCache _analogPlusWalkSpeed { ANALOG_PLUS_AVATAR_MAX_WALKING_SPEED }; ThreadSafeValueCache _analogPlusWalkBackwardSpeed { ANALOG_PLUS_AVATAR_MAX_WALKING_BACKWARD_SPEED }; ThreadSafeValueCache _analogPlusSprintSpeed { ANALOG_PLUS_AVATAR_MAX_SPRINT_SPEED }; float _walkSpeedScalar { AVATAR_WALK_SPEED_SCALAR }; bool _isInWalkingState { false }; ThreadSafeValueCache _isInSittingState { false }; ThreadSafeValueCache _userRecenterModel { MyAvatar::SitStandModelType::Auto }; float _sitStandStateTimer { 0.0f }; float _squatTimer { 0.0f }; float _tippingPoint { _userHeight.get() }; // load avatar scripts once when rig is ready bool _shouldLoadScripts { false }; bool _haveReceivedHeightLimitsFromDomain { false }; int _disableHandTouchCount { 0 }; bool _skeletonModelLoaded { false }; bool _reloadAvatarEntityDataFromSettings { true }; TimePoint _nextTraitsSendWindow; Setting::Handle _dominantHandSetting; Setting::Handle _strafeEnabledSetting; Setting::Handle _hmdAvatarAlignmentTypeSetting; Setting::Handle _headPitchSetting; Setting::Handle _scaleSetting; Setting::Handle _yawSpeedSetting; Setting::Handle _pitchSpeedSetting; Setting::Handle _fullAvatarURLSetting; Setting::Handle _fullAvatarModelNameSetting; Setting::Handle _animGraphURLSetting; Setting::Handle _displayNameSetting; Setting::Handle _collisionSoundURLSetting; Setting::Handle _useSnapTurnSetting; Setting::Handle _hoverWhenUnsupportedSetting; Setting::Handle _userHeightSetting; Setting::Handle _flyingHMDSetting; Setting::Handle _movementReferenceSetting; Setting::Handle _avatarEntityCountSetting; Setting::Handle _allowTeleportingSetting { "allowTeleporting", true }; Setting::Handle _driveGear1Setting; Setting::Handle _driveGear2Setting; Setting::Handle _driveGear3Setting; Setting::Handle _driveGear4Setting; Setting::Handle _driveGear5Setting; Setting::Handle _analogWalkSpeedSetting; Setting::Handle _analogPlusWalkSpeedSetting; Setting::Handle _controlSchemeIndexSetting; std::vector> _avatarEntityIDSettings; std::vector> _avatarEntityDataSettings; Setting::Handle _userRecenterModelSetting; // AvatarEntities stuff: // We cache the "map of unfortunately-formatted-binary-blobs" because they are expensive to compute // Do not confuse these with AvatarData::_packedAvatarEntityData which are in wire-format. mutable AvatarEntityMap _cachedAvatarEntityBlobs; // We collect changes to AvatarEntities and then handle them all in one spot per frame: updateAvatarEntities(). // Basically this is a "transaction pattern" with an extra complication: these changes can come from two // "directions" and the "authoritative source" of each direction is different, so maintain two distinct sets of // transaction lists; // // The _entitiesToDelete/Add/Update lists are for changes whose "authoritative sources" are already // correctly stored in _cachedAvatarEntityBlobs. These come from loadAvatarEntityDataFromSettings() and // setAvatarEntityData(). These changes need to be extracted from _cachedAvatarEntityBlobs and applied to // real EntityItems. std::vector _entitiesToDelete; std::vector _entitiesToAdd; std::vector _entitiesToUpdate; // // The _cachedAvatarEntityBlobsToDelete/Add/Update lists are for changes whose "authoritative sources" are // already reflected in real EntityItems. These changes need to be propagated to _cachedAvatarEntityBlobs // and eventually to settings. std::vector _cachedAvatarEntityBlobsToDelete; std::vector _cachedAvatarEntityBlobsToAddOrUpdate; std::vector _cachedAvatarEntityBlobUpdatesToSkip; // // Also these lists for tracking delayed changes to blobs and Settings mutable std::set _staleCachedAvatarEntityBlobs; // // keep a ScriptEngine around so we don't have to instantiate on the fly (these are very slow to create/delete) mutable std::mutex _scriptEngineLock; QScriptEngine* _scriptEngine { nullptr }; bool _needToSaveAvatarEntitySettings { false }; bool _reactionTriggers[NUM_AVATAR_TRIGGER_REACTIONS] { false, false }; int _reactionEnabledRefCounts[NUM_AVATAR_BEGIN_END_REACTIONS] { 0, 0, 0 }; mutable std::mutex _reactionLock; // used to prevent character from jumping after endSit is called. bool _endSitKeyPressComplete { false }; }; QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode); void audioListenModeFromScriptValue(const QScriptValue& object, AudioListenerMode& audioListenerMode); QScriptValue driveKeysToScriptValue(QScriptEngine* engine, const MyAvatar::DriveKeys& driveKeys); void driveKeysFromScriptValue(const QScriptValue& object, MyAvatar::DriveKeys& driveKeys); bool isWearableEntity(const EntityItemPointer& entity); #endif // hifi_MyAvatar_h