//// Camera.cpp// interface/src//// Copyright 2013 High Fidelity, Inc.//// Distributed under the Apache License, Version 2.0.// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html// #include <glm/gtx/quaternion.hpp> #include <SharedUtil.h>#include <EventTypes.h> #include "Application.h"#include "Camera.h"#include "Menu.h"#include "Util.h" CameraMode stringToMode(const QString& mode) { if (mode == "third person") { return CAMERA_MODE_THIRD_PERSON; } else if (mode == "first person") { return CAMERA_MODE_FIRST_PERSON; } else if (mode == "mirror") { return CAMERA_MODE_MIRROR; } else if (mode == "independent") { return CAMERA_MODE_INDEPENDENT; } else if (mode == "entity") { return CAMERA_MODE_ENTITY; } return CAMERA_MODE_NULL;} QString modeToString(CameraMode mode) { if (mode == CAMERA_MODE_THIRD_PERSON) { return "third person"; } else if (mode == CAMERA_MODE_FIRST_PERSON) { return "first person"; } else if (mode == CAMERA_MODE_MIRROR) { return "mirror"; } else if (mode == CAMERA_MODE_INDEPENDENT) { return "independent"; } else if (mode == CAMERA_MODE_ENTITY) { return "entity"; } return "unknown";} Camera::Camera() : _projection(glm::perspective(glm::radians(DEFAULT_FIELD_OF_VIEW_DEGREES), 16.0f/9.0f, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP)){} void Camera::update(float deltaTime) { if (_isKeepLookingAt) { lookAt(_lookingAt); } return;} void Camera::recompose() { mat4 orientation = glm::mat4_cast(_rotation); mat4 translation = glm::translate(mat4(), _position); _transform = translation * orientation;} void Camera::decompose() { _position = vec3(_transform[3]); _rotation = glm::quat_cast(_transform);} void Camera::setTransform(const glm::mat4& transform) { _transform = transform; decompose();} void Camera::setPosition(const glm::vec3& position) { _position = position; recompose(); if (_isKeepLookingAt) { lookAt(_lookingAt); }} void Camera::setRotation(const glm::quat& rotation) { _rotation = rotation; recompose(); if (_isKeepLookingAt) { lookAt(_lookingAt); }} void Camera::setMode(CameraMode mode) { _mode = mode; emit modeUpdated(modeToString(mode));} QUuid Camera::getCameraEntity() const { if (_cameraEntity != nullptr) { return _cameraEntity->getID(); } return QUuid();}; void Camera::setCameraEntity(QUuid entityID) { _cameraEntity = qApp->getEntities()->getTree()->findEntityByID(entityID);} void Camera::setProjection(const glm::mat4& projection) { _projection = projection;} PickRay Camera::computePickRay(float x, float y) { return qApp->computePickRay(x, y);} void Camera::setModeString(const QString& mode) { CameraMode targetMode = stringToMode(mode); switch (targetMode) { case CAMERA_MODE_FIRST_PERSON: Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, true); break; case CAMERA_MODE_THIRD_PERSON: Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, true); break; case CAMERA_MODE_MIRROR: Menu::getInstance()->setIsOptionChecked(MenuOption::FullscreenMirror, true); break; case CAMERA_MODE_INDEPENDENT: Menu::getInstance()->setIsOptionChecked(MenuOption::IndependentMode, true); break; case CAMERA_MODE_ENTITY: Menu::getInstance()->setIsOptionChecked(MenuOption::CameraEntityMode, true); break; default: break; } qApp->cameraMenuChanged(); if (_mode != targetMode) { setMode(targetMode); }} QString Camera::getModeString() const { return modeToString(_mode);} void Camera::lookAt(const glm::vec3& lookAt) { glm::vec3 up = IDENTITY_UP; glm::mat4 lookAtMatrix = glm::lookAt(_position, lookAt, up); glm::quat rotation = glm::quat_cast(lookAtMatrix); rotation.w = -rotation.w; // Rosedale approved _rotation = rotation;} void Camera::keepLookingAt(const glm::vec3& point) { lookAt(point); _isKeepLookingAt = true; _lookingAt = point;} void Camera::loadViewFrustum(ViewFrustum& frustum) const { // We will use these below, from either the camera or head vectors calculated above frustum.setProjection(getProjection()); // Set the viewFrustum up with the correct position and orientation of the camera frustum.setPosition(getPosition()); frustum.setOrientation(getRotation()); // Ask the ViewFrustum class to calculate our corners frustum.calculate();} ViewFrustum Camera::toViewFrustum() const { ViewFrustum result; loadViewFrustum(result); return result;}
//
// Camera.cpp
// interface/src
//
// Copyright 2013 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <glm/gtx/quaternion.hpp>
#include <SharedUtil.h>
#include <EventTypes.h>
#include "Application.h"
#include "Camera.h"
#include "Menu.h"
#include "Util.h"
CameraMode stringToMode(const QString& mode) {
if (mode == "third person") {
return CAMERA_MODE_THIRD_PERSON;
} else if (mode == "first person") {
return CAMERA_MODE_FIRST_PERSON;
} else if (mode == "mirror") {
return CAMERA_MODE_MIRROR;
} else if (mode == "independent") {
return CAMERA_MODE_INDEPENDENT;
} else if (mode == "entity") {
return CAMERA_MODE_ENTITY;
}
return CAMERA_MODE_NULL;
}
QString modeToString(CameraMode mode) {
if (mode == CAMERA_MODE_THIRD_PERSON) {
return "third person";
} else if (mode == CAMERA_MODE_FIRST_PERSON) {
return "first person";
} else if (mode == CAMERA_MODE_MIRROR) {
return "mirror";
} else if (mode == CAMERA_MODE_INDEPENDENT) {
return "independent";
} else if (mode == CAMERA_MODE_ENTITY) {
return "entity";
}
return "unknown";
}
Camera::Camera() :
_projection(glm::perspective(glm::radians(DEFAULT_FIELD_OF_VIEW_DEGREES), 16.0f/9.0f, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP))
{
}
void Camera::update(float deltaTime) {
if (_isKeepLookingAt) {
lookAt(_lookingAt);
}
return;
}
void Camera::recompose() {
mat4 orientation = glm::mat4_cast(_rotation);
mat4 translation = glm::translate(mat4(), _position);
_transform = translation * orientation;
}
void Camera::decompose() {
_position = vec3(_transform[3]);
_rotation = glm::quat_cast(_transform);
}
void Camera::setTransform(const glm::mat4& transform) {
_transform = transform;
decompose();
}
void Camera::setPosition(const glm::vec3& position) {
_position = position;
recompose();
if (_isKeepLookingAt) {
lookAt(_lookingAt);
}
}
void Camera::setRotation(const glm::quat& rotation) {
_rotation = rotation;
recompose();
if (_isKeepLookingAt) {
lookAt(_lookingAt);
}
}
void Camera::setMode(CameraMode mode) {
_mode = mode;
emit modeUpdated(modeToString(mode));
}
QUuid Camera::getCameraEntity() const {
if (_cameraEntity != nullptr) {
return _cameraEntity->getID();
}
return QUuid();
};
void Camera::setCameraEntity(QUuid entityID) {
_cameraEntity = qApp->getEntities()->getTree()->findEntityByID(entityID);
}
void Camera::setProjection(const glm::mat4& projection) {
_projection = projection;
}
PickRay Camera::computePickRay(float x, float y) {
return qApp->computePickRay(x, y);
}
void Camera::setModeString(const QString& mode) {
CameraMode targetMode = stringToMode(mode);
switch (targetMode) {
case CAMERA_MODE_FIRST_PERSON:
Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, true);
break;
case CAMERA_MODE_THIRD_PERSON:
Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, true);
break;
case CAMERA_MODE_MIRROR:
Menu::getInstance()->setIsOptionChecked(MenuOption::FullscreenMirror, true);
break;
case CAMERA_MODE_INDEPENDENT:
Menu::getInstance()->setIsOptionChecked(MenuOption::IndependentMode, true);
break;
case CAMERA_MODE_ENTITY:
Menu::getInstance()->setIsOptionChecked(MenuOption::CameraEntityMode, true);
break;
default:
break;
}
qApp->cameraMenuChanged();
if (_mode != targetMode) {
setMode(targetMode);
}
}
QString Camera::getModeString() const {
return modeToString(_mode);
}
void Camera::lookAt(const glm::vec3& lookAt) {
glm::vec3 up = IDENTITY_UP;
glm::mat4 lookAtMatrix = glm::lookAt(_position, lookAt, up);
glm::quat rotation = glm::quat_cast(lookAtMatrix);
rotation.w = -rotation.w; // Rosedale approved
_rotation = rotation;
}
void Camera::keepLookingAt(const glm::vec3& point) {
lookAt(point);
_isKeepLookingAt = true;
_lookingAt = point;
}
void Camera::loadViewFrustum(ViewFrustum& frustum) const {
// We will use these below, from either the camera or head vectors calculated above
frustum.setProjection(getProjection());
// Set the viewFrustum up with the correct position and orientation of the camera
frustum.setPosition(getPosition());
frustum.setOrientation(getRotation());
// Ask the ViewFrustum class to calculate our corners
frustum.calculate();
}
ViewFrustum Camera::toViewFrustum() const {
ViewFrustum result;
loadViewFrustum(result);
return result;
}