Merge pull request #345 from OpenVR-Advanced-Settings/friction

Add friction feature to motion tab
This commit is contained in:
Kung-vr
2020-01-03 14:02:15 +09:00
committed by GitHub
5 changed files with 120 additions and 24 deletions
@@ -113,6 +113,43 @@ GroupBox {
}
}
Item {
Layout.preferredWidth: 40
}
MyText {
text: "Friction:"
horizontalAlignment: Text.AlignRight
Layout.rightMargin: 2
}
MyTextField {
id: frictionPercentText
text: "0%"
keyBoardUID: 156
Layout.preferredWidth: 130
Layout.leftMargin: 5
horizontalAlignment: Text.AlignHCenter
function onInputEvent(input) {
var val = parseInt(input)
if (!isNaN(val)) {
if ( val > 999 )
{
val = 999
}
if ( val < 0 )
{
val = 0
}
MoveCenterTabController.frictionPercent = val
text = MoveCenterTabController.frictionPercent + "%"
} else {
text = MoveCenterTabController.frictionPercent + "%"
}
}
}
Item {
Layout.fillWidth: true
}
@@ -166,14 +203,6 @@ GroupBox {
}
}
MyPushButton2 {
Layout.preferredWidth: 50
text: "4x"
onClicked: {
MoveCenterTabController.flingStrength = 4.0
}
}
}
}
@@ -183,6 +212,7 @@ GroupBox {
gravityStrengthText.text = MoveCenterTabController.gravityStrength.toFixed(2)
momentumToggleButton.checked = MoveCenterTabController.momentumSave
flingStrengthText.text = MoveCenterTabController.flingStrength.toFixed(2)
frictionPercentText.text = MoveCenterTabController.frictionPercent + "%"
}
Connections {
@@ -200,5 +230,8 @@ GroupBox {
onFlingStrengthChanged: {
flingStrengthText.text = MoveCenterTabController.flingStrength.toFixed(2)
}
onFrictionPercentChanged: {
frictionPercentText.text = MoveCenterTabController.frictionPercent + "%"
}
}
}
@@ -455,6 +455,10 @@ private:
SettingCategory::Playspace,
QtInfo{ "turnComfortFactor" },
0 },
IntSettingValue{ IntSetting::PLAYSPACE_frictionPercent,
SettingCategory::Playspace,
QtInfo{ "frictionPercent" },
0 },
IntSettingValue{ IntSetting::APPLICATION_debugState,
SettingCategory::Application,
+1
View File
@@ -90,6 +90,7 @@ enum class IntSetting
PLAYSPACE_smoothTurnRate,
PLAYSPACE_dragComfortFactor,
PLAYSPACE_turnComfortFactor,
PLAYSPACE_frictionPercent,
APPLICATION_debugState,
APPLICATION_customTickRateMs,
+66 -16
View File
@@ -464,6 +464,12 @@ int MoveCenterTabController::smoothTurnRate() const
settings::IntSetting::PLAYSPACE_smoothTurnRate );
}
int MoveCenterTabController::frictionPercent() const
{
return settings::getSetting(
settings::IntSetting::PLAYSPACE_frictionPercent );
}
void MoveCenterTabController::setSmoothTurnRate( int value, bool notify )
{
settings::setSetting( settings::IntSetting::PLAYSPACE_smoothTurnRate,
@@ -475,6 +481,17 @@ void MoveCenterTabController::setSmoothTurnRate( int value, bool notify )
}
}
void MoveCenterTabController::setFrictionPercent( int value, bool notify )
{
settings::setSetting( settings::IntSetting::PLAYSPACE_frictionPercent,
value );
if ( notify )
{
emit frictionPercentChanged( value );
}
}
bool MoveCenterTabController::adjustChaperone() const
{
return settings::getSetting(
@@ -1929,12 +1946,6 @@ void MoveCenterTabController::gravityToggleAction(
void MoveCenterTabController::gravityReverseAction( bool gravityReverseHeld )
{
// detect new press or new release
if ( ( gravityReverseHeld && !m_gravityReversed )
|| ( !gravityReverseHeld && m_gravityReversed ) )
{
setGravityStrength( gravityStrength() * -1.0f );
}
m_gravityReversed = gravityReverseHeld;
}
@@ -2374,6 +2385,50 @@ void MoveCenterTabController::updateHandTurn(
void MoveCenterTabController::updateGravity()
{
float currentGravity = gravityStrength();
if ( m_gravityReversed )
{
currentGravity *= -1.0f;
}
double secondsSinceLastGravityUpdate
= std::chrono::duration<double>( std::chrono::steady_clock::now()
- m_lastGravityUpdateTimePoint )
.count();
// apply friction
if ( frictionPercent() > 0 )
{
// if we have friction and all velocity components are less than
// halt speed, we stop.
if ( abs( m_velocity[0] ) < k_frictionHalt_mps
&& abs( m_velocity[1] ) < k_frictionHalt_mps
&& abs( m_velocity[2] ) < k_frictionHalt_mps )
{
m_velocity[0] = 0.0;
m_velocity[1] = 0.0;
m_velocity[2] = 0.0;
}
else
{
// frictionPercent() * 10 is scaler such that at 90fps we
// reduce from terminal velocity (50m/s) to about 1mm/s in 1
// second using 100% friction. This is an arbitrary scaler,
// but doing a more accurate job would require a performance
// hit of the math pow() function to an arbitrary exponent.
double frictionVelocityMultiplier
= ( 100.0
- ( static_cast<double>( frictionPercent() * 10 )
* secondsSinceLastGravityUpdate ) )
/ 100.0;
frictionVelocityMultiplier
= std::clamp( frictionVelocityMultiplier, 0.0, 1.0 );
m_velocity[0] *= frictionVelocityMultiplier;
m_velocity[1] *= frictionVelocityMultiplier;
m_velocity[2] *= frictionVelocityMultiplier;
}
}
// prevent velocity underflow
if ( std::isnan( m_velocity[0] ) )
{
@@ -2405,23 +2460,18 @@ void MoveCenterTabController::updateGravity()
m_velocity[2] = 0.0;
}
double secondsSinceLastGravityUpdate
= std::chrono::duration<double>( std::chrono::steady_clock::now()
- m_lastGravityUpdateTimePoint )
.count();
// are we falling?
// note: up is negative y
// note: set to always fall if gravity reversed (strength < 0)
if ( ( m_offsetY < m_gravityFloor ) || ( gravityStrength() < 0 ) )
// note: set to always fall if gravity reversed (currentGravity < 0)
if ( ( m_offsetY < m_gravityFloor ) || ( currentGravity < 0 ) )
{
// check if we're about to land
// note: we don't land if gravity is reversed (strength < 0)
// note: we don't land if gravity is reversed (currentGravity < 0)
if ( ( m_offsetY
+ static_cast<float>( m_velocity[1]
* secondsSinceLastGravityUpdate )
>= m_gravityFloor )
&& gravityStrength() >= 0 )
&& currentGravity >= 0 )
{
// get ratio of how much from y velocity applied to overcome y
// offset and get down to ground.
@@ -2462,7 +2512,7 @@ void MoveCenterTabController::updateGravity()
// accelerate downward velocity for the next update
// note: downward is positive y
m_velocity[1] = m_velocity[1]
+ ( static_cast<double>( gravityStrength() )
+ ( static_cast<double>( currentGravity )
* secondsSinceLastGravityUpdate );
return;
}
@@ -17,6 +17,9 @@ constexpr double k_radiansToCentidegrees = 18000.0 / M_PI;
constexpr double k_quaternionInvalidValue = -1000.0;
constexpr double k_quaternionUnderIsInvalidValueThreshold = -900.0;
constexpr double k_terminalVelocity_mps = 50.0;
// k_frictionHalt_mps must be sufficiently small to allow a single tick of
// gravity through
constexpr double k_frictionHalt_mps = 0.0000001;
// give the max offset a buffer to avoid crossing when traveling at astronomical
// velocities
constexpr double k_maxOpenvrWorkingSetOffest = 39900.0;
@@ -53,6 +56,8 @@ class MoveCenterTabController : public QObject
NOTIFY snapTurnAngleChanged )
Q_PROPERTY( int smoothTurnRate READ smoothTurnRate WRITE setSmoothTurnRate
NOTIFY smoothTurnRateChanged )
Q_PROPERTY( int frictionPercent READ frictionPercent WRITE
setFrictionPercent NOTIFY frictionPercentChanged )
Q_PROPERTY( bool adjustChaperone READ adjustChaperone WRITE
setAdjustChaperone NOTIFY adjustChaperoneChanged )
Q_PROPERTY( bool moveShortcutRight READ moveShortcutRight WRITE
@@ -214,6 +219,7 @@ public:
int tempRotation() const;
int snapTurnAngle() const;
int smoothTurnRate() const;
int frictionPercent() const;
bool adjustChaperone() const;
bool moveShortcutRight() const;
bool moveShortcutLeft() const;
@@ -285,6 +291,7 @@ public slots:
void setTempRotation( int value, bool notify = true );
void setSnapTurnAngle( int value, bool notify = true );
void setSmoothTurnRate( int value, bool notify = true );
void setFrictionPercent( int value, bool notify = true );
void setAdjustChaperone( bool value, bool notify = true );
void setMoveShortcutRight( bool value, bool notify = true );
@@ -336,6 +343,7 @@ signals:
void tempRotationChanged( int value );
void snapTurnAngleChanged( int value );
void smoothTurnRateChanged( int value );
void frictionPercentChanged( int value );
void adjustChaperoneChanged( bool value );
void moveShortcutRightChanged( bool value );
void moveShortcutLeftChanged( bool value );