Lower inertia for more precise controls

This commit is contained in:
ksuprynowicz 2023-08-02 22:00:12 +02:00
parent 55c070d731
commit 74c5b6038f
4 changed files with 31 additions and 9 deletions

View file

@ -79,6 +79,7 @@ using namespace std;
const float DEFAULT_REAL_WORLD_FIELD_OF_VIEW_DEGREES = 30.0f;
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 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) :
Avatar(thread),
_yawSpeed(YAW_SPEED_DEFAULT),
_hmdYawSpeed(HMD_YAW_SPEED_DEFAULT),
_pitchSpeed(PITCH_SPEED_DEFAULT),
_scriptedMotorTimescale(DEFAULT_SCRIPTED_MOTOR_TIMESCALE),
_scriptedMotorFrame(SCRIPTED_MOTOR_CAMERA_FRAME),
@ -222,6 +224,7 @@ MyAvatar::MyAvatar(QThread* thread) :
_headPitchSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "", 0.0f),
_scaleSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "scale", _targetScale),
_yawSpeedSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "yawSpeed", _yawSpeed),
_hmdYawSpeedSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "hmdYawSpeed", _hmdYawSpeed),
_pitchSpeedSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "pitchSpeed", _pitchSpeed),
_fullAvatarURLSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "fullAvatarURL",
AvatarData::defaultFullAvatarModelUrl()),
@ -1335,6 +1338,7 @@ void MyAvatar::saveData() {
_headPitchSetting.set(getHead()->getBasePitch());
_scaleSetting.set(_targetScale);
_yawSpeedSetting.set(_yawSpeed);
_hmdYawSpeedSetting.set(_hmdYawSpeed);
_pitchSpeedSetting.set(_pitchSpeed);
// only save the fullAvatarURL if it has not been overwritten on command line
@ -2094,6 +2098,7 @@ void MyAvatar::loadData() {
getHead()->setBasePitch(_headPitchSetting.get());
_yawSpeed = _yawSpeedSetting.get(_yawSpeed);
_hmdYawSpeed = _hmdYawSpeedSetting.get(_hmdYawSpeed);
_pitchSpeed = _pitchSpeedSetting.get(_pitchSpeed);
_prefOverrideAnimGraphUrl.set(_animGraphURLSetting.get().toString());
@ -2801,8 +2806,8 @@ controller::Pose MyAvatar::getControllerPoseInAvatarFrame(controller::Action act
void MyAvatar::updateMotors() {
_characterController.clearMotors();
const float FLYING_MOTOR_TIMESCALE = 0.05f;
const float WALKING_MOTOR_TIMESCALE = 0.2f;
const float FLYING_MOTOR_TIMESCALE = 0.0002f; // Originally 0.05f;
const float WALKING_MOTOR_TIMESCALE = 0.0002f; // Originally 0.2f;
const float INVALID_MOTOR_TIMESCALE = 1.0e6f;
float horizontalMotorTimescale;
@ -3540,7 +3545,7 @@ void MyAvatar::setRotationThreshold(float angleRadians) {
void MyAvatar::updateOrientation(float deltaTime) {
// Smoothly rotate body with arrow keys
float targetSpeed = getDriveKey(YAW) * _yawSpeed;
float targetSpeed = getDriveKey(YAW) * (qApp->isHMDMode() ? _hmdYawSpeed : _yawSpeed);
CameraMode mode = qApp->getCamera().getMode();
bool computeLookAt = isReadyForPhysics() && !qApp->isHMDMode() &&
(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) {
const float ROTATION_RAMP_TIMESCALE = 0.5f;
const float ROTATION_RAMP_TIMESCALE = (qApp->isHMDMode() ? 0.02f : 0.5f);
float blend = deltaTime / ROTATION_RAMP_TIMESCALE;
if (blend > 1.0f) {
blend = 1.0f;
@ -3561,7 +3566,7 @@ void MyAvatar::updateOrientation(float deltaTime) {
_bodyYawDelta = (1.0f - blend) * _bodyYawDelta + blend * targetSpeed;
} else if (_bodyYawDelta != 0.0f) {
// 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;
if (attenuation < 0.0f) {
attenuation = 0.0f;
@ -3594,7 +3599,7 @@ void MyAvatar::updateOrientation(float deltaTime) {
const glm::vec3 characterForward = getWorldOrientation() * Vectors::UNIT_NEG_Z;
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) {
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 speedGrowthTimescale = 2.0f;
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
motorSpeed *= _characterController.getCollisionBrakeAttenuationFactor();
const float maxBoostSpeed = sensorToWorldScale * MAX_BOOST_SPEED;

View file

@ -404,6 +404,7 @@ class MyAvatar : public Avatar {
Q_PROPERTY(bool showPlayArea READ getShowPlayArea WRITE setShowPlayArea)
Q_PROPERTY(float yawSpeed MEMBER _yawSpeed)
Q_PROPERTY(float hmdYawSpeed MEMBER _hmdYawSpeed)
Q_PROPERTY(float pitchSpeed MEMBER _pitchSpeed)
Q_PROPERTY(bool hmdRollControlEnabled READ getHMDRollControlEnabled WRITE setHMDRollControlEnabled)
@ -1416,6 +1417,9 @@ public:
float getYawSpeed() const { return _yawSpeed; }
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_MAX;
static const float ZOOM_DEFAULT;
@ -2755,6 +2759,7 @@ private:
float _boomLength { ZOOM_DEFAULT };
float _yawSpeed; // degrees/sec
float _hmdYawSpeed; // degrees/sec
float _pitchSpeed; // degrees/sec
float _driveGear1 { DEFAULT_GEAR_1 };
float _driveGear2 { DEFAULT_GEAR_2 };
@ -3040,6 +3045,7 @@ private:
Setting::Handle<float> _headPitchSetting;
Setting::Handle<float> _scaleSetting;
Setting::Handle<float> _yawSpeedSetting;
Setting::Handle<float> _hmdYawSpeedSetting;
Setting::Handle<float> _pitchSpeedSetting;
Setting::Handle<QUrl> _fullAvatarURLSetting;
Setting::Handle<QUrl> _fullAvatarModelNameSetting;

View file

@ -400,6 +400,16 @@ void setupPreferences() {
preference->setItems(items);
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 setter = [myAvatar](float value) { qApp->getCamera().setSensitivity(value); };

View file

@ -927,9 +927,9 @@ void CharacterController::updateState() {
const btScalar FLY_TO_GROUND_THRESHOLD = 0.1f * _radius;
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 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
// rayStart is at center of bottom sphere
@ -1012,6 +1012,7 @@ void CharacterController::updateState() {
SET_STATE(State::InAir, "takeoff done");
// 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 jumpSpeed = sqrtf(2.0f * -DEFAULT_AVATAR_GRAVITY * jumpHeight);
velocity += jumpSpeed * _currentUp;