Fix camera position in first person

This commit is contained in:
luiscuenca 2019-10-15 18:25:33 -07:00
parent 3102a6ff08
commit 93a1adc736
No known key found for this signature in database
GPG key ID: 2387ECD129A6961D
4 changed files with 63 additions and 10 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,53 @@ 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) * TAU * timeScale;
glm::vec3 estimatedCameraPosition = defaultEyesPosition + getWorldOrientation() * _cameraEyesOffset;
return estimatedCameraPosition;
}
bool MyAvatar::isJumping() {
if (_skeletonModel->isLoaded()) {
return (_skeletonModel->getRig().getState() == Rig::RigRole::InAir ||
_skeletonModel->getRig().getState() == Rig::RigRole::Takeoff) && !isFlying();
}
return false;
}
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);

View file

@ -115,6 +115,16 @@ public:
Seated
};
enum class RigRole {
Idle = 0,
Turn,
Move,
Hover,
Takeoff,
InAir,
Seated
};
Rig();
virtual ~Rig();
@ -257,6 +267,7 @@ public:
bool getFlowActive() const;
bool getNetworkGraphActive() const;
void setDirectionalBlending(const QString& targetName, const glm::vec3& blendingTarget, const QString& alphaName, float alpha);
const RigRole getState() const { return _state; }
signals:
void onLoadComplete();
@ -339,15 +350,6 @@ protected:
AnimVariantMap _animVars;
AnimVariantMap _networkVars;
enum class RigRole {
Idle = 0,
Turn,
Move,
Hover,
Takeoff,
InAir,
Seated
};
RigRole _state { RigRole::Idle };
RigRole _desiredState { RigRole::Idle };
float _desiredStateAge { 0.0f };