Merge pull request #12107 from hyperlogic/bug-fix/better-third-person-camera

Improve stability for HMD third person avatars
This commit is contained in:
Seth Alves 2018-01-10 17:46:47 -08:00 committed by GitHub
commit aefd294bf2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 31 additions and 17 deletions

View file

@ -2444,7 +2444,7 @@ void Application::initializeUi() {
offscreenSurfaceCache->reserve(Web3DOverlay::QML, 2); offscreenSurfaceCache->reserve(Web3DOverlay::QML, 2);
} }
void Application::updateCamera(RenderArgs& renderArgs) { void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) {
PROFILE_RANGE(render, __FUNCTION__); PROFILE_RANGE(render, __FUNCTION__);
PerformanceTimer perfTimer("updateCamera"); PerformanceTimer perfTimer("updateCamera");
@ -2459,6 +2459,7 @@ void Application::updateCamera(RenderArgs& renderArgs) {
// Using the latter will cause the camera to wobble with idle animations, // Using the latter will cause the camera to wobble with idle animations,
// or with changes from the face tracker // or with changes from the face tracker
if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) {
_thirdPersonHMDCameraBoomValid= false;
if (isHMDMode()) { if (isHMDMode()) {
mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix();
_myCamera.setPosition(extractTranslation(camMat)); _myCamera.setPosition(extractTranslation(camMat));
@ -2471,12 +2472,25 @@ void Application::updateCamera(RenderArgs& renderArgs) {
} }
else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
if (isHMDMode()) { if (isHMDMode()) {
auto hmdWorldMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix();
_myCamera.setOrientation(glm::normalize(glmExtractRotation(hmdWorldMat))); if (!_thirdPersonHMDCameraBoomValid) {
_myCamera.setPosition(extractTranslation(hmdWorldMat) + const glm::vec3 CAMERA_OFFSET = glm::vec3(0.0f, 0.0f, 0.7f);
myAvatar->getWorldOrientation() * boomOffset); _thirdPersonHMDCameraBoom = cancelOutRollAndPitch(myAvatar->getHMDSensorOrientation()) * CAMERA_OFFSET;
_thirdPersonHMDCameraBoomValid = true;
}
glm::mat4 thirdPersonCameraSensorToWorldMatrix = myAvatar->getSensorToWorldMatrix();
const glm::vec3 cameraPos = myAvatar->getHMDSensorPosition() + _thirdPersonHMDCameraBoom * myAvatar->getBoomLength();
glm::mat4 sensorCameraMat = createMatFromQuatAndPos(myAvatar->getHMDSensorOrientation(), cameraPos);
glm::mat4 worldCameraMat = thirdPersonCameraSensorToWorldMatrix * sensorCameraMat;
_myCamera.setOrientation(glm::normalize(glmExtractRotation(worldCameraMat)));
_myCamera.setPosition(extractTranslation(worldCameraMat));
} }
else { else {
_thirdPersonHMDCameraBoomValid = false;
_myCamera.setOrientation(myAvatar->getHead()->getOrientation()); _myCamera.setOrientation(myAvatar->getHead()->getOrientation());
if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) { if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) {
_myCamera.setPosition(myAvatar->getDefaultEyePosition() _myCamera.setPosition(myAvatar->getDefaultEyePosition()
@ -2489,6 +2503,7 @@ void Application::updateCamera(RenderArgs& renderArgs) {
} }
} }
else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
_thirdPersonHMDCameraBoomValid= false;
if (isHMDMode()) { if (isHMDMode()) {
auto mirrorBodyOrientation = myAvatar->getWorldOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)); auto mirrorBodyOrientation = myAvatar->getWorldOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f));
@ -2523,6 +2538,7 @@ void Application::updateCamera(RenderArgs& renderArgs) {
renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE;
} }
else if (_myCamera.getMode() == CAMERA_MODE_ENTITY) { else if (_myCamera.getMode() == CAMERA_MODE_ENTITY) {
_thirdPersonHMDCameraBoomValid= false;
EntityItemPointer cameraEntity = _myCamera.getCameraEntityPointer(); EntityItemPointer cameraEntity = _myCamera.getCameraEntityPointer();
if (cameraEntity != nullptr) { if (cameraEntity != nullptr) {
if (isHMDMode()) { if (isHMDMode()) {
@ -5099,7 +5115,8 @@ void Application::update(float deltaTime) {
_postUpdateLambdas.clear(); _postUpdateLambdas.clear();
} }
editRenderArgs([this](AppRenderArgs& appRenderArgs) {
editRenderArgs([this, deltaTime](AppRenderArgs& appRenderArgs) {
PerformanceTimer perfTimer("editRenderArgs"); PerformanceTimer perfTimer("editRenderArgs");
appRenderArgs._headPose= getHMDSensorPose(); appRenderArgs._headPose= getHMDSensorPose();
@ -5146,7 +5163,7 @@ void Application::update(float deltaTime) {
resizeGL(); resizeGL();
} }
this->updateCamera(appRenderArgs._renderArgs); this->updateCamera(appRenderArgs._renderArgs, deltaTime);
appRenderArgs._eyeToWorld = _myCamera.getTransform(); appRenderArgs._eyeToWorld = _myCamera.getTransform();
appRenderArgs._isStereo = false; appRenderArgs._isStereo = false;

View file

@ -146,7 +146,7 @@ public:
void initializeGL(); void initializeGL();
void initializeUi(); void initializeUi();
void updateCamera(RenderArgs& renderArgs); void updateCamera(RenderArgs& renderArgs, float deltaTime);
void paintGL(); void paintGL();
void resizeGL(); void resizeGL();
@ -695,6 +695,9 @@ private:
void startHMDStandBySession(); void startHMDStandBySession();
void endHMDSession(); void endHMDSession();
glm::vec3 _thirdPersonHMDCameraBoom { 0.0f, 0.0f, -1.0f };
bool _thirdPersonHMDCameraBoomValid { true };
QUrl _avatarOverrideUrl; QUrl _avatarOverrideUrl;
bool _saveAvatarOverrideUrl { false }; bool _saveAvatarOverrideUrl { false };
QObject* _renderEventHandler{ nullptr }; QObject* _renderEventHandler{ nullptr };

View file

@ -2799,14 +2799,9 @@ void MyAvatar::FollowHelper::decrementTimeRemaining(float dt) {
} }
bool MyAvatar::FollowHelper::shouldActivateRotation(const MyAvatar& myAvatar, const glm::mat4& desiredBodyMatrix, const glm::mat4& currentBodyMatrix) const { bool MyAvatar::FollowHelper::shouldActivateRotation(const MyAvatar& myAvatar, const glm::mat4& desiredBodyMatrix, const glm::mat4& currentBodyMatrix) const {
auto cameraMode = qApp->getCamera().getMode(); const float FOLLOW_ROTATION_THRESHOLD = cosf(PI / 6.0f); // 30 degrees
if (cameraMode == CAMERA_MODE_THIRD_PERSON) { glm::vec2 bodyFacing = getFacingDir2D(currentBodyMatrix);
return false; return glm::dot(-myAvatar.getHeadControllerFacingMovingAverage(), bodyFacing) < FOLLOW_ROTATION_THRESHOLD;
} else {
const float FOLLOW_ROTATION_THRESHOLD = cosf(PI / 6.0f); // 30 degrees
glm::vec2 bodyFacing = getFacingDir2D(currentBodyMatrix);
return glm::dot(-myAvatar.getHeadControllerFacingMovingAverage(), bodyFacing) < FOLLOW_ROTATION_THRESHOLD;
}
} }
bool MyAvatar::FollowHelper::shouldActivateHorizontal(const MyAvatar& myAvatar, const glm::mat4& desiredBodyMatrix, const glm::mat4& currentBodyMatrix) const { bool MyAvatar::FollowHelper::shouldActivateHorizontal(const MyAvatar& myAvatar, const glm::mat4& desiredBodyMatrix, const glm::mat4& currentBodyMatrix) const {

View file

@ -34,7 +34,6 @@ Rig::CharacterControllerState convertCharacterControllerState(CharacterControlle
} }
static AnimPose computeHipsInSensorFrame(MyAvatar* myAvatar, bool isFlying) { static AnimPose computeHipsInSensorFrame(MyAvatar* myAvatar, bool isFlying) {
glm::mat4 worldToSensorMat = glm::inverse(myAvatar->getSensorToWorldMatrix()); glm::mat4 worldToSensorMat = glm::inverse(myAvatar->getSensorToWorldMatrix());
// check for pinned hips. // check for pinned hips.