mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 04:44:11 +02:00
Merge branch 'master' of https://github.com/amerhifi/hifi
This commit is contained in:
commit
89d494cf81
44 changed files with 450 additions and 260 deletions
|
@ -15,6 +15,7 @@
|
|||
<uses-feature android:name="android.hardware.sensor.gyroscope" android:required="true"/>
|
||||
<uses-feature android:name="android.software.vr.mode" android:required="true"/>
|
||||
<uses-feature android:name="android.hardware.vr.high_performance" android:required="true"/>
|
||||
<uses-feature android:name="android.hardware.vr.headtracking" android:version="1" android:required="true" />
|
||||
|
||||
<application
|
||||
android:name="org.qtproject.qt5.android.bindings.QtApplication"
|
||||
|
|
|
@ -399,6 +399,7 @@ void Agent::executeScript() {
|
|||
}
|
||||
|
||||
// these procedural movements are included in the recordings
|
||||
scriptedAvatar->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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
BIN
interface/resources/avatar/animations/settle_to_idle.fbx
Normal file
BIN
interface/resources/avatar/animations/settle_to_idle.fbx
Normal file
Binary file not shown.
BIN
interface/resources/avatar/animations/settle_to_idle02.fbx
Normal file
BIN
interface/resources/avatar/animations/settle_to_idle02.fbx
Normal file
Binary file not shown.
BIN
interface/resources/avatar/animations/settle_to_idle03.fbx
Normal file
BIN
interface/resources/avatar/animations/settle_to_idle03.fbx
Normal file
Binary file not shown.
BIN
interface/resources/avatar/animations/settle_to_idle04.fbx
Normal file
BIN
interface/resources/avatar/animations/settle_to_idle04.fbx
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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"
|
||||
|
|
|
@ -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" },
|
||||
|
|
|
@ -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" },
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -232,12 +232,6 @@ void AvatarBookmarks::loadBookmark(const QString& bookmarkName) {
|
|||
emit bookmarkLoaded(bookmarkName);
|
||||
});
|
||||
|
||||
std::shared_ptr<QMetaObject::Connection> connection2 = std::make_shared<QMetaObject::Connection>();
|
||||
*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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -330,6 +330,7 @@ protected:
|
|||
glm::vec3 _lastForward;
|
||||
glm::vec3 _lastPosition;
|
||||
glm::vec3 _lastVelocity;
|
||||
bool _isMovingWithMomentum{ false };
|
||||
|
||||
QUrl _animGraphURL;
|
||||
std::shared_ptr<AnimNode> _animNode;
|
||||
|
|
|
@ -111,11 +111,17 @@ QList<HifiAudioDeviceInfo> 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;
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <algorithm>
|
||||
|
||||
#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;
|
||||
|
|
|
@ -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"),
|
||||
|
|
|
@ -220,8 +220,6 @@ enum class Action {
|
|||
LIPSSTRETCH_R,
|
||||
LIPSUPPERCLOSE,
|
||||
LIPSLOWERCLOSE,
|
||||
LIPSUPPEROPEN,
|
||||
LIPSLOWEROPEN,
|
||||
LIPSFUNNEL,
|
||||
LIPSPUCKER,
|
||||
PUFF,
|
||||
|
|
|
@ -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"),
|
||||
|
|
|
@ -127,8 +127,6 @@ namespace controller {
|
|||
LIPSSTRETCH_R,
|
||||
LIPSUPPERCLOSE,
|
||||
LIPSLOWERCLOSE,
|
||||
LIPSUPPEROPEN,
|
||||
LIPSLOWEROPEN,
|
||||
LIPSFUNNEL,
|
||||
LIPSPUCKER,
|
||||
PUFF,
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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<std::vector<ShapeKey>> sortedShapeKeys(keys.size());
|
||||
|
||||
|
|
|
@ -47,8 +47,6 @@ const char* FACESHIFT_BLENDSHAPES[] = {
|
|||
"LipsStretch_R",
|
||||
"LipsUpperClose",
|
||||
"LipsLowerClose",
|
||||
"LipsUpperOpen",
|
||||
"LipsLowerOpen",
|
||||
"LipsFunnel",
|
||||
"LipsPucker",
|
||||
"Puff",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -25,38 +25,46 @@
|
|||
* <tr>
|
||||
* <td><strong>First Person</strong></td>
|
||||
* <td><code>"first person"</code></td>
|
||||
* <td>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.</td>
|
||||
* <td><p>The camera is positioned such that you have the same view as your avatar. The camera moves and rotates with
|
||||
* your avatar.</p>
|
||||
* <p><em>Legacy first person camera mode.</em></p></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><strong>First Person Look At</strong></td>
|
||||
* <td><code>"first person look at"</code></td>
|
||||
* <td>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.</td>
|
||||
* <td><p>The camera is positioned such that you have the same view as your avatar. The camera moves and rotates with
|
||||
* your avatar's head.</p>
|
||||
* <p><em>Default first person camera mode.</em></p></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><strong>Third Person</strong></td>
|
||||
* <td><code>"third person"</code></td>
|
||||
* <td>The camera is positioned such that you have a view from just behind your avatar. The camera moves and rotates with
|
||||
* your avatar.</td>
|
||||
* <td><p>The camera is positioned such that you have a view from just behind your avatar. The camera moves and rotates
|
||||
* with your avatar.</p>
|
||||
* <p><em>Legacy third person camera camera mode.</em></p>
|
||||
* <pre class="prettyprint"><code>Camera.mode = "third person";</code></pre></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><strong>Look At</strong></td>
|
||||
* <td><code>"look at"</code></td>
|
||||
* <td>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.</td>
|
||||
* <td><p>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.</p>
|
||||
* <p><em>Default third person camera mode.</em></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><strong>Selfie</strong></td>
|
||||
* <td><code>"selfie"</code></td>
|
||||
* <td>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.</td>
|
||||
* <td><p>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.</p>
|
||||
* <p><em>Default "look at myself" camera mode.</em></p></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><strong>Mirror</strong></td>
|
||||
* <td><code>"mirror"</code></td>
|
||||
* <td>The camera is positioned such that you are looking directly at your avatar. The camera moves and rotates with your
|
||||
* avatar.</td>
|
||||
* <td><p>The camera is positioned such that you are looking directly at your avatar. The camera is fixed and does not
|
||||
* move with your avatar.</p>
|
||||
* <p><em>Legacy "look at myself" behavior.</em></p>
|
||||
* <pre class="prettyprint"><code>Camera.mode = "mirror";</code></pre></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><strong>Independent</strong></td>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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") {
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
<input type="button" id="locked" class="glyph" value="" />
|
||||
<input type="button" id="visible" class="glyph" value="" />
|
||||
</div>
|
||||
<input type="button" id="pal" class="glyph" value="" />
|
||||
<button id="toggle-space-mode" class="hifi-edit-button space-mode-local">Local</button>
|
||||
<input type="button" class="red glyph" id="delete" value="{" />
|
||||
</div>
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in a new issue