From 8e56404c40f7ef78e59ac761221c74e7285e7c77 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Fri, 18 Aug 2017 16:26:50 -0700 Subject: [PATCH] Fixes for flying and rotation re-centering in wikiplanet --- interface/src/Application.cpp | 9 ++- interface/src/avatar/MyAvatar.cpp | 59 ++++--------------- interface/src/avatar/MyAvatar.h | 2 - libraries/physics/src/CharacterController.cpp | 10 +--- 4 files changed, 23 insertions(+), 57 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c07bf81785..560cb8c00d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -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(); 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. diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index dc9c55243b..11af475ab4 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -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; } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 3b87980018..3d335d0a19 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -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 _controllerPoseMap; diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index 9a7abc4e98..becc6c10bf 100755 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -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.