diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 3342db3f52..11496f727e 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1925,7 +1925,7 @@ void MyAvatar::preDisplaySide(RenderArgs* renderArgs) { _prevShouldDrawHead = shouldDrawHead; } -const float RENDER_HEAD_CUTOFF_DISTANCE = 0.3f; +const float RENDER_HEAD_CUTOFF_DISTANCE = 0.47f; bool MyAvatar::cameraInsideHead(const glm::vec3& cameraPosition) const { return glm::length(cameraPosition - getHeadPosition()) < (RENDER_HEAD_CUTOFF_DISTANCE * getModelScale()); @@ -2096,7 +2096,7 @@ void MyAvatar::updateActionMotor(float deltaTime) { _actionMotorVelocity = motorSpeed * direction; } else { // we're interacting with a floor --> simple horizontal speed and exponential decay - _actionMotorVelocity = getSensorToWorldScale() * DEFAULT_AVATAR_MAX_WALKING_SPEED * direction; + _actionMotorVelocity = getSensorToWorldScale() * _walkSpeed.get() * direction; } float boomChange = getDriveKey(ZOOM); @@ -2688,6 +2688,14 @@ float MyAvatar::getUserEyeHeight() const { return userHeight - userHeight * ratio; } +float MyAvatar::getWalkSpeed() const { + return _walkSpeed.get(); +} + +void MyAvatar::setWalkSpeed(float value) { + _walkSpeed.set(value); +} + glm::vec3 MyAvatar::getPositionForAudio() { switch (_audioListenerMode) { case AudioListenerMode::FROM_HEAD: diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index bdbfb09060..58b49b61ff 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -163,6 +163,8 @@ class MyAvatar : public Avatar { Q_PROPERTY(QUuid SELF_ID READ getSelfID CONSTANT) + Q_PROPERTY(float walkSpeed READ getWalkSpeed WRITE setWalkSpeed); + const QString DOMINANT_LEFT_HAND = "left"; const QString DOMINANT_RIGHT_HAND = "right"; @@ -557,6 +559,9 @@ public: const QUuid& getSelfID() const { return AVATAR_SELF_ID; } + void setWalkSpeed(float value); + float getWalkSpeed() const; + public slots: void increaseSize(); void decreaseSize(); @@ -840,6 +845,9 @@ private: // height of user in sensor space, when standing erect. ThreadSafeValueCache _userHeight { DEFAULT_AVATAR_HEIGHT }; + + // max unscaled forward movement speed + ThreadSafeValueCache _walkSpeed { DEFAULT_AVATAR_MAX_WALKING_SPEED }; }; QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode); diff --git a/scripts/system/assets/images/run.svg b/scripts/system/assets/images/run.svg new file mode 100644 index 0000000000..0957166346 --- /dev/null +++ b/scripts/system/assets/images/run.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/scripts/system/run.js b/scripts/system/run.js new file mode 100644 index 0000000000..054cca6d9c --- /dev/null +++ b/scripts/system/run.js @@ -0,0 +1,39 @@ +"use strict"; + +/* global Script, Tablet, MyAvatar */ + +(function() { // BEGIN LOCAL_SCOPE + var WALK_SPEED = 2.6; + var RUN_SPEED = 4.5; + var MIDDLE_SPEED = (WALK_SPEED + RUN_SPEED) / 2.0; + + var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); + var button = tablet.addButton({ + icon: Script.resolvePath("assets/images/run.svg"), + text: "RUN", + sortOrder: 15 + }); + + function onClicked() { + if (MyAvatar.walkSpeed < MIDDLE_SPEED) { + button.editProperties({isActive: true}); + MyAvatar.walkSpeed = RUN_SPEED; + } else { + button.editProperties({isActive: false}); + MyAvatar.walkSpeed = WALK_SPEED; + } + } + + function cleanup() { + button.clicked.disconnect(onClicked); + tablet.removeButton(button); + } + + button.clicked.connect(onClicked); + if (MyAvatar.walkSpeed < MIDDLE_SPEED) { + button.editProperties({isActive: false}); + } else { + button.editProperties({isActive: true}); + } + +}());