mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 04:44:11 +02:00
Fixes for flying and rotation re-centering in wikiplanet
This commit is contained in:
parent
963ddce7bc
commit
8e56404c40
4 changed files with 23 additions and 57 deletions
|
@ -2497,7 +2497,8 @@ void Application::paintGL() {
|
|||
_myCamera.setProjection(displayPlugin->getCullingProjection(_myCamera.getProjection()));
|
||||
renderArgs._context->enableStereo(true);
|
||||
mat4 eyeOffsets[2];
|
||||
auto baseProjection = renderArgs.getViewFrustum().getProjection();
|
||||
mat4 eyeProjections[2];
|
||||
|
||||
auto hmdInterface = DependencyManager::get<HMDScriptingInterface>();
|
||||
float IPDScale = hmdInterface->getIPDScale();
|
||||
|
||||
|
@ -2505,6 +2506,12 @@ void Application::paintGL() {
|
|||
float heightRatio = getMyAvatar()->getEyeHeight() / getMyAvatar()->getUserEyeHeight();
|
||||
IPDScale *= heightRatio;
|
||||
|
||||
// adjust near clip plane by heightRatio
|
||||
auto baseProjection = glm::perspective(renderArgs.getViewFrustum().getFieldOfView(),
|
||||
renderArgs.getViewFrustum().getAspectRatio(),
|
||||
renderArgs.getViewFrustum().getNearClip() * heightRatio,
|
||||
renderArgs.getViewFrustum().getFarClip());
|
||||
|
||||
// FIXME we probably don't need to set the projection matrix every frame,
|
||||
// only when the display plugin changes (or in non-HMD modes when the user
|
||||
// changes the FOV manually, which right now I don't think they can.
|
||||
|
|
|
@ -1884,38 +1884,8 @@ void MyAvatar::updateOrientation(float deltaTime) {
|
|||
snapTurn = true;
|
||||
}
|
||||
|
||||
// use head/HMD orientation to turn while flying
|
||||
if (getCharacterController()->getState() == CharacterController::State::Hover) {
|
||||
|
||||
// This is the direction the user desires to fly in.
|
||||
glm::vec3 desiredFacing = getMyHead()->getHeadOrientation() * Vectors::UNIT_Z;
|
||||
desiredFacing.y = 0.0f;
|
||||
|
||||
// This is our reference frame, it is captured when the user begins to move.
|
||||
glm::vec3 referenceFacing = transformVectorFast(_sensorToWorldMatrix, _hoverReferenceCameraFacing);
|
||||
referenceFacing.y = 0.0f;
|
||||
referenceFacing = glm::normalize(referenceFacing);
|
||||
glm::vec3 referenceRight(referenceFacing.z, 0.0f, -referenceFacing.x);
|
||||
const float HOVER_FLY_ROTATION_PERIOD = 0.5f;
|
||||
float tau = glm::clamp(deltaTime / HOVER_FLY_ROTATION_PERIOD, 0.0f, 1.0f);
|
||||
|
||||
// new facing is a linear interpolation between the desired and reference vectors.
|
||||
glm::vec3 newFacing = glm::normalize((1.0f - tau) * referenceFacing + tau * desiredFacing);
|
||||
|
||||
// calcualte the signed delta yaw angle to apply so that we match our newFacing.
|
||||
float sign = copysignf(1.0f, glm::dot(desiredFacing, referenceRight));
|
||||
float deltaAngle = sign * acosf(glm::clamp(glm::dot(referenceFacing, newFacing), -1.0f, 1.0f));
|
||||
|
||||
// speedFactor is 0 when we are at rest adn 1.0 when we are at max flying speed.
|
||||
const float MAX_FLYING_SPEED = 30.0f;
|
||||
float speedFactor = glm::min(glm::length(getVelocity()) / MAX_FLYING_SPEED, 1.0f);
|
||||
|
||||
// apply our delta, but scale it by the speed factor, so we turn faster when we are flying faster.
|
||||
totalBodyYaw += (speedFactor * deltaAngle * (180.0f / PI));
|
||||
}
|
||||
|
||||
// Use head/HMD roll to turn while walking or flying, but not when standing still
|
||||
if (qApp->isHMDMode() && _hmdRollControlEnabled && hasDriveInput()) {
|
||||
// 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(getVelocity());
|
||||
|
@ -2067,18 +2037,6 @@ void MyAvatar::updatePosition(float deltaTime) {
|
|||
_characterController.setStepUpEnabled(result.walkable);
|
||||
}
|
||||
}
|
||||
|
||||
// capture the head rotation, in sensor space, when the user first indicates they would like to move/fly.
|
||||
if (!_hoverReferenceCameraFacingIsCaptured &&
|
||||
(fabs(getDriveKey(TRANSLATE_Z)) > 0.1f || fabs(getDriveKey(TRANSLATE_X)) > 0.1f)) {
|
||||
_hoverReferenceCameraFacingIsCaptured = true;
|
||||
// transform the camera facing vector into sensor space.
|
||||
_hoverReferenceCameraFacing = transformVectorFast(glm::inverse(_sensorToWorldMatrix),
|
||||
getMyHead()->getHeadOrientation() * Vectors::UNIT_Z);
|
||||
} else if (_hoverReferenceCameraFacingIsCaptured &&
|
||||
(fabs(getDriveKey(TRANSLATE_Z)) <= 0.1f && fabs(getDriveKey(TRANSLATE_X)) <= 0.1f)) {
|
||||
_hoverReferenceCameraFacingIsCaptured = false;
|
||||
}
|
||||
}
|
||||
|
||||
void MyAvatar::updateCollisionSound(const glm::vec3 &penetration, float deltaTime, float frequency) {
|
||||
|
@ -2756,7 +2714,6 @@ bool MyAvatar::FollowHelper::shouldActivateRotation(const MyAvatar& myAvatar, co
|
|||
}
|
||||
|
||||
bool MyAvatar::FollowHelper::shouldActivateHorizontal(const MyAvatar& myAvatar, const glm::mat4& desiredBodyMatrix, const glm::mat4& currentBodyMatrix) const {
|
||||
|
||||
// -z axis of currentBodyMatrix in world space.
|
||||
glm::vec3 forward = glm::normalize(glm::vec3(-currentBodyMatrix[0][2], -currentBodyMatrix[1][2], -currentBodyMatrix[2][2]));
|
||||
// x axis of currentBodyMatrix in world space.
|
||||
|
@ -2780,7 +2737,6 @@ bool MyAvatar::FollowHelper::shouldActivateHorizontal(const MyAvatar& myAvatar,
|
|||
}
|
||||
|
||||
bool MyAvatar::FollowHelper::shouldActivateVertical(const MyAvatar& myAvatar, const glm::mat4& desiredBodyMatrix, const glm::mat4& currentBodyMatrix) const {
|
||||
|
||||
const float CYLINDER_TOP = 0.1f;
|
||||
const float CYLINDER_BOTTOM = -1.5f;
|
||||
|
||||
|
@ -2807,6 +2763,16 @@ void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat
|
|||
glm::mat4 desiredWorldMatrix = myAvatar.getSensorToWorldMatrix() * desiredBodyMatrix;
|
||||
glm::mat4 currentWorldMatrix = myAvatar.getSensorToWorldMatrix() * currentBodyMatrix;
|
||||
|
||||
glm::vec4 RED(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
glm::vec4 GREEN(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
glm::vec4 BLUE(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
glm::vec4 WHITE(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
glm::vec4 desiredColor = glm::dot(Vectors::UNIT_Y, transformVectorFast(desiredBodyMatrix, Vectors::UNIT_Y)) < 0.9912f ? RED : GREEN;
|
||||
glm::vec4 currentColor = glm::dot(Vectors::UNIT_Y, transformVectorFast(currentBodyMatrix, Vectors::UNIT_Y)) < 0.9912f ? BLUE : WHITE;
|
||||
|
||||
DebugDraw::getInstance().addMarker("desiredBody", glmExtractRotation(desiredWorldMatrix), extractTranslation(desiredWorldMatrix), desiredColor);
|
||||
DebugDraw::getInstance().addMarker("currentBody", glmExtractRotation(currentWorldMatrix), extractTranslation(currentWorldMatrix), currentColor);
|
||||
|
||||
AnimPose followWorldPose(currentWorldMatrix);
|
||||
|
||||
// remove scale present from sensorToWorldMatrix
|
||||
|
@ -2846,7 +2812,6 @@ glm::mat4 MyAvatar::FollowHelper::postPhysicsUpdate(const MyAvatar& myAvatar, co
|
|||
glm::mat4 newBodyMat = createMatFromQuatAndPos(sensorAngularDisplacement * glmExtractRotation(currentBodyMatrix),
|
||||
sensorLinearDisplacement + extractTranslation(currentBodyMatrix));
|
||||
return newBodyMat;
|
||||
|
||||
} else {
|
||||
return currentBodyMatrix;
|
||||
}
|
||||
|
|
|
@ -774,8 +774,6 @@ private:
|
|||
|
||||
AtRestDetector _hmdAtRestDetector;
|
||||
bool _lastIsMoving { false };
|
||||
bool _hoverReferenceCameraFacingIsCaptured { false };
|
||||
glm::vec3 _hoverReferenceCameraFacing { 0.0f, 0.0f, -1.0f }; // hmd sensor space
|
||||
|
||||
// all poses are in sensor-frame
|
||||
std::map<controller::Action, controller::Pose> _controllerPoseMap;
|
||||
|
|
|
@ -265,13 +265,9 @@ void CharacterController::playerStep(btCollisionWorld* collisionWorld, btScalar
|
|||
btVector3 endPos = startPos + linearDisplacement;
|
||||
|
||||
btQuaternion startRot = bodyTransform.getRotation();
|
||||
glm::vec2 currentFacing = getFacingDir2D(bulletToGLM(startRot));
|
||||
glm::vec2 currentRight(currentFacing.y, -currentFacing.x);
|
||||
glm::vec2 desiredFacing = getFacingDir2D(bulletToGLM(_followDesiredBodyTransform.getRotation()));
|
||||
float deltaAngle = acosf(glm::clamp(glm::dot(currentFacing, desiredFacing), -1.0f, 1.0f));
|
||||
float angularSpeed = deltaAngle / _followTimeRemaining;
|
||||
float sign = copysignf(1.0f, glm::dot(desiredFacing, currentRight));
|
||||
btQuaternion angularDisplacement = btQuaternion(btVector3(0.0f, 1.0f, 0.0f), sign * angularSpeed * dt);
|
||||
btQuaternion deltaRot = _followDesiredBodyTransform.getRotation() * startRot.inverse();
|
||||
float angularSpeed = deltaRot.getAngle() / _followTimeRemaining;
|
||||
btQuaternion angularDisplacement = btQuaternion(deltaRot.getAxis(), angularSpeed * dt);
|
||||
btQuaternion endRot = angularDisplacement * startRot;
|
||||
|
||||
// in order to accumulate displacement of avatar position, we need to take _shapeLocalOffset into account.
|
||||
|
|
Loading…
Reference in a new issue