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);
}
void Application::updateCamera(RenderArgs& renderArgs) {
void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) {
PROFILE_RANGE(render, __FUNCTION__);
PerformanceTimer perfTimer("updateCamera");
@ -2459,6 +2459,7 @@ void Application::updateCamera(RenderArgs& renderArgs) {
// Using the latter will cause the camera to wobble with idle animations,
// or with changes from the face tracker
if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) {
_thirdPersonHMDCameraBoomValid= false;
if (isHMDMode()) {
mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix();
_myCamera.setPosition(extractTranslation(camMat));
@ -2471,12 +2472,25 @@ void Application::updateCamera(RenderArgs& renderArgs) {
}
else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
if (isHMDMode()) {
auto hmdWorldMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix();
_myCamera.setOrientation(glm::normalize(glmExtractRotation(hmdWorldMat)));
_myCamera.setPosition(extractTranslation(hmdWorldMat) +
myAvatar->getWorldOrientation() * boomOffset);
if (!_thirdPersonHMDCameraBoomValid) {
const glm::vec3 CAMERA_OFFSET = glm::vec3(0.0f, 0.0f, 0.7f);
_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 {
_thirdPersonHMDCameraBoomValid = false;
_myCamera.setOrientation(myAvatar->getHead()->getOrientation());
if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) {
_myCamera.setPosition(myAvatar->getDefaultEyePosition()
@ -2489,6 +2503,7 @@ void Application::updateCamera(RenderArgs& renderArgs) {
}
}
else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
_thirdPersonHMDCameraBoomValid= false;
if (isHMDMode()) {
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;
}
else if (_myCamera.getMode() == CAMERA_MODE_ENTITY) {
_thirdPersonHMDCameraBoomValid= false;
EntityItemPointer cameraEntity = _myCamera.getCameraEntityPointer();
if (cameraEntity != nullptr) {
if (isHMDMode()) {
@ -5099,7 +5115,8 @@ void Application::update(float deltaTime) {
_postUpdateLambdas.clear();
}
editRenderArgs([this](AppRenderArgs& appRenderArgs) {
editRenderArgs([this, deltaTime](AppRenderArgs& appRenderArgs) {
PerformanceTimer perfTimer("editRenderArgs");
appRenderArgs._headPose= getHMDSensorPose();
@ -5146,7 +5163,7 @@ void Application::update(float deltaTime) {
resizeGL();
}
this->updateCamera(appRenderArgs._renderArgs);
this->updateCamera(appRenderArgs._renderArgs, deltaTime);
appRenderArgs._eyeToWorld = _myCamera.getTransform();
appRenderArgs._isStereo = false;

View file

@ -146,7 +146,7 @@ public:
void initializeGL();
void initializeUi();
void updateCamera(RenderArgs& renderArgs);
void updateCamera(RenderArgs& renderArgs, float deltaTime);
void paintGL();
void resizeGL();
@ -695,6 +695,9 @@ private:
void startHMDStandBySession();
void endHMDSession();
glm::vec3 _thirdPersonHMDCameraBoom { 0.0f, 0.0f, -1.0f };
bool _thirdPersonHMDCameraBoomValid { true };
QUrl _avatarOverrideUrl;
bool _saveAvatarOverrideUrl { false };
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 {
auto cameraMode = qApp->getCamera().getMode();
if (cameraMode == CAMERA_MODE_THIRD_PERSON) {
return false;
} 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;
}
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 {

View file

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