diff --git a/assignment-client/src/avatars/AvatarMixerClientData.cpp b/assignment-client/src/avatars/AvatarMixerClientData.cpp index 8c4ceb2288..8081c77ee8 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.cpp +++ b/assignment-client/src/avatars/AvatarMixerClientData.cpp @@ -204,10 +204,8 @@ void AvatarMixerClientData::processSetTraitsMessage(ReceivedMessage& message, if (traitType == AvatarTraits::SkeletonModelURL) { // special handling for skeleton model URL, since we need to make sure it is in the whitelist checkSkeletonURLAgainstWhitelist(slaveSharedData, sendingNode, packetTraitVersion); -#ifdef AVATAR_POP_CHECK // Deferred for UX work. With no PoP check, no need to get the .fst. _avatar->fetchAvatarFST(); -#endif } anyTraitsChanged = true; diff --git a/interface/resources/avatar/animations/emote_agree_acknowledge.fbx b/interface/resources/avatar/animations/emote_agree_acknowledge.fbx new file mode 100644 index 0000000000..8d44c898ca Binary files /dev/null and b/interface/resources/avatar/animations/emote_agree_acknowledge.fbx differ diff --git a/interface/resources/avatar/animations/emote_clap01_all.fbx b/interface/resources/avatar/animations/emote_clap01_all.fbx new file mode 100644 index 0000000000..cddab6d535 Binary files /dev/null and b/interface/resources/avatar/animations/emote_clap01_all.fbx differ diff --git a/interface/resources/avatar/animations/emote_disagree_defeated.fbx b/interface/resources/avatar/animations/emote_disagree_defeated.fbx new file mode 100644 index 0000000000..44be8619eb Binary files /dev/null and b/interface/resources/avatar/animations/emote_disagree_defeated.fbx differ diff --git a/interface/resources/avatar/animations/emote_point01_all.fbx b/interface/resources/avatar/animations/emote_point01_all.fbx new file mode 100644 index 0000000000..7bd660db9f Binary files /dev/null and b/interface/resources/avatar/animations/emote_point01_all.fbx differ diff --git a/interface/resources/avatar/animations/emote_raisehand01_all.fbx b/interface/resources/avatar/animations/emote_raisehand01_all.fbx new file mode 100644 index 0000000000..3c7c761523 Binary files /dev/null and b/interface/resources/avatar/animations/emote_raisehand01_all.fbx differ diff --git a/interface/resources/avatar/avatar-animation.json b/interface/resources/avatar/avatar-animation.json index b1277a26f5..dd6e75a20f 100644 --- a/interface/resources/avatar/avatar-animation.json +++ b/interface/resources/avatar/avatar-animation.json @@ -903,246 +903,162 @@ "children": [ { "id": "idle", - "type": "overlay", + "type": "stateMachine", "data": { - "alpha": 1.0, - "alphaVar": "idleOverlayAlpha", - "boneSet": "upperBody" + "currentState": "idleOverlay", + "states": [ + { + "id": "idleOverlay", + "interpTarget": 6, + "interpDuration": 6, + "interpType": "snapshotPrev", + "transitions": [ + { "var": "reactionPositiveTrigger", "state": "reactionPositive" }, + { "var": "reactionNegativeTrigger", "state": "reactionNegative" }, + { "var": "reactionRaiseHandEnabled", "state": "reactionRaiseHand" }, + { "var": "reactionApplaudEnabled", "state": "reactionApplaud" }, + { "var": "reactionPointEnabled", "state": "reactionPoint" } + ] + }, + { + "id": "reactionPositive", + "interpTarget": 6, + "interpDuration": 6, + "interpType": "snapshotPrev", + "transitions": [ + { "var": "reactionPositiveOnDone", "state": "idleOverlay" }, + { "var": "reactionNegativeTrigger", "state": "reactionNegative" }, + { "var": "reactionRaiseHandEnabled", "state": "reactionRaiseHand" }, + { "var": "reactionApplaudEnabled", "state": "reactionApplaud" }, + { "var": "reactionPointEnabled", "state": "reactionPoint" } + ] + }, + { + "id": "reactionNegative", + "interpTarget": 6, + "interpDuration": 6, + "interpType": "snapshotPrev", + "transitions": [ + { "var": "reactionPositiveTrigger", "state": "reactionPositive" }, + { "var": "reactionNegativeOnDone", "state": "idleOverlay" }, + { "var": "reactionRaiseHandEnabled", "state": "reactionRaiseHand" }, + { "var": "reactionApplaudEnabled", "state": "reactionApplaud" }, + { "var": "reactionPointEnabled", "state": "reactionPoint" } + ] + }, + { + "id": "reactionRaiseHand", + "interpTarget": 6, + "interpDuration": 6, + "interpType": "snapshotPrev", + "transitions": [ + { "var": "reactionNegativeTrigger", "state": "reactionNegative" }, + { "var": "reactionPositiveTrigger", "state": "reactionPositive" }, + { "var": "reactionRaiseHandDisabled", "state": "idleOverlay" }, + { "var": "reactionApplaudEnabled", "state": "reactionApplaud" }, + { "var": "reactionPointEnabled", "state": "reactionPoint" } + ] + }, + { + "id": "reactionApplaud", + "interpTarget": 6, + "interpDuration": 6, + "interpType": "snapshotPrev", + "transitions": [ + { "var": "reactionNegativeTrigger", "state": "reactionNegative" }, + { "var": "reactionPositiveTrigger", "state": "reactionPositive" }, + { "var": "reactionRaiseHandEnabled", "state": "reactionRaiseHand" }, + { "var": "reactionApplaudDisabled", "state": "idleOverlay" }, + { "var": "reactionPointEnabled", "state": "reactionPoint" } + ] + }, + { + "id": "reactionPoint", + "interpTarget": 6, + "interpDuration": 6, + "interpType": "snapshotPrev", + "transitions": [ + { "var": "reactionNegativeTrigger", "state": "reactionNegative" }, + { "var": "reactionPositiveTrigger", "state": "reactionPositive" }, + { "var": "reactionRaiseHandEnabled", "state": "reactionRaiseHand" }, + { "var": "reactionApplaudEnabled", "state": "reactionApplaud" }, + { "var": "reactionPointDisabled", "state": "idleOverlay" } + ] + } + ] }, "children": [ { - "id": "idleTalk", - "type": "randomSwitchStateMachine", + "id": "idleOverlay", + "type": "overlay", "data": { - "currentState": "talk", - "triggerRandomSwitch": "idleTalkSwitch", - "randomSwitchTimeMin": 7.0, - "randomSwitchTimeMax": 12.0, - "states": [ - { - "id": "talk", - "interpTarget": 20, - "interpDuration": 20, - "priority": 0.33, - "resume": true, - "transitions": [] - }, - { - "id": "talk02", - "interpTarget": 20, - "interpDuration": 20, - "priority": 0.33, - "resume": true, - "transitions": [] - }, - { - "id": "talk03", - "interpTarget": 20, - "interpDuration": 20, - "priority": 0.33, - "resume": true, - "transitions": [] - }, - { - "id": "talk04", - "interpTarget": 20, - "interpDuration": 20, - "priority": 0.33, - "resume": true, - "transitions": [] - }, - { - "id": "talk_armsdown", - "interpTarget": 20, - "interpDuration": 20, - "priority": 0.33, - "resume": true, - "transitions": [] - }, - { - "id": "talk_lefthand", - "interpTarget": 20, - "interpDuration": 20, - "priority": 0.33, - "resume": true, - "transitions": [] - }, - { - "id": "talk_righthand", - "interpTarget": 20, - "interpDuration": 20, - "priority": 0.33, - "resume": true, - "transitions": [] - } - ] + "alpha": 1.0, + "alphaVar": "idleOverlayAlpha", + "boneSet": "upperBody" }, "children": [ { - "id": "talk", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/talk.fbx", - "startFrame": 1.0, - "endFrame": 500.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "talk02", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/talk02.fbx", - "startFrame": 1.0, - "endFrame": 325.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "talk03", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/talk03.fbx", - "startFrame": 1.0, - "endFrame": 300.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "talk04", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/talk04.fbx", - "startFrame": 1.0, - "endFrame": 500.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "talk_armsdown", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/talk_armsdown.fbx", - "startFrame": 1.0, - "endFrame": 215.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "talk_lefthand", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/talk_lefthand.fbx", - "startFrame": 1.0, - "endFrame": 500.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "talk_righthand", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/talk_righthand.fbx", - "startFrame": 1.0, - "endFrame": 502.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - } - ] - }, - { - "id": "idleStand", - "type": "randomSwitchStateMachine", - "data": { - "currentState": "masterIdle", - "triggerTimeMin": 10.0, - "triggerTimeMax": 50.0, - "transitionVar": "timeToFidget", - "states": [ - { - "id": "masterIdle", - "interpTarget": 21, - "interpDuration": 20, - "priority": 1.0, - "resume": false, - "transitions": [ - { "var": "timeToFidget", "randomSwitchState": "fidget" } - ] - }, - { - "id": "fidget", - "interpTarget": 21, - "interpDuration": 20, - "priority": -1.0, - "resume": false, - "transitions": [ - { "var": "idle_once_slownodOnDone", "randomSwitchState": "masterIdle" }, - { "var": "idle_once_headtiltOnDone", "randomSwitchState": "masterIdle" }, - { "var": "idle_once_shiftheelpivotOnDone", "randomSwitchState": "masterIdle" }, - { "var": "idleWS_allOnDone", "randomSwitchState": "masterIdle" }, - { "var": "idle_once_lookaroundOnDone", "randomSwitchState": "masterIdle" }, - { "var": "idle_once_neckstretchOnDone", "randomSwitchState": "masterIdle" }, - { "var": "idle_once_lookleftrightOnDone", "randomSwitchState": "masterIdle" }, - { "var": "idle_once_fidgetOnDone", "randomSwitchState": "masterIdle" }, - { "var": "alt1ToMasterIdleOnDone", "randomSwitchState": "masterIdle" }, - { "var": "alt2ToMasterIdleOnDone", "randomSwitchState": "masterIdle" } - ] - } - ] - }, - "children": [ - { - "id": "masterIdle", + "id": "idleTalk", "type": "randomSwitchStateMachine", "data": { - "currentState": "masterIdle1", - "triggerRandomSwitch": "masterIdleSwitch", - "randomSwitchTimeMin": 10.0, - "randomSwitchTimeMax": 30.0, + "currentState": "talk", + "triggerRandomSwitch": "idleTalkSwitch", + "randomSwitchTimeMin": 7.0, + "randomSwitchTimeMax": 12.0, "states": [ { - "id": "masterIdle1", - "interpTarget": 21, + "id": "talk", + "interpTarget": 20, "interpDuration": 20, - "priority": 0.25, + "priority": 0.33, "resume": true, "transitions": [] }, { - "id": "masterIdle2", - "interpTarget": 21, + "id": "talk02", + "interpTarget": 20, "interpDuration": 20, - "priority": 0.25, + "priority": 0.33, "resume": true, "transitions": [] }, { - "id": "masterIdle3", - "interpTarget": 21, + "id": "talk03", + "interpTarget": 20, "interpDuration": 20, - "priority": 0.25, + "priority": 0.33, "resume": true, "transitions": [] }, { - "id": "masterIdle4", - "interpTarget": 21, + "id": "talk04", + "interpTarget": 20, "interpDuration": 20, - "priority": 0.25, + "priority": 0.33, + "resume": true, + "transitions": [] + }, + { + "id": "talk_armsdown", + "interpTarget": 20, + "interpDuration": 20, + "priority": 0.33, + "resume": true, + "transitions": [] + }, + { + "id": "talk_lefthand", + "interpTarget": 20, + "interpDuration": 20, + "priority": 0.33, + "resume": true, + "transitions": [] + }, + { + "id": "talk_righthand", + "interpTarget": 20, + "interpDuration": 20, + "priority": 0.33, "resume": true, "transitions": [] } @@ -1150,10 +1066,34 @@ }, "children": [ { - "id": "masterIdle1", + "id": "talk", "type": "clip", "data": { - "url": "qrc:///avatar/animations/idle.fbx", + "url": "qrc:///avatar/animations/talk.fbx", + "startFrame": 1.0, + "endFrame": 500.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "talk02", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/talk02.fbx", + "startFrame": 1.0, + "endFrame": 325.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "talk03", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/talk03.fbx", "startFrame": 1.0, "endFrame": 300.0, "timeScale": 1.0, @@ -1162,36 +1102,48 @@ "children": [] }, { - "id": "masterIdle2", + "id": "talk04", "type": "clip", "data": { - "url": "qrc:///avatar/animations/idle02.fbx", + "url": "qrc:///avatar/animations/talk04.fbx", "startFrame": 1.0, - "endFrame": 400.0, - "timeScale": 0.75, - "loopFlag": true - }, - "children": [] - }, - { - "id": "masterIdle3", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/idle03.fbx", - "startFrame": 1.0, - "endFrame": 800.0, + "endFrame": 500.0, "timeScale": 1.0, "loopFlag": true }, "children": [] }, { - "id": "masterIdle4", + "id": "talk_armsdown", "type": "clip", "data": { - "url": "qrc:///avatar/animations/idle04.fbx", + "url": "qrc:///avatar/animations/talk_armsdown.fbx", "startFrame": 1.0, - "endFrame": 902.0, + "endFrame": 215.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "talk_lefthand", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/talk_lefthand.fbx", + "startFrame": 1.0, + "endFrame": 500.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "talk_righthand", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/talk_righthand.fbx", + "startFrame": 1.0, + "endFrame": 502.0, "timeScale": 1.0, "loopFlag": true }, @@ -1200,275 +1152,159 @@ ] }, { - "id": "fidget", + "id": "idleStand", "type": "randomSwitchStateMachine", "data": { - "currentState": "movement", + "currentState": "masterIdle", + "triggerTimeMin": 10.0, + "triggerTimeMax": 50.0, + "transitionVar": "timeToFidget", "states": [ { - "id": "movement", - "interpTarget": 17, - "interpDuration": 15, - "priority": 0.6, + "id": "masterIdle", + "interpTarget": 21, + "interpDuration": 20, + "priority": 1.0, "resume": false, - "transitions": [] + "transitions": [ + { "var": "timeToFidget", "randomSwitchState": "fidget" } + ] }, { - "id": "alternateIdle", - "interpTarget": 17, - "interpDuration": 15, - "priority": 0.4, + "id": "fidget", + "interpTarget": 21, + "interpDuration": 20, + "priority": -1.0, "resume": false, - "transitions": [] + "transitions": [ + { "var": "idle_once_slownodOnDone", "randomSwitchState": "masterIdle" }, + { "var": "idle_once_headtiltOnDone", "randomSwitchState": "masterIdle" }, + { "var": "idle_once_shiftheelpivotOnDone", "randomSwitchState": "masterIdle" }, + { "var": "idleWS_allOnDone", "randomSwitchState": "masterIdle" }, + { "var": "idle_once_lookaroundOnDone", "randomSwitchState": "masterIdle" }, + { "var": "idle_once_neckstretchOnDone", "randomSwitchState": "masterIdle" }, + { "var": "idle_once_lookleftrightOnDone", "randomSwitchState": "masterIdle" }, + { "var": "idle_once_fidgetOnDone", "randomSwitchState": "masterIdle" }, + { "var": "alt1ToMasterIdleOnDone", "randomSwitchState": "masterIdle" }, + { "var": "alt2ToMasterIdleOnDone", "randomSwitchState": "masterIdle" } + ] } ] }, "children": [ { - "id": "movement", + "id": "masterIdle", "type": "randomSwitchStateMachine", "data": { - "currentState": "idle_once_slownod", + "currentState": "masterIdle1", + "triggerRandomSwitch": "masterIdleSwitch", + "randomSwitchTimeMin": 10.0, + "randomSwitchTimeMax": 30.0, "states": [ { - "id": "idle_once_slownod", + "id": "masterIdle1", "interpTarget": 21, "interpDuration": 20, - "priority": 0.2, - "resume": false, + "priority": 0.25, + "resume": true, "transitions": [] }, { - "id": "idle_once_headtilt", + "id": "masterIdle2", "interpTarget": 21, "interpDuration": 20, - "priority": 0.2, - "resume": false, + "priority": 0.25, + "resume": true, "transitions": [] }, { - "id": "idle_once_shiftheelpivot", + "id": "masterIdle3", "interpTarget": 21, "interpDuration": 20, - "priority": 0.2, - "resume": false, + "priority": 0.25, + "resume": true, "transitions": [] }, { - "id": "idleWS_all", + "id": "masterIdle4", "interpTarget": 21, "interpDuration": 20, - "priority": 0.2, - "resume": false, - "transitions": [] - }, - { - "id": "idle_once_lookaround", - "interpTarget": 21, - "interpDuration": 20, - "priority": 0.2, - "resume": false, - "transitions": [] - }, - { - "id": "idle_once_neckstretch", - "interpTarget": 21, - "interpDuration": 20, - "priority": 0.2, - "resume": false, - "transitions": [] - }, - { - "id": "idle_once_lookleftright", - "interpTarget": 21, - "interpDuration": 20, - "priority": 0.2, - "resume": false, - "transitions": [] - }, - { - "id": "idle_once_fidget", - "interpTarget": 21, - "interpDuration": 20, - "priority": 0.2, - "resume": false, + "priority": 0.25, + "resume": true, "transitions": [] } ] }, "children": [ { - "id": "idle_once_slownod", + "id": "masterIdle1", "type": "clip", "data": { - "url": "qrc:///avatar/animations/idle_once_slownod.fbx", + "url": "qrc:///avatar/animations/idle.fbx", "startFrame": 1.0, - "endFrame": 91.0, + "endFrame": 300.0, "timeScale": 1.0, - "loopFlag": false + "loopFlag": true }, "children": [] }, { - "id": "idle_once_headtilt", + "id": "masterIdle2", "type": "clip", "data": { - "url": "qrc:///avatar/animations/idle_once_headtilt.fbx", + "url": "qrc:///avatar/animations/idle02.fbx", "startFrame": 1.0, - "endFrame": 154.0, + "endFrame": 400.0, + "timeScale": 0.75, + "loopFlag": true + }, + "children": [] + }, + { + "id": "masterIdle3", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle03.fbx", + "startFrame": 1.0, + "endFrame": 800.0, "timeScale": 1.0, - "loopFlag": false + "loopFlag": true }, "children": [] }, { - "id": "idle_once_shiftheelpivot", + "id": "masterIdle4", "type": "clip", "data": { - "url": "qrc:///avatar/animations/idle_once_shiftheelpivot.fbx", + "url": "qrc:///avatar/animations/idle04.fbx", "startFrame": 1.0, - "endFrame": 491.0, + "endFrame": 902.0, "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "idleWS_all", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/idleWS_all.fbx", - "startFrame": 1.0, - "endFrame": 1620.0, - "timeScale": 0.7, - "loopFlag": false - }, - "children": [] - }, - { - "id": "idle_once_lookaround", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/idle_once_lookaround.fbx", - "startFrame": 1.0, - "endFrame": 324.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "idle_once_neckstretch", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/idle_once_neckstretch.fbx", - "startFrame": 1.0, - "endFrame": 169.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "idle_once_lookleftright", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/idle_once_lookleftright.fbx", - "startFrame": 1.0, - "endFrame": 375.0, - "timeScale": 0.7, - "loopFlag": false - }, - "children": [] - }, - { - "id": "idle_once_fidget", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/idle_once_fidget.fbx", - "startFrame": 1.0, - "endFrame": 429.0, - "timeScale": 1.0, - "loopFlag": false + "loopFlag": true }, "children": [] } ] }, { - "id": "alternateIdle", + "id": "fidget", "type": "randomSwitchStateMachine", "data": { - "currentState": "transitionToAltIdle1", - "triggerTimeMin": 10.0, - "triggerTimeMax": 60.0, - "transitionVar": "finishAltIdle2", + "currentState": "movement", "states": [ { - "id": "transitionToAltIdle1", - "interpTarget": 11, - "interpDuration": 10, - "priority": 0.5, - "resume": false, - "transitions": [ - { - "var": "transitionToAltIdle1OnDone", - "randomSwitchState": "altIdle1" - } - ] - }, - { - "id": "transitionToAltIdle2", - "interpTarget": 11, - "interpDuration": 10, - "priority": 0.5, - "resume": false, - "transitions": [ - { - "var": "transitionToAltIdle2OnDone", - "randomSwitchState": "altIdle2" - } - ] - }, - { - "id": "altIdle1", - "interpTarget": 11, - "interpDuration": 10, - "priority": -1.0, - "resume": false, - "transitions": [ - { - "var": "finishAltIdle2", - "randomSwitchState": "alt1ToMasterIdle" - } - ] - }, - { - "id": "altIdle2", - "interpTarget": 11, - "interpDuration": 10, - "priority": -1.0, - "resume": false, - "transitions": [ - { - "var": "finishAltIdle2", - "randomSwitchState": "alt2ToMasterIdle" - } - ] - }, - { - "id": "alt1ToMasterIdle", - "interpTarget": 11, - "interpDuration": 10, - "priority": -1.0, + "id": "movement", + "interpTarget": 17, + "interpDuration": 15, + "priority": 0.6, "resume": false, "transitions": [] }, { - "id": "alt2ToMasterIdle", - "interpTarget": 11, - "interpDuration": 10, - "priority": -1.0, + "id": "alternateIdle", + "interpTarget": 17, + "interpDuration": 15, + "priority": 0.4, "resume": false, "transitions": [] } @@ -1476,84 +1312,396 @@ }, "children": [ { - "id": "transitionToAltIdle1", - "type": "clip", + "id": "movement", + "type": "randomSwitchStateMachine", "data": { - "url": "qrc:///avatar/animations/idle_LFF_all.fbx", - "startFrame": 1, - "endFrame": 80, - "timeScale": 1.0, - "loopFlag": false + "currentState": "idle_once_slownod", + "states": [ + { + "id": "idle_once_slownod", + "interpTarget": 21, + "interpDuration": 20, + "priority": 0.2, + "resume": false, + "transitions": [] + }, + { + "id": "idle_once_headtilt", + "interpTarget": 21, + "interpDuration": 20, + "priority": 0.2, + "resume": false, + "transitions": [] + }, + { + "id": "idle_once_shiftheelpivot", + "interpTarget": 21, + "interpDuration": 20, + "priority": 0.2, + "resume": false, + "transitions": [] + }, + { + "id": "idleWS_all", + "interpTarget": 21, + "interpDuration": 20, + "priority": 0.2, + "resume": false, + "transitions": [] + }, + { + "id": "idle_once_lookaround", + "interpTarget": 21, + "interpDuration": 20, + "priority": 0.2, + "resume": false, + "transitions": [] + }, + { + "id": "idle_once_neckstretch", + "interpTarget": 21, + "interpDuration": 20, + "priority": 0.2, + "resume": false, + "transitions": [] + }, + { + "id": "idle_once_lookleftright", + "interpTarget": 21, + "interpDuration": 20, + "priority": 0.2, + "resume": false, + "transitions": [] + }, + { + "id": "idle_once_fidget", + "interpTarget": 21, + "interpDuration": 20, + "priority": 0.2, + "resume": false, + "transitions": [] + } + ] }, - "children": [] + "children": [ + { + "id": "idle_once_slownod", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle_once_slownod.fbx", + "startFrame": 1.0, + "endFrame": 91.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "idle_once_headtilt", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle_once_headtilt.fbx", + "startFrame": 1.0, + "endFrame": 154.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "idle_once_shiftheelpivot", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle_once_shiftheelpivot.fbx", + "startFrame": 1.0, + "endFrame": 491.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "idleWS_all", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idleWS_all.fbx", + "startFrame": 1.0, + "endFrame": 1620.0, + "timeScale": 0.7, + "loopFlag": false + }, + "children": [] + }, + { + "id": "idle_once_lookaround", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle_once_lookaround.fbx", + "startFrame": 1.0, + "endFrame": 324.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "idle_once_neckstretch", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle_once_neckstretch.fbx", + "startFrame": 1.0, + "endFrame": 169.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "idle_once_lookleftright", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle_once_lookleftright.fbx", + "startFrame": 1.0, + "endFrame": 375.0, + "timeScale": 0.7, + "loopFlag": false + }, + "children": [] + }, + { + "id": "idle_once_fidget", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle_once_fidget.fbx", + "startFrame": 1.0, + "endFrame": 429.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + } + ] }, { - "id": "transitionToAltIdle2", - "type": "clip", + "id": "alternateIdle", + "type": "randomSwitchStateMachine", "data": { - "url": "qrc:///avatar/animations/idle_RFF_all.fbx", - "startFrame": 1.0, - "endFrame": 80.0, - "timeScale": 1.0, - "loopFlag": false + "currentState": "transitionToAltIdle1", + "triggerTimeMin": 10.0, + "triggerTimeMax": 60.0, + "transitionVar": "finishAltIdle2", + "states": [ + { + "id": "transitionToAltIdle1", + "interpTarget": 11, + "interpDuration": 10, + "priority": 0.5, + "resume": false, + "transitions": [ + { + "var": "transitionToAltIdle1OnDone", + "randomSwitchState": "altIdle1" + } + ] + }, + { + "id": "transitionToAltIdle2", + "interpTarget": 11, + "interpDuration": 10, + "priority": 0.5, + "resume": false, + "transitions": [ + { + "var": "transitionToAltIdle2OnDone", + "randomSwitchState": "altIdle2" + } + ] + }, + { + "id": "altIdle1", + "interpTarget": 11, + "interpDuration": 10, + "priority": -1.0, + "resume": false, + "transitions": [ + { + "var": "finishAltIdle2", + "randomSwitchState": "alt1ToMasterIdle" + } + ] + }, + { + "id": "altIdle2", + "interpTarget": 11, + "interpDuration": 10, + "priority": -1.0, + "resume": false, + "transitions": [ + { + "var": "finishAltIdle2", + "randomSwitchState": "alt2ToMasterIdle" + } + ] + }, + { + "id": "alt1ToMasterIdle", + "interpTarget": 11, + "interpDuration": 10, + "priority": -1.0, + "resume": false, + "transitions": [] + }, + { + "id": "alt2ToMasterIdle", + "interpTarget": 11, + "interpDuration": 10, + "priority": -1.0, + "resume": false, + "transitions": [] + } + ] }, - "children": [] - }, - { - "id": "altIdle1", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/idle_LFF_all.fbx", - "startFrame": 80, - "endFrame": 389, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "altIdle2", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/idle_RFF_all.fbx", - "startFrame": 80.0, - "endFrame": 390.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "alt1ToMasterIdle", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/idle_LFF_all.fbx", - "startFrame": 389, - "endFrame": 472, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "alt2ToMasterIdle", - "type": "clip", - "data": { - "url": "qrc:///avatar/animations/idle_RFF_all.fbx", - "startFrame": 390.0, - "endFrame": 453.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] + "children": [ + { + "id": "transitionToAltIdle1", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle_LFF_all.fbx", + "startFrame": 1, + "endFrame": 80, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "transitionToAltIdle2", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle_RFF_all.fbx", + "startFrame": 1.0, + "endFrame": 80.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "altIdle1", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle_LFF_all.fbx", + "startFrame": 80, + "endFrame": 389, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "altIdle2", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle_RFF_all.fbx", + "startFrame": 80.0, + "endFrame": 390.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "alt1ToMasterIdle", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle_LFF_all.fbx", + "startFrame": 389, + "endFrame": 472, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "alt2ToMasterIdle", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle_RFF_all.fbx", + "startFrame": 390.0, + "endFrame": 453.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + } + ] } ] } ] } - ] + }, + { + "id": "reactionPositive", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/emote_agree_acknowledge.fbx", + "startFrame": 0.0, + "endFrame": 45.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "reactionNegative", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/emote_disagree_defeated.fbx", + "startFrame": 0.0, + "endFrame": 110.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "reactionRaiseHand", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/emote_raisehand01_all.fbx", + "startFrame": 18.0, + "endFrame": 300.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "reactionApplaud", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/emote_clap01_all.fbx", + "startFrame": 20.0, + "endFrame": 84.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "reactionPoint", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/emote_point01_all.fbx", + "startFrame": 20.0, + "endFrame": 50.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] } ] }, @@ -2224,4 +2372,4 @@ } ] } -} \ No newline at end of file +} diff --git a/interface/resources/qml/StatText.qml b/interface/resources/qml/StatText.qml index 9fefbd28b8..074ecaa785 100644 --- a/interface/resources/qml/StatText.qml +++ b/interface/resources/qml/StatText.qml @@ -5,4 +5,6 @@ Text { style: Text.Outline; styleColor: "black"; font.pixelSize: 12; + font.bold: true; + font.family: "monospace"; } diff --git a/interface/src/AvatarBookmarks.cpp b/interface/src/AvatarBookmarks.cpp index 54c67daab8..d9ac522dc8 100644 --- a/interface/src/AvatarBookmarks.cpp +++ b/interface/src/AvatarBookmarks.cpp @@ -179,6 +179,18 @@ void AvatarBookmarks::updateAvatarEntities(const QVariantList &avatarEntities) { } } +/**jsdoc + * Details of an avatar bookmark. + * @typedef {object} AvatarBookmarks.BookmarkData + * @property {number} version - The version of the bookmark data format. + * @property {string} avatarUrl - The URL of the avatar model. + * @property {number} avatarScale - The target scale of the avatar. + * @property {Array>} [avatarEntites] - The avatar entities included with the + * bookmark. + * @property {MyAvatar.AttachmentData[]} [attachments] - The attachments included with the bookmark. + *

Deprecated: Use avatar entities instead. + */ + void AvatarBookmarks::loadBookmark(const QString& bookmarkName) { if (QThread::currentThread() != thread()) { BLOCKING_INVOKE_METHOD(this, "loadBookmark", Q_ARG(QString, bookmarkName)); diff --git a/interface/src/AvatarBookmarks.h b/interface/src/AvatarBookmarks.h index df75fec865..646d06456a 100644 --- a/interface/src/AvatarBookmarks.h +++ b/interface/src/AvatarBookmarks.h @@ -16,7 +16,9 @@ #include "Bookmarks.h" /**jsdoc - * This API helps manage adding and deleting avatar bookmarks. + * The AvatarBookmarks API provides facilities for working with avatar bookmarks ("favorites" in the Avatar app). + * An avatar bookmark associates a name with an avatar model, scale, and avatar entities (wearables). + * * @namespace AvatarBookmarks * * @hifi-interface @@ -32,41 +34,100 @@ class AvatarBookmarks: public Bookmarks, public Dependency { public: AvatarBookmarks(); void setupMenus(Menu* menubar, MenuWrapper* menu) override {}; + + /**jsdoc + * Gets the details of an avatar bookmark. + * @function AvatarBookmarks.getBookmark + * @param {string} bookmarkName - The name of the avatar bookmark (case sensitive). + * @returns {AvatarBookmarks.BookmarkData|{}} The bookmark data if the bookmark exists, {} if it doesn't. + */ Q_INVOKABLE QVariantMap getBookmark(const QString& bookmarkName); public slots: /**jsdoc - * Add the current Avatar to your avatar bookmarks. - * @function AvatarBookmarks.addBookMark + * Adds a new (or updates an existing) avatar bookmark with your current avatar model, scale, and avatar entities. + * @function AvatarBookmarks.addBookmark + * @param {string} bookmarkName - The name of the avatar bookmark (case sensitive). + * @example Add a new avatar bookmark and report the bookmark data. + * var bookmarkName = "New Bookmark"; + * AvatarBookmarks.addBookmark(bookmarkName); + * var bookmarkData = AvatarBookmarks.getBookmark(bookmarkName); + * print("Bookmark data: " + JSON.stringify(bookmarkData)); */ void addBookmark(const QString& bookmarkName); + + /**jsdoc + * Updates an existing bookmark with your current avatar model, scale, and wearables. No action is taken if the bookmark + * doesn't exist. + * @function AvatarBookmarks.saveBookmark + * @param {string} bookmarkName - The name of the avatar bookmark (case sensitive). + */ void saveBookmark(const QString& bookmarkName); + + /**jsdoc + * Loads an avatar bookmark, setting your avatar model, scale, and avatar entities (or attachments if an old bookmark) to + * those in the bookmark. + * @function AvatarBookmarks.loadBookmark + * @param {string} bookmarkName - The name of the avatar bookmark to load (case sensitive). + */ void loadBookmark(const QString& bookmarkName); + + /**jsdoc + * Deletes an avatar bookmark. + * @function AvatarBookmarks.removeBookmark + * @param {string} bookmarkName - The name of the avatar bookmark to delete (case sensitive). + */ void removeBookmark(const QString& bookmarkName); + + /**jsdoc + * Updates the avatar entities and their properties. Current avatar entities not included in the list provided are deleted. + * @function AvatarBookmarks.updateAvatarEntities + * @param {MyAvatar.AvatarEntityData[]} avatarEntities - The avatar entity IDs and properties. + * @deprecated This function is deprecated and will be removed. Use the {@link MyAvatar} API instead. + */ void updateAvatarEntities(const QVariantList& avatarEntities); + + /**jsdoc + * Gets the details of all avatar bookmarks. + * @function AvatarBookmarks.getBookmarks + * @returns {Object} The current avatar bookmarks in an object where the keys are the + * bookmark names and the values are the bookmark details. + * @example List the names and URLs of all the avatar bookmarks. + * var bookmarks = AvatarBookmarks.getBookmarks(); + * print("Avatar bookmarks:"); + * for (var key in bookmarks) { + * print("- " + key + " " + bookmarks[key].avatarUrl); + * }; + */ QVariantMap getBookmarks() { return _bookmarks; } signals: /**jsdoc - * This function gets triggered after avatar loaded from bookmark + * Triggered when an avatar bookmark is loaded, setting your avatar model, scale, and avatar entities (or attachments if an + * old bookmark) to those in the bookmark. * @function AvatarBookmarks.bookmarkLoaded - * @param {string} bookmarkName + * @param {string} bookmarkName - The name of the avatar bookmark loaded. * @returns {Signal} */ void bookmarkLoaded(const QString& bookmarkName); /**jsdoc - * This function gets triggered after avatar bookmark deleted + * Triggered when an avatar bookmark is deleted. * @function AvatarBookmarks.bookmarkDeleted - * @param {string} bookmarkName + * @param {string} bookmarkName - The name of the avatar bookmark deleted. * @returns {Signal} + * @example Report when a bookmark is deleted. + * AvatarBookmarks.bookmarkDeleted.connect(function (bookmarkName) { + * print("Bookmark deleted: " + bookmarkName); + * }); */ void bookmarkDeleted(const QString& bookmarkName); /**jsdoc - * This function gets triggered after avatar bookmark added + * Triggered when a new avatar bookmark is added or an existing avatar bookmark is updated, using + * {@link AvatarBookmarks.addBookmark|addBookmark}. * @function AvatarBookmarks.bookmarkAdded - * @param {string} bookmarkName + * @param {string} bookmarkName - The name of the avatar bookmark added or updated. * @returns {Signal} */ void bookmarkAdded(const QString& bookmarkName); @@ -77,6 +138,11 @@ protected: QVariantMap getAvatarDataToBookmark(); protected slots: + /**jsdoc + * Performs no action. + * @function AvatarBookmarks.deleteBookmark + * @deprecated This function is deprecated and will be removed. + */ void deleteBookmark() override; private: diff --git a/interface/src/Bookmarks.h b/interface/src/Bookmarks.h index c31aee6e33..e4480b7552 100644 --- a/interface/src/Bookmarks.h +++ b/interface/src/Bookmarks.h @@ -52,6 +52,7 @@ protected: protected slots: /**jsdoc + * Prompts the user to delete a bookmark. The user can select the bookmark to delete in the dialog that is opened. * @function LocationBookmarks.deleteBookmark */ virtual void deleteBookmark(); diff --git a/interface/src/LocationBookmarks.h b/interface/src/LocationBookmarks.h index eebaf2f383..574060fb61 100644 --- a/interface/src/LocationBookmarks.h +++ b/interface/src/LocationBookmarks.h @@ -17,6 +17,9 @@ #include "Bookmarks.h" /**jsdoc + * The LocationBookmarks API provides facilities for working with location bookmarks. A location bookmark + * associates a name with a metaverse address. + * * @namespace LocationBookmarks * * @hifi-client-entity @@ -35,28 +38,35 @@ public: static const QString HOME_BOOKMARK; /**jsdoc + * Gets the metaverse address associated with a bookmark. * @function LocationBookmarks.getAddress - * @param {string} bookmarkName Name of the bookmark to get the address for. - * @returns {string} The url for the specified bookmark. If the bookmark does not exist, the empty string will be returned. + * @param {string} bookmarkName - Name of the bookmark to get the metaverse address for (case sensitive). + * @returns {string} The metaverse address for the bookmark. If the bookmark does not exist, "" is returned. + * @example Report the "Home" bookmark's metaverse address. + * print("Home bookmark's address: " + LocationBookmarks.getAddress("Home")); */ Q_INVOKABLE QString getAddress(const QString& bookmarkName); public slots: /**jsdoc + * Prompts the user to bookmark their current location. The user can specify the name of the bookmark in the dialog that is + * opened. * @function LocationBookmarks.addBookmark */ void addBookmark(); /**jsdoc + * Sets the metaverse address associated with the "Home" bookmark. * @function LocationBookmarks.setHomeLocationToAddress - * @param {string} address + * @param {string} address - The metaverse address to set the "Home" bookmark to. */ void setHomeLocationToAddress(const QVariant& address); /**jsdoc + * Gets the metaverse address associated with the "Home" bookmark. * @function LocationBookmarks.getHomeLocationAddress - * @returns {string} The url for the home location bookmark + * @returns {string} The metaverse address for the "Home" bookmark. */ QString getHomeLocationAddress(); diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index ce23a80309..30f68297b4 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -238,7 +238,7 @@ public: * @function AvatarManager.getPalData * @param {string[]} [avatarIDs=[]] - The IDs of the avatars to get the PAL data for. If empty, then PAL data is obtained * for all avatars. - * @returns {object<"data", AvatarManager.PalData[]>} An array of objects, each object being the PAL data for an avatar. + * @returns {Object<"data", AvatarManager.PalData[]>} An array of objects, each object being the PAL data for an avatar. * @example Report the PAL data for an avatar nearby. * var palData = AvatarManager.getPalData(); * print("PAL data for one avatar: " + JSON.stringify(palData.data[0])); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index c2b9a97509..fb7f1a690f 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -125,6 +125,18 @@ QString userRecenterModelToString(MyAvatar::SitStandModelType model) { } } +static const QStringList REACTION_NAMES = { + QString("positive"), + QString("negative"), + QString("raiseHand"), + QString("applaud"), + QString("point") +}; + +static int reactionNameToIndex(const QString& reactionName) { + return REACTION_NAMES.indexOf(reactionName); +} + MyAvatar::MyAvatar(QThread* thread) : Avatar(thread), _yawSpeed(YAW_SPEED_DEFAULT), @@ -2751,19 +2763,23 @@ QString MyAvatar::getScriptedMotorMode() const { } void MyAvatar::setScriptedMotorVelocity(const glm::vec3& velocity) { - float MAX_SCRIPTED_MOTOR_SPEED = 500.0f; - _scriptedMotorVelocity = velocity; - float speed = glm::length(_scriptedMotorVelocity); - if (speed > MAX_SCRIPTED_MOTOR_SPEED) { - _scriptedMotorVelocity *= MAX_SCRIPTED_MOTOR_SPEED / speed; + float newSpeed = glm::length(velocity); + if (!glm::isnan(newSpeed)) { + _scriptedMotorVelocity = velocity; + constexpr float MAX_SCRIPTED_MOTOR_SPEED = 500.0f; + if (newSpeed > MAX_SCRIPTED_MOTOR_SPEED) { + _scriptedMotorVelocity *= MAX_SCRIPTED_MOTOR_SPEED / newSpeed; + } } } void MyAvatar::setScriptedMotorTimescale(float timescale) { - // we clamp the timescale on the large side (instead of just the low side) to prevent - // obnoxiously large values from introducing NaN into avatar's velocity - _scriptedMotorTimescale = glm::clamp(timescale, MIN_SCRIPTED_MOTOR_TIMESCALE, - DEFAULT_SCRIPTED_MOTOR_TIMESCALE); + if (!glm::isnan(timescale)) { + // we clamp the timescale on the large side (instead of just the low side) to prevent + // obnoxiously large values from introducing NaN into avatar's velocity + _scriptedMotorTimescale = glm::clamp(timescale, MIN_SCRIPTED_MOTOR_TIMESCALE, + DEFAULT_SCRIPTED_MOTOR_TIMESCALE); + } } void MyAvatar::setScriptedMotorFrame(QString frame) { @@ -5808,6 +5824,53 @@ void MyAvatar::setModelScale(float scale) { } } +QStringList MyAvatar::getReactions() const { + return REACTION_NAMES; +} + +bool MyAvatar::triggerReaction(QString reactionName) { + int reactionIndex = reactionNameToIndex(reactionName); + if (reactionIndex >= 0 && reactionIndex < (int)NUM_AVATAR_REACTIONS) { + std::lock_guard guard(_reactionLock); + _reactionTriggers[reactionIndex] = true; + return true; + } + return false; +} + +bool MyAvatar::beginReaction(QString reactionName) { + int reactionIndex = reactionNameToIndex(reactionName); + if (reactionIndex >= 0 && reactionIndex < (int)NUM_AVATAR_REACTIONS) { + std::lock_guard guard(_reactionLock); + _reactionEnabledRefCounts[reactionIndex]++; + return true; + } + return false; +} + +bool MyAvatar::endReaction(QString reactionName) { + int reactionIndex = reactionNameToIndex(reactionName); + if (reactionIndex >= 0 && reactionIndex < (int)NUM_AVATAR_REACTIONS) { + std::lock_guard guard(_reactionLock); + _reactionEnabledRefCounts[reactionIndex]--; + return true; + } + return false; +} + +void MyAvatar::updateRigControllerParameters(Rig::ControllerParameters& params) { + std::lock_guard guard(_reactionLock); + for (int i = 0; i < NUM_AVATAR_REACTIONS; i++) { + + // copy current state into params. + params.reactionEnabledFlags[i] = _reactionEnabledRefCounts[i] > 0; + params.reactionTriggers[i] = _reactionTriggers[i]; + + // clear reaction triggers here as well + _reactionTriggers[i] = false; + } +} + SpatialParentTree* MyAvatar::getParentTree() const { auto entityTreeRenderer = qApp->getEntities(); EntityTreePointer entityTree = entityTreeRenderer ? entityTreeRenderer->getTree() : nullptr; diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 24fda81969..c456931db2 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1369,9 +1369,9 @@ public: bool hasDriveInput() const; /**jsdoc - * Gets the list of avatar entities and their properties. + * Gets the current avatar entity IDs and their properties. * @function MyAvatar.getAvatarEntitiesVariant - * @returns {MyAvatar.AvatarEntityData[]} The list of avatar entities and their properties. + * @returns {MyAvatar.AvatarEntityData[]} The current avatar entity IDs and their properties. */ Q_INVOKABLE QVariantList getAvatarEntitiesVariant(); @@ -1855,6 +1855,10 @@ public: bool getFlowActive() const; bool getNetworkGraphActive() const; + // sets the reaction enabled and triggered parameters of the passed in params + // also clears internal reaction triggers + void updateRigControllerParameters(Rig::ControllerParameters& params); + public slots: /**jsdoc @@ -2208,6 +2212,33 @@ public slots: */ virtual void setModelScale(float scale) override; + /**jsdoc + * MyAvatar.getReactions + * @returns {string[]} Array of reaction names. + */ + QStringList getReactions() const; + + /**jsdoc + * MyAvatar.triggerReaction + * @param {string} reactionName - reaction name + * @returns {bool} false if the given reaction is not supported. + */ + bool triggerReaction(QString reactionName); + + /**jsdoc + * MyAvatar.beginReaction + * @param {string} reactionName - reaction name + * @returns {bool} false if the given reaction is not supported. + */ + bool beginReaction(QString reactionName); + + /**jsdoc + * MyAvatar.endReaction + * @param {string} reactionName - reaction name + * @returns {bool} false if the given reaction is not supported. + */ + bool endReaction(QString reactionName); + signals: /**jsdoc @@ -2842,6 +2873,10 @@ private: mutable std::mutex _scriptEngineLock; QScriptEngine* _scriptEngine { nullptr }; bool _needToSaveAvatarEntitySettings { false }; + + int _reactionEnabledRefCounts[NUM_AVATAR_REACTIONS] { 0, 0, 0, 0, 0 }; + bool _reactionTriggers[NUM_AVATAR_REACTIONS] { false, false, false, false, false }; + mutable std::mutex _reactionLock; }; QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode); diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 141166a150..6080911dd9 100755 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -296,8 +296,6 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { _prevIsEstimatingHips = false; } - params.isTalking = head->getTimeWithoutTalking() <= 1.5f; - // pass detailed torso k-dops to rig. int hipsJoint = _rig.indexOfJoint("Hips"); if (hipsJoint >= 0) { @@ -316,6 +314,10 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { params.spine2ShapeInfo = hfmModel.joints[spine2Joint].shapeInfo; } + params.isTalking = head->getTimeWithoutTalking() <= 1.5f; + + myAvatar->updateRigControllerParameters(params); + _rig.updateFromControllerParameters(params, deltaTime); Rig::CharacterControllerState ccState = convertCharacterControllerState(myAvatar->getCharacterController()->getState()); diff --git a/interface/src/raypick/PickScriptingInterface.h b/interface/src/raypick/PickScriptingInterface.h index e973ee3643..473413ca58 100644 --- a/interface/src/raypick/PickScriptingInterface.h +++ b/interface/src/raypick/PickScriptingInterface.h @@ -29,7 +29,7 @@ * @property {FilterFlags} PICK_AVATAR_ENTITIES - Include avatar entities when intersecting. Read-only. * @property {FilterFlags} PICK_LOCAL_ENTITIES - Include local entities when intersecting. Read-only. * @property {FilterFlags} PICK_AVATARS - Include avatars when intersecting. Read-only. - * @property {FilterFlags} PICK_HUD - Include the HUD sphere when intersecting in HMD mode. Read-only. + * @property {FilterFlags} PICK_HUD - Include the HUD surface when intersecting in HMD mode. Read-only. * * @property {FilterFlags} PICK_ENTITIES - Include domain and avatar entities when intersecting. Read-only. *

Deprecated: This property is deprecated and will be removed. Use PICK_DOMAIN_ENTITIES | @@ -61,7 +61,7 @@ *

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

* @property {IntersectionType} INTERSECTED_AVATAR - Intersected an avatar. Read-only. - * @property {IntersectionType} INTERSECTED_HUD - Intersected the HUD sphere. Read-only. + * @property {IntersectionType} INTERSECTED_HUD - Intersected the HUD surface. Read-only. * * @property {number} perFrameTimeBudget - The maximum time, in microseconds, to spend per frame updating pick results. */ diff --git a/interface/src/raypick/RayPickScriptingInterface.h b/interface/src/raypick/RayPickScriptingInterface.h index 2a00847510..204407e92d 100644 --- a/interface/src/raypick/RayPickScriptingInterface.h +++ b/interface/src/raypick/RayPickScriptingInterface.h @@ -33,7 +33,7 @@ * Read-only. * @property {FilterFlags} PICK_OVERLAYS - Include local entities when intersecting. Read-only. * @property {FilterFlags} PICK_AVATARS - Include avatars when intersecting. Read-only. - * @property {FilterFlags} PICK_HUD - Include the HUD sphere when intersecting in HMD mode. Read-only. + * @property {FilterFlags} PICK_HUD - Include the HUD surface when intersecting in HMD mode. Read-only. * @property {FilterFlags} PICK_PRECISE - Pick against exact meshes. Read-only. * @property {FilterFlags} PICK_INCLUDE_INVISIBLE - Include invisible objects when intersecting. Read-only. * @property {FilterFlags} PICK_INCLUDE_NONCOLLIDABLE - Include non-collidable objects when intersecting. Read-only. @@ -43,7 +43,7 @@ * @property {IntersectionType} INTERSECTED_LOCAL_ENTITY - Intersected a local entity. Read-only. * @property {IntersectionType} INTERSECTED_OVERLAY - Intersected an entity (3D Overlays no longer exist). Read-only. * @property {IntersectionType} INTERSECTED_AVATAR - Intersected an avatar. Read-only. - * @property {IntersectionType} INTERSECTED_HUD - Intersected the HUD sphere. Read-only. + * @property {IntersectionType} INTERSECTED_HUD - Intersected the HUD surface. Read-only. */ class RayPickScriptingInterface : public QObject, public Dependency { Q_OBJECT diff --git a/interface/src/scripting/Audio.h b/interface/src/scripting/Audio.h index d62fd70cc4..aab1ade95b 100644 --- a/interface/src/scripting/Audio.h +++ b/interface/src/scripting/Audio.h @@ -459,7 +459,7 @@ signals: /**jsdoc * Triggered when the server injector gain changes. * @function Audio.serverInjectorGainChanged - * @param {float} gain - The new server injector gain value. + * @param {number} gain - The new server injector gain value. * @returns {Signal} */ void serverInjectorGainChanged(float gain); diff --git a/interface/src/scripting/HMDScriptingInterface.h b/interface/src/scripting/HMDScriptingInterface.h index 030f817477..30a1353d81 100644 --- a/interface/src/scripting/HMDScriptingInterface.h +++ b/interface/src/scripting/HMDScriptingInterface.h @@ -62,7 +62,7 @@ class QScriptEngine; * @property {Uuid} miniTabletScreenID - The UUID of the mini tablet's screen entity. null if not in HMD mode. * @property {number} miniTabletHand - The hand that the mini tablet is displayed on: 0 for left hand, * 1 for right hand, -1 if not in HMD mode. - * @property {bool} miniTabletEnabled=true - true if the mini tablet is enabled to be displayed, otherwise + * @property {boolean} miniTabletEnabled=true - true if the mini tablet is enabled to be displayed, otherwise * false. * @property {Rect} playArea=0,0,0,0 - The size and position of the HMD play area in sensor coordinates. Read-only. * @property {Vec3[]} sensorPositions=[]] - The positions of the VR system sensors in sensor coordinates. Read-only. diff --git a/interface/src/scripting/WindowScriptingInterface.h b/interface/src/scripting/WindowScriptingInterface.h index eab1c65ebb..010f3bcca2 100644 --- a/interface/src/scripting/WindowScriptingInterface.h +++ b/interface/src/scripting/WindowScriptingInterface.h @@ -658,7 +658,8 @@ signals: /**jsdoc * Triggered when you try to visit a domain but are redirected into the error state. * @function Window.redirectErrorStateChanged - * @param {boolean} isInErrorState - If true, the user has been redirected to the error URL. + * @param {boolean} isInErrorState - true if the user has been redirected to the error URL, false + * if they haven't. * @returns {Signal} */ void redirectErrorStateChanged(bool isInErrorState); @@ -666,8 +667,8 @@ signals: /**jsdoc * Triggered when the interstitial mode changes. * @function Window.interstitialModeChanged - * @param {bool} interstitialMode - The new interstitial mode value. If true, the interstitial graphics are - * displayed when the domain is loading. + * @param {boolean} interstitialMode - true if the interstitial graphics are displayed when the domain is + * loading, false if they are not. * @returns {Signal} */ void interstitialModeChanged(bool interstitialMode); diff --git a/interface/src/ui/AvatarInputs.h b/interface/src/ui/AvatarInputs.h index 976771d82b..9e7d231dd2 100644 --- a/interface/src/ui/AvatarInputs.h +++ b/interface/src/ui/AvatarInputs.h @@ -24,18 +24,31 @@ class AvatarInputs : public QObject { HIFI_QML_DECL /**jsdoc - * API to help manage your Avatar's input + * The AvatarInputs API provides facilities to manage user inputs. + * * @namespace AvatarInputs * * @hifi-interface * @hifi-client-entity * @hifi-avatar * - * @property {boolean} cameraEnabled Read-only. - * @property {boolean} cameraMuted Read-only. - * @property {boolean} isHMD Read-only. - * @property {boolean} showAudioTools - * @property {boolean} showBubbleTools + * @property {boolean} cameraEnabled - true if webcam face tracking is enabled, false if it is + * disabled. + * Read-only. + *

Deprecated: This property is deprecated and will be removed.

+ * @property {boolean} cameraMuted - true if webcam face tracking is muted (temporarily disabled), + * false it if isn't. + * Read-only. + *

Deprecated: This property is deprecated and will be removed.

+ * @property {boolean} ignoreRadiusEnabled - true if the privacy shield is enabled, false if it + * is disabled. + * Read-only. + * @property {boolean} isHMD - true if the display mode is HMD, false if it isn't. + * Read-only. + * @property {boolean} showAudioTools - true if the microphone mute button and audio level meter are shown, + * false if they are hidden. + * @property {boolean} showBubbleTools - true if the privacy shield UI button is shown, false if + * it is hidden. */ AI_PROPERTY(bool, cameraEnabled, false) @@ -51,9 +64,10 @@ public: static AvatarInputs* getInstance(); /**jsdoc + * Converts non-linear audio loudness to a linear audio level. * @function AvatarInputs.loudnessToAudioLevel - * @param {number} loudness - * @returns {number} + * @param {number} loudness - The non-linear audio loudness. + * @returns {number} The linear audio level. */ Q_INVOKABLE float loudnessToAudioLevel(float loudness); @@ -67,76 +81,96 @@ public: public slots: /**jsdoc + * Sets whether or not the microphone mute button and audio level meter is shown. * @function AvatarInputs.setShowAudioTools - * @param {boolean} showAudioTools + * @param {boolean} showAudioTools - true to show the microphone mute button and audio level meter, + * false to hide it. */ void setShowAudioTools(bool showAudioTools); /**jsdoc + * Sets whether or not the privacy shield button is shown. * @function AvatarInputs.setShowBubbleTools - * @param {boolean} showBubbleTools + * @param {boolean} showBubbleTools - true to show the privacy shield button, false to hide it. */ void setShowBubbleTools(bool showBubbleTools); signals: /**jsdoc + * Triggered when webcam face tracking is enabled or disabled. + * @deprecated This signal is deprecated and will be removed. * @function AvatarInputs.cameraEnabledChanged * @returns {Signal} */ void cameraEnabledChanged(); /**jsdoc + * Triggered when webcam face tracking is muted (temporarily disabled) or unmuted. + * @deprecated This signal is deprecated and will be removed. * @function AvatarInputs.cameraMutedChanged * @returns {Signal} */ void cameraMutedChanged(); /**jsdoc + * Triggered when the display mode changes between desktop and HMD. * @function AvatarInputs.isHMDChanged * @returns {Signal} */ - void isHMDChanged(); /**jsdoc + * Triggered when the visibility of the microphone mute button and audio level meter changes. * @function AvatarInputs.showAudioToolsChanged - * @param {boolean} show + * @param {boolean} show - true if the microphone mute button and audio level meter are shown, + * false if they are is hidden. * @returns {Signal} */ void showAudioToolsChanged(bool show); /**jsdoc + * Triggered when the visibility of the privacy shield button changes. * @function AvatarInputs.showBubbleToolsChanged - * @param {boolean} show + * @param {boolean} show - true if the privacy shield UI button is shown, false if + * it is hidden. * @returns {Signal} */ void showBubbleToolsChanged(bool show); /**jsdoc + * Triggered when another user enters the privacy shield. * @function AvatarInputs.avatarEnteredIgnoreRadius - * @param {QUuid} avatarID + * @param {QUuid} avatarID - The session ID of the user that entered the privacy shield. * @returns {Signal} - */ + * @example Report when a user enters the privacy shield. + * AvatarInputs.avatarEnteredIgnoreRadius.connect(function(avatarID) { + * print("User entered the privacy shield: " + avatarID); + * }; + */ void avatarEnteredIgnoreRadius(QUuid avatarID); /**jsdoc + * Triggered when another user leaves the privacy shield. + *

Note: Currently doesn't work.

* @function AvatarInputs.avatarLeftIgnoreRadius - * @param {QUuid} avatarID + * @param {QUuid} avatarID - The session ID of the user that exited the privacy shield. * @returns {Signal} - */ + * @deprecated This signal is deprecated and will be removed. + */ void avatarLeftIgnoreRadius(QUuid avatarID); /**jsdoc + * Triggered when the privacy shield is enabled or disabled. * @function AvatarInputs.ignoreRadiusEnabledChanged - * @param {boolean} enabled + * @param {boolean} enabled - true if the privacy shield is enabled, false if it is disabled. * @returns {Signal} */ void ignoreRadiusEnabledChanged(bool enabled); /**jsdoc + * Triggered when another user enters the privacy shield. * @function AvatarInputs.enteredIgnoreRadiusChanged - * @param {boolean} enabled * @returns {Signal} */ void enteredIgnoreRadiusChanged(); @@ -144,11 +178,14 @@ signals: protected: /**jsdoc + * Resets sensors, audio, avatar animations, and the avatar rig. * @function AvatarInputs.resetSensors */ Q_INVOKABLE void resetSensors(); /**jsdoc + * Toggles the muting (temporary disablement) of webcam face tracking on/off. + *

Deprecated: This function is deprecated and will be removed.

* @function AvatarInputs.toggleCameraMute */ Q_INVOKABLE void toggleCameraMute(); diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 2ade5edda5..be371c900b 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -1333,127 +1333,170 @@ QVector Overlays::findOverlays(const glm::vec3& center, float radius) { *

An overlay may be one of the following types:

* * - * + * * * - * - * - * - * - * - * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * * *
Value2D/3DDescription
Value2D/3DDescriptionProperties
image2DAn image. Synonym: billboard.
rectangle2DA rectangle.
text2DText.
cube3DA cube. Can also use a shape overlay to create a cube.
sphere3DA sphere. Can also use a shape overlay to create a sphere.
rectangle3d3DA rectangle.
shape3DA geometric shape, such as a cube, sphere, or cylinder.
model3DA model.
text3d3DText.
image3d3DAn image.
web3d3DWeb content.
line3d3DA line.
grid3DA grid of lines in a plane.
circle3d3DA circle.
"rectangle"2DA rectangle.{@link Overlays.OverlayProperties-Rectangle|OverlayProperties-Rectangle}
"image"2DAn image.{@link Overlays.OverlayProperties-Image|OverlayProperties-Image}
"text"2DSome text.{@link Overlays.OverlayProperties-Text|OverlayProperties-Text}
"cube"3DA cube. A "shape" overlay can also be used to create a cube.
+ * Deprecated. + *
{@link Overlays.OverlayProperties-Cube|OverlayProperties-Cube}
"sphere"3DA sphere. A "shape" overlay can also be used to create a sphere.
+ * Deprecated.
{@link Overlays.OverlayProperties-Sphere|OverlayProperties-Sphere}
"shape"3DA geometric shape, such as a cube, sphere, or cylinder.
+ * Deprecated.
{@link Overlays.OverlayProperties-Shape|OverlayProperties-Shape}
"model"3DA model.
+ * Deprecated.
{@link Overlays.OverlayProperties-Model|OverlayProperties-Model}
"image3d"3DAn image. Synonym: "billboard".
+ * Deprecated.
{@link Overlays.OverlayProperties-Image3D|OverlayProperties-Image3D}
"rectangle3d"3DA rectangle.
+ * Deprecated.
{@link Overlays.OverlayProperties-Rectangle3D|OverlayProperties-Rectangle3D}
"text3d"3DSome text.
+ * Deprecated.
{@link Overlays.OverlayProperties-Text3D|OverlayProperties-Text3D}
"web3d"3DWeb content.
+ * Deprecated.
{@link Overlays.OverlayProperties-Web3D|OverlayProperties-Web3D}
"line3d"3DA line.
+ * Deprecated.
{@link Overlays.OverlayProperties-Line3D|OverlayProperties-Line3D}
"grid"3DA grid of lines in a plane.
+ * Deprecated.
{@link Overlays.OverlayProperties-Grid|OverlayProperties-Grid}
"circle3d"3DA circle.
+ * Deprecated.
{@link Overlays.OverlayProperties-Circle3D|OverlayProperties-Circle3D}
*

2D overlays are rendered on the display surface in desktop mode and on the HUD surface in HMD mode. 3D overlays are - * rendered at a position and orientation in-world, but are deprecated (use local entities instead).

- *

Each overlay type has different {@link Overlays.OverlayProperties|OverlayProperties}.

+ * rendered at a position and orientation in-world.

+ *

3D overlays are deprecated. Use local {@link Entities} instead.

* @typedef {string} Overlays.OverlayType */ /**jsdoc - * Different overlay types have different properties: some common to all overlays (listed below) and some specific to each - * {@link Overlays.OverlayType|OverlayType} (linked to below). The properties are accessed as an object of property names and - * values. 3D Overlays are local entities, internally, so they also support the corresponding entity properties. - * + * Different overlay types have different properties: some common to all overlays (listed in the table) and some specific to + * each {@link Overlays.OverlayType|OverlayType} (linked to below). + *

3D overlays are local entities, internally, so they also support the relevant entity's properties.

* @typedef {object} Overlays.OverlayProperties * @property {Uuid} id - The ID of the overlay. Read-only. - * @property {Overlays.OverlayType} type - The overlay type. Read-only. - * @property {boolean} visible=true - If true, the overlay is rendered, otherwise it is not rendered. + * @property {Overlays.OverlayType} type - The overlay's type. Read-only. + * @property {boolean} visible=true - true if the overlay is rendered, false if it isn't. * - * @see The different entity types have additional properties as follows: + * @see {@link Overlays.OverlayProperties-Rectangle|OverlayProperties-Rectangle} * @see {@link Overlays.OverlayProperties-Image|OverlayProperties-Image} * @see {@link Overlays.OverlayProperties-Text|OverlayProperties-Text} - * @see {@link Overlays.OverlayProperties-Rectangle|OverlayProperties-Rectangle} - * @see {@link Overlays.OverlayProperties-Cube|OverlayProperties-Cube} - * @see {@link Overlays.OverlayProperties-Sphere|OverlayProperties-Sphere} - * @see {@link Overlays.OverlayProperties-Rectangle3D|OverlayProperties-Rectangle3D} - * @see {@link Overlays.OverlayProperties-Shape|OverlayProperties-Shape} - * @see {@link Overlays.OverlayProperties-Model|OverlayProperties-Model} - * @see {@link Overlays.OverlayProperties-Text3D|OverlayProperties-Text3D} - * @see {@link Overlays.OverlayProperties-Image3D|OverlayProperties-Image3D} - * @see {@link Overlays.OverlayProperties-Web|OverlayProperties-Web} - * @see {@link Overlays.OverlayProperties-Line|OverlayProperties-Line} - * @see {@link Overlays.OverlayProperties-Grid|OverlayProperties-Grid} - * @see {@link Overlays.OverlayProperties-Circle|OverlayProperties-Circle} + * @see {@link Overlays.OverlayProperties-Cube|OverlayProperties-Cube} Deprecated. + * @see {@link Overlays.OverlayProperties-Sphere|OverlayProperties-Sphere} Deprecated. + * @see {@link Overlays.OverlayProperties-Shape|OverlayProperties-Shape} Deprecated. + * @see {@link Overlays.OverlayProperties-Model|OverlayProperties-Model} Deprecated. + * @see {@link Overlays.OverlayProperties-Rectangle3D|OverlayProperties-Rectangle3D} Deprecated. + * @see {@link Overlays.OverlayProperties-Image3D|OverlayProperties-Image3D} Deprecated. + * @see {@link Overlays.OverlayProperties-Text3D|OverlayProperties-Text3D} Deprecated. + * @see {@link Overlays.OverlayProperties-Web3D|OverlayProperties-Web3D} Deprecated. + * @see {@link Overlays.OverlayProperties-Line3D|OverlayProperties-Line3D} Deprecated. + * @see {@link Overlays.OverlayProperties-Grid|OverlayProperties-Grid} Deprecated. + * @see {@link Overlays.OverlayProperties-Circle3D|OverlayProperties-Circle3D} Deprecated. */ /**jsdoc - * The "Image" {@link Overlays.OverlayType|OverlayType} is a 2D image. + * The "image" {@link Overlays.OverlayType|OverlayType} is for 2D images. + * It has properties in addition to the common {@link Overlays.OverlayProperties|OverlayProperties}. * @typedef {object} Overlays.OverlayProperties-Image * @property {Rect} bounds - The position and size of the image display area, in pixels. Write-only. * @property {number} x - Integer left, x-coordinate value of the image display area = bounds.x. * Write-only. - * @property {number} y - Integer top, y-coordinate value of the image display area = bounds.y. + * @property {number} y - Integer top, y-coordinate value of the image display area = bounds.y. * Write-only. * @property {number} width - Integer width of the image display area = bounds.width. Write-only. - * @property {number} height - Integer height of the image display area = bounds.height. Write-only. + * @property {number} height - Integer height of the image display area = bounds.height. Write-only. * @property {string} imageURL - The URL of the image file to display. The image is scaled to fit to the bounds. * Write-only. - * @property {Vec2} subImage=0,0 - Integer coordinates of the top left pixel to start using image content from. + * @property {Rect} subImage - The portion of the image to use. If not specified, the whole image is used. * Write-only. * @property {Color} color=0,0,0 - The color to apply over the top of the image to colorize it. Write-only. - * @property {number} alpha=0.0 - The opacity of the color applied over the top of the image, 0.0 - + * @property {number} alpha=0.0 - The opacity of the color applied over the top of the image, 0.0 – * 1.0. Write-only. */ /**jsdoc - * The "Text" {@link Overlays.OverlayType|OverlayType} is for 2D text. + * The "text" {@link Overlays.OverlayType|OverlayType} is for 2D text. + * It has properties in addition to the common {@link Overlays.OverlayProperties|OverlayProperties}. * @typedef {object} Overlays.OverlayProperties-Text * @property {Rect} bounds - The position and size of the rectangle, in pixels. Write-only. * @property {number} x - Integer left, x-coordinate value = bounds.x. Write-only. * @property {number} y - Integer top, y-coordinate value = bounds.y. Write-only. * @property {number} width - Integer width of the rectangle = bounds.width. Write-only. * @property {number} height - Integer height of the rectangle = bounds.height. Write-only. - * - * @property {number} margin=0 - Sets the leftMargin and topMargin values, in pixels. + * @property {number} margin=0 - The leftMargin and topMargin values, in pixels. * Write-only. * @property {number} leftMargin=0 - The left margin's size, in pixels. This value is also used for the right margin. * Write-only. * @property {number} topMargin=0 - The top margin's size, in pixels. This value is also used for the bottom margin. * Write-only. - * @property {string} text="" - The text to display. Text does not automatically wrap; use \n for a line break. Text - * is clipped to the bounds. Write-only. + * @property {string} text="" - The text to display. Text does not automatically wrap; use "\n" for a line break. + * Text is clipped to the bounds. Write-only. * @property {number} font.size=18 - The size of the text, in pixels. Write-only. * @property {number} lineHeight=18 - The height of a line of text, in pixels. Write-only. * @property {Color} color=255,255,255 - The color of the text. Synonym: textColor. Write-only. - * @property {number} alpha=1.0 - The opacity of the overlay, 0.0 - 1.0. Write-only. + * @property {number} alpha=1.0 - The opacity of the overlay, 0.01.0. Write-only. * @property {Color} backgroundColor=0,0,0 - The color of the background rectangle. Write-only. - * @property {number} backgroundAlpha=0.7 - The opacity of the background rectangle. Write-only. + * @property {number} backgroundAlpha=0.7 - The opacity of the background rectangle, 0.01.0. + * Write-only. */ /**jsdoc - * The "Rectangle" {@link Overlays.OverlayType|OverlayType} is for 2D rectangles. + * The "rectangle" {@link Overlays.OverlayType|OverlayType} is for 2D rectangles. + * It has properties in addition to the common {@link Overlays.OverlayProperties|OverlayProperties}. * @typedef {object} Overlays.OverlayProperties-Rectangle * @property {Rect} bounds - The position and size of the rectangle, in pixels. Write-only. * @property {number} x - Integer left, x-coordinate value = bounds.x. Write-only. * @property {number} y - Integer top, y-coordinate value = bounds.y. Write-only. * @property {number} width - Integer width of the rectangle = bounds.width. Write-only. * @property {number} height - Integer height of the rectangle = bounds.height. Write-only. - * + * @property {number} radius=0 - Integer corner radius, in pixels. Write-only. * @property {Color} color=0,0,0 - The color of the overlay. Write-only. - * @property {number} alpha=1.0 - The opacity of the overlay, 0.0 - 1.0. Write-only. + * @property {number} alpha=1.0 - The opacity of the overlay, 0.01.0. Write-only. * @property {number} borderWidth=1 - Integer width of the border, in pixels. The border is drawn within the rectangle's bounds. * It is not drawn unless either borderColor or borderAlpha are specified. Write-only. - * @property {number} radius=0 - Integer corner radius, in pixels. Write-only. * @property {Color} borderColor=0,0,0 - The color of the border. Write-only. - * @property {number} borderAlpha=1.0 - The opacity of the border, 0.0 - 1.0. + * @property {number} borderAlpha=1.0 - The opacity of the border, 0.01.0. * Write-only. */ /**jsdoc - * The "Cube" {@link Overlays.OverlayType|OverlayType} is for 3D cubes. + * The "cube" {@link Overlays.OverlayType|OverlayType} is for 3D cubes. + * It has properties in addition to the common {@link Overlays.OverlayProperties|OverlayProperties}. + * It additionally has properties per the {@link Entities.EntityProperties-Box|Box} entity. + *

Deprecated: Use local {@link Entities} instead.

* @typedef {object} Overlays.OverlayProperties-Cube * @property {string} name - The name of the overlay. * @property {Color} color=255,255,255 - The color of the overlay. - * @property {number} alpha=0.7 - The opacity of the overlay, 0.0 - 1.0. + * @property {number} alpha=0.7 - The opacity of the overlay, 0.01.0. * @property {number} pulseMax=0 - The maximum value of the pulse multiplier. * @property {number} pulseMin=0 - The minimum value of the pulse multiplier. * @property {number} pulsePeriod=1 - The duration of the color and alpha pulse, in seconds. A pulse multiplier value goes from @@ -1475,24 +1518,33 @@ QVector Overlays::findOverlays(const glm::vec3& center, float radius) { * parentID set, otherwise the same value as position. * @property {Quat} localRotation - The orientation of the overlay relative to its parent if the overlay has a * parentID set, otherwise the same value as rotation. Synonym: localOrientation. - * @property {boolean} isSolid=false - Synonyms: solid
, isFilled, and filled. + * @property {boolean} isSolid=false - true if the overlay is rendered as a solid, false if it is + * rendered as a wire frame. + * Synonyms: solid, isFilled, and filled. * Antonyms: isWire and wire. - * @property {boolean} ignorePickIntersection=false - If true, picks ignore the overlay. ignoreRayIntersection is a synonym. - * @property {boolean} drawInFront=false - If true, the overlay is rendered in front of objects in the world, but behind the HUD. - * @property {boolean} drawHUDLayer=false - If true, the overlay is rendered in front of everything, including the HUD. - * @property {boolean} grabbable=false - Signal to grabbing scripts whether or not this overlay can be grabbed. + * @property {boolean} ignorePickIntersection=false - true if {@link Picks} ignore the overlay, false + * if they don't. + * Synonym: ignoreRayIntersection. + * @property {boolean} drawInFront=false - true if the overlay is rendered on top of the world layer but behind + * the HUD surface. + * @property {boolean} drawHUDLayer=false - true if the overlay is rendered in front of everything, including the + * HUD surface. + * @property {boolean} grabbable=false - true if the overlay can be grabbed, false if it can't be. * @property {Uuid} parentID=null - The avatar, entity, or overlay that the overlay is parented to. - * @property {number} parentJointIndex=65535 - Integer value specifying the skeleton joint that the overlay is attached to if - * parentID is an avatar skeleton. A value of 65535 means "no joint". - * + * @property {number} parentJointIndex=65535 - Integer value specifying the joint of the entity or avatar that the entity is + * parented to if parentID is set. Use 65535 or -1 to parent to the parent's position and orientation rather + * than a joint. */ /**jsdoc - * The "Sphere" {@link Overlays.OverlayType|OverlayType} is for 3D spheres. + * The "sphere" {@link Overlays.OverlayType|OverlayType} is for 3D spheres. + * It has properties in addition to the common {@link Overlays.OverlayProperties|OverlayProperties}. + * It additionally has properties per the {@link Entities.EntityProperties-Sphere|Sphere} entity. + *

Deprecated: Use local {@link Entities} instead.

* @typedef {object} Overlays.OverlayProperties-Sphere * @property {string} name - The name of the overlay. * @property {Color} color=255,255,255 - The color of the overlay. - * @property {number} alpha=0.7 - The opacity of the overlay, 0.0 - 1.0. + * @property {number} alpha=0.7 - The opacity of the overlay, 0.01.0. * @property {number} pulseMax=0 - The maximum value of the pulse multiplier. * @property {number} pulseMin=0 - The minimum value of the pulse multiplier. * @property {number} pulsePeriod=1 - The duration of the color and alpha pulse, in seconds. A pulse multiplier value goes from @@ -1514,24 +1566,34 @@ QVector Overlays::findOverlays(const glm::vec3& center, float radius) { * parentID set, otherwise the same value as position. * @property {Quat} localRotation - The orientation of the overlay relative to its parent if the overlay has a * parentID set, otherwise the same value as rotation. Synonym: localOrientation. - * @property {boolean} isSolid=false - Synonyms: solid, isFilled, and filled. + * @property {boolean} isSolid=false - true if the overlay is rendered as a solid, false if it is + * rendered as a wire frame. + * Synonyms: solid, isFilled, and filled. * Antonyms: isWire and wire. - * @property {boolean} ignorePickIntersection=false - If true, picks ignore the overlay. ignoreRayIntersection is a synonym. - * @property {boolean} drawInFront=false - If true, the overlay is rendered in front of objects in the world, but behind the HUD. - * @property {boolean} drawHUDLayer=false - If true, the overlay is rendered in front of everything, including the HUD. - * @property {boolean} grabbable=false - Signal to grabbing scripts whether or not this overlay can be grabbed. + * @property {boolean} ignorePickIntersection=false - true if {@link Picks} ignore the overlay, false + * if they don't. + * Synonym: ignoreRayIntersection. + * @property {boolean} drawInFront=false - true if the overlay is rendered on top of the world layer but behind + * the HUD surface. + * @property {boolean} drawHUDLayer=false - true if the overlay is rendered in front of everything, including the + * HUD surface. + * @property {boolean} grabbable=false - true if the overlay can be grabbed, false if it can't be. * @property {Uuid} parentID=null - The avatar, entity, or overlay that the overlay is parented to. - * @property {number} parentJointIndex=65535 - Integer value specifying the skeleton joint that the overlay is attached to if - * parentID is an avatar skeleton. A value of 65535 means "no joint". - * + * @property {number} parentJointIndex=65535 - Integer value specifying the joint of the entity or avatar that the entity is + * parented to if parentID is set. Use 65535 or -1 to parent to the parent's position and orientation rather + * than a joint. */ /**jsdoc - * The "Rectangle3D" {@link Overlays.OverlayType|OverlayType} is for 3D rectangles. + * The "rectangle3D" {@link Overlays.OverlayType|OverlayType} is for 3D rectangles. + * It has properties in addition to the common {@link Overlays.OverlayProperties|OverlayProperties}. + * It additionally has properties per the {@link Entities.EntityProperties-Shape|Shape} entity, with the shape + * property value being "Quad". + *

Deprecated: Use local {@link Entities} instead.

* @typedef {object} Overlays.OverlayProperties-Rectangle3D * @property {string} name - The name of the overlay. * @property {Color} color=255,255,255 - The color of the overlay. - * @property {number} alpha=0.7 - The opacity of the overlay, 0.0 - 1.0. + * @property {number} alpha=0.7 - The opacity of the overlay, 0.01.0. * @property {number} pulseMax=0 - The maximum value of the pulse multiplier. * @property {number} pulseMin=0 - The minimum value of the pulse multiplier. * @property {number} pulsePeriod=1 - The duration of the color and alpha pulse, in seconds. A pulse multiplier value goes from @@ -1553,20 +1615,27 @@ QVector Overlays::findOverlays(const glm::vec3& center, float radius) { * parentID set, otherwise the same value as position. * @property {Quat} localRotation - The orientation of the overlay relative to its parent if the overlay has a * parentID set, otherwise the same value as rotation. Synonym: localOrientation. - * @property {boolean} isSolid=false - Synonyms: solid, isFilled, and filled. + * @property {boolean} isSolid=false - true if the overlay is rendered as a solid, false if it is + * rendered as a wire frame. + * Synonyms: solid, isFilled, and filled. * Antonyms: isWire and wire. - * @property {boolean} ignorePickIntersection=false - If true, picks ignore the overlay. ignoreRayIntersection is a synonym. - * @property {boolean} drawInFront=false - If true, the overlay is rendered in front of objects in the world, but behind the HUD. - * @property {boolean} drawHUDLayer=false - If true, the overlay is rendered in front of everything, including the HUD. - * @property {boolean} grabbable=false - Signal to grabbing scripts whether or not this overlay can be grabbed. + * @property {boolean} ignorePickIntersection=false - true if {@link Picks} ignore the overlay, false + * if they don't. + * Synonym: ignoreRayIntersection. + * @property {boolean} drawInFront=false - true if the overlay is rendered on top of the world layer but behind + * the HUD surface. + * @property {boolean} drawHUDLayer=false - true if the overlay is rendered in front of everything, including the + * HUD surface. + * @property {boolean} grabbable=false - true if the overlay can be grabbed, false if it can't be. * @property {Uuid} parentID=null - The avatar, entity, or overlay that the overlay is parented to. - * @property {number} parentJointIndex=65535 - Integer value specifying the skeleton joint that the overlay is attached to if - * parentID is an avatar skeleton. A value of 65535 means "no joint". - * + * @property {number} parentJointIndex=65535 - Integer value specifying the joint of the entity or avatar that the entity is + * parented to if parentID is set. Use 65535 or -1 to parent to the parent's position and orientation rather + * than a joint. */ /**jsdoc - *

A shape {@link Overlays.OverlayType|OverlayType} may display as one of the following geometrical shapes:

+ *

A "shape" {@link Overlays.OverlayType|OverlayType} may display as one of the following geometrical + * shapes:

* * * @@ -1579,7 +1648,6 @@ QVector Overlays::findOverlays(const glm::vec3& center, float radius) { * * * - * * * * @@ -1593,11 +1661,14 @@ QVector Overlays::findOverlays(const glm::vec3& center, float radius) { */ /**jsdoc - * The "Shape" {@link Overlays.OverlayType|OverlayType} is for 3D shapes. + * The "shape" {@link Overlays.OverlayType|OverlayType} is for 3D shapes. + * It has properties in addition to the common {@link Overlays.OverlayProperties|OverlayProperties}. + * It additionally has properties per the {@link Entities.EntityProperties-Shape|Shape} entity. + *

Deprecated: Use local {@link Entities} instead.

* @typedef {object} Overlays.OverlayProperties-Shape * @property {string} name - The name of the overlay. * @property {Color} color=255,255,255 - The color of the overlay. - * @property {number} alpha=0.7 - The opacity of the overlay, 0.0 - 1.0. + * @property {number} alpha=0.7 - The opacity of the overlay, 0.01.0. * @property {number} pulseMax=0 - The maximum value of the pulse multiplier. * @property {number} pulseMin=0 - The minimum value of the pulse multiplier. * @property {number} pulsePeriod=1 - The duration of the color and alpha pulse, in seconds. A pulse multiplier value goes from @@ -1619,21 +1690,31 @@ QVector Overlays::findOverlays(const glm::vec3& center, float radius) { * parentID set, otherwise the same value as position. * @property {Quat} localRotation - The orientation of the overlay relative to its parent if the overlay has a * parentID set, otherwise the same value as rotation. Synonym: localOrientation. - * @property {boolean} isSolid=false - Synonyms: solid, isFilled, and filled. + * @property {boolean} isSolid=false - true if the overlay is rendered as a solid, false if it is + * rendered as a wire frame. + * Synonyms: solid, isFilled, and filled. * Antonyms: isWire and wire. - * @property {boolean} ignorePickIntersection=false - If true, picks ignore the overlay. ignoreRayIntersection is a synonym. - * @property {boolean} drawInFront=false - If true, the overlay is rendered in front of objects in the world, but behind the HUD. - * @property {boolean} drawHUDLayer=false - If true, the overlay is rendered in front of everything, including the HUD. - * @property {boolean} grabbable=false - Signal to grabbing scripts whether or not this overlay can be grabbed. + * @property {boolean} ignorePickIntersection=false - true if {@link Picks} ignore the overlay, false + * if they don't. + * Synonym: ignoreRayIntersection. + * @property {boolean} drawInFront=false - true if the overlay is rendered on top of the world layer but behind + * the HUD surface. + * @property {boolean} drawHUDLayer=false - true if the overlay is rendered in front of everything, including the + * HUD surface. + * @property {boolean} grabbable=false - true if the overlay can be grabbed, false if it can't be. * @property {Uuid} parentID=null - The avatar, entity, or overlay that the overlay is parented to. - * @property {number} parentJointIndex=65535 - Integer value specifying the skeleton joint that the overlay is attached to if - * parentID is an avatar skeleton. A value of 65535 means "no joint". + * @property {number} parentJointIndex=65535 - Integer value specifying the joint of the entity or avatar that the entity is + * parented to if parentID is set. Use 65535 or -1 to parent to the parent's position and orientation rather + * than a joint. * * @property {Overlays.Shape} shape=Hexagon - The geometrical shape of the overlay. */ /**jsdoc - * The "Model" {@link Overlays.OverlayType|OverlayType} is for 3D models. + * The "model" {@link Overlays.OverlayType|OverlayType} is for 3D models. + * It has properties in addition to the common {@link Overlays.OverlayProperties|OverlayProperties}. + * It additionally has properties per the {@link Entities.EntityProperties-Model|Model} entity. + *

Deprecated: Use local {@link Entities} instead.

* @typedef {object} Overlays.OverlayProperties-Model * @property {string} name - The name of the overlay. * @@ -1646,42 +1727,39 @@ QVector Overlays::findOverlays(const glm::vec3& center, float radius) { * parentID set, otherwise the same value as position. * @property {Quat} localRotation - The orientation of the overlay relative to its parent if the overlay has a * parentID set, otherwise the same value as rotation. Synonym: localOrientation. - * @property {boolean} ignorePickIntersection=false - If true, picks ignore the overlay. ignoreRayIntersection is a synonym. - * @property {boolean} drawInFront=false - If true, the overlay is rendered in front of objects in the world, but behind the HUD. - * @property {boolean} drawHUDLayer=false - If true, the overlay is rendered in front of everything, including the HUD. - * @property {boolean} grabbable=false - Signal to grabbing scripts whether or not this overlay can be grabbed. + * @property {boolean} ignorePickIntersection=false - true if {@link Picks} ignore the overlay, false + * if they don't. + * Synonym: ignoreRayIntersection. + * @property {boolean} drawInFront=false - true if the overlay is rendered on top of the world layer but behind + * the HUD surface. + * @property {boolean} drawHUDLayer=false - true if the overlay is rendered in front of everything, including the + * HUD surface. + * @property {boolean} grabbable=false - true if the overlay can be grabbed, false if it can't be. * @property {Uuid} parentID=null - The avatar, entity, or overlay that the overlay is parented to. - * @property {number} parentJointIndex=65535 - Integer value specifying the skeleton joint that the overlay is attached to if - * parentID is an avatar skeleton. A value of 65535 means "no joint". + * @property {number} parentJointIndex=65535 - Integer value specifying the joint of the entity or avatar that the entity is + * parented to if parentID is set. Use 65535 or -1 to parent to the parent's position and orientation rather + * than a joint. * * @property {string} url - The URL of the FBX or OBJ model used for the overlay. * @property {number} loadPriority=0.0 - The priority for loading and displaying the overlay. Overlays with higher values load - * first. - * @property {object.} textures - Maps the named textures in the model to the JPG or PNG images in the urls. - * @property {string[]} jointNames - The names of the joints - if any - in the model. Read-only. - * @property {Quat[]} jointRotations - The relative rotations of the model's joints. - * @property {Vec3[]} jointTranslations - The relative translations of the model's joints. - * @property {Quat[]} jointOrientations - The absolute orientations of the model's joints, in world coordinates. Read-only. - * @property {Vec3[]} jointPositions - The absolute positions of the model's joints, in world coordinates. Read-only. - * @property {string} animationSettings.url="" - The URL of an FBX file containing an animation to play. - * @property {number} animationSettings.fps=0 - The frame rate (frames/sec) to play the animation at. - * @property {number} animationSettings.firstFrame=0 - The frame to start playing at. - * @property {number} animationSettings.lastFrame=0 - The frame to finish playing at. - * @property {number} animationSettings.currentFrame=0 - The current frame being played. - * @property {boolean} animationSettings.running=false - Whether or not the animation is playing. - * @property {boolean} animationSettings.loop=false - Whether or not the animation should repeat in a loop. - * @property {boolean} animationSettings.hold=false - Whether or not when the animation finishes, the rotations and - * translations of the last frame played should be maintained. - * @property {boolean} animationSettings.allowTranslation=false - Whether or not translations contained in the animation should - * be played. + * first. Currently not used. + * @property {Object.|string} textures - Texture name, URL pairs used when rendering the model in place of the + * model's original textures, per the {@link Entities.EntityProperties-Model} property of the same name. + *

The value can be an object or a JSON string when setting the value; it is a JSON string when getting the value.

+ * @property {Entities.AnimationProperties} animationSettings - An animation to play on the model. */ /**jsdoc - * The "Text3D" {@link Overlays.OverlayType|OverlayType} is for 3D text. + * The "text3D" {@link Overlays.OverlayType|OverlayType} is for 3D text. + * It has properties in addition to the common {@link Overlays.OverlayProperties|OverlayProperties}. + * It additionally has properties per the {@link Entities.EntityProperties-Text|Text} entity. + *

Deprecated: Use local {@link Entities} instead.

* @typedef {object} Overlays.OverlayProperties-Text3D * @property {string} name - The name of the overlay. - * @property {Color} color=255,255,255 - The color of the overlay. - * @property {number} alpha=0.7 - The opacity of the overlay, 0.0 - 1.0. + * @property {Color} color=255,255,255 - The color of the overlay text. Synonym: textColor. + * @property {number} alpha=0.7 - The opacity of the overlay text, 0.01.0. + *

Currently not used; use textAlpha instead.

+ * * @property {number} pulseMax=0 - The maximum value of the pulse multiplier. * @property {number} pulseMin=0 - The minimum value of the pulse multiplier. * @property {number} pulsePeriod=1 - The duration of the color and alpha pulse, in seconds. A pulse multiplier value goes from @@ -1703,33 +1781,29 @@ QVector Overlays::findOverlays(const glm::vec3& center, float radius) { * parentID set, otherwise the same value as position. * @property {Quat} localRotation - The orientation of the overlay relative to its parent if the overlay has a * parentID set, otherwise the same value as rotation. Synonym: localOrientation. - * @property {boolean} ignorePickIntersection=false - If true, picks ignore the overlay. ignoreRayIntersection is a synonym. - * @property {boolean} drawInFront=false - If true, the overlay is rendered in front of objects in the world, but behind the HUD. - * @property {boolean} drawHUDLayer=false - If true, the overlay is rendered in front of everything, including the HUD. - * @property {boolean} grabbable=false - Signal to grabbing scripts whether or not this overlay can be grabbed. + * @property {boolean} ignorePickIntersection=false - true if {@link Picks} ignore the overlay, false + * if they don't. + * Synonym: ignoreRayIntersection. + * @property {boolean} drawInFront=false - true if the overlay is rendered on top of the world layer but behind + * the HUD surface. + * @property {boolean} drawHUDLayer=false - true if the overlay is rendered in front of everything, including the + * HUD surface. + * @property {boolean} grabbable=false - true if the overlay can be grabbed, false if it can't be. * @property {Uuid} parentID=null - The avatar, entity, or overlay that the overlay is parented to. - * @property {number} parentJointIndex=65535 - Integer value specifying the skeleton joint that the overlay is attached to if - * parentID is an avatar skeleton. A value of 65535 means "no joint". - * - * @property {boolean} isFacingAvatar - If true, the overlay is rotated to face the user's camera about an axis - * parallel to the user's avatar's "up" direction. - * @property {string} text="" - The text to display.Text does not automatically wrap; use \n for a line break. - * @property {number} textAlpha=1 - The text alpha value. - * @property {Color} backgroundColor=0,0,0 - The background color. - * @property {number} backgroundAlpha=0.7 - The background alpha value. - * @property {number} lineHeight=1 - The height of a line of text in meters. - * @property {number} leftMargin=0.1 - The left margin, in meters. - * @property {number} topMargin=0.1 - The top margin, in meters. - * @property {number} rightMargin=0.1 - The right margin, in meters. - * @property {number} bottomMargin=0.1 - The bottom margin, in meters. + * @property {number} parentJointIndex=65535 - Integer value specifying the joint of the entity or avatar that the entity is + * parented to if parentID is set. Use 65535 or -1 to parent to the parent's position and orientation rather + * than a joint. */ /**jsdoc - * The "Image3D" {@link Overlays.OverlayType|OverlayType} is for 3D images. + * The "image3D" {@link Overlays.OverlayType|OverlayType} is for 3D images. + * It has properties in addition to the common {@link Overlays.OverlayProperties|OverlayProperties}. + * It additionally has properties per the {@link Entities.EntityProperties-Image|Image} entity. + *

Deprecated: Use local {@link Entities} instead.

* @typedef {object} Overlays.OverlayProperties-Image3D * @property {string} name - The name of the overlay. * @property {Color} color=255,255,255 - The color of the overlay. - * @property {number} alpha=0.7 - The opacity of the overlay, 0.0 - 1.0. + * @property {number} alpha=0.7 - The opacity of the overlay, 0.01.0. * @property {number} pulseMax=0 - The maximum value of the pulse multiplier. * @property {number} pulseMin=0 - The minimum value of the pulse multiplier. * @property {number} pulsePeriod=1 - The duration of the color and alpha pulse, in seconds. A pulse multiplier value goes from @@ -1751,29 +1825,31 @@ QVector Overlays::findOverlays(const glm::vec3& center, float radius) { * parentID set, otherwise the same value as position. * @property {Quat} localRotation - The orientation of the overlay relative to its parent if the overlay has a * parentID set, otherwise the same value as rotation. Synonym: localOrientation. - * @property {boolean} ignorePickIntersection=false - If true, picks ignore the overlay. ignoreRayIntersection is a synonym. - * @property {boolean} drawInFront=false - If true, the overlay is rendered in front of objects in the world, but behind the HUD. - * @property {boolean} drawHUDLayer=false - If true, the overlay is rendered in front of everything, including the HUD. - * @property {boolean} grabbable=false - Signal to grabbing scripts whether or not this overlay can be grabbed. + * @property {boolean} ignorePickIntersection=false - true if {@link Picks} ignore the overlay, false + * if they don't. + * Synonym: ignoreRayIntersection. + * @property {boolean} drawInFront=false - true if the overlay is rendered on top of the world layer but behind + * the HUD surface. + * @property {boolean} drawHUDLayer=false - true if the overlay is rendered in front of everything, including the + * HUD surface. + * @property {boolean} grabbable=false - true if the overlay can be grabbed, false if it can't be. * @property {Uuid} parentID=null - The avatar, entity, or overlay that the overlay is parented to. - * @property {number} parentJointIndex=65535 - Integer value specifying the skeleton joint that the overlay is attached to if - * parentID is an avatar skeleton. A value of 65535 means "no joint". + * @property {number} parentJointIndex=65535 - Integer value specifying the joint of the entity or avatar that the entity is + * parented to if parentID is set. Use 65535 or -1 to parent to the parent's position and orientation rather + * than a joint. * - * @property {boolean} isFacingAvatar - If true, the overlay is rotated to face the user's camera about an axis - * parallel to the user's avatar's "up" direction. - * @property {string} url - The URL of the PNG or JPG image to display. - * @property {Rect} subImage - The portion of the image to display. Defaults to the full image. - * @property {boolean} emissive - If true, the overlay is displayed at full brightness, otherwise it is rendered - * with scene lighting. - * @property {bool} keepAspectRatio=true - overlays will maintain the aspect ratio when the subImage is applied. + * @property {string} url - The URL of the image to display. */ /**jsdoc - * The "Web" {@link Overlays.OverlayType|OverlayType} is for 3D web surfaces. - * @typedef {object} Overlays.OverlayProperties-Web + * The "web3d" {@link Overlays.OverlayType|OverlayType} is for 3D web surfaces. + * It has properties in addition to the common {@link Overlays.OverlayProperties|OverlayProperties}. + * It additionally has properties per the {@link Entities.EntityProperties-Web|Web} entity. + *

Deprecated: Use local {@link Entities} instead.

+ * @typedef {object} Overlays.OverlayProperties-Web3D * @property {string} name - The name of the overlay. * @property {Color} color=255,255,255 - The color of the overlay. - * @property {number} alpha=0.7 - The opacity of the overlay, 0.0 - 1.0. + * @property {number} alpha=0.7 - The opacity of the overlay, 0.01.0. * @property {number} pulseMax=0 - The maximum value of the pulse multiplier. * @property {number} pulseMin=0 - The minimum value of the pulse multiplier. * @property {number} pulsePeriod=1 - The duration of the color and alpha pulse, in seconds. A pulse multiplier value goes from @@ -1795,29 +1871,31 @@ QVector Overlays::findOverlays(const glm::vec3& center, float radius) { * parentID set, otherwise the same value as position. * @property {Quat} localRotation - The orientation of the overlay relative to its parent if the overlay has a * parentID set, otherwise the same value as rotation. Synonym: localOrientation. - * @property {boolean} ignorePickIntersection=false - If true, picks ignore the overlay. ignoreRayIntersection is a synonym. - * @property {boolean} drawInFront=false - If true, the overlay is rendered in front of objects in the world, but behind the HUD. - * @property {boolean} drawHUDLayer=false - If true, the overlay is rendered in front of everything, including the HUD. - * @property {boolean} grabbable=false - Signal to grabbing scripts whether or not this overlay can be grabbed. + * @property {boolean} ignorePickIntersection=false - true if {@link Picks} ignore the overlay, false + * if they don't. + * Synonym: ignoreRayIntersection. + * @property {boolean} drawInFront=false - true if the overlay is rendered on top of the world layer but behind + * the HUD surface. + * @property {boolean} drawHUDLayer=false - true if the overlay is rendered in front of everything, including the + * HUD surface. + * @property {boolean} grabbable=false - true if the overlay can be grabbed, false if it can't be. * @property {Uuid} parentID=null - The avatar, entity, or overlay that the overlay is parented to. - * @property {number} parentJointIndex=65535 - Integer value specifying the skeleton joint that the overlay is attached to if - * parentID is an avatar skeleton. A value of 65535 means "no joint". + * @property {number} parentJointIndex=65535 - Integer value specifying the joint of the entity or avatar that the entity is + * parented to if parentID is set. Use 65535 or -1 to parent to the parent's position and orientation rather + * than a joint. * - * @property {boolean} isFacingAvatar - If true, the overlay is rotated to face the user's camera about an axis - * parallel to the user's avatar's "up" direction. - * @property {string} url - The URL of the Web page to display. - * @property {string} scriptURL="" - The URL of a JavaScript file to inject into the Web page. - * @property {number} dpi=30 - The dots per inch to display the Web page at, on the overlay. - * @property {number} maxFPS=10 - The maximum update rate for the Web overlay content, in frames/second. - * @property {string} inputMode=Touch - The user input mode to use - either "Touch" or "Mouse". + * @property {string} url - The URL of the web page to display. */ /**jsdoc - * The "Line" {@link Overlays.OverlayType|OverlayType} is for 3D lines. - * @typedef {object} Overlays.OverlayProperties-Line + * The "line3d" {@link Overlays.OverlayType|OverlayType} is for 3D lines. + * It has properties in addition to the common {@link Overlays.OverlayProperties|OverlayProperties}. + * It additionally has properties per the {@link Entities.EntityProperties-PolyLine|PolyLine} entity. + *

Deprecated: Use local {@link Entities} instead.

+ * @typedef {object} Overlays.OverlayProperties-Line3D * @property {string} name - The name of the overlay. * @property {Color} color=255,255,255 - The color of the overlay. - * @property {number} alpha=0.7 - The opacity of the overlay, 0.0 - 1.0. + * @property {number} alpha=0.7 - The opacity of the overlay, 0.01.0. * * @property {Vec3} position - The position of the overlay center. Synonyms: p1, point, and * start. @@ -1827,35 +1905,61 @@ QVector Overlays::findOverlays(const glm::vec3& center, float radius) { * parentID set, otherwise the same value as position. * @property {Quat} localRotation - The orientation of the overlay relative to its parent if the overlay has a * parentID set, otherwise the same value as rotation. Synonym: localOrientation. - * @property {boolean} ignorePickIntersection=false - If true, picks ignore the overlay. ignoreRayIntersection is a synonym. - * @property {boolean} drawInFront=false - If true, the overlay is rendered in front of objects in the world, but behind the HUD. - * @property {boolean} drawHUDLayer=false - If true, the overlay is rendered in front of everything, including the HUD. - * @property {boolean} grabbable=false - Signal to grabbing scripts whether or not this overlay can be grabbed. + * @property {boolean} ignorePickIntersection=false - true if {@link Picks} ignore the overlay, false + * if they don't. + * Synonym: ignoreRayIntersection. + * @property {boolean} drawInFront=false - true if the overlay is rendered on top of the world layer but behind + * the HUD surface. + * @property {boolean} drawHUDLayer=false - true if the overlay is rendered in front of everything, including the + * HUD surface. + * @property {boolean} grabbable=false - true if the overlay can be grabbed, false if it can't be. * @property {Uuid} parentID=null - The avatar, entity, or overlay that the overlay is parented to. - * @property {number} parentJointIndex=65535 - Integer value specifying the skeleton joint that the overlay is attached to if - * parentID is an avatar skeleton. A value of 65535 means "no joint". + * @property {number} parentJointIndex=65535 - Integer value specifying the joint of the entity or avatar that the entity is + * parented to if parentID is set. Use 65535 or -1 to parent to the parent's position and orientation rather + * than a joint. * * @property {Uuid} endParentID=null - The avatar, entity, or overlay that the end point of the line is parented to. + *

Currently doesn't work.

+ * * @property {number} endParentJointIndex=65535 - Integer value specifying the skeleton joint that the end point of the line is - * attached to if parentID is an avatar skeleton. A value of 65535 means "no joint". + * attached to if parentID is an avatar skeleton. A value of 65535 means "no joint". + *

Currently doesn't work.

+ * + * @property {Vec3} start - The start point of the line. Synonyms: startPoint and p1. + *

If parentID is set, use localStart to set the local position of the start point.

+ * * @property {Vec3} end - The end point of the line. Synonyms: endPoint and p2. + *

If parentID is set, use localEnd to set the local position of the end point.

+ * + * @property {Vec3} localStart - The local position of the overlay relative to its parent if the overlay has a - * parentID set, otherwise the same value as start. Synonym: localPosition. + * parentID set, otherwise the same value as start. + * * @property {Vec3} localEnd - The local position of the overlay relative to its parent if the overlay has a - * endParentID set, otherwise the same value as end. + * endParentID set, otherwise the same value as end. + * + * @property {number} length - The length of the line, in meters. This can be set after creating a line with start and end - * points. + * points. + *

Currently doesn't work.

+ * + * @property {number} glow=0 - If glow > 0, the line is rendered with a glow. * @property {number} lineWidth=0.02 - Width of the line, in meters. + *

You can set this property's value but currently cannot retrieve its value. Use the strokeWidths + * property to retrieve its value instead.

*/ /**jsdoc - * The "Grid" {@link Overlays.OverlayType|OverlayType} is for 3D grid. + * The "grid" {@link Overlays.OverlayType|OverlayType} is for 3D grids. + * It has properties in addition to the common {@link Overlays.OverlayProperties|OverlayProperties}. + * It additionally has properties per the {@link Entities.EntityProperties-Grid|Grid} entity. + *

Deprecated: Use local {@link Entities} instead.

* @typedef {object} Overlays.OverlayProperties-Grid * @property {string} name - The name of the overlay. * @property {Color} color=255,255,255 - The color of the overlay. - * @property {number} alpha=0.7 - The opacity of the overlay, 0.0 - 1.0. + * @property {number} alpha=0.7 - The opacity of the overlay, 0.01.0. * @property {number} pulseMax=0 - The maximum value of the pulse multiplier. * @property {number} pulseMin=0 - The minimum value of the pulse multiplier. * @property {number} pulsePeriod=1 - The duration of the color and alpha pulse, in seconds. A pulse multiplier value goes from @@ -1877,25 +1981,28 @@ QVector Overlays::findOverlays(const glm::vec3& center, float radius) { * parentID set, otherwise the same value as position. * @property {Quat} localRotation - The orientation of the overlay relative to its parent if the overlay has a * parentID set, otherwise the same value as rotation. Synonym: localOrientation. - * @property {boolean} ignorePickIntersection=false - If true, picks ignore the overlay. ignoreRayIntersection is a synonym. - * @property {boolean} drawInFront=false - If true, the overlay is rendered in front of objects in the world, but behind the HUD. - * @property {boolean} drawHUDLayer=false - If true, the overlay is rendered in front of everything, including the HUD. - * @property {boolean} grabbable=false - Signal to grabbing scripts whether or not this overlay can be grabbed. + * @property {boolean} ignorePickIntersection=false - true if {@link Picks} ignore the overlay, false + * if they don't. + * Synonym: ignoreRayIntersection. + * @property {boolean} drawInFront=false - true if the overlay is rendered on top of the world layer but behind + * the HUD surface. + * @property {boolean} drawHUDLayer=false - true if the overlay is rendered in front of everything, including the + * HUD surface. + * @property {boolean} grabbable=false - true if the overlay can be grabbed, false if it can't be. * @property {Uuid} parentID=null - The avatar, entity, or overlay that the overlay is parented to. - * @property {number} parentJointIndex=65535 - Integer value specifying the skeleton joint that the overlay is attached to if - * parentID is an avatar skeleton. A value of 65535 means "no joint". - * - * @property {boolean} followCamera=true - If true, the grid is always visible even as the camera moves to another position. - * @property {number} majorGridEvery=5 - Integer number of minorGridEvery intervals at which to draw a thick grid line. Minimum value = 1. - * @property {number} minorGridEvery=1 - Real number of meters at which to draw thin grid lines. Minimum value = 0.001. + * @property {number} parentJointIndex=65535 - Integer value specifying the joint of the entity or avatar that the entity is + * parented to if parentID is set. Use 65535 or -1 to parent to the parent's position and orientation rather + * than a joint. */ /**jsdoc - * The "Circle" {@link Overlays.OverlayType|OverlayType} is for 3D circle. - * @typedef {object} Overlays.OverlayProperties-Circle + * The "circle3d" {@link Overlays.OverlayType|OverlayType} is for 3D circles. + * It has properties in addition to the common {@link Overlays.OverlayProperties|OverlayProperties}. + * It additionally has properties per the {@link Entities.EntityProperties-Gizmo|Gizmo} entity, with the + * gizmoType property value being "ring". + *

Deprecated: Use local {@link Entities} instead.

+ * @typedef {object} Overlays.OverlayProperties-Circle3D * @property {string} name - The name of the overlay. - * @property {Color} color=255,255,255 - The color of the overlay. - * @property {number} alpha=0.7 - The opacity of the overlay, 0.0 - 1.0. * @property {number} pulseMax=0 - The maximum value of the pulse multiplier. * @property {number} pulseMin=0 - The minimum value of the pulse multiplier. * @property {number} pulsePeriod=1 - The duration of the color and alpha pulse, in seconds. A pulse multiplier value goes from @@ -1912,62 +2019,75 @@ QVector Overlays::findOverlays(const glm::vec3& center, float radius) { * @property {Vec3} position - The position of the overlay center. Synonyms: p1, point, and * start. * @property {Vec3} dimensions - The dimensions of the overlay. Synonyms: scale, size. + * Read-only. * @property {Quat} rotation - The orientation of the overlay. Synonym: orientation. * @property {Vec3} localPosition - The local position of the overlay relative to its parent if the overlay has a * parentID set, otherwise the same value as position. * @property {Quat} localRotation - The orientation of the overlay relative to its parent if the overlay has a * parentID set, otherwise the same value as rotation. Synonym: localOrientation. - * @property {boolean} isSolid=false - Synonyms: solid
, isFilled, and filled. + * @property {boolean} isSolid=false - true if the overlay is rendered as a solid, false if it is + * rendered as a wire frame. + * Synonyms: solid
, isFilled, and filled. * Antonyms: isWire and wire. - * @property {boolean} ignorePickIntersection=false - If true, picks ignore the overlay. ignoreRayIntersection is a synonym. - * @property {boolean} drawInFront=false - If true, the overlay is rendered in front of objects in the world, but behind the HUD. - * @property {boolean} drawHUDLayer=false - If true, the overlay is rendered in front of everything, including the HUD. - * @property {boolean} grabbable=false - Signal to grabbing scripts whether or not this overlay can be grabbed. + * @property {boolean} ignorePickIntersection=false - true if {@link Picks} ignore the overlay, false + * if they don't. + * Synonym: ignoreRayIntersection. + * @property {boolean} drawInFront=false - true if the overlay is rendered on top of the world layer but behind + * the HUD surface. + * @property {boolean} drawHUDLayer=false - true if the overlay is rendered in front of everything, including the + * HUD surface. + * @property {boolean} grabbable=false - true if the overlay can be grabbed, false if it can't be. * @property {Uuid} parentID=null - The avatar, entity, or overlay that the overlay is parented to. - * @property {number} parentJointIndex=65535 - Integer value specifying the skeleton joint that the overlay is attached to if - * parentID is an avatar skeleton. A value of 65535 means "no joint". + * @property {number} parentJointIndex=65535 - Integer value specifying the joint of the entity or avatar that the entity is + * parented to if parentID is set. Use 65535 or -1 to parent to the parent's position and orientation rather + * than a joint. * - * @property {number} startAt = 0 - The counter - clockwise angle from the overlay's x-axis that drawing starts at in degrees. - * @property {number} endAt = 360 - The counter - clockwise angle from the overlay's x-axis that drawing ends at in degrees. - * @property {number} outerRadius = 1 - The outer radius of the overlay in meters. Synonym: radius. - * @property {number} innerRadius = 0 - The inner radius of the overlay in meters. - * @property {Color} color = 255, 255, 255 - The color of the overlay. Setting this value also sets the values of - * innerStartColor, innerEndColor, outerStartColor, and outerEndColor. + * @property {number} startAt=0 - The counter-clockwise angle from the overlay's x-axis that drawing starts at, in degrees. + * @property {number} endAt=360 - The counter-clockwise angle from the overlay's x-axis that drawing ends at, in degrees. + * @property {number} outerRadius=1 - The outer radius of the overlay in meters. Synonym: radius. + * @property {number} innerRadius=0 - The inner radius of the overlay in meters. + * @property {Color} color - Sets the color of the overlay. Setting this value sets the values of innerStartColor, + * innerEndColor, outerStartColor, and outerEndColor. + * Write-only. * @property {Color} startColor - Sets the values of innerStartColor and outerStartColor. - * Write - only. + * Write-only. * @property {Color} endColor - Sets the values of innerEndColor and outerEndColor. - * Write - only. + * Write-only. * @property {Color} innerColor - Sets the values of innerStartColor and innerEndColor. - * Write - only. + * Write-only. * @property {Color} outerColor - Sets the values of outerStartColor and outerEndColor. - * Write - only. - * @property {Color} innerStartcolor - The color at the inner start point of the overlay. - * @property {Color} innerEndColor - The color at the inner end point of the overlay. - * @property {Color} outerStartColor - The color at the outer start point of the overlay. - * @property {Color} outerEndColor - The color at the outer end point of the overlay. - * @property {number} alpha = 0.5 - The opacity of the overlay, 0.0 -1.0. Setting this value also sets - * the values of innerStartAlpha, innerEndAlpha, outerStartAlpha, and - * outerEndAlpha. Synonym: Alpha; write - only. + * Write-only. + * @property {Color} innerStartcolor=255,255,255 - The color at the inner start point of the overlay. + * @property {Color} innerEndColor=255,255,255 - The color at the inner end point of the overlay. + * @property {Color} outerStartColor=255,255,255 - The color at the outer start point of the overlay. + * @property {Color} outerEndColor=255,255,255 - The color at the outer end point of the overlay. + * @property {number} alpha - Sets the opacity of the overlay, 0.01.0. Setting this value + * sets the values of innerStartAlpha, innerEndAlpha, outerStartAlpha, and + * outerEndAlpha. Synonym: Alpha. * @property {number} startAlpha - Sets the values of innerStartAlpha and outerStartAlpha. - * Write - only. + * Write-only. * @property {number} endAlpha - Sets the values of innerEndAlpha and outerEndAlpha. - * Write - only. + * Write-only. * @property {number} innerAlpha - Sets the values of innerStartAlpha and innerEndAlpha. - * Write - only. + * Write-only. * @property {number} outerAlpha - Sets the values of outerStartAlpha and outerEndAlpha. - * Write - only. - * @property {number} innerStartAlpha = 0 - The alpha at the inner start point of the overlay. - * @property {number} innerEndAlpha = 0 - The alpha at the inner end point of the overlay. - * @property {number} outerStartAlpha = 0 - The alpha at the outer start point of the overlay. - * @property {number} outerEndAlpha = 0 - The alpha at the outer end point of the overlay. + * Write-only. + * @property {number} innerStartAlpha=0.7 - The opacity at the inner start point of the overlay, 0.0 – + * 1.0. + * @property {number} innerEndAlpha=0.7 - The opacity at the inner end point of the overlay, 0.0 – + * 1.0. + * @property {number} outerStartAlpha=0.7 - The opacity at the outer start point of the overlay, 0.0 – + * 1.0. + * @property {number} outerEndAlpha=0.7 - The opacity at the outer end point of the overlay, 0.0 – + * 1.0. * - * @property {boolean} hasTickMarks = false - If true, tick marks are drawn. - * @property {number} majorTickMarksAngle = 0 - The angle between major tick marks, in degrees. - * @property {number} minorTickMarksAngle = 0 - The angle between minor tick marks, in degrees. - * @property {number} majorTickMarksLength = 0 - The length of the major tick marks, in meters. A positive value draws tick marks + * @property {boolean} hasTickMarks=false - true if tick marks are drawn, false if they aren't. + * @property {number} majorTickMarksAngle=0 - The angle between major tick marks, in degrees. + * @property {number} minorTickMarksAngle=0 - The angle between minor tick marks, in degrees. + * @property {number} majorTickMarksLength=0 - The length of the major tick marks, in meters. A positive value draws tick marks * outwards from the inner radius; a negative value draws tick marks inwards from the outer radius. - * @property {number} minorTickMarksLength = 0 - The length of the minor tick marks, in meters. A positive value draws tick marks + * @property {number} minorTickMarksLength=0 - The length of the minor tick marks, in meters. A positive value draws tick marks * outwards from the inner radius; a negative value draws tick marks inwards from the outer radius. - * @property {Color} majorTickMarksColor = 0, 0, 0 - The color of the major tick marks. - * @property {Color} minorTickMarksColor = 0, 0, 0 - The color of the minor tick marks. + * @property {Color} majorTickMarksColor=0,0,0 - The color of the major tick marks. + * @property {Color} minorTickMarksColor=0,0,0 - The color of the minor tick marks. */ diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index 1a2382769c..739f5ba45a 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -68,17 +68,23 @@ public: }; /**jsdoc - * (Note: 3D Overlays are deprecated. Use local entities instead.) The Overlays API provides facilities to create and interact with overlays. Overlays are 2D and 3D objects visible only to - * yourself and that aren't persisted to the domain. They are used for UI. + * The Overlays API provides facilities to create and interact with overlays. These are 2D and 3D objects visible + * only to yourself and that aren't persisted to the domain. They are used for UI. + * + *

Note: 3D overlays are local {@link Entities}, internally, so many of the methods also work with + * entities.

+ * + *

3D overlays are deprecated: Use local {@link Entities} for these instead.

+ * * @namespace Overlays * * @hifi-interface * @hifi-client-entity * @hifi-avatar * - * @property {Uuid} keyboardFocusOverlay - Get or set the {@link Entities.EntityTypes|Web} entity that has keyboard focus. - * If no entity has keyboard focus, returns null; set to null or {@link Uuid(0)|Uuid.NULL} to - * clear keyboard focus. + * @property {Uuid} keyboardFocusOverlay - The {@link Overlays.OverlayProperties-Web3D|"web3d"} overlay + * ({@link Entities.EntityProperties-Web|Web} entity) that has keyboard focus. If no overlay (entity) has keyboard focus, + * returns null; set to null or {@link Uuid(0)|Uuid.NULL} to clear keyboard focus. */ class Overlays : public QObject { @@ -118,7 +124,7 @@ public: public slots: /**jsdoc - * Add an overlay to the scene. + * Adds an overlay to the scene. * @function Overlays.addOverlay * @param {Overlays.OverlayType} type - The type of the overlay to add. * @param {Overlays.OverlayProperties} properties - The properties of the overlay to add. @@ -134,19 +140,21 @@ public slots: QUuid addOverlay(const QString& type, const QVariant& properties); /**jsdoc - * Create a clone of an existing entity (or 2D overlay). + * Creates a clone of an existing overlay (or entity). + *

Note: For cloning behavior of 3D overlays and entities, see {@link Entities.cloneEntity}.

* @function Overlays.cloneOverlay - * @param {Uuid} id - The ID of the entity/2D overlay to clone. - * @returns {Uuid} The ID of the new object if successful, otherwise {@link Uuid(0)|Uuid.NULL}. + * @param {Uuid} id - The ID of the overlay (or entity) to clone. + * @returns {Uuid} The ID of the new overlay (or entity) if successful, otherwise {@link Uuid(0)|Uuid.NULL}. */ QUuid cloneOverlay(const QUuid& id); /**jsdoc - * Edit an overlay's properties. + * Edits an overlay's (or entity's) properties. * @function Overlays.editOverlay - * @param {Uuid} id - The ID of the overlay to edit. + * @param {Uuid} id - The ID of the overlay (or entity) to edit. * @param {Overlays.OverlayProperties} properties - The properties changes to make. - * @returns {boolean} true if the overlay was found and edited, otherwise false. + * @returns {boolean} false if Interface is exiting. Otherwise, if a 2D overlay then true always, + * and if a 3D overlay then true if the overlay was found and edited, otherwise false. * @example
* var overlay = Overlays.addOverlay("cube", { * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -3 })), @@ -163,12 +171,11 @@ public slots: bool editOverlay(const QUuid& id, const QVariant& properties); /**jsdoc - * Edit multiple overlays' properties. + * Edits the properties of multiple overlays (or entities). * @function Overlays.editOverlays - * @param propertiesById {object.} - An object with overlay IDs as keys and + * @param propertiesById {object.} - An object with overlay (or entity) IDs as keys and * {@link Overlays.OverlayProperties|OverlayProperties} edits to make as values. - * @returns {boolean} true if all overlays were found and edited, otherwise false (some may have - * been found and edited). + * @returns {boolean} false if Interface is exiting, otherwise true. * @example * var overlayA = Overlays.addOverlay("cube", { * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: -0.3, y: 0, z: -3 })), @@ -192,18 +199,18 @@ public slots: bool editOverlays(const QVariant& propertiesById); /**jsdoc - * Delete an entity or 2D overlay. + * Deletes an overlay (or entity). * @function Overlays.deleteOverlay - * @param {Uuid} id - The ID of the object to delete. + * @param {Uuid} id - The ID of the overlay (or entity) to delete. */ void deleteOverlay(const QUuid& id); /**jsdoc - * Get the type of an entity or 2D overlay. + * Gets the type of an overlay. * @function Overlays.getOverlayType - * @param {Uuid} id - The ID of the object to get the type of. - * @returns {string} The type of the object if found, otherwise an empty string. - * @example + * @param {Uuid} id - The ID of the overlay to get the type of. + * @returns {Overlays.OverlayType} The type of the overlay if found, otherwise "unknown". + * @example * var overlay = Overlays.addOverlay("cube", { * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -3 })), * rotation: MyAvatar.orientation, @@ -211,56 +218,82 @@ public slots: * solid: true * }); * var type = Overlays.getOverlayType(overlay); - * print("Type: " + type); + * print("Type: " + type); // cube */ QString getOverlayType(const QUuid& id); /**jsdoc - * Get the overlay script object. In particular, this is useful for accessing the event bridge for a web3d - * overlay. + * Gets an overlay's (or entity's) script object. In particular, this is useful for accessing a + * {@link Overlays.OverlayProperties-Web3D|"web3d"} overlay's EventBridge script object to + * exchange messages with the web page script. + *

To send a message from an Interface script to a "web3d" overlay over its event bridge:

+ *
var overlayObject = Overlays.getOverlayObject(overlayID);
+     * overlayObject.emitScriptEvent(message);
+ *

To receive a message from a "web3d" overlay over its event bridge in an Interface script:

+ *
var overlayObject = Overlays.getOverlayObject(overlayID);
+     * overlayObject.webEventReceived.connect(function(message) {
+     *     ...
+     * };
* @function Overlays.getOverlayObject * @param {Uuid} overlayID - The ID of the overlay to get the script object of. * @returns {object} The script object for the overlay if found. - * @example
- * // HTML file: name "web3d.html". + * @example + * // HTML file, name: "web3d.html". * * * * HELLO * * - *

HELLO

+ *

HELLO

* * * - * - * // Script file. - * var web3dOverlay = Overlays.addOverlay("web3d", { - * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, {x: 0, y: 0.5, z: -3 })), - * rotation: MyAvatar.orientation, - * url: Script.resolvePath("web3d.html"), - * alpha: 1.0 - * }); - * - * function onWebEventReceived(event) { - * print("onWebEventReceived() : " + JSON.stringify(event)); + * + * // Interface script file. + * var web3DOverlay = Overlays.addOverlay("web3d", { + * type: "Web", + * position : Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y : 0.5, z : -3 })), + * rotation : MyAvatar.orientation, + * sourceUrl : Script.resolvePath("web3d.html"), + * alpha : 1.0 + * }); + * + * var overlayObject; + * + * function onWebEventReceived(message) { + * // Message received. + * print("Message received: " + message); + * + * // Send a message back. + * overlayObject.emitScriptEvent(message + " back"); * } - * - * overlayObject = Overlays.getOverlayObject(web3dOverlay); - * overlayObject.webEventReceived.connect(onWebEventReceived); - * - * Script.scriptEnding.connect(function () { - * Overlays.deleteOverlay(web3dOverlay); + * + * Script.setTimeout(function() { + * overlayObject = Overlays.getOverlayObject(web3DOverlay); + * overlayObject.webEventReceived.connect(onWebEventReceived); + * }, 500); + * + * Script.scriptEnding.connect(function() { + * Overlays.deleteOverlay(web3DOverlay); * }); */ QObject* getOverlayObject(const QUuid& id); /**jsdoc - * Get the ID of the 2D overlay at a particular point on the screen or HUD. + * Gets the ID of the 2D overlay at a particular point on the desktop screen or HUD surface. * @function Overlays.getOverlayAtPoint * @param {Vec2} point - The point to check for an overlay. * @returns {Uuid} The ID of the 2D overlay at the specified point if found, otherwise null. @@ -279,10 +312,11 @@ public slots: QUuid getOverlayAtPoint(const glm::vec2& point); /**jsdoc - * Get the value of a 3D overlay's property. + * Gets a specified property value of a 3D overlay (or entity). + *

Note: 2D overlays' property values cannot be retrieved.

* @function Overlays.getProperty - * @param {Uuid} id - The ID of the overlay. Must be for a 3D {@link Overlays.OverlayType|OverlayType}. - * @param {string} property - The name of the property value to get. + * @param {Uuid} id - The ID of the 3D overlay (or entity). + * @param {string} property - The name of the property to get the value of. * @returns {object} The value of the property if the 3D overlay and property can be found, otherwise * undefined. * @example
@@ -298,12 +332,13 @@ public slots: QVariant getProperty(const QUuid& id, const QString& property); /**jsdoc - * Get the values of an overlay's properties. + * Gets specified property values of a 3D overlay (or entity). + *

Note: 2D overlays' property values cannot be retrieved.

* @function Overlays.getProperties - * @param {Uuid} id - The ID of the overlay. - * @param {Array.} properties - An array of names of properties to get the values of. - * @returns {Overlays.OverlayProperties} The values of valid properties if the overlay can be found, otherwise - * undefined. + * @param {Uuid} id - The ID of the overlay (or entity). + * @param {Array.} properties - The names of the properties to get the values of. + * @returns {Overlays.OverlayProperties} The values of valid properties if the overlay can be found, otherwise an empty + * object. * @example
* var overlay = Overlays.addOverlay("cube", { * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -3 })), @@ -317,11 +352,11 @@ public slots: QVariantMap getProperties(const QUuid& id, const QStringList& properties); /**jsdoc - * Get the values of multiple overlays' properties. + * Gets the values of multiple overlays' (or entities') properties. * @function Overlays.getOverlaysProperties - * @param propertiesById {object.>} - An object with overlay IDs as keys and arrays of the names of - * properties to get for each as values. - * @returns {object.} An object with overlay IDs as keys and + * @param propertiesById {object.>} - An object with overlay (or entity) IDs as keys and arrays of the + * names of properties to get for each as values. + * @returns {object.} An object with overlay (or entity) IDs as keys and * {@link Overlays.OverlayProperties|OverlayProperties} as values. * @example * var overlayA = Overlays.addOverlay("cube", { @@ -345,22 +380,20 @@ public slots: QVariantMap getOverlaysProperties(const QVariant& overlaysProperties); /**jsdoc - * Find the closest 3D overlay intersected by a {@link PickRay}. Overlays with their drawInFront property set - * to true have priority over overlays that don't, except that tablet overlays have priority over any - * drawInFront overlays behind them. I.e., if a drawInFront overlay is behind one that isn't - * drawInFront, the drawInFront overlay is returned, but if a tablet overlay is in front of a - * drawInFront overlay, the tablet overlay is returned. + * Finds the closest 3D overlay (or local entity) intersected by a {@link PickRay}. * @function Overlays.findRayIntersection * @param {PickRay} pickRay - The PickRay to use for finding overlays. - * @param {boolean} [precisionPicking=false] - Unused; exists to match Entity API. - * @param {Array.} [include=[]] - If not empty then the search is restricted to these overlays. - * @param {Array.} [discard=[]] - Overlays to ignore during the search. - * @param {boolean} [visibleOnly=false] - If true then only entities that are - * {@link Entities.EntityProperties|visible} are searched. - * @param {boolean} [collideableOnly=false] - If true then only entities that are not - * {@link Entities.EntityProperties|collisionless} are searched. - * @returns {Overlays.RayToOverlayIntersectionResult} The closest 3D overlay intersected by pickRay, taking - * into account overlayIDsToInclude and overlayIDsToExclude if they're not empty. + * @param {boolean} [precisionPicking=false] - true to pick against precise meshes, false to pick + * against coarse meshes. If true and the intersected entity is a model, the result's + * extraInfo property includes more information than it otherwise would. + * @param {Array.} [include=[]] - If not empty, then the search is restricted to these overlays (and local entities). + * @param {Array.} [discard=[]] - Overlays (and local entities) to ignore during the search. + * @param {boolean} [visibleOnly=false] - true if only overlays (and local entities) that are + * {@link Overlays.OverlayProperties|visible} should be searched. + * @param {boolean} [collideableOnly=false] - true if only local entities that are not + * {@link Entities.EntityProperties|collisionless} should be searched. + * @returns {Overlays.RayToOverlayIntersectionResult} The result of the search for the first intersected overlay (or local + * entity. * @example * var overlay = Overlays.addOverlay("cube", { @@ -384,12 +417,13 @@ public slots: bool collidableOnly = false); /**jsdoc - * Return a list of local entities with bounding boxes that touch a search sphere. + * Gets a list of visible 3D overlays (local entities) with bounding boxes that touch a search sphere. * @function Overlays.findOverlays * @param {Vec3} center - The center of the search sphere. * @param {number} radius - The radius of the search sphere. - * @returns {Uuid[]} An array of entity IDs with bounding boxes that touch a search sphere. - * @example + * @returns {Uuid[]} The IDs of the overlays (local entities) that are visible and have bounding boxes that touch a search + * sphere. + * @example * var overlayA = Overlays.addOverlay("cube", { * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: -0.3, y: 0, z: -3 })), * rotation: MyAvatar.orientation, @@ -411,11 +445,13 @@ public slots: QVector findOverlays(const glm::vec3& center, float radius); /**jsdoc - * Check whether an overlay's assets have been loaded. For example, for an image overlay the result indicates - * whether its image has been loaded. + * Checks whether an overlay's (or entity's) assets have been loaded. For example, for an + * {@link Overlays.OverlayProperties-Image|"image"} overlay, the result indicates whether its image has been + * loaded. * @function Overlays.isLoaded - * @param {Uuid} id - The ID of the overlay to check. - * @returns {boolean} true if the overlay's assets have been loaded, otherwise false. + * @param {Uuid} id - The ID of the overlay (or entity) to check. + * @returns {boolean} true if the overlay's (or entity's) assets have been loaded, otherwise + * false. * @example * var overlay = Overlays.addOverlay("image", { * bounds: { x: 100, y: 100, width: 200, height: 200 }, @@ -429,55 +465,60 @@ public slots: bool isLoaded(const QUuid& id); /**jsdoc - * Calculates the size of the given text in the specified object if it is a text entity or overlay. + * Calculates the size of some text in a text overlay (or entity). The overlay (or entity) need not be set visible. + *

Note: The size of text in a 3D overlay (or entity) cannot be calculated immediately after the + * overlay (or entity) is created; a short delay is required while the overlay (or entity) finishes being created.

* @function Overlays.textSize - * @param {Uuid} id - The ID of the object to use for calculation. + * @param {Uuid} id - The ID of the overlay (or entity) to use for calculation. * @param {string} text - The string to calculate the size of. - * @returns {Size} The size of the text if the object is a text entity or overlay, otherwise - * { height: 0, width : 0 }. If the object is a 2D overlay, the size is in pixels; if the object is an entity, - * the size is in meters. + * @returns {Size} The size of the text if the object is a text overlay (or entity), otherwise + * { height: 0, width : 0 }. If the object is a 2D overlay, the size is in pixels; if the object is a 3D + * overlay (or entity), the size is in meters. * @example
* var overlay = Overlays.addOverlay("text3d", { * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -2 })), * rotation: MyAvatar.orientation, - * text: "hello", - * lineHeight: 0.2 + * lineHeight: 0.2, + * visible: false * }); - * var textSize = Overlays.textSize(overlay, "hello"); - * print("Size of \"hello\": " + JSON.stringify(textSize)); + * + * Script.setTimeout(function() { + * var textSize = Overlays.textSize(overlay, "hello"); + * print("Size of \"hello\": " + JSON.stringify(textSize)); + * }, 500); */ QSizeF textSize(const QUuid& id, const QString& text); /**jsdoc - * Get the width of the window or HUD. + * Gets the width of the Interface window or HUD surface. * @function Overlays.width - * @returns {number} The width, in pixels, of the Interface window if in desktop mode or the HUD if in HMD mode. + * @returns {number} The width, in pixels, of the Interface window if in desktop mode or the HUD surface if in HMD mode. */ float width(); /**jsdoc - * Get the height of the window or HUD. + * Gets the height of the Interface window or HUD surface. * @function Overlays.height - * @returns {number} The height, in pixels, of the Interface window if in desktop mode or the HUD if in HMD mode. + * @returns {number} The height, in pixels, of the Interface window if in desktop mode or the HUD surface if in HMD mode. */ float height(); /**jsdoc - * Check if there is an object of a given ID. + * Checks if an overlay (or entity) exists. * @function Overlays.isAddedOverlay - * @param {Uuid} id - The ID to check. - * @returns {boolean} true if an object with the given ID exists, false otherwise. + * @param {Uuid} id - The ID of the overlay (or entity) to check. + * @returns {boolean} true if an overlay (or entity) with the given ID exists, false if it doesn't. */ bool isAddedOverlay(const QUuid& id); /**jsdoc - * Generate a mouse press event on an overlay. + * Generates a mouse press event on an overlay (or local entity). * @function Overlays.sendMousePressOnOverlay - * @param {Uuid} id - The ID of the overlay to generate a mouse press event on. + * @param {Uuid} id - The ID of the overlay (or local entity) to generate a mouse press event on. * @param {PointerEvent} event - The mouse press event details. - * @example - * var overlay = Overlays.addOverlay("cube", { + * @example + * var overlay3D = Overlays.addOverlay("cube", { * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -3 })), * rotation: MyAvatar.orientation, * dimensions: { x: 0.3, y: 0.3, z: 0.3 }, @@ -485,7 +526,7 @@ public slots: * }); * print("3D overlay: " + overlay); * - * var overlay = Overlays.addOverlay("rectangle", { + * var overlay2D = Overlays.addOverlay("rectangle", { * bounds: { x: 100, y: 100, width: 200, height: 100 }, * color: { red: 255, green: 255, blue: 255 } * }); @@ -511,66 +552,69 @@ public slots: void sendMousePressOnOverlay(const QUuid& id, const PointerEvent& event); /**jsdoc - * Generate a mouse release event on an overlay. + * Generates a mouse release event on an overlay (or local entity). * @function Overlays.sendMouseReleaseOnOverlay - * @param {Uuid} id - The ID of the overlay to generate a mouse release event on. + * @param {Uuid} id - The ID of the overlay (or local entity) to generate a mouse release event on. * @param {PointerEvent} event - The mouse release event details. */ void sendMouseReleaseOnOverlay(const QUuid& id, const PointerEvent& event); /**jsdoc - * Generate a mouse move event on an overlay. + * Generates a mouse move event on an overlay (or local entity). * @function Overlays.sendMouseMoveOnOverlay - * @param {Uuid} id - The ID of the overlay to generate a mouse move event on. + * @param {Uuid} id - The ID of the overlay (or local entity) to generate a mouse move event on. * @param {PointerEvent} event - The mouse move event details. */ void sendMouseMoveOnOverlay(const QUuid& id, const PointerEvent& event); /**jsdoc - * Generate a hover enter event on an overlay. + * Generates a hover enter event on an overlay (or local entity). * @function Overlays.sendHoverEnterOverlay - * @param {Uuid} id - The ID of the overlay to generate a hover enter event on. + * @param {Uuid} id - The ID of the overlay (or local entity) to generate a hover enter event on. * @param {PointerEvent} event - The hover enter event details. */ void sendHoverEnterOverlay(const QUuid& id, const PointerEvent& event); /**jsdoc - * Generate a hover over event on an overlay. + * Generates a hover over event on an overlay (or entity). * @function Overlays.sendHoverOverOverlay - * @param {Uuid} id - The ID of the overlay to generate a hover over event on. + * @param {Uuid} id - The ID of the overlay (or local entity) to generate a hover over event on. * @param {PointerEvent} event - The hover over event details. */ void sendHoverOverOverlay(const QUuid& id, const PointerEvent& event); /**jsdoc - * Generate a hover leave event on an overlay. + * Generates a hover leave event on an overlay (or local entity). * @function Overlays.sendHoverLeaveOverlay - * @param {Uuid} id - The ID of the overlay to generate a hover leave event on. + * @param {Uuid} id - The ID of the overlay (or local entity) to generate a hover leave event on. * @param {PointerEvent} event - The hover leave event details. */ void sendHoverLeaveOverlay(const QUuid& id, const PointerEvent& event); /**jsdoc - * Get the ID of the Web3D entity that has keyboard focus. + * Gets the ID of the {@link Overlays.OverlayProperties-Web3D|"web3d"} overlay + * ({@link Entities.EntityProperties-Web|Web} entity) that has keyboard focus. * @function Overlays.getKeyboardFocusOverlay - * @returns {Uuid} The ID of the {@link Entities.EntityTypes|Web} overlay that has focus, if any, otherwise - * null. + * @returns {Uuid} The ID of the {@link Overlays.OverlayProperties-Web3D|"web3d"} overlay + * ({@link Entities.EntityProperties-Web|Web} entity) that has focus, if any, otherwise null. */ QUuid getKeyboardFocusOverlay() { return DependencyManager::get()->getKeyboardFocusEntity(); } /**jsdoc - * Set the Web3D entity that has keyboard focus. + * Sets the {@link Overlays.OverlayProperties-Web3D|"web3d"} overlay + * ({@link Entities.EntityProperties-Web|Web} entity) that has keyboard focus. * @function Overlays.setKeyboardFocusOverlay - * @param {Uuid} id - The ID of the {@link Entities.EntityTypes|Web} entity to set keyboard focus to. Use - * null or {@link Uuid(0)|Uuid.NULL} to unset keyboard focus from an overlay. + * @param {Uuid} id - The ID of the {@link Overlays.OverlayProperties-Web3D|"web3d"} overlay + * ({@link Entities.EntityProperties-Web|Web} entity) to set keyboard focus to. Use null or + * {@link Uuid(0)|Uuid.NULL} to unset keyboard focus from an overlay (entity). */ void setKeyboardFocusOverlay(const QUuid& id) { DependencyManager::get()->setKeyboardFocusEntity(id); } signals: /**jsdoc - * Triggered when an overlay is deleted. + * Triggered when an overlay (or entity) is deleted. * @function Overlays.overlayDeleted - * @param {Uuid} id - The ID of the overlay that was deleted. + * @param {Uuid} id - The ID of the overlay (or entity) that was deleted. * @returns {Signal} * @example * var overlay = Overlays.addOverlay("cube", { diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 4722201c05..5f4c49364e 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1904,6 +1904,61 @@ void Rig::updateFeet(bool leftFootEnabled, bool rightFootEnabled, bool headEnabl } } +void Rig::updateReactions(const ControllerParameters& params) { + + // enable/disable animVars + bool enabled = params.reactionEnabledFlags[AVATAR_REACTION_POSITIVE]; + _animVars.set("reactionPositiveEnabled", enabled); + _animVars.set("reactionPositiveDisabled", !enabled); + + enabled = params.reactionEnabledFlags[AVATAR_REACTION_NEGATIVE]; + _animVars.set("reactionNegativeEnabled", enabled); + _animVars.set("reactionNegativeDisabled", !enabled); + + enabled = params.reactionEnabledFlags[AVATAR_REACTION_RAISE_HAND]; + _animVars.set("reactionRaiseHandEnabled", enabled); + _animVars.set("reactionRaiseHandDisabled", !enabled); + + enabled = params.reactionEnabledFlags[AVATAR_REACTION_APPLAUD]; + _animVars.set("reactionApplaudEnabled", enabled); + _animVars.set("reactionApplaudDisabled", !enabled); + + enabled = params.reactionEnabledFlags[AVATAR_REACTION_POINT]; + _animVars.set("reactionPointEnabled", enabled); + _animVars.set("reactionPointDisabled", !enabled); + + // trigger animVars + if (params.reactionTriggers[AVATAR_REACTION_POSITIVE]) { + _animVars.set("reactionPositiveTrigger", true); + } else { + _animVars.set("reactionPositiveTrigger", false); + } + + if (params.reactionTriggers[AVATAR_REACTION_NEGATIVE]) { + _animVars.set("reactionNegativeTrigger", true); + } else { + _animVars.set("reactionNegativeTrigger", false); + } + + if (params.reactionTriggers[AVATAR_REACTION_RAISE_HAND]) { + _animVars.set("reactionRaiseHandTrigger", true); + } else { + _animVars.set("reactionRaiseHandTrigger", false); + } + + if (params.reactionTriggers[AVATAR_REACTION_APPLAUD]) { + _animVars.set("reactionApplaudTrigger", true); + } else { + _animVars.set("reactionApplaudTrigger", false); + } + + if (params.reactionTriggers[AVATAR_REACTION_POINT]) { + _animVars.set("reactionPointTrigger", true); + } else { + _animVars.set("reactionPointTrigger", false); + } +} + void Rig::updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm::quat& modelRotation, const glm::vec3& lookAtSpot, const glm::vec3& saccade) { // TODO: does not properly handle avatar scale. @@ -2183,6 +2238,8 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo } } + updateReactions(params); + _previousControllerParameters = params; } diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 8056d1eff1..7cf17ca391 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -88,6 +88,8 @@ public: AnimPose secondaryControllerPoses[NumSecondaryControllerTypes]; // rig space uint8_t secondaryControllerFlags[NumSecondaryControllerTypes]; bool isTalking; + bool reactionEnabledFlags[NUM_AVATAR_REACTIONS]; + bool reactionTriggers[NUM_AVATAR_REACTIONS]; HFMJointShapeInfo hipsShapeInfo; HFMJointShapeInfo spineShapeInfo; HFMJointShapeInfo spine1ShapeInfo; @@ -269,6 +271,7 @@ protected: void updateFeet(bool leftFootEnabled, bool rightFootEnabled, bool headEnabled, const AnimPose& leftFootPose, const AnimPose& rightFootPose, const glm::mat4& rigToSensorMatrix, const glm::mat4& sensorToRigMatrix); + void updateReactions(const ControllerParameters& params); void updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm::quat& modelRotation, const glm::vec3& lookAt, const glm::vec3& saccade); void calcAnimAlpha(float speed, const std::vector& referenceSpeeds, float* alphaOut) const; diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index a2dde3d651..22b070464d 100755 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -2861,7 +2861,7 @@ glm::vec3 AvatarData::getAbsoluteJointTranslationInObjectFrame(int index) const * Information on an attachment worn by the avatar. * @typedef {object} AttachmentData * @property {string} modelUrl - The URL of the model file. Models can be FBX or OBJ format. - * @property {string} jointName - The offset to apply to the model relative to the joint position. + * @property {string} jointName - The name of the joint that the attachment is parented to. * @property {Vec3} translation - The offset from the joint that the attachment is positioned at. * @property {Vec3} rotation - The rotation applied to the model relative to the joint orientation. * @property {number} scale - The scale applied to the attachment model. diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 498f39cdf9..3c8e2d6fcc 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -1292,7 +1292,7 @@ public: * jointName: "Head", * translation: {"x": 0, "y": 0.25, "z": 0}, * rotation: {"x": 0, "y": 0, "z": 0, "w": 1}, - * scale: 1, + * scale: 0.01, * isSoft: false * }; * diff --git a/libraries/display-plugins/src/display-plugins/CompositorHelper.h b/libraries/display-plugins/src/display-plugins/CompositorHelper.h index 9c7d01082c..1279050a57 100644 --- a/libraries/display-plugins/src/display-plugins/CompositorHelper.h +++ b/libraries/display-plugins/src/display-plugins/CompositorHelper.h @@ -174,20 +174,35 @@ private: }; /**jsdoc + * The Reticle API provides access to the mouse cursor. The cursor may be an arrow or a reticle circle, depending + * on Interface settings. The mouse cursor is visible in HMD mode if controllers aren't being used. + * * @namespace Reticle * * @hifi-interface * @hifi-client-entity * @hifi-avatar * - * @property {boolean} allowMouseCapture - * @property {number} depth - * @property {Vec2} maximumPosition - * @property {boolean} mouseCaptured - * @property {boolean} pointingAtSystemOverlay - * @property {Vec2} position - * @property {number} scale - * @property {boolean} visible + * @property {boolean} allowMouseCapture=true - true if the mouse cursor will be captured when in HMD mode and the + * Interface window content (excluding menus) has focus, false if the mouse cursor will not be captured. + * @property {number} depth - The depth (distance) that the reticle is displayed at relative to the HMD view, in HMD mode. + * @property {Vec2} maximumPosition - The maximum reticle coordinates on the display device in desktop mode or the HUD surface + * in HMD mode. (The minimum reticle coordinates on the desktop display device or HUD surface are 0, + * 0.) Read-only. + * @property {boolean} mouseCaptured - true if the mouse cursor is captured, displaying only in Interface and + * not on the rest of the desktop. The mouse cursor may be captured when in HMD mode and the Interface window content + * (excluding menu items) has focus, if capturing is enabled (allowMouseCapture is true). + * Read-only. + * @property {boolean} pointingAtSystemOverlay - true if the mouse cursor is pointing at UI in the Interface + * window in desktop mode or on the HUD surface in HMD mode, false if it isn't. Read-only. + * @property {Vec2} position - The position of the cursor. This is the position relative to the Interface window in desktop + * mode, and the HUD surface in HMD mode. + *

Note: The position values may be negative.

+ * @property {number} scale=1 - The scale of the reticle circle in desktop mode, and the arrow and reticle circle in HMD mode. + * (Does not affect the size of the arrow in desktop mode.) + * @property {boolean} visible=true - true if the reticle circle is visible in desktop mode, and the arrow or + * reticle circle are visible in HMD mode; false otherwise. (Does not affect the visibility of the mouse + * pointer in desktop mode.) */ // Scripting interface available to control the Reticle class ReticleInterface : public QObject { @@ -205,80 +220,113 @@ public: ReticleInterface(CompositorHelper* outer) : QObject(outer), _compositor(outer) {} /**jsdoc + * Checks whether the mouse cursor is captured, displaying only in Interface and not on the rest of the desktop. The mouse + * cursor is captured when in HMD mode and the Interface window content (excluding menu items) has focus, if capturing is + * enabled (allowMouseCapture property value is true). * @function Reticle.isMouseCaptured - * @returns {boolean} + * @returns {boolean} true if the mouse cursor is captured, displaying only in Interface and not on the + * desktop. */ Q_INVOKABLE bool isMouseCaptured() { return _compositor->shouldCaptureMouse(); } /**jsdoc + * Gets whether the mouse cursor will be captured when in HMD mode and the Interface window content (excluding menu items) + * has focus. When captured, the mouse cursor displays only in Interface, not on the rest of the desktop. * @function Reticle.getAllowMouseCapture - * @returns {boolean} + * @returns {boolean} true if the mouse cursor will be captured when in HMD mode and the Interface window + * content has focus, false if the mouse cursor will not be captured. */ Q_INVOKABLE bool getAllowMouseCapture() { return _compositor->getAllowMouseCapture(); } /**jsdoc + * Sets whether the mouse cursor will be captured when in HMD mode and the Interface window content (excluding menu items) + * has focus. When captured, the mouse cursor displays only in Interface, not on the rest of desktop. * @function Reticle.setAllowMouseCapture - * @param {boolean} allowMouseCaptured + * @param {boolean} allowMouseCaptured - true if the mouse cursor will be captured when in HMD mode and the + * Interface window content has focus, false if the mouse cursor will not be captured. */ Q_INVOKABLE void setAllowMouseCapture(bool value) { return _compositor->setAllowMouseCapture(value); } /**jsdoc + * Gets whether the mouse cursor is pointing at UI in the Interface window in desktop mode or on the HUD surface in HMD + * mode. * @function Reticle.isPointingAtSystemOverlay - * @returns {boolean} + * @returns {boolean} true if the mouse cursor is pointing at UI in the Interface window in desktop mode or on + * the HUD surface in HMD mode, false if it isn't. */ Q_INVOKABLE bool isPointingAtSystemOverlay() { return !_compositor->getReticleOverDesktop(); } /**jsdoc + * Gets whether the reticle circle is visible in desktop mode, or the arrow or reticle circle are visible in HMD mode. * @function Reticle.getVisible - * @returns {boolean} + * @returns {boolean} true if the reticle circle is visible in desktop mode, and the arrow or + * reticle circle are visible in HMD mode; false otherwise. (The mouse pointer is always visible in + * desktop mode.) */ Q_INVOKABLE bool getVisible() { return _compositor->getReticleVisible(); } /**jsdoc + * Sets whether the reticle circle is visible in desktop mode, or the arrow or reticle circle are visible in HMD mode. * @function Reticle.setVisible - * @param {boolean} visible + * @param {boolean} visible - true if the reticle circle is visible in desktop mode, and the arrow or reticle + * circle are visible in HMD mode; false otherwise. (Does not affect the visibility of the mouse pointer + * in desktop mode.) */ Q_INVOKABLE void setVisible(bool visible) { _compositor->setReticleVisible(visible); } /**jsdoc + * Gets the depth (distance) that the reticle is displayed at relative to the HMD view, in HMD mode. * @function Reticle.getDepth - * @returns {number} + * @returns {number} The depth (distance) that the reticle is displayed at relative to the HMD view, in HMD mode. */ Q_INVOKABLE float getDepth() { return _compositor->getReticleDepth(); } /**jsdoc + * Sets the depth (distance) that the reticle is displayed at relative to the HMD view, in HMD mode. * @function Reticle.setDepth - * @param {number} depth + * @param {number} depth - The depth (distance) that the reticle is displayed at relative to the HMD view, in HMD mode. */ Q_INVOKABLE void setDepth(float depth) { _compositor->setReticleDepth(depth); } /**jsdoc + * Gets the scale of the reticle circle in desktop mode, and the arrow and reticle circle in HMD mode. (Does not affect the + * size of the arrow in desktop mode.) The default scale is 1.0. * @function Reticle.getScale - * @returns {number} + * @returns {number} The scale of the reticle. */ Q_INVOKABLE float getScale() const; /**jsdoc + * Sets the scale of the reticle circle in desktop mode, and the arrow and reticle circle in HMD mode. (Does not affect the + * size of the arrow in desktop mode.) The default scale is 1.0. * @function Reticle.setScale - * @param {number} scale + * @param {number} scale - The scale of the reticle. */ Q_INVOKABLE void setScale(float scale); /**jsdoc + * Gets the position of the cursor. This is the position relative to the Interface window in desktop mode, and the HUD + * surface in HMD mode. + *

Note: The position values may be negative.

* @function Reticle.getPosition - * @returns {Vec2} + * @returns {Vec2} The position of the cursor. */ Q_INVOKABLE QVariant getPosition() const; /**jsdoc + * Sets the position of the cursor. This is the position relative to the Interface window in desktop mode, and the HUD + * surface in HMD mode. + *

Note: The position values may be negative.

* @function Reticle.setPosition - * @param {Vec2} position + * @param {Vec2} position - The position of the cursor. */ Q_INVOKABLE void setPosition(QVariant position); /**jsdoc + * Gets the maximum reticle coordinates on the display device in desktop mode or the HUD surface in HMD mode. (The minimum + * reticle coordinates on the desktop display device or HUD surface are 0, 0.) * @function Reticle.getMaximumPosition - * @returns {Vec2} + * @returns {Vec2} The maximum reticle coordinates on the display device in desktop mode or the HUD surface in HMD mode. */ Q_INVOKABLE glm::vec2 getMaximumPosition() { return _compositor->getReticleMaximumPosition(); } diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 980cd31652..b89788040f 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -988,8 +988,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * false otherwise; [] if none are applied or the model hasn't loaded. The array indexes are per * {@link Entities.getJointIndex|getJointIndex}. * @property {Vec3[]} jointTranslations=[]] - Joint translations applied to the model; [] if none are applied or - * the model hasn't loaded. The array indexes are per {@link Entities.getJointIndex|getJointIndex}. Rotations are relative - * to each joint's parent. + * the model hasn't loaded. The array indexes are per {@link Entities.getJointIndex|getJointIndex}. Translations are + * relative to each joint's parent. *

Joint translations can be set by {@link Entities.setLocalJointTranslation|setLocalJointTranslation} and similar * functions, or by setting the value of this property. If you set a joint translation using this property you also need to * set the corresponding jointTranslationsSet value to true.

diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index ad2aaf2160..0442756300 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -446,7 +446,15 @@ public slots: /**jsdoc * Gets an entity's script object. In particular, this is useful for accessing a {@link Entities.EntityProperties-Web|Web} * entity's HTML EventBridge script object to exchange messages with the web page script. - *

Alternatively, you can use {@link Entities.emitScriptEvent} and {@link Entities.webEventReceived} to exchange + *

To send a message from an Interface script to a Web entity over its event bridge:

+ *
var entityObject = Entities.getEntityObject(entityID);
+     * entityObject.emitScriptEvent(message);
+ *

To receive a message from a Web entity over its event bridge in an Interface script:

+ *
var entityObject = Entities.getentityObject(entityID);
+     * entityObject.webEventReceived.connect(function(message) {
+     *     ...
+     * };
+ *

Alternatively, you can use {@link Entities.emitScriptEvent} and {@link Entities.webEventReceived} to exchange * messages with a Web entity over its event bridge.

* @function Entities.getEntityObject * @param {Uuid} id - The ID of the entity to get the script object for. @@ -459,7 +467,7 @@ public slots: * HELLO * * - *

HELLO

+ *

HELLO

*
ValueDimensionsDescription
"Dodecahedron"3D
"Hexagon"3DA hexagonal prism.
"Icosahedron"3D
"Line"1DA line oriented in 3D.
"Octagon"3DAn octagonal prism.
"Octahedron"3D
"Quad"2DA square oriented in 3D.
Add an overlay in front of your avatar then change its color.Create two overlays in front of your avatar then change their colors.Create an object in front of your avatar then get and report its type.Create an overlay in front of your avatar then get and report its type.Receive "hello" messages from a web3d overlay.Exchange messages with a "web3d" overlay.Create an overlay in front of your avatar then report its alpha property value.Create an overlay in front of your avatar then report some of its properties.Create two cube overlays in front of your avatar then get some of their properties.Create a cube overlay in front of your avatar. Report 3D overlay intersection details for mouse * clicks.Create two cube entities in front of your avatar then search for entities near your avatar.Create two overlays in front of your avatar then search for overlays near your avatar.Create an image overlay and report whether its image is loaded after 1s.Calculate the size of "hello" in a 3D text entity.Create a 2D rectangle overlay plus a 3D cube overlay and generate mousePressOnOverlay events for the 2D - * overlay.Create a 2D rectangle overlay plus a 3D cube overlay and generate mousePressOnOverlay events for the + * 2D overlay.Create an overlay then delete it after 1s.