@@ -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 {
|
Item {
|
||||||
Layout.fillWidth: true
|
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)
|
gravityStrengthText.text = MoveCenterTabController.gravityStrength.toFixed(2)
|
||||||
momentumToggleButton.checked = MoveCenterTabController.momentumSave
|
momentumToggleButton.checked = MoveCenterTabController.momentumSave
|
||||||
flingStrengthText.text = MoveCenterTabController.flingStrength.toFixed(2)
|
flingStrengthText.text = MoveCenterTabController.flingStrength.toFixed(2)
|
||||||
|
frictionPercentText.text = MoveCenterTabController.frictionPercent + "%"
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
@@ -200,5 +230,8 @@ GroupBox {
|
|||||||
onFlingStrengthChanged: {
|
onFlingStrengthChanged: {
|
||||||
flingStrengthText.text = MoveCenterTabController.flingStrength.toFixed(2)
|
flingStrengthText.text = MoveCenterTabController.flingStrength.toFixed(2)
|
||||||
}
|
}
|
||||||
|
onFrictionPercentChanged: {
|
||||||
|
frictionPercentText.text = MoveCenterTabController.frictionPercent + "%"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -455,6 +455,10 @@ private:
|
|||||||
SettingCategory::Playspace,
|
SettingCategory::Playspace,
|
||||||
QtInfo{ "turnComfortFactor" },
|
QtInfo{ "turnComfortFactor" },
|
||||||
0 },
|
0 },
|
||||||
|
IntSettingValue{ IntSetting::PLAYSPACE_frictionPercent,
|
||||||
|
SettingCategory::Playspace,
|
||||||
|
QtInfo{ "frictionPercent" },
|
||||||
|
0 },
|
||||||
|
|
||||||
IntSettingValue{ IntSetting::APPLICATION_debugState,
|
IntSettingValue{ IntSetting::APPLICATION_debugState,
|
||||||
SettingCategory::Application,
|
SettingCategory::Application,
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ enum class IntSetting
|
|||||||
PLAYSPACE_smoothTurnRate,
|
PLAYSPACE_smoothTurnRate,
|
||||||
PLAYSPACE_dragComfortFactor,
|
PLAYSPACE_dragComfortFactor,
|
||||||
PLAYSPACE_turnComfortFactor,
|
PLAYSPACE_turnComfortFactor,
|
||||||
|
PLAYSPACE_frictionPercent,
|
||||||
|
|
||||||
APPLICATION_debugState,
|
APPLICATION_debugState,
|
||||||
APPLICATION_customTickRateMs,
|
APPLICATION_customTickRateMs,
|
||||||
|
|||||||
@@ -464,6 +464,12 @@ int MoveCenterTabController::smoothTurnRate() const
|
|||||||
settings::IntSetting::PLAYSPACE_smoothTurnRate );
|
settings::IntSetting::PLAYSPACE_smoothTurnRate );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int MoveCenterTabController::frictionPercent() const
|
||||||
|
{
|
||||||
|
return settings::getSetting(
|
||||||
|
settings::IntSetting::PLAYSPACE_frictionPercent );
|
||||||
|
}
|
||||||
|
|
||||||
void MoveCenterTabController::setSmoothTurnRate( int value, bool notify )
|
void MoveCenterTabController::setSmoothTurnRate( int value, bool notify )
|
||||||
{
|
{
|
||||||
settings::setSetting( settings::IntSetting::PLAYSPACE_smoothTurnRate,
|
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
|
bool MoveCenterTabController::adjustChaperone() const
|
||||||
{
|
{
|
||||||
return settings::getSetting(
|
return settings::getSetting(
|
||||||
@@ -1929,12 +1946,6 @@ void MoveCenterTabController::gravityToggleAction(
|
|||||||
|
|
||||||
void MoveCenterTabController::gravityReverseAction( bool gravityReverseHeld )
|
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;
|
m_gravityReversed = gravityReverseHeld;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2374,6 +2385,50 @@ void MoveCenterTabController::updateHandTurn(
|
|||||||
|
|
||||||
void MoveCenterTabController::updateGravity()
|
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
|
// prevent velocity underflow
|
||||||
if ( std::isnan( m_velocity[0] ) )
|
if ( std::isnan( m_velocity[0] ) )
|
||||||
{
|
{
|
||||||
@@ -2405,23 +2460,18 @@ void MoveCenterTabController::updateGravity()
|
|||||||
m_velocity[2] = 0.0;
|
m_velocity[2] = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
double secondsSinceLastGravityUpdate
|
|
||||||
= std::chrono::duration<double>( std::chrono::steady_clock::now()
|
|
||||||
- m_lastGravityUpdateTimePoint )
|
|
||||||
.count();
|
|
||||||
|
|
||||||
// are we falling?
|
// are we falling?
|
||||||
// note: up is negative y
|
// note: up is negative y
|
||||||
// note: set to always fall if gravity reversed (strength < 0)
|
// note: set to always fall if gravity reversed (currentGravity < 0)
|
||||||
if ( ( m_offsetY < m_gravityFloor ) || ( gravityStrength() < 0 ) )
|
if ( ( m_offsetY < m_gravityFloor ) || ( currentGravity < 0 ) )
|
||||||
{
|
{
|
||||||
// check if we're about to land
|
// 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
|
if ( ( m_offsetY
|
||||||
+ static_cast<float>( m_velocity[1]
|
+ static_cast<float>( m_velocity[1]
|
||||||
* secondsSinceLastGravityUpdate )
|
* secondsSinceLastGravityUpdate )
|
||||||
>= m_gravityFloor )
|
>= m_gravityFloor )
|
||||||
&& gravityStrength() >= 0 )
|
&& currentGravity >= 0 )
|
||||||
{
|
{
|
||||||
// get ratio of how much from y velocity applied to overcome y
|
// get ratio of how much from y velocity applied to overcome y
|
||||||
// offset and get down to ground.
|
// offset and get down to ground.
|
||||||
@@ -2462,7 +2512,7 @@ void MoveCenterTabController::updateGravity()
|
|||||||
// accelerate downward velocity for the next update
|
// accelerate downward velocity for the next update
|
||||||
// note: downward is positive y
|
// note: downward is positive y
|
||||||
m_velocity[1] = m_velocity[1]
|
m_velocity[1] = m_velocity[1]
|
||||||
+ ( static_cast<double>( gravityStrength() )
|
+ ( static_cast<double>( currentGravity )
|
||||||
* secondsSinceLastGravityUpdate );
|
* secondsSinceLastGravityUpdate );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ constexpr double k_radiansToCentidegrees = 18000.0 / M_PI;
|
|||||||
constexpr double k_quaternionInvalidValue = -1000.0;
|
constexpr double k_quaternionInvalidValue = -1000.0;
|
||||||
constexpr double k_quaternionUnderIsInvalidValueThreshold = -900.0;
|
constexpr double k_quaternionUnderIsInvalidValueThreshold = -900.0;
|
||||||
constexpr double k_terminalVelocity_mps = 50.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
|
// give the max offset a buffer to avoid crossing when traveling at astronomical
|
||||||
// velocities
|
// velocities
|
||||||
constexpr double k_maxOpenvrWorkingSetOffest = 39900.0;
|
constexpr double k_maxOpenvrWorkingSetOffest = 39900.0;
|
||||||
@@ -53,6 +56,8 @@ class MoveCenterTabController : public QObject
|
|||||||
NOTIFY snapTurnAngleChanged )
|
NOTIFY snapTurnAngleChanged )
|
||||||
Q_PROPERTY( int smoothTurnRate READ smoothTurnRate WRITE setSmoothTurnRate
|
Q_PROPERTY( int smoothTurnRate READ smoothTurnRate WRITE setSmoothTurnRate
|
||||||
NOTIFY smoothTurnRateChanged )
|
NOTIFY smoothTurnRateChanged )
|
||||||
|
Q_PROPERTY( int frictionPercent READ frictionPercent WRITE
|
||||||
|
setFrictionPercent NOTIFY frictionPercentChanged )
|
||||||
Q_PROPERTY( bool adjustChaperone READ adjustChaperone WRITE
|
Q_PROPERTY( bool adjustChaperone READ adjustChaperone WRITE
|
||||||
setAdjustChaperone NOTIFY adjustChaperoneChanged )
|
setAdjustChaperone NOTIFY adjustChaperoneChanged )
|
||||||
Q_PROPERTY( bool moveShortcutRight READ moveShortcutRight WRITE
|
Q_PROPERTY( bool moveShortcutRight READ moveShortcutRight WRITE
|
||||||
@@ -214,6 +219,7 @@ public:
|
|||||||
int tempRotation() const;
|
int tempRotation() const;
|
||||||
int snapTurnAngle() const;
|
int snapTurnAngle() const;
|
||||||
int smoothTurnRate() const;
|
int smoothTurnRate() const;
|
||||||
|
int frictionPercent() const;
|
||||||
bool adjustChaperone() const;
|
bool adjustChaperone() const;
|
||||||
bool moveShortcutRight() const;
|
bool moveShortcutRight() const;
|
||||||
bool moveShortcutLeft() const;
|
bool moveShortcutLeft() const;
|
||||||
@@ -285,6 +291,7 @@ public slots:
|
|||||||
void setTempRotation( int value, bool notify = true );
|
void setTempRotation( int value, bool notify = true );
|
||||||
void setSnapTurnAngle( int value, bool notify = true );
|
void setSnapTurnAngle( int value, bool notify = true );
|
||||||
void setSmoothTurnRate( 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 setAdjustChaperone( bool value, bool notify = true );
|
||||||
void setMoveShortcutRight( bool value, bool notify = true );
|
void setMoveShortcutRight( bool value, bool notify = true );
|
||||||
@@ -336,6 +343,7 @@ signals:
|
|||||||
void tempRotationChanged( int value );
|
void tempRotationChanged( int value );
|
||||||
void snapTurnAngleChanged( int value );
|
void snapTurnAngleChanged( int value );
|
||||||
void smoothTurnRateChanged( int value );
|
void smoothTurnRateChanged( int value );
|
||||||
|
void frictionPercentChanged( int value );
|
||||||
void adjustChaperoneChanged( bool value );
|
void adjustChaperoneChanged( bool value );
|
||||||
void moveShortcutRightChanged( bool value );
|
void moveShortcutRightChanged( bool value );
|
||||||
void moveShortcutLeftChanged( bool value );
|
void moveShortcutLeftChanged( bool value );
|
||||||
|
|||||||
Reference in New Issue
Block a user