From 05f19d54f4b7ddabb6039b125d902dc4262b6092 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 14 Jun 2017 11:55:04 +1200 Subject: [PATCH 1/6] Add HMD roll control JavaScript API --- interface/src/avatar/MyAvatar.h | 17 +++++++++++++++++ scripts/developer/hmdRollControlDisable.js | 17 +++++++++++++++++ scripts/developer/hmdRollControlEnable.js | 21 +++++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 scripts/developer/hmdRollControlDisable.js create mode 100644 scripts/developer/hmdRollControlEnable.js diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index cfe66eb10e..bfc7cd1085 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -132,6 +132,10 @@ class MyAvatar : public Avatar { Q_PROPERTY(bool characterControllerEnabled READ getCharacterControllerEnabled WRITE setCharacterControllerEnabled) Q_PROPERTY(bool useAdvancedMovementControls READ useAdvancedMovementControls WRITE setUseAdvancedMovementControls) + Q_PROPERTY(bool hmdRollControlEnabled READ getHMDRollControlEnabled WRITE setHMDRollControlEnabled) + Q_PROPERTY(float hmdRollControlDeadZone READ getHMDRollControlDeadZone WRITE setHMDRollControlDeadZone) + Q_PROPERTY(float hmdRollControlSpeed READ getHMDRollControlSpeed WRITE setHMDRollControlSpeed) + public: enum DriveKeys { TRANSLATE_X = 0, @@ -337,6 +341,13 @@ public: void setUseAdvancedMovementControls(bool useAdvancedMovementControls) { _useAdvancedMovementControls.set(useAdvancedMovementControls); } + void setHMDRollControlEnabled(bool value) { _hmdRollControlEnabled = value; } + bool getHMDRollControlEnabled() const { return _hmdRollControlEnabled; } + void setHMDRollControlDeadZone(float value) { _hmdRollControlDeadZone = value; } + float getHMDRollControlDeadZone() const { return _hmdRollControlDeadZone; } + void setHMDRollControlSpeed(float value) { _hmdRollControlSpeed = value; } + float getHMDRollControlSpeed() const { return _hmdRollControlSpeed; } + // get/set avatar data void saveData(); void loadData(); @@ -687,6 +698,12 @@ private: bool _useSnapTurn { true }; bool _clearOverlayWhenMoving { true }; + const float ROLL_CONTROL_DEAD_ZONE_DEFAULT = 8.0f; // deg + const float ROLL_CONTROL_SPEED_DEFAULT = 2.5f; // deg/sec/deg + bool _hmdRollControlEnabled { true }; + float _hmdRollControlDeadZone { ROLL_CONTROL_DEAD_ZONE_DEFAULT }; + float _hmdRollControlSpeed { ROLL_CONTROL_SPEED_DEFAULT }; + // working copies -- see AvatarData for thread-safe _sensorToWorldMatrixCache, used for outward facing access glm::mat4 _sensorToWorldMatrix { glm::mat4() }; diff --git a/scripts/developer/hmdRollControlDisable.js b/scripts/developer/hmdRollControlDisable.js new file mode 100644 index 0000000000..9d87a62264 --- /dev/null +++ b/scripts/developer/hmdRollControlDisable.js @@ -0,0 +1,17 @@ +// +// hmdRollControlDisable.js +// +// Created by David Rowe on 4 Jun 2017. +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0 +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +var hmdRollControlEnabled = false; + +print("HMD roll control: " + hmdRollControlEnabled); + +MyAvatar.hmdRollControlEnabled = hmdRollControlEnabled; + +Script.stop(); diff --git a/scripts/developer/hmdRollControlEnable.js b/scripts/developer/hmdRollControlEnable.js new file mode 100644 index 0000000000..d18e099b44 --- /dev/null +++ b/scripts/developer/hmdRollControlEnable.js @@ -0,0 +1,21 @@ +// +// hmdRollControlEnable.js +// +// Created by David Rowe on 4 Jun 2017. +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0 +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +var hmdRollControlEnabled = true; +var hmdRollControlDeadZone = 8.0; // deg +var hmdRollControlSpeed = 1.0; // deg/sec/deg + +print("HMD roll control: " + hmdRollControlEnabled + ", " + hmdRollControlDeadZone + ", " + hmdRollControlSpeed); + +MyAvatar.hmdRollControlEnabled = hmdRollControlEnabled; +MyAvatar.hmdRollControlDeadZone = hmdRollControlDeadZone; +MyAvatar.hmdRollControlSpeed = hmdRollControlSpeed; + +Script.stop(); From be2bcb1c13d4f90739620637d3f859f9c41cfd84 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 14 Jun 2017 12:20:46 +1200 Subject: [PATCH 2/6] Turn with head roll in HMD when walking or flying --- interface/src/avatar/MyAvatar.cpp | 26 ++++++++++++++++++++++++++ interface/src/avatar/MyAvatar.h | 1 + 2 files changed, 27 insertions(+) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 24a25f314d..bd217a98a2 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1961,6 +1961,32 @@ void MyAvatar::updateOrientation(float deltaTime) { totalBodyYaw += (speedFactor * deltaAngle * (180.0f / PI)); } + // Use head/HMD roll to turn while walking or flying. + if (qApp->isHMDMode() && _hmdRollControlEnabled) { + // Turn with head roll. + const float MIN_CONTROL_SPEED = 0.01f; + float speed = glm::length(getVelocity()); + if (speed >= MIN_CONTROL_SPEED) { + // Feather turn when stopping moving. + float speedFactor; + if (getDriveKey(TRANSLATE_Z) != 0.0f || _lastDrivenSpeed == 0.0f) { + _lastDrivenSpeed = speed; + speedFactor = 1.0; + } else { + speedFactor = glm::min(speed / _lastDrivenSpeed, 1.0f); + } + + float direction = glm::dot(getVelocity(), getRotation() * Vectors::UNIT_NEG_Z) > 0.0f ? 1.0f : -1.0f; + + float rollAngle = glm::degrees(asin(glm::dot(IDENTITY_UP, _hmdSensorOrientation * IDENTITY_RIGHT))); + float rollSign = rollAngle < 0.0f ? -1.0f : 1.0f; + rollAngle = fabsf(rollAngle); + + float yawChange = rollAngle > _hmdRollControlDeadZone ? rollSign * (rollAngle - _hmdRollControlDeadZone) : 0.0f; + totalBodyYaw += speedFactor * direction * yawChange * deltaTime * _hmdRollControlSpeed; + } + } + // update body orientation by movement inputs glm::quat initialOrientation = getOrientationOutbound(); setOrientation(getOrientation() * glm::quat(glm::radians(glm::vec3(0.0f, totalBodyYaw, 0.0f)))); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index bfc7cd1085..8039674605 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -703,6 +703,7 @@ private: bool _hmdRollControlEnabled { true }; float _hmdRollControlDeadZone { ROLL_CONTROL_DEAD_ZONE_DEFAULT }; float _hmdRollControlSpeed { ROLL_CONTROL_SPEED_DEFAULT }; + float _lastDrivenSpeed { 0.0f }; // working copies -- see AvatarData for thread-safe _sensorToWorldMatrixCache, used for outward facing access glm::mat4 _sensorToWorldMatrix { glm::mat4() }; From 395d40f0f9026f4ef3935522b7a2a02f4d3405b0 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 14 Jun 2017 12:21:19 +1200 Subject: [PATCH 3/6] Fix script default to match C++ default --- scripts/developer/hmdRollControlEnable.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/developer/hmdRollControlEnable.js b/scripts/developer/hmdRollControlEnable.js index d18e099b44..3cdc02a466 100644 --- a/scripts/developer/hmdRollControlEnable.js +++ b/scripts/developer/hmdRollControlEnable.js @@ -10,7 +10,7 @@ var hmdRollControlEnabled = true; var hmdRollControlDeadZone = 8.0; // deg -var hmdRollControlSpeed = 1.0; // deg/sec/deg +var hmdRollControlSpeed = 2.5; // deg/sec/deg print("HMD roll control: " + hmdRollControlEnabled + ", " + hmdRollControlDeadZone + ", " + hmdRollControlSpeed); From e3b4e4aa2045ac14ba7c31350164192a1b193798 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 14 Jun 2017 15:37:36 +1200 Subject: [PATCH 4/6] Disable print statements --- scripts/developer/hmdRollControlDisable.js | 2 +- scripts/developer/hmdRollControlEnable.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/developer/hmdRollControlDisable.js b/scripts/developer/hmdRollControlDisable.js index 9d87a62264..fe8a85e3e5 100644 --- a/scripts/developer/hmdRollControlDisable.js +++ b/scripts/developer/hmdRollControlDisable.js @@ -10,7 +10,7 @@ var hmdRollControlEnabled = false; -print("HMD roll control: " + hmdRollControlEnabled); +//print("HMD roll control: " + hmdRollControlEnabled); MyAvatar.hmdRollControlEnabled = hmdRollControlEnabled; diff --git a/scripts/developer/hmdRollControlEnable.js b/scripts/developer/hmdRollControlEnable.js index 3cdc02a466..8af6cca6a5 100644 --- a/scripts/developer/hmdRollControlEnable.js +++ b/scripts/developer/hmdRollControlEnable.js @@ -12,7 +12,7 @@ var hmdRollControlEnabled = true; var hmdRollControlDeadZone = 8.0; // deg var hmdRollControlSpeed = 2.5; // deg/sec/deg -print("HMD roll control: " + hmdRollControlEnabled + ", " + hmdRollControlDeadZone + ", " + hmdRollControlSpeed); +//print("HMD roll control: " + hmdRollControlEnabled + ", " + hmdRollControlDeadZone + ", " + hmdRollControlSpeed); MyAvatar.hmdRollControlEnabled = hmdRollControlEnabled; MyAvatar.hmdRollControlDeadZone = hmdRollControlDeadZone; From 55e0082792605ee4713d7bc14ce96d77617466d7 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 15 Jun 2017 09:10:08 +1200 Subject: [PATCH 5/6] Code review --- interface/src/avatar/MyAvatar.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index bd217a98a2..b2c469f614 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1971,19 +1971,19 @@ void MyAvatar::updateOrientation(float deltaTime) { float speedFactor; if (getDriveKey(TRANSLATE_Z) != 0.0f || _lastDrivenSpeed == 0.0f) { _lastDrivenSpeed = speed; - speedFactor = 1.0; + speedFactor = 1.0f; } else { speedFactor = glm::min(speed / _lastDrivenSpeed, 1.0f); } float direction = glm::dot(getVelocity(), getRotation() * Vectors::UNIT_NEG_Z) > 0.0f ? 1.0f : -1.0f; - float rollAngle = glm::degrees(asin(glm::dot(IDENTITY_UP, _hmdSensorOrientation * IDENTITY_RIGHT))); + float rollAngle = glm::degrees(asinf(glm::dot(IDENTITY_UP, _hmdSensorOrientation * IDENTITY_RIGHT))); float rollSign = rollAngle < 0.0f ? -1.0f : 1.0f; rollAngle = fabsf(rollAngle); + rollAngle = rollAngle > _hmdRollControlDeadZone ? rollSign * (rollAngle - _hmdRollControlDeadZone) : 0.0f; - float yawChange = rollAngle > _hmdRollControlDeadZone ? rollSign * (rollAngle - _hmdRollControlDeadZone) : 0.0f; - totalBodyYaw += speedFactor * direction * yawChange * deltaTime * _hmdRollControlSpeed; + totalBodyYaw += speedFactor * direction * rollAngle * deltaTime * _hmdRollControlSpeed; } } From 16bebdd40945cf19878abf364f8dc4ad56f02e18 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 15 Jun 2017 09:20:55 +1200 Subject: [PATCH 6/6] Rename identifiers --- interface/src/avatar/MyAvatar.cpp | 2 +- interface/src/avatar/MyAvatar.h | 10 +++++----- scripts/developer/hmdRollControlEnable.js | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index b2c469f614..1adcfbd345 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1983,7 +1983,7 @@ void MyAvatar::updateOrientation(float deltaTime) { rollAngle = fabsf(rollAngle); rollAngle = rollAngle > _hmdRollControlDeadZone ? rollSign * (rollAngle - _hmdRollControlDeadZone) : 0.0f; - totalBodyYaw += speedFactor * direction * rollAngle * deltaTime * _hmdRollControlSpeed; + totalBodyYaw += speedFactor * direction * rollAngle * deltaTime * _hmdRollControlRate; } } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 8039674605..f61f24fb11 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -134,7 +134,7 @@ class MyAvatar : public Avatar { Q_PROPERTY(bool hmdRollControlEnabled READ getHMDRollControlEnabled WRITE setHMDRollControlEnabled) Q_PROPERTY(float hmdRollControlDeadZone READ getHMDRollControlDeadZone WRITE setHMDRollControlDeadZone) - Q_PROPERTY(float hmdRollControlSpeed READ getHMDRollControlSpeed WRITE setHMDRollControlSpeed) + Q_PROPERTY(float hmdRollControlRate READ getHMDRollControlRate WRITE setHMDRollControlRate) public: enum DriveKeys { @@ -345,8 +345,8 @@ public: bool getHMDRollControlEnabled() const { return _hmdRollControlEnabled; } void setHMDRollControlDeadZone(float value) { _hmdRollControlDeadZone = value; } float getHMDRollControlDeadZone() const { return _hmdRollControlDeadZone; } - void setHMDRollControlSpeed(float value) { _hmdRollControlSpeed = value; } - float getHMDRollControlSpeed() const { return _hmdRollControlSpeed; } + void setHMDRollControlRate(float value) { _hmdRollControlRate = value; } + float getHMDRollControlRate() const { return _hmdRollControlRate; } // get/set avatar data void saveData(); @@ -699,10 +699,10 @@ private: bool _clearOverlayWhenMoving { true }; const float ROLL_CONTROL_DEAD_ZONE_DEFAULT = 8.0f; // deg - const float ROLL_CONTROL_SPEED_DEFAULT = 2.5f; // deg/sec/deg + const float ROLL_CONTROL_RATE_DEFAULT = 2.5f; // deg/sec/deg bool _hmdRollControlEnabled { true }; float _hmdRollControlDeadZone { ROLL_CONTROL_DEAD_ZONE_DEFAULT }; - float _hmdRollControlSpeed { ROLL_CONTROL_SPEED_DEFAULT }; + float _hmdRollControlRate { ROLL_CONTROL_RATE_DEFAULT }; float _lastDrivenSpeed { 0.0f }; // working copies -- see AvatarData for thread-safe _sensorToWorldMatrixCache, used for outward facing access diff --git a/scripts/developer/hmdRollControlEnable.js b/scripts/developer/hmdRollControlEnable.js index 8af6cca6a5..81318b7ddd 100644 --- a/scripts/developer/hmdRollControlEnable.js +++ b/scripts/developer/hmdRollControlEnable.js @@ -10,12 +10,12 @@ var hmdRollControlEnabled = true; var hmdRollControlDeadZone = 8.0; // deg -var hmdRollControlSpeed = 2.5; // deg/sec/deg +var hmdRollControlRate = 2.5; // deg/sec/deg -//print("HMD roll control: " + hmdRollControlEnabled + ", " + hmdRollControlDeadZone + ", " + hmdRollControlSpeed); +//print("HMD roll control: " + hmdRollControlEnabled + ", " + hmdRollControlDeadZone + ", " + hmdRollControlRate); MyAvatar.hmdRollControlEnabled = hmdRollControlEnabled; MyAvatar.hmdRollControlDeadZone = hmdRollControlDeadZone; -MyAvatar.hmdRollControlSpeed = hmdRollControlSpeed; +MyAvatar.hmdRollControlRate = hmdRollControlRate; Script.stop();