mirror of
https://github.com/overte-org/overte.git
synced 2025-08-07 00:44:38 +02:00
Merge pull request #542 from overte-org/fix/contols_inertia
Lower inertia for more precise controls
This commit is contained in:
commit
77ec716363
7 changed files with 130 additions and 14 deletions
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
import QtQuick 2.5
|
import QtQuick 2.5
|
||||||
import QtGraphicalEffects 1.0
|
import QtGraphicalEffects 1.0
|
||||||
|
import QtQuick.Controls 2.2
|
||||||
|
|
||||||
import stylesUit 1.0
|
import stylesUit 1.0
|
||||||
import "../../controls"
|
import "../../controls"
|
||||||
|
@ -26,6 +27,39 @@ Flickable {
|
||||||
property string pluginName: ""
|
property string pluginName: ""
|
||||||
property var page: null;
|
property var page: null;
|
||||||
|
|
||||||
|
ScrollBar.vertical: ScrollBar {
|
||||||
|
policy: ScrollBar.AlwaysOn
|
||||||
|
parent: flick.parent
|
||||||
|
anchors.top: flick.top
|
||||||
|
anchors.right: flick.right
|
||||||
|
anchors.bottom: flick.bottom
|
||||||
|
z: 100 // Display over top of separators.
|
||||||
|
|
||||||
|
background: Item {
|
||||||
|
implicitWidth: verticalScrollWidth
|
||||||
|
Rectangle {
|
||||||
|
color: hifi.colors.baseGrayShadow
|
||||||
|
radius: 4
|
||||||
|
anchors {
|
||||||
|
fill: parent
|
||||||
|
bottomMargin: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
contentItem: Item {
|
||||||
|
implicitWidth: verticalScrollShaft
|
||||||
|
Rectangle {
|
||||||
|
radius: verticalScrollShaft/2
|
||||||
|
color: hifi.colors.white30
|
||||||
|
anchors {
|
||||||
|
fill: parent
|
||||||
|
topMargin: 1
|
||||||
|
bottomMargin: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onPluginNameChanged: {
|
onPluginNameChanged: {
|
||||||
if (page !== null) {
|
if (page !== null) {
|
||||||
page.pluginName = flick.pluginName;
|
page.pluginName = flick.pluginName;
|
||||||
|
@ -932,6 +966,43 @@ Flickable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: controllerStickHysteresisTimeRow
|
||||||
|
anchors.top: outOfRangeDataStrategyRow.bottom
|
||||||
|
anchors.topMargin: 20
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: leftMargin
|
||||||
|
spacing: 15
|
||||||
|
|
||||||
|
HifiControls.SpinBox {
|
||||||
|
id: controllerStickHysteresisTime
|
||||||
|
width: 70
|
||||||
|
|
||||||
|
minimumValue: 0
|
||||||
|
maximumValue: 0.2
|
||||||
|
realValue: 0
|
||||||
|
realStepSize: 0.05
|
||||||
|
colorScheme: hifi.colorSchemes.dark
|
||||||
|
|
||||||
|
onRealValueChanged: {
|
||||||
|
sendConfigurationSettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RalewayBold {
|
||||||
|
id: controllerStickHysteresisTimeInfo
|
||||||
|
size: 12
|
||||||
|
text: "Stick Hysteresis Time (set to 0.2 for Vive wands)"
|
||||||
|
color: hifi.colors.white
|
||||||
|
}
|
||||||
|
|
||||||
|
RalewayRegular {
|
||||||
|
size: 12
|
||||||
|
text: "sec"
|
||||||
|
color: hifi.colors.lightGray
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RalewayBold {
|
RalewayBold {
|
||||||
id: viveDesktopText
|
id: viveDesktopText
|
||||||
size: 12
|
size: 12
|
||||||
|
@ -1048,6 +1119,8 @@ Flickable {
|
||||||
armCircumference.realValue = settings["armCircumference"];
|
armCircumference.realValue = settings["armCircumference"];
|
||||||
shoulderWidth.realValue = settings["shoulderWidth"];
|
shoulderWidth.realValue = settings["shoulderWidth"];
|
||||||
|
|
||||||
|
controllerStickHysteresisTime.realValue = settings["controllerStickHysteresisTime"];
|
||||||
|
|
||||||
if (HmdHead) {
|
if (HmdHead) {
|
||||||
headBox.checked = true;
|
headBox.checked = true;
|
||||||
headPuckBox.checked = false;
|
headPuckBox.checked = false;
|
||||||
|
@ -1236,7 +1309,8 @@ Flickable {
|
||||||
"desktopMode": viveInDesktop.checked,
|
"desktopMode": viveInDesktop.checked,
|
||||||
"hmdDesktopTracking": hmdInDesktop.checked,
|
"hmdDesktopTracking": hmdInDesktop.checked,
|
||||||
"eyeTrackingEnabled": eyeTracking.checked,
|
"eyeTrackingEnabled": eyeTracking.checked,
|
||||||
"outOfRangeDataStrategy": outOfRangeDataStrategyComboBox.model[outOfRangeDataStrategyComboBox.currentIndex]
|
"outOfRangeDataStrategy": outOfRangeDataStrategyComboBox.model[outOfRangeDataStrategyComboBox.currentIndex],
|
||||||
|
"controllerStickHysteresisTime": controllerStickHysteresisTime.realValue
|
||||||
}
|
}
|
||||||
|
|
||||||
return settingsObject;
|
return settingsObject;
|
||||||
|
|
|
@ -79,6 +79,7 @@ using namespace std;
|
||||||
const float DEFAULT_REAL_WORLD_FIELD_OF_VIEW_DEGREES = 30.0f;
|
const float DEFAULT_REAL_WORLD_FIELD_OF_VIEW_DEGREES = 30.0f;
|
||||||
|
|
||||||
const float YAW_SPEED_DEFAULT = 100.0f; // degrees/sec
|
const float YAW_SPEED_DEFAULT = 100.0f; // degrees/sec
|
||||||
|
const float HMD_YAW_SPEED_DEFAULT = 300.0f; // degrees/sec
|
||||||
const float PITCH_SPEED_DEFAULT = 75.0f; // degrees/sec
|
const float PITCH_SPEED_DEFAULT = 75.0f; // degrees/sec
|
||||||
|
|
||||||
const float MAX_BOOST_SPEED = 0.5f * DEFAULT_AVATAR_MAX_WALKING_SPEED; // action motor gets additive boost below this speed
|
const float MAX_BOOST_SPEED = 0.5f * DEFAULT_AVATAR_MAX_WALKING_SPEED; // action motor gets additive boost below this speed
|
||||||
|
@ -190,6 +191,7 @@ static int beginEndReactionNameToIndex(const QString& reactionName) {
|
||||||
MyAvatar::MyAvatar(QThread* thread) :
|
MyAvatar::MyAvatar(QThread* thread) :
|
||||||
Avatar(thread),
|
Avatar(thread),
|
||||||
_yawSpeed(YAW_SPEED_DEFAULT),
|
_yawSpeed(YAW_SPEED_DEFAULT),
|
||||||
|
_hmdYawSpeed(HMD_YAW_SPEED_DEFAULT),
|
||||||
_pitchSpeed(PITCH_SPEED_DEFAULT),
|
_pitchSpeed(PITCH_SPEED_DEFAULT),
|
||||||
_scriptedMotorTimescale(DEFAULT_SCRIPTED_MOTOR_TIMESCALE),
|
_scriptedMotorTimescale(DEFAULT_SCRIPTED_MOTOR_TIMESCALE),
|
||||||
_scriptedMotorFrame(SCRIPTED_MOTOR_CAMERA_FRAME),
|
_scriptedMotorFrame(SCRIPTED_MOTOR_CAMERA_FRAME),
|
||||||
|
@ -222,6 +224,7 @@ MyAvatar::MyAvatar(QThread* thread) :
|
||||||
_headPitchSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "", 0.0f),
|
_headPitchSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "", 0.0f),
|
||||||
_scaleSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "scale", _targetScale),
|
_scaleSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "scale", _targetScale),
|
||||||
_yawSpeedSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "yawSpeed", _yawSpeed),
|
_yawSpeedSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "yawSpeed", _yawSpeed),
|
||||||
|
_hmdYawSpeedSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "hmdYawSpeed", _hmdYawSpeed),
|
||||||
_pitchSpeedSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "pitchSpeed", _pitchSpeed),
|
_pitchSpeedSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "pitchSpeed", _pitchSpeed),
|
||||||
_fullAvatarURLSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "fullAvatarURL",
|
_fullAvatarURLSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "fullAvatarURL",
|
||||||
AvatarData::defaultFullAvatarModelUrl()),
|
AvatarData::defaultFullAvatarModelUrl()),
|
||||||
|
@ -1335,6 +1338,7 @@ void MyAvatar::saveData() {
|
||||||
_headPitchSetting.set(getHead()->getBasePitch());
|
_headPitchSetting.set(getHead()->getBasePitch());
|
||||||
_scaleSetting.set(_targetScale);
|
_scaleSetting.set(_targetScale);
|
||||||
_yawSpeedSetting.set(_yawSpeed);
|
_yawSpeedSetting.set(_yawSpeed);
|
||||||
|
_hmdYawSpeedSetting.set(_hmdYawSpeed);
|
||||||
_pitchSpeedSetting.set(_pitchSpeed);
|
_pitchSpeedSetting.set(_pitchSpeed);
|
||||||
|
|
||||||
// only save the fullAvatarURL if it has not been overwritten on command line
|
// only save the fullAvatarURL if it has not been overwritten on command line
|
||||||
|
@ -2094,6 +2098,7 @@ void MyAvatar::loadData() {
|
||||||
getHead()->setBasePitch(_headPitchSetting.get());
|
getHead()->setBasePitch(_headPitchSetting.get());
|
||||||
|
|
||||||
_yawSpeed = _yawSpeedSetting.get(_yawSpeed);
|
_yawSpeed = _yawSpeedSetting.get(_yawSpeed);
|
||||||
|
_hmdYawSpeed = _hmdYawSpeedSetting.get(_hmdYawSpeed);
|
||||||
_pitchSpeed = _pitchSpeedSetting.get(_pitchSpeed);
|
_pitchSpeed = _pitchSpeedSetting.get(_pitchSpeed);
|
||||||
|
|
||||||
_prefOverrideAnimGraphUrl.set(_animGraphURLSetting.get().toString());
|
_prefOverrideAnimGraphUrl.set(_animGraphURLSetting.get().toString());
|
||||||
|
@ -2801,8 +2806,8 @@ controller::Pose MyAvatar::getControllerPoseInAvatarFrame(controller::Action act
|
||||||
void MyAvatar::updateMotors() {
|
void MyAvatar::updateMotors() {
|
||||||
_characterController.clearMotors();
|
_characterController.clearMotors();
|
||||||
|
|
||||||
const float FLYING_MOTOR_TIMESCALE = 0.05f;
|
const float FLYING_MOTOR_TIMESCALE = 0.0002f; // Originally 0.05f;
|
||||||
const float WALKING_MOTOR_TIMESCALE = 0.2f;
|
const float WALKING_MOTOR_TIMESCALE = 0.0002f; // Originally 0.2f;
|
||||||
const float INVALID_MOTOR_TIMESCALE = 1.0e6f;
|
const float INVALID_MOTOR_TIMESCALE = 1.0e6f;
|
||||||
|
|
||||||
float horizontalMotorTimescale;
|
float horizontalMotorTimescale;
|
||||||
|
@ -3540,7 +3545,7 @@ void MyAvatar::setRotationThreshold(float angleRadians) {
|
||||||
|
|
||||||
void MyAvatar::updateOrientation(float deltaTime) {
|
void MyAvatar::updateOrientation(float deltaTime) {
|
||||||
// Smoothly rotate body with arrow keys
|
// Smoothly rotate body with arrow keys
|
||||||
float targetSpeed = getDriveKey(YAW) * _yawSpeed;
|
float targetSpeed = getDriveKey(YAW) * (qApp->isHMDMode() ? _hmdYawSpeed : _yawSpeed);
|
||||||
CameraMode mode = qApp->getCamera().getMode();
|
CameraMode mode = qApp->getCamera().getMode();
|
||||||
bool computeLookAt = isReadyForPhysics() && !qApp->isHMDMode() &&
|
bool computeLookAt = isReadyForPhysics() && !qApp->isHMDMode() &&
|
||||||
(mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE);
|
(mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE);
|
||||||
|
@ -3553,7 +3558,7 @@ void MyAvatar::updateOrientation(float deltaTime) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targetSpeed != 0.0f) {
|
if (targetSpeed != 0.0f) {
|
||||||
const float ROTATION_RAMP_TIMESCALE = 0.5f;
|
const float ROTATION_RAMP_TIMESCALE = (qApp->isHMDMode() ? 0.02f : 0.5f);
|
||||||
float blend = deltaTime / ROTATION_RAMP_TIMESCALE;
|
float blend = deltaTime / ROTATION_RAMP_TIMESCALE;
|
||||||
if (blend > 1.0f) {
|
if (blend > 1.0f) {
|
||||||
blend = 1.0f;
|
blend = 1.0f;
|
||||||
|
@ -3561,7 +3566,7 @@ void MyAvatar::updateOrientation(float deltaTime) {
|
||||||
_bodyYawDelta = (1.0f - blend) * _bodyYawDelta + blend * targetSpeed;
|
_bodyYawDelta = (1.0f - blend) * _bodyYawDelta + blend * targetSpeed;
|
||||||
} else if (_bodyYawDelta != 0.0f) {
|
} else if (_bodyYawDelta != 0.0f) {
|
||||||
// attenuate body rotation speed
|
// attenuate body rotation speed
|
||||||
const float ROTATION_DECAY_TIMESCALE = 0.05f;
|
const float ROTATION_DECAY_TIMESCALE = (qApp->isHMDMode() ? 0.001f : 0.05f);
|
||||||
float attenuation = 1.0f - deltaTime / ROTATION_DECAY_TIMESCALE;
|
float attenuation = 1.0f - deltaTime / ROTATION_DECAY_TIMESCALE;
|
||||||
if (attenuation < 0.0f) {
|
if (attenuation < 0.0f) {
|
||||||
attenuation = 0.0f;
|
attenuation = 0.0f;
|
||||||
|
@ -3594,7 +3599,7 @@ void MyAvatar::updateOrientation(float deltaTime) {
|
||||||
const glm::vec3 characterForward = getWorldOrientation() * Vectors::UNIT_NEG_Z;
|
const glm::vec3 characterForward = getWorldOrientation() * Vectors::UNIT_NEG_Z;
|
||||||
float forwardSpeed = glm::dot(characterForward, getWorldVelocity());
|
float forwardSpeed = glm::dot(characterForward, getWorldVelocity());
|
||||||
|
|
||||||
// only enable roll-turns if we are moving forward or backward at greater then MIN_CONTROL_SPEED
|
// only enable roll-turns if we are moving forward or backward at greater than MIN_CONTROL_SPEED
|
||||||
if (fabsf(forwardSpeed) >= MIN_CONTROL_SPEED) {
|
if (fabsf(forwardSpeed) >= MIN_CONTROL_SPEED) {
|
||||||
|
|
||||||
float direction = forwardSpeed > 0.0f ? 1.0f : -1.0f;
|
float direction = forwardSpeed > 0.0f ? 1.0f : -1.0f;
|
||||||
|
@ -4086,7 +4091,7 @@ void MyAvatar::updateActionMotor(float deltaTime) {
|
||||||
float finalMaxMotorSpeed = sensorToWorldScale * DEFAULT_AVATAR_MAX_FLYING_SPEED * _walkSpeedScalar;
|
float finalMaxMotorSpeed = sensorToWorldScale * DEFAULT_AVATAR_MAX_FLYING_SPEED * _walkSpeedScalar;
|
||||||
float speedGrowthTimescale = 2.0f;
|
float speedGrowthTimescale = 2.0f;
|
||||||
float speedIncreaseFactor = 1.8f * _walkSpeedScalar;
|
float speedIncreaseFactor = 1.8f * _walkSpeedScalar;
|
||||||
motorSpeed *= 1.0f + glm::clamp(deltaTime / speedGrowthTimescale, 0.0f, 1.0f) * speedIncreaseFactor;
|
motorSpeed *= 1.0f + glm::pow(glm::clamp(deltaTime / speedGrowthTimescale, 0.0f, 1.0f), 0.7f) * speedIncreaseFactor;
|
||||||
// use feedback from CharacterController to prevent tunneling under high motorspeed
|
// use feedback from CharacterController to prevent tunneling under high motorspeed
|
||||||
motorSpeed *= _characterController.getCollisionBrakeAttenuationFactor();
|
motorSpeed *= _characterController.getCollisionBrakeAttenuationFactor();
|
||||||
const float maxBoostSpeed = sensorToWorldScale * MAX_BOOST_SPEED;
|
const float maxBoostSpeed = sensorToWorldScale * MAX_BOOST_SPEED;
|
||||||
|
|
|
@ -404,6 +404,7 @@ class MyAvatar : public Avatar {
|
||||||
Q_PROPERTY(bool showPlayArea READ getShowPlayArea WRITE setShowPlayArea)
|
Q_PROPERTY(bool showPlayArea READ getShowPlayArea WRITE setShowPlayArea)
|
||||||
|
|
||||||
Q_PROPERTY(float yawSpeed MEMBER _yawSpeed)
|
Q_PROPERTY(float yawSpeed MEMBER _yawSpeed)
|
||||||
|
Q_PROPERTY(float hmdYawSpeed MEMBER _hmdYawSpeed)
|
||||||
Q_PROPERTY(float pitchSpeed MEMBER _pitchSpeed)
|
Q_PROPERTY(float pitchSpeed MEMBER _pitchSpeed)
|
||||||
|
|
||||||
Q_PROPERTY(bool hmdRollControlEnabled READ getHMDRollControlEnabled WRITE setHMDRollControlEnabled)
|
Q_PROPERTY(bool hmdRollControlEnabled READ getHMDRollControlEnabled WRITE setHMDRollControlEnabled)
|
||||||
|
@ -1416,6 +1417,9 @@ public:
|
||||||
float getYawSpeed() const { return _yawSpeed; }
|
float getYawSpeed() const { return _yawSpeed; }
|
||||||
void setYawSpeed(float speed) { _yawSpeed = speed; }
|
void setYawSpeed(float speed) { _yawSpeed = speed; }
|
||||||
|
|
||||||
|
float getHMDYawSpeed() const { return _hmdYawSpeed; }
|
||||||
|
void setHMDYawSpeed(float speed) { _hmdYawSpeed = speed; }
|
||||||
|
|
||||||
static const float ZOOM_MIN;
|
static const float ZOOM_MIN;
|
||||||
static const float ZOOM_MAX;
|
static const float ZOOM_MAX;
|
||||||
static const float ZOOM_DEFAULT;
|
static const float ZOOM_DEFAULT;
|
||||||
|
@ -2755,6 +2759,7 @@ private:
|
||||||
|
|
||||||
float _boomLength { ZOOM_DEFAULT };
|
float _boomLength { ZOOM_DEFAULT };
|
||||||
float _yawSpeed; // degrees/sec
|
float _yawSpeed; // degrees/sec
|
||||||
|
float _hmdYawSpeed; // degrees/sec
|
||||||
float _pitchSpeed; // degrees/sec
|
float _pitchSpeed; // degrees/sec
|
||||||
float _driveGear1 { DEFAULT_GEAR_1 };
|
float _driveGear1 { DEFAULT_GEAR_1 };
|
||||||
float _driveGear2 { DEFAULT_GEAR_2 };
|
float _driveGear2 { DEFAULT_GEAR_2 };
|
||||||
|
@ -3040,6 +3045,7 @@ private:
|
||||||
Setting::Handle<float> _headPitchSetting;
|
Setting::Handle<float> _headPitchSetting;
|
||||||
Setting::Handle<float> _scaleSetting;
|
Setting::Handle<float> _scaleSetting;
|
||||||
Setting::Handle<float> _yawSpeedSetting;
|
Setting::Handle<float> _yawSpeedSetting;
|
||||||
|
Setting::Handle<float> _hmdYawSpeedSetting;
|
||||||
Setting::Handle<float> _pitchSpeedSetting;
|
Setting::Handle<float> _pitchSpeedSetting;
|
||||||
Setting::Handle<QUrl> _fullAvatarURLSetting;
|
Setting::Handle<QUrl> _fullAvatarURLSetting;
|
||||||
Setting::Handle<QUrl> _fullAvatarModelNameSetting;
|
Setting::Handle<QUrl> _fullAvatarModelNameSetting;
|
||||||
|
|
|
@ -400,6 +400,16 @@ void setupPreferences() {
|
||||||
preference->setItems(items);
|
preference->setItems(items);
|
||||||
preferences->addPreference(preference);
|
preferences->addPreference(preference);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
auto getter = [myAvatar]()->float { return myAvatar->getHMDYawSpeed(); };
|
||||||
|
auto setter = [myAvatar](float value) { myAvatar->setHMDYawSpeed(value); };
|
||||||
|
auto preference = new SpinnerSliderPreference(VR_MOVEMENT, "HMD smooth turning sensitivity:", getter, setter);
|
||||||
|
preference->setMin(50.0f);
|
||||||
|
preference->setMax(400.0f);
|
||||||
|
preference->setStep(1);
|
||||||
|
preference->setDecimals(0);
|
||||||
|
preferences->addPreference(preference);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
auto getter = [myAvatar]()->float { return qApp->getCamera().getSensitivity(); };
|
auto getter = [myAvatar]()->float { return qApp->getCamera().getSensitivity(); };
|
||||||
auto setter = [myAvatar](float value) { qApp->getCamera().setSensitivity(value); };
|
auto setter = [myAvatar](float value) { qApp->getCamera().setSensitivity(value); };
|
||||||
|
|
|
@ -927,9 +927,9 @@ void CharacterController::updateState() {
|
||||||
|
|
||||||
const btScalar FLY_TO_GROUND_THRESHOLD = 0.1f * _radius;
|
const btScalar FLY_TO_GROUND_THRESHOLD = 0.1f * _radius;
|
||||||
const btScalar GROUND_TO_FLY_THRESHOLD = 0.8f * _radius + _halfHeight;
|
const btScalar GROUND_TO_FLY_THRESHOLD = 0.8f * _radius + _halfHeight;
|
||||||
const quint64 TAKE_OFF_TO_IN_AIR_PERIOD = 250 * MSECS_PER_SECOND;
|
const quint64 TAKE_OFF_TO_IN_AIR_PERIOD = 5 * MSECS_PER_SECOND; // Originally 250 ms
|
||||||
const btScalar MIN_HOVER_HEIGHT = _scaleFactor * DEFAULT_AVATAR_MIN_HOVER_HEIGHT;
|
const btScalar MIN_HOVER_HEIGHT = _scaleFactor * DEFAULT_AVATAR_MIN_HOVER_HEIGHT;
|
||||||
const quint64 JUMP_TO_HOVER_PERIOD = _scaleFactor < 1.0f ? _scaleFactor * 1100 * MSECS_PER_SECOND : 1100 * MSECS_PER_SECOND;
|
const quint64 JUMP_TO_HOVER_PERIOD = _scaleFactor < 1.0f ? _scaleFactor * 350 * MSECS_PER_SECOND : 350 * MSECS_PER_SECOND; // Originally 1100 ms
|
||||||
|
|
||||||
// scan for distant floor
|
// scan for distant floor
|
||||||
// rayStart is at center of bottom sphere
|
// rayStart is at center of bottom sphere
|
||||||
|
@ -1012,6 +1012,7 @@ void CharacterController::updateState() {
|
||||||
SET_STATE(State::InAir, "takeoff done");
|
SET_STATE(State::InAir, "takeoff done");
|
||||||
|
|
||||||
// compute jumpSpeed based on the scaled jump height for the default avatar in default gravity.
|
// compute jumpSpeed based on the scaled jump height for the default avatar in default gravity.
|
||||||
|
// TODO: we should add scriptable jump height independent of avatar size - it would make making platforming games possible
|
||||||
const float jumpHeight = std::max(_scaleFactor * DEFAULT_AVATAR_JUMP_HEIGHT, DEFAULT_AVATAR_MIN_JUMP_HEIGHT);
|
const float jumpHeight = std::max(_scaleFactor * DEFAULT_AVATAR_JUMP_HEIGHT, DEFAULT_AVATAR_MIN_JUMP_HEIGHT);
|
||||||
const float jumpSpeed = sqrtf(2.0f * -DEFAULT_AVATAR_GRAVITY * jumpHeight);
|
const float jumpSpeed = sqrtf(2.0f * -DEFAULT_AVATAR_GRAVITY * jumpHeight);
|
||||||
velocity += jumpSpeed * _currentUp;
|
velocity += jumpSpeed * _currentUp;
|
||||||
|
|
|
@ -817,10 +817,12 @@ void ViveControllerManager::loadSettings() {
|
||||||
if (_inputDevice) {
|
if (_inputDevice) {
|
||||||
const double DEFAULT_ARM_CIRCUMFERENCE = 0.33;
|
const double DEFAULT_ARM_CIRCUMFERENCE = 0.33;
|
||||||
const double DEFAULT_SHOULDER_WIDTH = 0.48;
|
const double DEFAULT_SHOULDER_WIDTH = 0.48;
|
||||||
|
const float DEFAULT_ZERO_HYSTERESIS_PERIOD = 0.0f; // in seconds, 0.0f for most controllers and 0.2f for Vive wands
|
||||||
const QString DEFAULT_OUT_OF_RANGE_STRATEGY = "DropAfterDelay";
|
const QString DEFAULT_OUT_OF_RANGE_STRATEGY = "DropAfterDelay";
|
||||||
_inputDevice->_armCircumference = settings.value("armCircumference", QVariant(DEFAULT_ARM_CIRCUMFERENCE)).toDouble();
|
_inputDevice->_armCircumference = settings.value("armCircumference", QVariant(DEFAULT_ARM_CIRCUMFERENCE)).toDouble();
|
||||||
_inputDevice->_shoulderWidth = settings.value("shoulderWidth", QVariant(DEFAULT_SHOULDER_WIDTH)).toDouble();
|
_inputDevice->_shoulderWidth = settings.value("shoulderWidth", QVariant(DEFAULT_SHOULDER_WIDTH)).toDouble();
|
||||||
_inputDevice->_outOfRangeDataStrategy = stringToOutOfRangeDataStrategy(settings.value("outOfRangeDataStrategy", QVariant(DEFAULT_OUT_OF_RANGE_STRATEGY)).toString());
|
_inputDevice->_outOfRangeDataStrategy = stringToOutOfRangeDataStrategy(settings.value("outOfRangeDataStrategy", QVariant(DEFAULT_OUT_OF_RANGE_STRATEGY)).toString());
|
||||||
|
_inputDevice->setControllerStickHysteresisTime(settings.value("controllerStickHysteresisTime", QVariant(DEFAULT_ZERO_HYSTERESIS_PERIOD)).toFloat());
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool DEFAULT_EYE_TRACKING_ENABLED = false;
|
const bool DEFAULT_EYE_TRACKING_ENABLED = false;
|
||||||
|
@ -838,6 +840,7 @@ void ViveControllerManager::saveSettings() const {
|
||||||
settings.setValue(QString("armCircumference"), _inputDevice->_armCircumference);
|
settings.setValue(QString("armCircumference"), _inputDevice->_armCircumference);
|
||||||
settings.setValue(QString("shoulderWidth"), _inputDevice->_shoulderWidth);
|
settings.setValue(QString("shoulderWidth"), _inputDevice->_shoulderWidth);
|
||||||
settings.setValue(QString("outOfRangeDataStrategy"), outOfRangeDataStrategyToString(_inputDevice->_outOfRangeDataStrategy));
|
settings.setValue(QString("outOfRangeDataStrategy"), outOfRangeDataStrategyToString(_inputDevice->_outOfRangeDataStrategy));
|
||||||
|
settings.setValue(QString("controllerStickHysteresisTime"), _inputDevice->getControllerStickHysteresisTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.setValue(QString("eyeTrackingEnabled"), _eyeTrackingEnabled);
|
settings.setValue(QString("eyeTrackingEnabled"), _eyeTrackingEnabled);
|
||||||
|
@ -858,6 +861,13 @@ ViveControllerManager::InputDevice::InputDevice(vr::IVRSystem*& system) :
|
||||||
_configStringMap[Config::FeetHipsChestAndShoulders] = QString("FeetHipsChestAndShoulders");
|
_configStringMap[Config::FeetHipsChestAndShoulders] = QString("FeetHipsChestAndShoulders");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ViveControllerManager::InputDevice::setControllerStickHysteresisTime(float value) {
|
||||||
|
qDebug() << "ViveControllerManager::InputDevice::setControllerStickHysteresisTime: " << value;
|
||||||
|
_filteredLeftStick.setHysteresisPeriod(value);
|
||||||
|
_filteredRightStick.setHysteresisPeriod(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ViveControllerManager::InputDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
|
void ViveControllerManager::InputDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
|
||||||
_poseStateMap.clear();
|
_poseStateMap.clear();
|
||||||
_buttonPressedMap.clear();
|
_buttonPressedMap.clear();
|
||||||
|
@ -988,6 +998,9 @@ void ViveControllerManager::InputDevice::configureCalibrationSettings(const QJso
|
||||||
hmdDesktopMode = iter.value().toBool();
|
hmdDesktopMode = iter.value().toBool();
|
||||||
} else if (iter.key() == "outOfRangeDataStrategy") {
|
} else if (iter.key() == "outOfRangeDataStrategy") {
|
||||||
_outOfRangeDataStrategy = stringToOutOfRangeDataStrategy(iter.value().toString());
|
_outOfRangeDataStrategy = stringToOutOfRangeDataStrategy(iter.value().toString());
|
||||||
|
} else if (iter.key() == "controllerStickHysteresisTime") {
|
||||||
|
qDebug() << "controllerStickHysteresisTime: " << iter.value().toDouble();
|
||||||
|
setControllerStickHysteresisTime(iter.value().toDouble());
|
||||||
}
|
}
|
||||||
iter++;
|
iter++;
|
||||||
}
|
}
|
||||||
|
@ -1011,6 +1024,7 @@ QJsonObject ViveControllerManager::InputDevice::configurationSettings() {
|
||||||
configurationSettings["armCircumference"] = (double)(_armCircumference * M_TO_CM);
|
configurationSettings["armCircumference"] = (double)(_armCircumference * M_TO_CM);
|
||||||
configurationSettings["shoulderWidth"] = (double)(_shoulderWidth * M_TO_CM);
|
configurationSettings["shoulderWidth"] = (double)(_shoulderWidth * M_TO_CM);
|
||||||
configurationSettings["outOfRangeDataStrategy"] = outOfRangeDataStrategyToString(_outOfRangeDataStrategy);
|
configurationSettings["outOfRangeDataStrategy"] = outOfRangeDataStrategyToString(_outOfRangeDataStrategy);
|
||||||
|
configurationSettings["controllerStickHysteresisTime"] = getControllerStickHysteresisTime();
|
||||||
return configurationSettings;
|
return configurationSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,6 +105,9 @@ private:
|
||||||
public:
|
public:
|
||||||
InputDevice(vr::IVRSystem*& system);
|
InputDevice(vr::IVRSystem*& system);
|
||||||
bool isHeadControllerMounted() const { return _overrideHead; }
|
bool isHeadControllerMounted() const { return _overrideHead; }
|
||||||
|
float getControllerStickHysteresisTime() { return _filteredLeftStick.getHysteresisPeriod(); };
|
||||||
|
// Sets hysteresis period for the filter. This is a workaround needed only for Vive wands which use value 0.2f.
|
||||||
|
void setControllerStickHysteresisTime(float value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Device functions
|
// Device functions
|
||||||
|
@ -156,10 +159,12 @@ private:
|
||||||
|
|
||||||
class FilteredStick {
|
class FilteredStick {
|
||||||
public:
|
public:
|
||||||
|
float getHysteresisPeriod() { return _hysteresis_period; };
|
||||||
|
// Sets hysteresis period for the filter. This is a workaround needed only for Vive wands which use value 0.2f.
|
||||||
|
void setHysteresisPeriod(float value) { _hysteresis_period = value; };
|
||||||
glm::vec2 process(float deltaTime, const glm::vec2& stick) {
|
glm::vec2 process(float deltaTime, const glm::vec2& stick) {
|
||||||
// Use a timer to prevent the stick going to back to zero.
|
// Use a timer to prevent the stick going back to zero.
|
||||||
// This to work around the noisy touch pad that will flash back to zero breifly
|
// This to work around the noisy touchpad that will flash back to zero briefly
|
||||||
const float ZERO_HYSTERESIS_PERIOD = 0.2f; // 200 ms
|
|
||||||
if (glm::length(stick) == 0.0f) {
|
if (glm::length(stick) == 0.0f) {
|
||||||
if (_timer <= 0.0f) {
|
if (_timer <= 0.0f) {
|
||||||
return glm::vec2(0.0f, 0.0f);
|
return glm::vec2(0.0f, 0.0f);
|
||||||
|
@ -168,12 +173,13 @@ private:
|
||||||
return _stick;
|
return _stick;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_timer = ZERO_HYSTERESIS_PERIOD;
|
_timer = _hysteresis_period;
|
||||||
_stick = stick;
|
_stick = stick;
|
||||||
return stick;
|
return stick;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
|
float _hysteresis_period{ 0.0f };
|
||||||
float _timer { 0.0f };
|
float _timer { 0.0f };
|
||||||
glm::vec2 _stick { 0.0f, 0.0f };
|
glm::vec2 _stick { 0.0f, 0.0f };
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue