mirror of
https://github.com/overte-org/overte.git
synced 2025-04-16 21:02:17 +02:00
Merge pull request #11894 from hyperlogic/bug-fix/flying
Improvements to HMD flying
This commit is contained in:
commit
ed231fa4a1
3 changed files with 48 additions and 26 deletions
|
@ -13,11 +13,11 @@
|
|||
|
||||
{ "from": "OculusTouch.LY", "to": "Standard.LY",
|
||||
"filters": [
|
||||
{ "type": "deadZone", "min": 0.3 },
|
||||
{ "type": "deadZone", "min": 0.7 },
|
||||
"invert"
|
||||
]
|
||||
},
|
||||
{ "from": "OculusTouch.LX", "filters": { "type": "deadZone", "min": 0.3 }, "to": "Standard.LX" },
|
||||
{ "from": "OculusTouch.LX", "filters": { "type": "deadZone", "min": 0.7 }, "to": "Standard.LX" },
|
||||
{ "from": "OculusTouch.LT", "to": "Standard.LTClick",
|
||||
"peek": true,
|
||||
"filters": [ { "type": "hysteresis", "min": 0.85, "max": 0.9 } ]
|
||||
|
@ -29,11 +29,11 @@
|
|||
|
||||
{ "from": "OculusTouch.RY", "to": "Standard.RY",
|
||||
"filters": [
|
||||
{ "type": "deadZone", "min": 0.3 },
|
||||
{ "type": "deadZone", "min": 0.7 },
|
||||
"invert"
|
||||
]
|
||||
},
|
||||
{ "from": "OculusTouch.RX", "filters": { "type": "deadZone", "min": 0.3 }, "to": "Standard.RX" },
|
||||
{ "from": "OculusTouch.RX", "filters": { "type": "deadZone", "min": 0.7 }, "to": "Standard.RX" },
|
||||
{ "from": "OculusTouch.RT", "to": "Standard.RTClick",
|
||||
"peek": true,
|
||||
"filters": [ { "type": "hysteresis", "min": 0.85, "max": 0.9 } ]
|
||||
|
|
|
@ -1516,9 +1516,19 @@ void MyAvatar::updateMotors() {
|
|||
_characterController.clearMotors();
|
||||
glm::quat motorRotation;
|
||||
if (_motionBehaviors & AVATAR_MOTION_ACTION_MOTOR_ENABLED) {
|
||||
|
||||
const float FLYING_MOTOR_TIMESCALE = 0.05f;
|
||||
const float WALKING_MOTOR_TIMESCALE = 0.2f;
|
||||
const float INVALID_MOTOR_TIMESCALE = 1.0e6f;
|
||||
|
||||
float horizontalMotorTimescale;
|
||||
float verticalMotorTimescale;
|
||||
|
||||
if (_characterController.getState() == CharacterController::State::Hover ||
|
||||
_characterController.computeCollisionGroup() == BULLET_COLLISION_GROUP_COLLISIONLESS) {
|
||||
motorRotation = getMyHead()->getHeadOrientation();
|
||||
horizontalMotorTimescale = FLYING_MOTOR_TIMESCALE;
|
||||
verticalMotorTimescale = FLYING_MOTOR_TIMESCALE;
|
||||
} else {
|
||||
// non-hovering = walking: follow camera twist about vertical but not lift
|
||||
// we decompose camera's rotation and store the twist part in motorRotation
|
||||
|
@ -1529,11 +1539,12 @@ void MyAvatar::updateMotors() {
|
|||
glm::quat liftRotation;
|
||||
swingTwistDecomposition(headOrientation, Vectors::UNIT_Y, liftRotation, motorRotation);
|
||||
motorRotation = orientation * motorRotation;
|
||||
horizontalMotorTimescale = WALKING_MOTOR_TIMESCALE;
|
||||
verticalMotorTimescale = INVALID_MOTOR_TIMESCALE;
|
||||
}
|
||||
const float DEFAULT_MOTOR_TIMESCALE = 0.2f;
|
||||
const float INVALID_MOTOR_TIMESCALE = 1.0e6f;
|
||||
|
||||
if (_isPushing || _isBraking || !_isBeingPushed) {
|
||||
_characterController.addMotor(_actionMotorVelocity, motorRotation, DEFAULT_MOTOR_TIMESCALE, INVALID_MOTOR_TIMESCALE);
|
||||
_characterController.addMotor(_actionMotorVelocity, motorRotation, horizontalMotorTimescale, verticalMotorTimescale);
|
||||
} else {
|
||||
// _isBeingPushed must be true --> disable action motor by giving it a long timescale,
|
||||
// otherwise it's attempt to "stand in in place" could defeat scripted motor/thrusts
|
||||
|
@ -1957,27 +1968,33 @@ void MyAvatar::updateOrientation(float deltaTime) {
|
|||
|
||||
// Use head/HMD roll to turn while flying, but not when standing still.
|
||||
if (qApp->isHMDMode() && getCharacterController()->getState() == CharacterController::State::Hover && _hmdRollControlEnabled && hasDriveInput()) {
|
||||
|
||||
// Turn with head roll.
|
||||
const float MIN_CONTROL_SPEED = 0.01f;
|
||||
float speed = glm::length(getWorldVelocity());
|
||||
if (speed >= MIN_CONTROL_SPEED) {
|
||||
// Feather turn when stopping moving.
|
||||
float speedFactor;
|
||||
if (getDriveKey(TRANSLATE_Z) != 0.0f || _lastDrivenSpeed == 0.0f) {
|
||||
_lastDrivenSpeed = speed;
|
||||
speedFactor = 1.0f;
|
||||
} else {
|
||||
speedFactor = glm::min(speed / _lastDrivenSpeed, 1.0f);
|
||||
}
|
||||
const float MIN_CONTROL_SPEED = 2.0f * getSensorToWorldScale(); // meters / sec
|
||||
const glm::vec3 characterForward = getWorldOrientation() * Vectors::UNIT_NEG_Z;
|
||||
float forwardSpeed = glm::dot(characterForward, getWorldVelocity());
|
||||
|
||||
float direction = glm::dot(getWorldVelocity(), getWorldOrientation() * Vectors::UNIT_NEG_Z) > 0.0f ? 1.0f : -1.0f;
|
||||
// only enable roll-turns if we are moving forward or backward at greater then MIN_CONTROL_SPEED
|
||||
if (fabsf(forwardSpeed) >= MIN_CONTROL_SPEED) {
|
||||
|
||||
float direction = forwardSpeed > 0.0f ? 1.0f : -1.0f;
|
||||
float rollAngle = glm::degrees(asinf(glm::dot(IDENTITY_UP, _hmdSensorOrientation * IDENTITY_RIGHT)));
|
||||
float rollSign = rollAngle < 0.0f ? -1.0f : 1.0f;
|
||||
rollAngle = fabsf(rollAngle);
|
||||
rollAngle = rollAngle > _hmdRollControlDeadZone ? rollSign * (rollAngle - _hmdRollControlDeadZone) : 0.0f;
|
||||
|
||||
totalBodyYaw += speedFactor * direction * rollAngle * deltaTime * _hmdRollControlRate;
|
||||
const float MIN_ROLL_ANGLE = _hmdRollControlDeadZone;
|
||||
const float MAX_ROLL_ANGLE = 90.0f; // degrees
|
||||
|
||||
if (rollAngle > MIN_ROLL_ANGLE) {
|
||||
// rate of turning is linearly proportional to rollAngle
|
||||
rollAngle = glm::clamp(rollAngle, MIN_ROLL_ANGLE, MAX_ROLL_ANGLE);
|
||||
|
||||
// scale rollAngle into a value from zero to one.
|
||||
float rollFactor = (rollAngle - MIN_ROLL_ANGLE) / (MAX_ROLL_ANGLE - MIN_ROLL_ANGLE);
|
||||
|
||||
float angularSpeed = rollSign * rollFactor * _hmdRollControlRate;
|
||||
totalBodyYaw += direction * angularSpeed * deltaTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2023,12 +2040,13 @@ void MyAvatar::updateActionMotor(float deltaTime) {
|
|||
_isBraking = _wasPushing || (_isBraking && speed > MIN_ACTION_BRAKE_SPEED);
|
||||
}
|
||||
|
||||
CharacterController::State state = _characterController.getState();
|
||||
|
||||
// compute action input
|
||||
glm::vec3 forward = (getDriveKey(TRANSLATE_Z)) * IDENTITY_FORWARD;
|
||||
glm::vec3 right = (getDriveKey(TRANSLATE_X)) * IDENTITY_RIGHT;
|
||||
|
||||
glm::vec3 direction = forward + right;
|
||||
CharacterController::State state = _characterController.getState();
|
||||
if (state == CharacterController::State::Hover ||
|
||||
_characterController.computeCollisionGroup() == BULLET_COLLISION_GROUP_COLLISIONLESS) {
|
||||
// we can fly --> support vertical motion
|
||||
|
|
|
@ -110,6 +110,10 @@ class MyAvatar : public Avatar {
|
|||
* @property userEyeHeight {number} Estimated height of the users eyes in sensor space. (meters)
|
||||
* @property SELF_ID {string} READ-ONLY. UUID representing "my avatar". Only use for local-only entities and overlays in situations where MyAvatar.sessionUUID is not available (e.g., if not connected to a domain).
|
||||
* Note: Likely to be deprecated.
|
||||
* @property hmdRollControlEnabled {bool} When enabled the roll angle of your HMD will turn your avatar while flying.
|
||||
* @property hmdRollControlDeadZone {number} If hmdRollControlEnabled is true, this value can be used to tune what roll angle is required to begin turning.
|
||||
* This angle is specified in degrees.
|
||||
* @property hmdRollControlRate {number} If hmdRollControlEnabled is true, this value determines the maximum turn rate of your avatar when rolling your HMD in degrees per second.
|
||||
*/
|
||||
|
||||
// FIXME: `glm::vec3 position` is not accessible from QML, so this exposes position in a QML-native type
|
||||
|
@ -158,7 +162,7 @@ class MyAvatar : public Avatar {
|
|||
Q_PROPERTY(float userEyeHeight READ getUserEyeHeight)
|
||||
|
||||
Q_PROPERTY(QUuid SELF_ID READ getSelfID CONSTANT)
|
||||
|
||||
|
||||
const QString DOMINANT_LEFT_HAND = "left";
|
||||
const QString DOMINANT_RIGHT_HAND = "right";
|
||||
|
||||
|
@ -735,12 +739,12 @@ private:
|
|||
bool _clearOverlayWhenMoving { true };
|
||||
QString _dominantHand { DOMINANT_RIGHT_HAND };
|
||||
|
||||
const float ROLL_CONTROL_DEAD_ZONE_DEFAULT = 8.0f; // deg
|
||||
const float ROLL_CONTROL_RATE_DEFAULT = 2.5f; // deg/sec/deg
|
||||
const float ROLL_CONTROL_DEAD_ZONE_DEFAULT = 8.0f; // degrees
|
||||
const float ROLL_CONTROL_RATE_DEFAULT = 114.0f; // degrees / sec
|
||||
|
||||
bool _hmdRollControlEnabled { true };
|
||||
float _hmdRollControlDeadZone { ROLL_CONTROL_DEAD_ZONE_DEFAULT };
|
||||
float _hmdRollControlRate { ROLL_CONTROL_RATE_DEFAULT };
|
||||
float _lastDrivenSpeed { 0.0f };
|
||||
|
||||
// working copy -- see AvatarData for thread-safe _sensorToWorldMatrixCache, used for outward facing access
|
||||
glm::mat4 _sensorToWorldMatrix { glm::mat4() };
|
||||
|
|
Loading…
Reference in a new issue