Merge pull request #16356 from luiscuenca/fixLookAtNoHead

DEV-2316: Fix camera position in first person
This commit is contained in:
Anthony Thibault 2019-10-16 10:52:53 -07:00 committed by GitHub
commit 5115b52ca0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 1 deletions

View file

@ -3618,7 +3618,7 @@ void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) {
_myCamera.setPosition(extractTranslation(camMat));
_myCamera.setOrientation(glmExtractRotation(camMat));
} else {
_myCamera.setPosition(myAvatar->getLookAtPivotPoint());
_myCamera.setPosition(myAvatar->getCameraEyesPosition(deltaTime));
_myCamera.setOrientation(myAvatar->getLookAtRotation());
}
} else if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE) {

View file

@ -6812,6 +6812,50 @@ glm::vec3 MyAvatar::getLookAtPivotPoint() {
return yAxisEyePosition;
}
glm::vec3 MyAvatar::getCameraEyesPosition(float deltaTime) {
glm::vec3 defaultEyesPosition = getLookAtPivotPoint();
if (isFlying()) {
return defaultEyesPosition;
}
glm::vec3 avatarFrontVector = getWorldOrientation() * Vectors::FRONT;
glm::vec3 avatarUpVector = getWorldOrientation() * Vectors::UP;
// Compute the offset between the default and real eye positions.
glm::vec3 defaultEyesToEyesVector = getHead()->getEyePosition() - defaultEyesPosition;
float FRONT_OFFSET_IDLE_MULTIPLIER = 2.0f;
float FRONT_OFFSET_JUMP_MULTIPLIER = 1.5f;
float frontOffset = FRONT_OFFSET_IDLE_MULTIPLIER * glm::length(defaultEyesPosition - getDefaultEyePosition());
// Looking down will aproximate move the camera forward to meet the real eye position
float mixAlpha = glm::dot(_lookAtPitch * Vectors::FRONT, -avatarUpVector);
// When jumping the camera should follow the real eye on the Y coordenate
float upOffset = 0.0f;
if (isJumping() || _characterController.getState() == CharacterController::State::Takeoff) {
upOffset = glm::dot(defaultEyesToEyesVector, avatarUpVector);
frontOffset = glm::dot(defaultEyesToEyesVector, avatarFrontVector) * FRONT_OFFSET_JUMP_MULTIPLIER;
mixAlpha = 1.0f;
} else {
// Limit the range effect from 45 to 90 degrees
const float HEAD_OFFSET_DOT_THRESHOLD = 0.7f; // 45 degrees aprox
mixAlpha = mixAlpha < HEAD_OFFSET_DOT_THRESHOLD ? 0.0f : (mixAlpha - HEAD_OFFSET_DOT_THRESHOLD) /
(1.0f - HEAD_OFFSET_DOT_THRESHOLD);
}
const float FPS = 60.0f;
float timeScale = deltaTime * FPS;
frontOffset = frontOffset < 0.0f ? 0.0f : mixAlpha * frontOffset;
glm::vec3 cameraOffset = upOffset * Vectors::UP + frontOffset * Vectors::FRONT;
const float TAU = 0.1f;
_cameraEyesOffset = _cameraEyesOffset + (cameraOffset - _cameraEyesOffset) * min(1.0f, TAU * timeScale);
glm::vec3 estimatedCameraPosition = defaultEyesPosition + getWorldOrientation() * _cameraEyesOffset;
return estimatedCameraPosition;
}
bool MyAvatar::isJumping() {
return (_characterController.getState() == CharacterController::State::InAir ||
_characterController.getState() == CharacterController::State::Takeoff) && !isFlying();
}
bool MyAvatar::setPointAt(const glm::vec3& pointAtTarget) {
if (QThread::currentThread() != thread()) {
bool result = false;

View file

@ -1919,6 +1919,8 @@ public:
bool getIsJointOverridden(int jointIndex) const;
glm::vec3 getLookAtPivotPoint();
glm::vec3 getCameraEyesPosition(float deltaTime);
bool isJumping();
public slots:
@ -2973,6 +2975,8 @@ private:
// used to prevent character from jumping after endSit is called.
bool _endSitKeyPressComplete { false };
glm::vec3 _cameraEyesOffset;
};
QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode);