diff --git a/android/apps/questInterface/src/main/AndroidManifest.xml b/android/apps/questInterface/src/main/AndroidManifest.xml index a5de47bdce..27cc18072b 100644 --- a/android/apps/questInterface/src/main/AndroidManifest.xml +++ b/android/apps/questInterface/src/main/AndroidManifest.xml @@ -15,6 +15,7 @@ + setHasScriptedBlendshapes(true); scriptedAvatar->setHasProceduralEyeFaceMovement(false); scriptedAvatar->setHasProceduralBlinkFaceMovement(false); scriptedAvatar->setHasAudioEnabledFaceMovement(false); @@ -406,6 +407,7 @@ void Agent::executeScript() { scriptedAvatar->clearRecordingBasis(); // restore procedural blendshape movement + scriptedAvatar->setHasScriptedBlendshapes(false); scriptedAvatar->setHasProceduralEyeFaceMovement(true); scriptedAvatar->setHasProceduralBlinkFaceMovement(true); scriptedAvatar->setHasAudioEnabledFaceMovement(true); diff --git a/assignment-client/src/audio/AudioMixerSlave.cpp b/assignment-client/src/audio/AudioMixerSlave.cpp index e5e9f89984..204095ab94 100644 --- a/assignment-client/src/audio/AudioMixerSlave.cpp +++ b/assignment-client/src/audio/AudioMixerSlave.cpp @@ -782,7 +782,7 @@ float computeGain(float masterAvatarGain, gain *= std::max(1.0f - d / (distanceLimit - ATTN_DISTANCE_REF), 0.0f); gain = std::min(gain, ATTN_GAIN_MAX); - } else { + } else if (attenuationPerDoublingInDistance < 1.0f) { // translate a positive zone setting to gain per log2(distance) const float MIN_ATTENUATION_COEFFICIENT = 0.001f; // -60dB per log2(distance) float g = glm::clamp(1.0f - attenuationPerDoublingInDistance, MIN_ATTENUATION_COEFFICIENT, 1.0f); @@ -792,6 +792,10 @@ float computeGain(float masterAvatarGain, float d = (1.0f / ATTN_DISTANCE_REF) * std::max(distance, HRTF_NEARFIELD_MIN); gain *= fastExp2f(fastLog2f(g) * fastLog2f(d)); gain = std::min(gain, ATTN_GAIN_MAX); + + } else { + // translate a zone setting of 1.0 be silent at any distance + gain = 0.0f; } return gain; diff --git a/cmake/init.cmake b/cmake/init.cmake index 3f632b30f8..aac350ce0b 100644 --- a/cmake/init.cmake +++ b/cmake/init.cmake @@ -58,3 +58,7 @@ if (ANDROID) list(APPEND EXTERNAL_ARGS -DANDROID_TOOLCHAIN=${ANDROID_TOOLCHAIN}) list(APPEND EXTERNAL_ARGS -DANDROID_STL=${ANDROID_STL}) endif () + +if (APPLE) + set(CMAKE_XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS "--deep") +endif() \ No newline at end of file diff --git a/interface/resources/avatar/animations/settle_to_idle.fbx b/interface/resources/avatar/animations/settle_to_idle.fbx new file mode 100644 index 0000000000..7b801d2c54 Binary files /dev/null and b/interface/resources/avatar/animations/settle_to_idle.fbx differ diff --git a/interface/resources/avatar/animations/settle_to_idle02.fbx b/interface/resources/avatar/animations/settle_to_idle02.fbx new file mode 100644 index 0000000000..be7429091d Binary files /dev/null and b/interface/resources/avatar/animations/settle_to_idle02.fbx differ diff --git a/interface/resources/avatar/animations/settle_to_idle03.fbx b/interface/resources/avatar/animations/settle_to_idle03.fbx new file mode 100644 index 0000000000..e7b48309bb Binary files /dev/null and b/interface/resources/avatar/animations/settle_to_idle03.fbx differ diff --git a/interface/resources/avatar/animations/settle_to_idle04.fbx b/interface/resources/avatar/animations/settle_to_idle04.fbx new file mode 100644 index 0000000000..cc31a240cb Binary files /dev/null and b/interface/resources/avatar/animations/settle_to_idle04.fbx differ diff --git a/interface/resources/avatar/animations/settle_to_idle_small.fbx b/interface/resources/avatar/animations/settle_to_idle_small.fbx index 9161a95d95..21e2ee8478 100644 Binary files a/interface/resources/avatar/animations/settle_to_idle_small.fbx and b/interface/resources/avatar/animations/settle_to_idle_small.fbx differ diff --git a/interface/resources/avatar/animations/sitting_idle04.fbx b/interface/resources/avatar/animations/sitting_idle04.fbx index 7012481b2a..7967627daf 100644 Binary files a/interface/resources/avatar/animations/sitting_idle04.fbx and b/interface/resources/avatar/animations/sitting_idle04.fbx differ diff --git a/interface/resources/avatar/animations/sitting_idle05.fbx b/interface/resources/avatar/animations/sitting_idle05.fbx index 1b89d26f15..bef1e3f73b 100644 Binary files a/interface/resources/avatar/animations/sitting_idle05.fbx and b/interface/resources/avatar/animations/sitting_idle05.fbx differ diff --git a/interface/resources/avatar/animations/sitting_idle_once_leanforward.fbx b/interface/resources/avatar/animations/sitting_idle_once_leanforward.fbx index 75a4603335..66be22f4c4 100644 Binary files a/interface/resources/avatar/animations/sitting_idle_once_leanforward.fbx and b/interface/resources/avatar/animations/sitting_idle_once_leanforward.fbx differ diff --git a/interface/resources/avatar/animations/sitting_idle_once_lookfidget.fbx b/interface/resources/avatar/animations/sitting_idle_once_lookfidget.fbx index b3ab378c26..ce0f4861cc 100644 Binary files a/interface/resources/avatar/animations/sitting_idle_once_lookfidget.fbx and b/interface/resources/avatar/animations/sitting_idle_once_lookfidget.fbx differ diff --git a/interface/resources/avatar/animations/sitting_idle_once_shakelegs.fbx b/interface/resources/avatar/animations/sitting_idle_once_shakelegs.fbx index a020e20044..2a6db1cf3f 100644 Binary files a/interface/resources/avatar/animations/sitting_idle_once_shakelegs.fbx and b/interface/resources/avatar/animations/sitting_idle_once_shakelegs.fbx differ diff --git a/interface/resources/avatar/animations/sitting_idle_once_shiftweight.fbx b/interface/resources/avatar/animations/sitting_idle_once_shiftweight.fbx index 90d2bd220b..9016403b96 100644 Binary files a/interface/resources/avatar/animations/sitting_idle_once_shiftweight.fbx and b/interface/resources/avatar/animations/sitting_idle_once_shiftweight.fbx differ diff --git a/interface/resources/avatar/avatar-animation.json b/interface/resources/avatar/avatar-animation.json index cfcf1cff73..9c417be90b 100644 --- a/interface/resources/avatar/avatar-animation.json +++ b/interface/resources/avatar/avatar-animation.json @@ -4804,16 +4804,117 @@ }, { "children": [ + { + "children": [ + ], + "data": { + "endFrame": 59, + "loopFlag": false, + "startFrame": 1, + "timeScale": 1, + "url": "qrc:///avatar/animations/settle_to_idle.fbx" + }, + "id": "idleSettle01", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "blendType": "", + "endFrame": 40, + "loopFlag": false, + "startFrame": 1, + "timeScale": 1, + "url": "qrc:///avatar/animations/settle_to_idle02.fbx" + }, + "id": "idleSettle02", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 60, + "loopFlag": false, + "startFrame": 1, + "timeScale": 1, + "url": "qrc:///avatar/animations/settle_to_idle03.fbx" + }, + "id": "idleSettle03", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 82, + "loopFlag": false, + "startFrame": 1, + "timeScale": 1, + "url": "qrc:///avatar/animations/settle_to_idle04.fbx" + }, + "id": "idleSettle04", + "type": "clip" + } ], "data": { + "currentState": "idleSettle01", "endFrame": 59, "loopFlag": false, + "randomSwitchTimeMin": 1, "startFrame": 1, + "states": [ + { + "easingType": "easeInOutQuad", + "id": "idleSettle01", + "interpDuration": 1, + "interpTarget": 1, + "interpType": "evaluateBoth", + "priority": 1, + "resume": false, + "transitions": [ + ] + }, + { + "easingType": "easeInOutQuad", + "id": "idleSettle02", + "interpDuration": 1, + "interpTarget": 1, + "interpType": "evaluateBoth", + "priority": 1, + "resume": false, + "transitions": [ + ] + }, + { + "easingType": "easeInOutQuad", + "id": "idleSettle03", + "interpDuration": 1, + "interpTarget": 1, + "interpType": "evaluateBoth", + "priority": 1, + "resume": false, + "transitions": [ + ] + }, + { + "easingType": "easeInOutQuad", + "id": "idleSettle04", + "interpDuration": 1, + "interpTarget": 1, + "interpType": "evaluateBoth", + "priority": 1, + "resume": false, + "transitions": [ + ] + } + ], "timeScale": 1, - "url": "qrc:///avatar/animations/settle_to_idle_small.fbx" + "url": "qrc:///avatar/animations/settle_to_idle.fbx" }, "id": "idleSettle", - "type": "clip" + "type": "randomSwitchStateMachine" }, { "children": [ @@ -5346,6 +5447,19 @@ }, "id": "LANDRUN", "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 40, + "loopFlag": false, + "startFrame": 1, + "timeScale": 1, + "url": "qrc:///avatar/animations/settle_to_idle_small.fbx" + }, + "id": "idleSettleSmall", + "type": "clip" } ], "data": { @@ -5371,7 +5485,7 @@ { "easingType": "easeInOutQuad", "id": "idle", - "interpDuration": 15, + "interpDuration": 20, "interpTarget": 20, "interpType": "evaluateBoth", "transitions": [ @@ -5503,13 +5617,114 @@ { "easingType": "easeInOutQuad", "id": "idleSettle", - "interpDuration": 13, - "interpTarget": 14, + "interpDuration": 15, + "interpTarget": 15, "interpType": "snapshotPrev", "transitions": [ { "state": "idle", - "var": "idleSettleOnDone" + "var": "idleSettle01OnDone" + }, + { + "state": "idle", + "var": "idleSettle02OnDone" + }, + { + "state": "idle", + "var": "idleSettle03OnDone" + }, + { + "state": "idle", + "var": "idleSettle04OnDone" + }, + { + "state": "idle", + "var": "reactionPositiveTrigger" + }, + { + "state": "idle", + "var": "reactionNegativeTrigger" + }, + { + "state": "idle", + "var": "reactionRaiseHandEnabled" + }, + { + "state": "idle", + "var": "reactionApplaudEnabled" + }, + { + "state": "idle", + "var": "reactionPointEnabled" + }, + { + "state": "WALKFWD", + "var": "isInputForward" + }, + { + "state": "WALKBWD", + "var": "isInputBackward" + }, + { + "state": "STRAFERIGHT", + "var": "isInputRight" + }, + { + "state": "STRAFELEFT", + "var": "isInputLeft" + }, + { + "state": "strafeRightHmd", + "var": "isMovingRightHmd" + }, + { + "state": "strafeLeftHmd", + "var": "isMovingLeftHmd" + }, + { + "state": "turnRight", + "var": "isTurningRight" + }, + { + "state": "turnLeft", + "var": "isTurningLeft" + }, + { + "state": "fly", + "var": "isFlying" + }, + { + "state": "takeoffStand", + "var": "isTakeoffStand" + }, + { + "state": "TAKEOFFRUN", + "var": "isTakeoffRun" + }, + { + "state": "inAirStand", + "var": "isInAirStand" + }, + { + "state": "INAIRRUN", + "var": "isInAirRun" + }, + { + "state": "seated", + "var": "isSeated" + } + ] + }, + { + "easingType": "easeInOutQuad", + "id": "idleSettleSmall", + "interpDuration": 10, + "interpTarget": 10, + "interpType": "snapshotPrev", + "transitions": [ + { + "state": "idle", + "var": "idleSettleSmallOnDone" }, { "state": "idle", @@ -5595,6 +5810,10 @@ "interpTarget": 35, "interpType": "snapshotPrev", "transitions": [ + { + "state": "idleSettleSmall", + "var": "isNotInputNoMomentum" + }, { "state": "idleSettle", "var": "isNotInputSlow" @@ -5659,6 +5878,10 @@ "interpTarget": 35, "interpType": "snapshotPrev", "transitions": [ + { + "state": "idleSettleSmall", + "var": "isNotInputNoMomentum" + }, { "state": "idleSettle", "var": "isNotInputSlow" @@ -5723,6 +5946,10 @@ "interpTarget": 25, "interpType": "snapshotPrev", "transitions": [ + { + "state": "idleSettleSmall", + "var": "isNotInputNoMomentum" + }, { "state": "idleSettle", "var": "isNotInputSlow" @@ -5787,6 +6014,10 @@ "interpTarget": 25, "interpType": "snapshotPrev", "transitions": [ + { + "state": "idleSettleSmall", + "var": "isNotInputNoMomentum" + }, { "state": "idleSettle", "var": "isNotInputSlow" diff --git a/interface/resources/controllers/standard.json b/interface/resources/controllers/standard.json index b6cb4e3e27..aa995c6ecb 100644 --- a/interface/resources/controllers/standard.json +++ b/interface/resources/controllers/standard.json @@ -201,8 +201,6 @@ { "from": "Standard.LipsStretch_R", "to": "Actions.LipsStretch_R" }, { "from": "Standard.LipsUpperClose", "to": "Actions.LipsUpperClose" }, { "from": "Standard.LipsLowerClose", "to": "Actions.LipsLowerClose" }, - { "from": "Standard.LipsUpperOpen", "to": "Actions.LipsUpperOpen" }, - { "from": "Standard.LipsLowerOpen", "to": "Actions.LipsLowerOpen" }, { "from": "Standard.LipsFunnel", "to": "Actions.LipsFunnel" }, { "from": "Standard.LipsPucker", "to": "Actions.LipsPucker" }, { "from": "Standard.Puff", "to": "Actions.Puff" }, diff --git a/interface/resources/controllers/standard_nomovement.json b/interface/resources/controllers/standard_nomovement.json index 04c0d2f329..9e1437d2e8 100644 --- a/interface/resources/controllers/standard_nomovement.json +++ b/interface/resources/controllers/standard_nomovement.json @@ -96,8 +96,6 @@ { "from": "Standard.LipsStretch_R", "to": "Actions.LipsStretch_R" }, { "from": "Standard.LipsUpperClose", "to": "Actions.LipsUpperClose" }, { "from": "Standard.LipsLowerClose", "to": "Actions.LipsLowerClose" }, - { "from": "Standard.LipsUpperOpen", "to": "Actions.LipsUpperOpen" }, - { "from": "Standard.LipsLowerOpen", "to": "Actions.LipsLowerOpen" }, { "from": "Standard.LipsFunnel", "to": "Actions.LipsFunnel" }, { "from": "Standard.LipsPucker", "to": "Actions.LipsPucker" }, { "from": "Standard.Puff", "to": "Actions.Puff" }, diff --git a/interface/resources/qml/hifi/simplifiedUI/avatarApp/AvatarApp.qml b/interface/resources/qml/hifi/simplifiedUI/avatarApp/AvatarApp.qml index 7dbadc59f4..5ca2227dfb 100644 --- a/interface/resources/qml/hifi/simplifiedUI/avatarApp/AvatarApp.qml +++ b/interface/resources/qml/hifi/simplifiedUI/avatarApp/AvatarApp.qml @@ -106,33 +106,6 @@ Rectangle { } } - Image { - id: homeButton - source: "images/homeIcon.svg" - opacity: homeButtonMouseArea.containsMouse ? 1.0 : 0.7 - anchors.top: parent.top - anchors.topMargin: 15 - anchors.right: parent.right - anchors.rightMargin: 24 - width: 14 - height: 13 - - MouseArea { - id: homeButtonMouseArea - anchors.fill: parent - hoverEnabled: true - onEntered: { - Tablet.playSound(TabletEnums.ButtonHover); - } - onClicked: { - Tablet.playSound(TabletEnums.ButtonClick); - // Can't use `Window.location` in QML, so just use what setting `Window.location` actually calls under the hood: - // AddressManager.handleLookupString(). - AddressManager.handleLookupString(LocationBookmarks.getAddress("hqhome")); - } - } - } - AvatarAppComponents.DisplayNameHeader { id: displayNameHeader previewUrl: root.avatarPreviewUrl diff --git a/interface/src/AvatarBookmarks.cpp b/interface/src/AvatarBookmarks.cpp index 2ebe769bec..6f6a93ff19 100644 --- a/interface/src/AvatarBookmarks.cpp +++ b/interface/src/AvatarBookmarks.cpp @@ -232,12 +232,6 @@ void AvatarBookmarks::loadBookmark(const QString& bookmarkName) { emit bookmarkLoaded(bookmarkName); }); - std::shared_ptr connection2 = std::make_shared(); - *connection2 = connect(myAvatar.get(), &MyAvatar::onLoadFailed, [this, bookmarkName, connection2]() { - qCDebug(interfaceapp) << "Failed to load avatar bookmark" << bookmarkName; - QObject::disconnect(*connection2); - }); - qCDebug(interfaceapp) << "Start loading avatar bookmark" << bookmarkName; const QString& avatarUrl = bookmark.value(ENTRY_AVATAR_URL, "").toString(); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 7c730e865b..2522d0e4c6 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -3452,7 +3452,7 @@ void MyAvatar::updateOrientation(float deltaTime) { bool isCameraYawing = getDriveKey(DELTA_YAW) + getDriveKey(STEP_YAW) + getDriveKey(YAW) != 0.0f; bool isRotatingWhileSeated = !isCameraYawing && isMovingSideways && _characterController.getSeated(); glm::quat previousOrientation = getWorldOrientation(); - + glm::quat previousYaw = _lookAtYaw; if (!computeLookAt) { setWorldOrientation(getWorldOrientation() * glm::quat(glm::radians(glm::vec3(0.0f, totalBodyYaw, 0.0f)))); _lookAtCameraTarget = eyesPosition + getWorldOrientation() * Vectors::FRONT; @@ -3462,6 +3462,7 @@ void MyAvatar::updateOrientation(float deltaTime) { // Compute new look at vectors if (totalBodyYaw != 0.0f) { _lookAtYaw = _lookAtYaw * glm::quat(glm::radians(glm::vec3(0.0f, totalBodyYaw, 0.0f))); + _lookAtYawSpeed = glm::degrees(glm::angle(_lookAtYaw * glm::inverse(previousYaw))) / deltaTime; } float pitchIncrement = getDriveKey(PITCH) * _pitchSpeed * deltaTime + getDriveKey(DELTA_PITCH) * _pitchSpeed / PITCH_SPEED_DEFAULT; @@ -3482,7 +3483,19 @@ void MyAvatar::updateOrientation(float deltaTime) { const float REORIENT_FORWARD_BLEND = 0.25f; const float REORIENT_TURN_BLEND = 0.03f; const float DIAGONAL_TURN_BLEND = 0.1f; + const float AVATAR_TURNS_TO_CAM_IN_SPEED = 130.0f; // Degrees per second + const float AVATAR_TURNS_TO_CAM_OUT_SPEED = 720.0f; // Degrees per second + float blend = (_shouldTurnToFaceCamera ? REORIENT_TURN_BLEND : REORIENT_FORWARD_BLEND) * timeScale; + if (mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT && _lookAtYawSpeed > AVATAR_TURNS_TO_CAM_IN_SPEED) { + // When the camera is rotating fast we should accelerate the avatar's face forward speed + // to avoid showing the cauterized head; + float cameraYawSpeed = glm::min(_lookAtYawSpeed, AVATAR_TURNS_TO_CAM_OUT_SPEED); + float blendFactor = REORIENT_TURN_BLEND + REORIENT_FORWARD_BLEND * ((cameraYawSpeed - AVATAR_TURNS_TO_CAM_IN_SPEED) / + (AVATAR_TURNS_TO_CAM_OUT_SPEED - AVATAR_TURNS_TO_CAM_IN_SPEED)); + blend = glm::min(1.0f, blendFactor * timeScale); + } + if (blend > 1.0f) { blend = 1.0f; } @@ -3573,7 +3586,6 @@ void MyAvatar::updateOrientation(float deltaTime) { if (frontBackDot < limitAngle) { if (frontBackDot < 0.0f) { ajustedYawVector = (leftRightDot < 0.0f ? -avatarVectorRight : avatarVectorRight); - cameraVector = (ajustedYawVector * _lookAtPitch) * Vectors::FRONT; } if (!isRotatingWhileSeated) { if (frontBackDot < triggerAngle) { @@ -6762,19 +6774,18 @@ glm::vec3 MyAvatar::getLookAtPivotPoint() { glm::vec3 MyAvatar::getCameraEyesPosition(float deltaTime) { glm::vec3 defaultEyesPosition = getLookAtPivotPoint(); - if (isFlying()) { - return defaultEyesPosition; - } + glm::vec3 avatarFrontVector = getWorldOrientation() * Vectors::FRONT; glm::vec3 avatarUpVector = getWorldOrientation() * Vectors::UP; // Compute the offset between the default and real eye positions. glm::vec3 defaultEyesToEyesVector = getHead()->getEyePosition() - defaultEyesPosition; - float FRONT_OFFSET_IDLE_MULTIPLIER = 2.5f; - float FRONT_OFFSET_JUMP_MULTIPLIER = 1.5f; + const float FRONT_OFFSET_IDLE_MULTIPLIER = 3.5f; + const float FRONT_OFFSET_JUMP_MULTIPLIER = 1.5f; float frontOffset = FRONT_OFFSET_IDLE_MULTIPLIER * glm::length(defaultEyesPosition - getDefaultEyePosition()); - - // Looking down will aproximate move the camera forward to meet the real eye position + + // Looking down will move the camera forward to meet the real eye position float mixAlpha = glm::dot(_lookAtPitch * Vectors::FRONT, -avatarUpVector); + bool isLanding = false; // When jumping the camera should follow the real eye on the Y coordenate float upOffset = 0.0f; diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 4d0dea61c1..5a59e6129a 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -2693,6 +2693,7 @@ private: const float MAX_LOOK_AT_TIME_SCRIPT_CONTROL = 2.0f; glm::quat _lookAtPitch; glm::quat _lookAtYaw; + float _lookAtYawSpeed { 0.0f }; glm::vec3 _lookAtCameraTarget; glm::vec3 _lookAtScriptTarget; bool _headLookAtActive { false }; diff --git a/interface/src/avatar/MyHead.cpp b/interface/src/avatar/MyHead.cpp index a0e70a3049..1b88a518c8 100644 --- a/interface/src/avatar/MyHead.cpp +++ b/interface/src/avatar/MyHead.cpp @@ -57,8 +57,6 @@ static controller::Action blendshapeActions[] = { controller::Action::LIPSSTRETCH_R, controller::Action::LIPSUPPERCLOSE, controller::Action::LIPSLOWERCLOSE, - controller::Action::LIPSUPPEROPEN, - controller::Action::LIPSLOWEROPEN, controller::Action::LIPSFUNNEL, controller::Action::LIPSPUCKER, controller::Action::PUFF, diff --git a/interface/src/scripting/WindowScriptingInterface.h b/interface/src/scripting/WindowScriptingInterface.h index 341b012c2d..f3e9dea45f 100644 --- a/interface/src/scripting/WindowScriptingInterface.h +++ b/interface/src/scripting/WindowScriptingInterface.h @@ -206,7 +206,7 @@ public slots: void browseAsync(const QString& title = "", const QString& directory = "", const QString& nameFilter = ""); /**jsdoc - * Prompts the user to specify the path and name of a file to save to. Displays a model dialog that navigates the directory + * Prompts the user to specify the path and name of a file to save to. Displays a modal dialog that navigates the directory * tree and allows the user to type in a file name. * @function Window.save * @param {string} [title=""] - The title to display at the top of the dialog. @@ -222,7 +222,7 @@ public slots: QScriptValue save(const QString& title = "", const QString& directory = "", const QString& nameFilter = ""); /**jsdoc - * Prompts the user to specify the path and name of a file to save to. Displays a non-model dialog that navigates the + * Prompts the user to specify the path and name of a file to save to. Displays a non-modal dialog that navigates the * directory tree and allows the user to type in a file name. A {@link Window.saveFileChanged|saveFileChanged} signal is * emitted when a file is specified; no signal is emitted if the user cancels the dialog. * @function Window.saveAsync diff --git a/libraries/animation/src/AnimBlendDirectional.cpp b/libraries/animation/src/AnimBlendDirectional.cpp index 4e7c67f276..4cc67683da 100644 --- a/libraries/animation/src/AnimBlendDirectional.cpp +++ b/libraries/animation/src/AnimBlendDirectional.cpp @@ -96,7 +96,9 @@ const AnimPoseVec& AnimBlendDirectional::evaluate(const AnimVariantMap& animVars } } _poses.resize(minSize); - blend4(minSize, &poseVecs[0][0], &poseVecs[1][0], &poseVecs[2][0], &poseVecs[3][0], &alphas[0], &_poses[0]); + if (minSize > 0) { + blend4(minSize, &poseVecs[0][0], &poseVecs[1][0], &poseVecs[2][0], &poseVecs[3][0], &alphas[0], &_poses[0]); + } // animation stack debug stats for (int i = 0; i < 9; i++) { diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index fc1885ea2b..fd8bdb1a0b 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1171,6 +1171,7 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos _desiredStateAge += deltaTime; + if (_state == RigRole::Move) { glm::vec3 horizontalVel = localVel - glm::vec3(0.0f, localVel.y, 0.0f); if (glm::length(horizontalVel) > MOVE_ENTER_SPEED_THRESHOLD) { @@ -1437,17 +1438,37 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos //stategraph vars based on input const float INPUT_DEADZONE_THRESHOLD = 0.05f; const float SLOW_SPEED_THRESHOLD = 1.5f; + const float HAS_MOMENTUM_THRESHOLD = 2.2f; + const float RESET_MOMENTUM_THRESHOLD = 0.05f; if (fabsf(_previousControllerParameters.inputX) <= INPUT_DEADZONE_THRESHOLD && fabsf(_previousControllerParameters.inputZ) <= INPUT_DEADZONE_THRESHOLD) { // no WASD input if (fabsf(forwardSpeed) <= SLOW_SPEED_THRESHOLD && fabsf(lateralSpeed) <= SLOW_SPEED_THRESHOLD) { + + //reset this when stopped + if (fabsf(forwardSpeed) <= RESET_MOMENTUM_THRESHOLD && + fabsf(lateralSpeed) <= RESET_MOMENTUM_THRESHOLD) { + _isMovingWithMomentum = false; + } + + _animVars.set("isInputForward", false); _animVars.set("isInputBackward", false); _animVars.set("isInputRight", false); _animVars.set("isInputLeft", false); - _animVars.set("isNotInput", true); - _animVars.set("isNotInputSlow", true); + + // directly reflects input + _animVars.set("isNotInput", true); + + // no input + speed drops to SLOW_SPEED_THRESHOLD + // (don't transition run->idle - slow to walk first) + _animVars.set("isNotInputSlow", _isMovingWithMomentum); + + // no input + speed didn't get above HAS_MOMENTUM_THRESHOLD since last idle + // (brief inputs and movement adjustments) + _animVars.set("isNotInputNoMomentum", !_isMovingWithMomentum); + } else { _animVars.set("isInputForward", false); @@ -1456,8 +1477,13 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos _animVars.set("isInputLeft", false); _animVars.set("isNotInput", true); _animVars.set("isNotInputSlow", false); + _animVars.set("isNotInputNoMomentum", false); } } else if (fabsf(_previousControllerParameters.inputZ) >= fabsf(_previousControllerParameters.inputX)) { + if (fabsf(forwardSpeed) > HAS_MOMENTUM_THRESHOLD) { + _isMovingWithMomentum = true; + } + if (_previousControllerParameters.inputZ > 0.0f) { // forward _animVars.set("isInputForward", true); @@ -1466,6 +1492,7 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos _animVars.set("isInputLeft", false); _animVars.set("isNotInput", false); _animVars.set("isNotInputSlow", false); + _animVars.set("isNotInputNoMomentum", false); } else { // backward _animVars.set("isInputForward", false); @@ -1474,8 +1501,13 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos _animVars.set("isInputLeft", false); _animVars.set("isNotInput", false); _animVars.set("isNotInputSlow", false); + _animVars.set("isNotInputNoMomentum", false); } } else { + if (fabsf(lateralSpeed) > HAS_MOMENTUM_THRESHOLD) { + _isMovingWithMomentum = true; + } + if (_previousControllerParameters.inputX > 0.0f) { // right _animVars.set("isInputForward", false); @@ -1484,6 +1516,7 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos _animVars.set("isInputLeft", false); _animVars.set("isNotInput", false); _animVars.set("isNotInputSlow", false); + _animVars.set("isNotInputNoMomentum", false); } else { // left _animVars.set("isInputForward", false); @@ -1492,6 +1525,7 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos _animVars.set("isInputLeft", true); _animVars.set("isNotInput", false); _animVars.set("isNotInputSlow", false); + _animVars.set("isNotInputNoMomentum", false); } } diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index b2b9ecd5b4..60a2602316 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -330,6 +330,7 @@ protected: glm::vec3 _lastForward; glm::vec3 _lastPosition; glm::vec3 _lastVelocity; + bool _isMovingWithMomentum{ false }; QUrl _animGraphURL; std::shared_ptr _animNode; diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 612493db2e..b26c00e82b 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -111,11 +111,17 @@ QList getAvailableDevices(QAudio::Mode mode, const QString& } if (defaultDesktopDevice.getDevice().isNull()) { - qCDebug(audioclient) << __FUNCTION__ << "Default device not found in list:" << defDeviceName - << "Setting Default to: " << devices.first().deviceName(); - defaultDesktopDevice = HifiAudioDeviceInfo(devices.first(), true, mode, HifiAudioDeviceInfo::desktop); + if (devices.size() > 0) { + qCDebug(audioclient) << __FUNCTION__ << "Default device not found in list:" << defDeviceName + << "Setting Default to: " << devices.first().deviceName(); + newDevices.push_front(HifiAudioDeviceInfo(devices.first(), true, mode, HifiAudioDeviceInfo::desktop)); + } else { + //current audio list is empty for some reason. + qCDebug(audioclient) << __FUNCTION__ << "Default device not found in list no alternative selection available"; + } + } else { + newDevices.push_front(defaultDesktopDevice); } - newDevices.push_front(defaultDesktopDevice); if (!hmdName.isNull()) { HifiAudioDeviceInfo hmdDevice; diff --git a/libraries/audio/src/AudioHRTF.cpp b/libraries/audio/src/AudioHRTF.cpp index e5e32781b0..be7fecb450 100644 --- a/libraries/audio/src/AudioHRTF.cpp +++ b/libraries/audio/src/AudioHRTF.cpp @@ -25,13 +25,6 @@ #define ALIGN32 #endif -#ifndef MAX -#define MAX(a,b) (((a) > (b)) ? (a) : (b)) -#endif -#ifndef MIN -#define MIN(a,b) (((a) < (b)) ? (a) : (b)) -#endif - // // Equal-gain crossfade // @@ -114,106 +107,49 @@ static const float nearFieldTable[NNEARFIELD][3] = { // { b0, b1, a1 } }; // -// Model the frequency-dependent attenuation of sound propogation in air. +// Parametric lowpass filter to model sound propogation or occlusion. // -// Fit using linear regression to a log-log model of lowpass cutoff frequency vs distance, -// loosely based on data from Handbook of Acoustics. Only the onset of significant -// attenuation is modelled, not the filter slope. +// lpf = 0.0 -> -3dB @ 50kHz +// lpf = 0.5 -> -3dB @ 1kHz +// lpf = 1.0 -> -3dB @ 20Hz // -// 1m -> -3dB @ 55kHz -// 10m -> -3dB @ 12kHz -// 100m -> -3dB @ 2.5kHz -// 1km -> -3dB @ 0.6kHz -// 10km -> -3dB @ 0.1kHz -// -static const int NLOWPASS = 64; -static const float lowpassTable[NLOWPASS][5] = { // { b0, b1, b2, a1, a2 } - // distance = 1 - { 0.999772371f, 1.399489756f, 0.454495527f, 1.399458985f, 0.454298669f }, - { 0.999631480f, 1.357609808f, 0.425210203f, 1.357549905f, 0.424901586f }, - { 0.999405154f, 1.311503050f, 0.394349994f, 1.311386830f, 0.393871368f }, - { 0.999042876f, 1.260674595f, 0.361869089f, 1.260450057f, 0.361136504f }, - // distance = 2 - { 0.998465222f, 1.204646525f, 0.327757118f, 1.204214978f, 0.326653886f }, - { 0.997548106f, 1.143019308f, 0.292064663f, 1.142195387f, 0.290436690f }, - { 0.996099269f, 1.075569152f, 0.254941286f, 1.074009405f, 0.252600301f }, - { 0.993824292f, 1.002389610f, 0.216688640f, 0.999469185f, 0.213433357f }, - // distance = 4 - { 0.990280170f, 0.924075266f, 0.177827150f, 0.918684864f, 0.173497723f }, - { 0.984818279f, 0.841917936f, 0.139164195f, 0.832151968f, 0.133748443f }, - { 0.976528670f, 0.758036513f, 0.101832398f, 0.740761682f, 0.095635899f }, - { 0.964216485f, 0.675305244f, 0.067243474f, 0.645654855f, 0.061110348f }, - // distance = 8 - { 0.946463038f, 0.596943020f, 0.036899688f, 0.547879974f, 0.032425772f }, - { 0.921823868f, 0.525770189f, 0.012060451f, 0.447952111f, 0.011702396f }, - { 0.890470015f, 0.463334299f, -0.001227816f, 0.347276405f, 0.005300092f }, - { 0.851335343f, 0.407521164f, -0.009353968f, 0.241900234f, 0.007602305f }, - // distance = 16 - { 0.804237360f, 0.358139558f, -0.014293332f, 0.130934213f, 0.017149373f }, - { 0.750073259f, 0.314581568f, -0.016625381f, 0.014505388f, 0.033524057f }, - { 0.690412072f, 0.275936128f, -0.017054561f, -0.106682490f, 0.055976129f }, - { 0.627245545f, 0.241342015f, -0.016246850f, -0.231302564f, 0.083643275f }, - // distance = 32 - { 0.562700627f, 0.210158533f, -0.014740899f, -0.357562697f, 0.115680957f }, - { 0.498787849f, 0.181982455f, -0.012925406f, -0.483461730f, 0.151306628f }, - { 0.437224055f, 0.156585449f, -0.011055180f, -0.607042210f, 0.189796534f }, - { 0.379336998f, 0.133834032f, -0.009281617f, -0.726580065f, 0.230469477f }, - // distance = 64 - { 0.326040627f, 0.113624970f, -0.007683443f, -0.840693542f, 0.272675696f }, - { 0.277861727f, 0.095845793f, -0.006291936f, -0.948380091f, 0.315795676f }, - { 0.234997480f, 0.080357656f, -0.005109519f, -1.049001190f, 0.359246807f }, - { 0.197386484f, 0.066993521f, -0.004122547f, -1.142236313f, 0.402493771f }, - // distance = 128 - { 0.164780457f, 0.055564709f, -0.003309645f, -1.228023442f, 0.445058962f }, - { 0.136808677f, 0.045870650f, -0.002646850f, -1.306498037f, 0.486530514f }, - { 0.113031290f, 0.037708627f, -0.002110591f, -1.377937457f, 0.526566783f }, - { 0.092980475f, 0.030881892f, -0.001679255f, -1.442713983f, 0.564897095f }, - // distance = 256 - { 0.076190239f, 0.025205585f, -0.001333863f, -1.501257246f, 0.601319206f }, - { 0.062216509f, 0.020510496f, -0.001058229f, -1.554025452f, 0.635694228f }, - { 0.050649464f, 0.016644994f, -0.000838826f, -1.601484205f, 0.667939837f }, - { 0.041120009f, 0.013475547f, -0.000664513f, -1.644091518f, 0.698022561f }, - // distance = 512 - { 0.033302044f, 0.010886252f, -0.000526217f, -1.682287704f, 0.725949783f }, - { 0.026911868f, 0.008777712f, -0.000416605f, -1.716488979f, 0.751761953f }, - { 0.021705773f, 0.007065551f, -0.000329788f, -1.747083800f, 0.775525335f }, - { 0.017476603f, 0.005678758f, -0.000261057f, -1.774431204f, 0.797325509f }, - // distance = 1024 - { 0.014049828f, 0.004558012f, -0.000206658f, -1.798860530f, 0.817261711f }, - { 0.011279504f, 0.003654067f, -0.000163610f, -1.820672082f, 0.835442043f }, - { 0.009044384f, 0.002926264f, -0.000129544f, -1.840138412f, 0.851979516f }, - { 0.007244289f, 0.002341194f, -0.000102586f, -1.857505967f, 0.866988864f }, - // distance = 2048 - { 0.005796846f, 0.001871515f, -0.000081250f, -1.872996926f, 0.880584038f }, - { 0.004634607f, 0.001494933f, -0.000064362f, -1.886811124f, 0.892876302f }, - { 0.003702543f, 0.001193324f, -0.000050993f, -1.899127955f, 0.903972829f }, - { 0.002955900f, 0.000951996f, -0.000040407f, -1.910108223f, 0.913975712f }, - // distance = 4096 - { 0.002358382f, 0.000759068f, -0.000032024f, -1.919895894f, 0.922981321f }, - { 0.001880626f, 0.000604950f, -0.000025383f, -1.928619738f, 0.931079931f }, - { 0.001498926f, 0.000481920f, -0.000020123f, -1.936394836f, 0.938355560f }, - { 0.001194182f, 0.000383767f, -0.000015954f, -1.943323983f, 0.944885977f }, - // distance = 8192 - { 0.000951028f, 0.000305502f, -0.000012651f, -1.949498943f, 0.950742822f }, - { 0.000757125f, 0.000243126f, -0.000010033f, -1.955001608f, 0.955991826f }, - { 0.000602572f, 0.000193434f, -0.000007957f, -1.959905036f, 0.960693085f }, - { 0.000479438f, 0.000153861f, -0.000006312f, -1.964274383f, 0.964901371f }, - // distance = 16384 - { 0.000381374f, 0.000122359f, -0.000005007f, -1.968167752f, 0.968666478f }, - { 0.000303302f, 0.000097288f, -0.000003972f, -1.971636944f, 0.972033562f }, - { 0.000241166f, 0.000077342f, -0.000003151f, -1.974728138f, 0.975043493f }, - { 0.000191726f, 0.000061475f, -0.000002500f, -1.977482493f, 0.977733194f }, - // distance = 32768 - { 0.000152399f, 0.000048857f, -0.000001984f, -1.979936697f, 0.980135969f }, - { 0.000121122f, 0.000038825f, -0.000001574f, -1.982123446f, 0.982281818f }, - { 0.000096252f, 0.000030849f, -0.000001249f, -1.984071877f, 0.984197728f }, - { 0.000076480f, 0.000024509f, -0.000000991f, -1.985807957f, 0.985907955f }, +static const int NLOWPASS = 32; +static const float lowpassTable[NLOWPASS+1][5] = { // { b0, b1, b2, a1, a2 } + { 0.9996582613f, 1.3644521648f, 0.4299107175f, 1.3643981990f, 0.4296229446f }, + { 0.9990601568f, 1.2627213717f, 0.3631477252f, 1.2625024258f, 0.3624268280f }, + { 0.9974547575f, 1.1378303854f, 0.2891398515f, 1.1369629374f, 0.2874620569f }, + { 0.9932384344f, 0.9872078424f, 0.2089943789f, 0.9839050501f, 0.2055356056f }, + { 0.9825457933f, 0.8153687744f, 0.1271135720f, 0.8036320348f, 0.1213961050f }, + { 0.9572356804f, 0.6404312275f, 0.0534129844f, 0.6033230637f, 0.0477568288f }, + { 0.9052878744f, 0.4902779401f, 0.0035032262f, 0.3924772681f, 0.0065917726f }, + { 0.8204774205f, 0.3736089028f, -0.0129974730f, 0.1678426876f, 0.0132461627f }, + { 0.7032096959f, 0.2836328681f, -0.0170877258f, -0.0810811878f, 0.0508360260f }, + { 0.5685067272f, 0.2128349296f, -0.0148937235f, -0.3461942779f, 0.1126422113f }, + { 0.4355093111f, 0.1558974062f, -0.0110025095f, -0.6105302595f, 0.1909344673f }, + { 0.3186188589f, 0.1108581568f, -0.0074653192f, -0.8569688248f, 0.2789805212f }, + { 0.2244962739f, 0.0766060095f, -0.0048289293f, -1.0745081373f, 0.3707814914f }, + { 0.1535044640f, 0.0516447640f, -0.0030384640f, -1.2590370066f, 0.4611477706f }, + { 0.1025113288f, 0.0341204303f, -0.0018818088f, -1.4113207964f, 0.5460707468f }, + { 0.0672016063f, 0.0221823522f, -0.0011552756f, -1.5347007285f, 0.6229294113f }, + { 0.0434202931f, 0.0142393067f, -0.0007060306f, -1.6334567973f, 0.6904103664f }, + { 0.0277383489f, 0.0090500025f, -0.0004305987f, -1.7118804671f, 0.7482382198f }, + { 0.0175636227f, 0.0057072537f, -0.0002624537f, -1.7738404438f, 0.7968488665f }, + { 0.0110441068f, 0.0035773504f, -0.0001599927f, -1.8226329785f, 0.8370944430f }, + { 0.0069069312f, 0.0022316608f, -0.0000975848f, -1.8609764152f, 0.8700174224f }, + { 0.0043012064f, 0.0013870046f, -0.0000595614f, -1.8910688315f, 0.8966974811f }, + { 0.0026696068f, 0.0008595333f, -0.0000363798f, -1.9146662133f, 0.9181589737f }, + { 0.0016526098f, 0.0005314445f, -0.0000222355f, -1.9331608518f, 0.9353226705f }, + { 0.0010209520f, 0.0003280036f, -0.0000135987f, -1.9476515008f, 0.9489868578f }, + { 0.0006297162f, 0.0002021591f, -0.0000083208f, -1.9590027292f, 0.9598262837f }, + { 0.0003879180f, 0.0001244611f, -0.0000050936f, -1.9678935939f, 0.9684008793f }, + { 0.0002387308f, 0.0000765601f, -0.0000031192f, -1.9748568416f, 0.9751690132f }, + { 0.0001468057f, 0.0000470631f, -0.0000019106f, -1.9803101382f, 0.9805020963f }, + { 0.0000902227f, 0.0000289155f, -0.0000011706f, -1.9845807858f, 0.9846987534f }, + { 0.0000554223f, 0.0000177584f, -0.0000007174f, -1.9879252038f, 0.9879976671f }, + { 0.0000340324f, 0.0000109027f, -0.0000004397f, -1.9905442465f, 0.9905887419f }, + { 0.0000208917f, 0.0000066920f, -0.0000002695f, -1.9925952275f, 0.9926225417f }, }; -static const float HALFPI = 1.570796327f; -static const float PI = 3.141592654f; -static const float TWOPI = 6.283185307f; - // // on x86 architecture, assume that SSE2 is present // @@ -811,44 +747,38 @@ static void splitf(float x, int& expn, float& frac) { expn = (bits.i >> IEEE754_MANT_BITS) - IEEE754_EXPN_BIAS; } -static void distanceBiquad(float distance, float& b0, float& b1, float& b2, float& a1, float& a2) { +static void lowpassBiquad(float lpf, float& b0, float& b1, float& b2, float& a1, float& a2) { // - // Computed from a lookup table quantized to distance = 2^(N/4) - // and reconstructed by piecewise linear interpolation. + // Computed from a lookup table and piecewise linear interpolation. // Approximation error < 0.25dB // + float x = lpf * NLOWPASS; - float x = distance; - x = MIN(x, 1<<30); - x *= x; - x *= x; // x = distance^4 - - // split x into e and frac, such that x = 2^(e+0) + frac * (2^(e+1) - 2^(e+0)) - int e; - float frac; - splitf(x, e, frac); + // split x into index and fraction + int i = (int)x; + float frac = x - (float)i; // clamp to table limits - if (e < 0) { - e = 0; + if (i < 0) { + i = 0; frac = 0.0f; } - if (e > NLOWPASS-2) { - e = NLOWPASS-2; + if (i > NLOWPASS-1) { + i = NLOWPASS-1; frac = 1.0f; } assert(frac >= 0.0f); assert(frac <= 1.0f); - assert(e+0 >= 0); - assert(e+1 < NLOWPASS); + assert(i+0 >= 0); + assert(i+1 <= NLOWPASS); // piecewise linear interpolation - b0 = lowpassTable[e+0][0] + frac * (lowpassTable[e+1][0] - lowpassTable[e+0][0]); - b1 = lowpassTable[e+0][1] + frac * (lowpassTable[e+1][1] - lowpassTable[e+0][1]); - b2 = lowpassTable[e+0][2] + frac * (lowpassTable[e+1][2] - lowpassTable[e+0][2]); - a1 = lowpassTable[e+0][3] + frac * (lowpassTable[e+1][3] - lowpassTable[e+0][3]); - a2 = lowpassTable[e+0][4] + frac * (lowpassTable[e+1][4] - lowpassTable[e+0][4]); + b0 = lowpassTable[i+0][0] + frac * (lowpassTable[i+1][0] - lowpassTable[i+0][0]); + b1 = lowpassTable[i+0][1] + frac * (lowpassTable[i+1][1] - lowpassTable[i+0][1]); + b2 = lowpassTable[i+0][2] + frac * (lowpassTable[i+1][2] - lowpassTable[i+0][2]); + a1 = lowpassTable[i+0][3] + frac * (lowpassTable[i+1][3] - lowpassTable[i+0][3]); + a2 = lowpassTable[i+0][4] + frac * (lowpassTable[i+1][4] - lowpassTable[i+0][4]); } // @@ -903,13 +833,13 @@ static void nearFieldGainCorrection(float azimuth, float distance, float& gainL, float d = (HRTF_NEARFIELD_MAX - distance) * (1.0f / (HRTF_NEARFIELD_MAX - HRTF_HEAD_RADIUS)); // angle of incidence at each ear - float angleL = azimuth + HALFPI; - float angleR = azimuth - HALFPI; + float angleL = azimuth + PI_OVER_TWO; + float angleR = azimuth - PI_OVER_TWO; if (angleL > +PI) { - angleL -= TWOPI; + angleL -= TWO_PI; } if (angleR < -PI) { - angleR += TWOPI; + angleR += TWO_PI; } assert(angleL >= -PI); assert(angleL <= +PI); @@ -968,7 +898,7 @@ static void nearFieldFilter(float gain, float& b0, float& b1, float& a1) { static void azimuthToIndex(float azimuth, int& index0, int& index1, float& frac) { // convert from radians to table units - azimuth *= (HRTF_AZIMUTHS / TWOPI); + azimuth *= (HRTF_AZIMUTHS / TWO_PI); if (azimuth < 0.0f) { azimuth += HRTF_AZIMUTHS; @@ -993,15 +923,15 @@ static void azimuthToIndex(float azimuth, int& index0, int& index1, float& frac) // compute new filters for a given azimuth, distance and gain static void setFilters(float firCoef[4][HRTF_TAPS], float bqCoef[5][8], int delay[4], - int index, float azimuth, float distance, float gain, int channel) { + int index, float azimuth, float distance, float gain, float lpf, int channel) { if (azimuth > PI) { - azimuth -= TWOPI; + azimuth -= TWO_PI; } assert(azimuth >= -PI); assert(azimuth <= +PI); - distance = MAX(distance, HRTF_NEARFIELD_MIN); + distance = std::max(distance, HRTF_NEARFIELD_MIN); // compute the azimuth correction at each ear float azimuthL = azimuth; @@ -1109,7 +1039,7 @@ static void setFilters(float firCoef[4][HRTF_TAPS], float bqCoef[5][8], int dela } else { - distanceBiquad(distance, b0, b1, b2, a1, a2); + lowpassBiquad(lpf, b0, b1, b2, a1, a2); bqCoef[0][channel+4] = b0; bqCoef[1][channel+4] = b1; @@ -1125,7 +1055,8 @@ static void setFilters(float firCoef[4][HRTF_TAPS], float bqCoef[5][8], int dela } } -void AudioHRTF::render(int16_t* input, float* output, int index, float azimuth, float distance, float gain, int numFrames) { +void AudioHRTF::render(int16_t* input, float* output, int index, float azimuth, float distance, float gain, int numFrames, + float lpfDistance) { assert(index >= 0); assert(index < HRTF_TABLES); @@ -1141,23 +1072,29 @@ void AudioHRTF::render(int16_t* input, float* output, int index, float azimuth, // apply global and local gain adjustment gain *= _gainAdjust; + // apply distance filter + float lpf = 0.5f * fastLog2f(std::max(distance, 1.0f)) / fastLog2f(std::max(lpfDistance, 2.0f)); + lpf = std::min(std::max(lpf, 0.0f), 1.0f); + // disable interpolation from reset state if (_resetState) { _azimuthState = azimuth; _distanceState = distance; _gainState = gain; + _lpfState = lpf; } // to avoid polluting the cache, old filters are recomputed instead of stored - setFilters(firCoef, bqCoef, delay, index, _azimuthState, _distanceState, _gainState, L0); + setFilters(firCoef, bqCoef, delay, index, _azimuthState, _distanceState, _gainState, _lpfState, L0); // compute new filters - setFilters(firCoef, bqCoef, delay, index, azimuth, distance, gain, L1); + setFilters(firCoef, bqCoef, delay, index, azimuth, distance, gain, lpf, L1); // new parameters become old _azimuthState = azimuth; _distanceState = distance; _gainState = gain; + _lpfState = lpf; // convert mono input to float for (int i = 0; i < HRTF_BLOCK; i++) { diff --git a/libraries/audio/src/AudioHRTF.h b/libraries/audio/src/AudioHRTF.h index 436d6318a5..6bbd9bc08a 100644 --- a/libraries/audio/src/AudioHRTF.h +++ b/libraries/audio/src/AudioHRTF.h @@ -14,6 +14,9 @@ #include #include +#include + +#include "AudioHelpers.h" static const int HRTF_AZIMUTHS = 72; // 360 / 5-degree steps static const int HRTF_TAPS = 64; // minimum-phase FIR coefficients @@ -34,6 +37,9 @@ static const float HRTF_HEAD_RADIUS = 0.0875f; // average human head in meters static const float ATTN_DISTANCE_REF = 2.0f; // distance where attn is 0dB static const float ATTN_GAIN_MAX = 16.0f; // max gain allowed by distance attn (+24dB) +// Distance filter +static const float LPF_DISTANCE_REF = 256.0f; // approximation of sound propogation in air + class AudioHRTF { public: @@ -47,8 +53,10 @@ public: // distance: source distance in meters // gain: gain factor for distance attenuation // numFrames: must be HRTF_BLOCK in this version + // lpfDistance: distance filter adjustment (distance to 1kHz lowpass in meters) // - void render(int16_t* input, float* output, int index, float azimuth, float distance, float gain, int numFrames); + void render(int16_t* input, float* output, int index, float azimuth, float distance, float gain, int numFrames, + float lpfDistance = LPF_DISTANCE_REF); // // Non-spatialized direct mix (accumulates into existing output) @@ -59,11 +67,14 @@ public: // // Fast path when input is known to be silent and state as been flushed // - void setParameterHistory(float azimuth, float distance, float gain) { + void setParameterHistory(float azimuth, float distance, float gain, float lpfDistance = LPF_DISTANCE_REF) { // new parameters become old _azimuthState = azimuth; _distanceState = distance; _gainState = gain; + + _lpfState = 0.5f * fastLog2f(std::max(distance, 1.0f)) / fastLog2f(std::max(lpfDistance, 2.0f)); + _lpfState = std::min(std::max(_lpfState, 0.0f), 1.0f); } // @@ -88,6 +99,7 @@ public: _azimuthState = 0.0f; _distanceState = 0.0f; _gainState = 0.0f; + _lpfState = 0.0f; // _gainAdjust is retained @@ -123,6 +135,7 @@ private: float _azimuthState = 0.0f; float _distanceState = 0.0f; float _gainState = 0.0f; + float _lpfState = 0.0f; // global and local gain adjustment float _gainAdjust = HRTF_GAIN; diff --git a/libraries/controllers/src/controllers/Actions.cpp b/libraries/controllers/src/controllers/Actions.cpp index 36f454b5d0..30f4181b43 100644 --- a/libraries/controllers/src/controllers/Actions.cpp +++ b/libraries/controllers/src/controllers/Actions.cpp @@ -386,8 +386,6 @@ namespace controller { makeAxisPair(Action::LIPSSTRETCH_R, "LipsStretch_R"), makeAxisPair(Action::LIPSUPPERCLOSE, "LipsUpperClose"), makeAxisPair(Action::LIPSLOWERCLOSE, "LipsLowerClose"), - makeAxisPair(Action::LIPSUPPEROPEN, "LipsUpperOpen"), - makeAxisPair(Action::LIPSLOWEROPEN, "LipsLowerOpen"), makeAxisPair(Action::LIPSFUNNEL, "LipsFunnel"), makeAxisPair(Action::LIPSPUCKER, "LipsPucker"), makeAxisPair(Action::PUFF, "Puff"), diff --git a/libraries/controllers/src/controllers/Actions.h b/libraries/controllers/src/controllers/Actions.h index 5c96923dc3..6868483a14 100644 --- a/libraries/controllers/src/controllers/Actions.h +++ b/libraries/controllers/src/controllers/Actions.h @@ -220,8 +220,6 @@ enum class Action { LIPSSTRETCH_R, LIPSUPPERCLOSE, LIPSLOWERCLOSE, - LIPSUPPEROPEN, - LIPSLOWEROPEN, LIPSFUNNEL, LIPSPUCKER, PUFF, diff --git a/libraries/controllers/src/controllers/StandardController.cpp b/libraries/controllers/src/controllers/StandardController.cpp index 936f1c391f..41835223ea 100644 --- a/libraries/controllers/src/controllers/StandardController.cpp +++ b/libraries/controllers/src/controllers/StandardController.cpp @@ -392,8 +392,6 @@ Input::NamedVector StandardController::getAvailableInputs() const { makePair(LIPSSTRETCH_R, "LipsStretch_R"), makePair(LIPSUPPERCLOSE, "LipsUpperClose"), makePair(LIPSLOWERCLOSE, "LipsLowerClose"), - makePair(LIPSUPPEROPEN, "LipsUpperOpen"), - makePair(LIPSLOWEROPEN, "LipsLowerOpen"), makePair(LIPSFUNNEL, "LipsFunnel"), makePair(LIPSPUCKER, "LipsPucker"), makePair(PUFF, "Puff"), diff --git a/libraries/controllers/src/controllers/StandardControls.h b/libraries/controllers/src/controllers/StandardControls.h index 965c095187..051f6dcc3a 100644 --- a/libraries/controllers/src/controllers/StandardControls.h +++ b/libraries/controllers/src/controllers/StandardControls.h @@ -127,8 +127,6 @@ namespace controller { LIPSSTRETCH_R, LIPSUPPERCLOSE, LIPSLOWERCLOSE, - LIPSUPPEROPEN, - LIPSLOWEROPEN, LIPSFUNNEL, LIPSPUCKER, PUFF, diff --git a/libraries/fbx/src/FSTReader.cpp b/libraries/fbx/src/FSTReader.cpp index 2835151bfe..b647fe2e7f 100644 --- a/libraries/fbx/src/FSTReader.cpp +++ b/libraries/fbx/src/FSTReader.cpp @@ -82,6 +82,8 @@ static void fixUpLegacyBlendshapes(QVariantHash& properties) { removeBlendshape(bs, "JawChew"); removeBlendshape(bs, "ChinLowerRaise"); removeBlendshape(bs, "ChinUpperRaise"); + removeBlendshape(bs, "LipsUpperOpen"); + removeBlendshape(bs, "LipsLowerOpen"); // These blendshapes are split in ARKit, we replace them with their left and right sides with a weight of 1/2. splitBlendshapes(bs, "LipsUpperUp", "MouthUpperUp_L", "MouthUpperUp_R"); diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index 0d0b776074..22decb47a7 100755 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -257,7 +257,9 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext, con ShapeKey::Builder(), ShapeKey::Builder().withFade(), ShapeKey::Builder().withDeformed(), ShapeKey::Builder().withDeformed().withFade(), ShapeKey::Builder().withDeformed().withDualQuatSkinned(), ShapeKey::Builder().withDeformed().withDualQuatSkinned().withFade(), - ShapeKey::Builder().withOwnPipeline(), ShapeKey::Builder().withOwnPipeline().withFade() + ShapeKey::Builder().withOwnPipeline(), ShapeKey::Builder().withOwnPipeline().withFade(), + ShapeKey::Builder().withDeformed().withOwnPipeline(), ShapeKey::Builder().withDeformed().withOwnPipeline().withFade(), + ShapeKey::Builder().withDeformed().withDualQuatSkinned().withOwnPipeline(), ShapeKey::Builder().withDeformed().withDualQuatSkinned().withOwnPipeline().withFade(), }; std::vector> sortedShapeKeys(keys.size()); diff --git a/libraries/shared/src/BlendshapeConstants.cpp b/libraries/shared/src/BlendshapeConstants.cpp index 91b68ed8a9..172df461fd 100644 --- a/libraries/shared/src/BlendshapeConstants.cpp +++ b/libraries/shared/src/BlendshapeConstants.cpp @@ -47,8 +47,6 @@ const char* FACESHIFT_BLENDSHAPES[] = { "LipsStretch_R", "LipsUpperClose", "LipsLowerClose", - "LipsUpperOpen", - "LipsLowerOpen", "LipsFunnel", "LipsPucker", "Puff", diff --git a/libraries/shared/src/BlendshapeConstants.h b/libraries/shared/src/BlendshapeConstants.h index 8db29856c3..e74146eb56 100644 --- a/libraries/shared/src/BlendshapeConstants.h +++ b/libraries/shared/src/BlendshapeConstants.h @@ -51,8 +51,6 @@ enum class Blendshapes : int { LipsStretch_R, LipsUpperClose, LipsLowerClose, - LipsUpperOpen, - LipsLowerOpen, LipsFunnel, LipsPucker, Puff, @@ -114,5 +112,8 @@ enum class LegacyBlendshpaes : int { // * Sneer (split in ARKit) // * ChinLowerRaise (not in ARKit) // * ChinUpperRaise (not in ARKit) +// * LipsUpperOpen (not in ARKit) +// * LipsLowerOpen (not in ARKit) + #endif // hifi_BlendshapeConstants_h diff --git a/libraries/shared/src/shared/Camera.cpp b/libraries/shared/src/shared/Camera.cpp index 6727f89d29..85761e0d29 100644 --- a/libraries/shared/src/shared/Camera.cpp +++ b/libraries/shared/src/shared/Camera.cpp @@ -25,38 +25,46 @@ * * First Person * "first person" - * Legacy first person camera mode. The camera is positioned such that you have the same view as your avatar. - * The camera moves and rotates with your avatar. + *

The camera is positioned such that you have the same view as your avatar. The camera moves and rotates with + * your avatar.

+ *

Legacy first person camera mode.

* * * First Person Look At * "first person look at" - * Default first person camera mode. The camera is positioned such that you have the same view as your avatar. - * The camera moves and rotates with your avatar's head. + *

The camera is positioned such that you have the same view as your avatar. The camera moves and rotates with + * your avatar's head.

+ *

Default first person camera mode.

* * * Third Person * "third person" - * The camera is positioned such that you have a view from just behind your avatar. The camera moves and rotates with - * your avatar. + *

The camera is positioned such that you have a view from just behind your avatar. The camera moves and rotates + * with your avatar.

+ *

Legacy third person camera camera mode.

+ *
Camera.mode = "third person";
* * * Look At * "look at" - * The camera is positioned behind your avatar. The camera moves and rotates independently from your avatar. - * The avatar's head always faces the camera look at point. + *

The camera is positioned behind your avatar. The camera moves and rotates independently from your avatar. The + * avatar's head always faces the camera look at point.

+ *

Default third person camera mode. * * * Selfie * "selfie" - * The camera is positioned in front of your avatar. The camera moves and rotates independently from your avatar. - * Your avatar's head is always facing the camera. + *

The camera is positioned in front of your avatar. The camera moves and rotates independently from your avatar. + * Your avatar's head is always facing the camera.

+ *

Default "look at myself" camera mode.

* * * Mirror * "mirror" - * The camera is positioned such that you are looking directly at your avatar. The camera moves and rotates with your - * avatar. + *

The camera is positioned such that you are looking directly at your avatar. The camera is fixed and does not + * move with your avatar.

+ *

Legacy "look at myself" behavior.

+ *
Camera.mode = "mirror";
* * * Independent diff --git a/scripts/system/create/edit.js b/scripts/system/create/edit.js index c57f4bae50..a036cf384d 100644 --- a/scripts/system/create/edit.js +++ b/scripts/system/create/edit.js @@ -561,7 +561,8 @@ var toolBar = (function () { if (!properties.grab) { properties.grab = {}; if (Menu.isOptionChecked(MENU_CREATE_ENTITIES_GRABBABLE) && - !(properties.type === "Zone" || properties.type === "Light" || properties.type === "ParticleEffect")) { + !(properties.type === "Zone" || properties.type === "Light" + || properties.type === "ParticleEffect" || properties.type === "Web")) { properties.grab.grabbable = true; } else { properties.grab.grabbable = false; diff --git a/scripts/system/create/entityList/entityList.js b/scripts/system/create/entityList/entityList.js index 06e100f457..b68dcf80ba 100644 --- a/scripts/system/create/entityList/entityList.js +++ b/scripts/system/create/entityList/entityList.js @@ -177,7 +177,7 @@ EntityListTool = function(shouldUseEditTabletApp) { var cameraPosition = Camera.position; PROFILE("getMultipleProperties", function () { - var multipleProperties = Entities.getMultipleEntityProperties(ids, ['name', 'type', 'locked', + var multipleProperties = Entities.getMultipleEntityProperties(ids, ['position', 'name', 'type', 'locked', 'visible', 'renderInfo', 'modelURL', 'materialURL', 'imageURL', 'script', 'certificateID', 'skybox.url', 'ambientLight.url']); for (var i = 0; i < multipleProperties.length; i++) { @@ -275,23 +275,6 @@ EntityListTool = function(shouldUseEditTabletApp) { Window.saveFileChanged.connect(onFileSaveChanged); Window.saveAsync("Select Where to Save", "", "*.json"); } - } else if (data.type === "pal") { - var sessionIds = {}; // Collect the sessionsIds of all selected entities, w/o duplicates. - selectionManager.selections.forEach(function (id) { - var lastEditedBy = Entities.getEntityProperties(id, 'lastEditedBy').lastEditedBy; - if (lastEditedBy) { - sessionIds[lastEditedBy] = true; - } - }); - var dedupped = Object.keys(sessionIds); - if (!selectionManager.selections.length) { - Window.alert('No objects selected.'); - } else if (!dedupped.length) { - Window.alert('There were no recent users of the ' + selectionManager.selections.length + ' selected objects.'); - } else { - // No need to subscribe if we're just sending. - Messages.sendMessage('com.highfidelity.pal', JSON.stringify({method: 'select', params: [dedupped, true, false]}), 'local'); - } } else if (data.type === "delete") { deleteSelectedEntities(); } else if (data.type === "toggleLocked") { diff --git a/scripts/system/create/entityList/html/entityList.html b/scripts/system/create/entityList/html/entityList.html index 3e17a66df5..b7ff7cd4e4 100644 --- a/scripts/system/create/entityList/html/entityList.html +++ b/scripts/system/create/entityList/html/entityList.html @@ -29,7 +29,6 @@ - diff --git a/scripts/system/create/entityList/html/js/entityList.js b/scripts/system/create/entityList/html/js/entityList.js index b15c4e6703..b70e53ce15 100644 --- a/scripts/system/create/entityList/html/js/entityList.js +++ b/scripts/system/create/entityList/html/js/entityList.js @@ -209,7 +209,6 @@ let elEntityTable, elFilterInView, elFilterRadius, elExport, - elPal, elSelectedEntitiesCount, elVisibleEntitiesCount, elNoEntitiesMessage, @@ -254,7 +253,6 @@ function loaded() { elFilterInView = document.getElementById("filter-in-view"); elFilterRadius = document.getElementById("filter-radius"); elExport = document.getElementById("export"); - elPal = document.getElementById("pal"); elSelectedEntitiesCount = document.getElementById("selected-entities-count"); elVisibleEntitiesCount = document.getElementById("visible-entities-count"); elNoEntitiesMessage = document.getElementById("no-entities"); @@ -272,9 +270,6 @@ function loaded() { elExport.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'export'})); }; - elPal.onclick = function() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'pal' })); - }; elDelete.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'delete' })); }; @@ -541,8 +536,9 @@ function loaded() { function onRowClicked(clickEvent) { let entityID = this.dataset.entityID; let selection = [entityID]; + let controlKey = window.navigator.platform.startsWith("Mac") ? clickEvent.metaKey : clickEvent.ctrlKey; - if (clickEvent.ctrlKey) { + if (controlKey) { let selectedIndex = selectedEntities.indexOf(entityID); if (selectedIndex >= 0) { selection = []; @@ -573,7 +569,7 @@ function loaded() { selection.reverse(); } } - } else if (!clickEvent.ctrlKey && !clickEvent.shiftKey && selectedEntities.length === 1) { + } else if (!controlKey && !clickEvent.shiftKey && selectedEntities.length === 1) { // if reselecting the same entity then start renaming it if (selectedEntities[0] === entityID) { if (renameLastBlur && renameLastEntityID === entityID && (Date.now() - renameLastBlur) < RENAME_COOLDOWN) { diff --git a/scripts/system/create/entityProperties/html/js/entityProperties.js b/scripts/system/create/entityProperties/html/js/entityProperties.js index 76264429ac..e581fbd194 100644 --- a/scripts/system/create/entityProperties/html/js/entityProperties.js +++ b/scripts/system/create/entityProperties/html/js/entityProperties.js @@ -398,8 +398,8 @@ const GROUPS = [ { label: "Base", type: "number-draggable", - min: -1000, - max: 1000, + min: -16000, + max: 16000, step: 1, decimals: 0, unit: "m", @@ -409,8 +409,8 @@ const GROUPS = [ { label: "Ceiling", type: "number-draggable", - min: -1000, - max: 5000, + min: -16000, + max: 16000, step: 1, decimals: 0, unit: "m",