terrain-gen/src/camera.cpp

146 lines
3.7 KiB
C++

#include "camera.h"
QMatrix4x4 Camera::m_reflection = QMatrix4x4(1, 0, 0, 0,
0,-1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1);
Camera::Camera(QVector3D position, QVector3D rotation): m_position(position)
{
setXAngleDegrees(double(rotation.x()));
setYAngleDegrees(double(rotation.y()));
m_ratio = 1.0;
connect(this, SIGNAL(positionChanged(QVector3D)), this, SLOT(computeViewMatrix()));
connect(this, SIGNAL(rotationXChanged(double)), this, SLOT(computeViewMatrix()));
connect(this, SIGNAL(rotationYChanged(double)), this, SLOT(computeViewMatrix()));
computeViewMatrix();
computeProjectionMatrix();
}
QMatrix4x4 Camera::view() const
{
return m_view;
}
QMatrix4x4 Camera::projection() const
{
return m_projection;
}
void Camera::rotateAroundX(float deltaAngleRad)
{
m_xAngle += deltaAngleRad;
emit rotationXChanged(double(m_xAngle) / M_PI * 180);
}
void Camera::rotateAroundY(float deltaAngleRad)
{
m_yAngle += deltaAngleRad;
emit rotationYChanged(double(m_yAngle) / M_PI * 180);
}
void Camera::moveX(float deltaX)
{
m_position += m_right * deltaX;
emit positionChanged(m_position);
}
void Camera::moveY(float deltaY)
{
m_position += m_up * deltaY;
emit positionChanged(m_position);
}
void Camera::moveZ(float deltaZ)
{
m_position -= m_front * deltaZ;
emit positionChanged(m_position);
}
void Camera::setRatio(float ratio)
{
m_ratio = ratio;
computeProjectionMatrix();
}
void Camera::computeViewMatrix()
{
m_front = QVector3D(std::cos(m_xAngle) * std::sin(m_yAngle), std::sin(m_xAngle), std::cos(m_xAngle) * std::cos(m_yAngle));
m_right = QVector3D(std::sin(m_yAngle - float(M_PI) / 2.f), 0, std::cos(m_yAngle - float(M_PI) / 2.f));
m_up = QVector3D::crossProduct(m_right, m_front);
m_view.setToIdentity();
m_view.lookAt(m_position, m_position + m_front, m_up);
m_reflectedView = m_view * m_reflection;
emit updated();
}
void Camera::computeProjectionMatrix()
{
m_projection.setToIdentity();
m_projection.perspective(90, m_ratio, 0.1f, 100);
emit updated();
}
void Camera::setX(double x)
{
if (!qFuzzyCompare(m_position.x(), float(x))) {
m_position.setX(float(x));
emit positionChanged(m_position);
}
}
void Camera::setY(double y)
{
if (!qFuzzyCompare(m_position.y(), float(y))) {
m_position.setY(float(y));
emit positionChanged(m_position);
}
}
void Camera::setZ(double z)
{
if (!qFuzzyCompare(m_position.z(), float(z))) {
m_position.setZ(float(z));
emit positionChanged(m_position);
}
}
void Camera::setXAngleDegrees(double xAngleDeg)
{
float xAngleRad = float(xAngleDeg / 180 * M_PI);
if (!qFuzzyCompare(m_xAngle, xAngleRad)) {
m_xAngle = xAngleRad;
emit rotationXChanged(xAngleDeg);
}
}
void Camera::setYAngleDegrees(double yAngleDeg)
{
float yAngleRad = float(yAngleDeg / 180 * M_PI);
if (!qFuzzyCompare(m_yAngle, yAngleRad)) {
m_yAngle = yAngleRad;
emit rotationYChanged(yAngleDeg);
}
}
void Camera::setUniforms(Shader* program, RenderPassType renderPass)
{
if (renderPass == RenderPassType::REFLECTION) {
glUniformMatrix4fv(program->uniformLocation("u_view"), 1, GL_FALSE, m_reflectedView.data());
} else {
glUniformMatrix4fv(program->uniformLocation("u_view"), 1, GL_FALSE, m_view.data());
}
glUniformMatrix4fv(program->uniformLocation("u_projection"), 1, GL_FALSE, m_projection.data());
glUniform3f(program->uniformLocation("u_cameraPosition"), m_position.x(), m_position.y(), m_position.z());
}
void Camera::initGl()
{
initializeOpenGLFunctions();
}