//------------------------------------------------------------------------------
/*!
\file ComponentCamera.cpp
\main author: Mary (m.khuu) Camera movement : Riti
\par Copyright © 2021 DigiPen (USA) Corporation.
\brief
\reference http://www.opengl-tutorial.org/beginners-tutorials/tutorial-6-keyboard-and-mouse/
*/
//------------------------------------------------------------------------------
#pragma once
//------------------------------------------------------------------------------
// Includes:
//------------------------------------------------------------------------------
#include "ComponentCamera.h"
ComponentCamera::ComponentCamera(void)
{
ModelMatrix = mat4(0.0f);
ViewMatrix = mat4(1.0f);
ProjectionMatrix = mat4(0.0f);
MVPmatrix = mat4(0.0f);
position = glm::vec3(0.0f, 0.0f, 1.0f);
cameraBoundariesMax = glm::vec3(0.0f, 0.0f, 1.0f);
cameraBoundariesMin = glm::vec3(0.0f, 0.0f, 1.0f);
cameraSize = glm::vec3(0.0f, 0.0f, 1.0f);
cameraSpeed = glm::vec3(0.45f, 0.35f, 0.0f);
horizontalAngle = 3.14f;
verticalAngle = 0.0f;
lockParallax = 0;
lastTime = 0;
}
glm::mat4 ComponentCamera::cameraInput(GLFWwindow* window)
{
double currentTime = glfwGetTime();
float deltaTime = float(currentTime - lastTime);
// Direction : Spherical coordinates to Cartesian coordinates conversion
glm::vec3 direction(
cos(verticalAngle) * sin(horizontalAngle),
sin(verticalAngle),
cos(verticalAngle) * cos(horizontalAngle)
);
// Right vector
glm::vec3 right = glm::vec3(
sin(horizontalAngle - 3.14f / 2.0f),
0,
cos(horizontalAngle - 3.14f / 2.0f)
);
// Up vector
glm::vec3 up = glm::cross(right, direction);
//vertical movements currently move diagonally
if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS)
{
position += deltaTime * cameraSpeed[1];
position -= right * deltaTime * cameraSpeed[1];
}
if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS)
{
position -= deltaTime * cameraSpeed[1];
position += right * deltaTime * cameraSpeed[1];
}
if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS)
{
position += right * deltaTime * cameraSpeed[0];
}
if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS)
{
position -= right * deltaTime * cameraSpeed[0];
}
ProjectionMatrix = glm::ortho((-cameraSize.x / 2), (cameraSize.x / 2), -(cameraSize.y / 2), (cameraSize.y / 2), 0.0f, 100.0f);
ViewMatrix = glm::lookAt(position, position + direction, up);
ModelMatrix = glm::mat4(1.0f);
lastTime = currentTime;
MVPmatrix = (ProjectionMatrix * ViewMatrix * ModelMatrix);
return MVPmatrix; //returns MVP matrix
}
glm::mat4 ComponentCamera::tieCameraToPlayer(GLFWwindow* window, glm::vec3 playerPos)
{
setlockParallax(false);
glm::vec3 direction(
cos(verticalAngle) * sin(horizontalAngle),
sin(verticalAngle),
cos(verticalAngle) * cos(horizontalAngle)
);
glm::vec3 right = glm::vec3(
sin(horizontalAngle - 3.14f / 2.0f),
0,
cos(horizontalAngle - 3.14f / 2.0f)
);
glm::vec3 up = glm::cross(right, direction);
ProjectionMatrix = glm::ortho((-cameraSize.x / 2), (cameraSize.x / 2), -(cameraSize.y / 2), (cameraSize.y / 2), 0.0f, 100.0f);
vec3 CamPos = getCameraPosition();
CamPos.x = playerPos.x;
CamPos.y = playerPos.y;
if (CamPos.x - (cameraSize.x / 2) < cameraBoundariesMin[0])
{
CamPos.x = cameraBoundariesMin[0] + (cameraSize.x / 2);
}
if (CamPos.x + (cameraSize.x / 2) > cameraBoundariesMax[0])
{
CamPos.x = cameraBoundariesMax[0] -(cameraSize.x / 2);
}
if (CamPos.y < cameraBoundariesMin[1])
{
CamPos.y = cameraBoundariesMin[1];
}
//uncommented to always lock the center of camera to player
//when player goes up
if (CamPos.y > cameraBoundariesMax[1])
{
CamPos.y = cameraBoundariesMax[1];
}
setCameraPosition(CamPos);
ViewMatrix = glm::lookAt(position, position + direction, up);
ModelMatrix = glm::mat4(1.0f);
MVPmatrix = (ProjectionMatrix * ViewMatrix * ModelMatrix);
return MVPmatrix; //returns MVP matrix
}
void ComponentCamera::UpdateCamera(GLFWwindow* window, Shader shader, glm::vec3 position)
{
shader.use();
if (position != glm::vec3(0))
{
GLuint MatrixID = glGetUniformLocation(shader.ID, "transformation");
//glm::matddddd4 MVP = cameraInput(window);
glm::mat4 MVP = tieCameraToPlayer(window, position);
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
}
}
glm::mat4 ComponentCamera::getModelMatrix()
{
return ModelMatrix;
}
glm::mat4 ComponentCamera::getViewMatrix()
{
return ViewMatrix;
}
glm::mat4 ComponentCamera::getProjectionMatrix()
{
return ProjectionMatrix;
}
glm::mat4 ComponentCamera::getMVPmatrix()
{
return MVPmatrix;
}
glm::vec3 ComponentCamera::getCameraBoundariesMin()
{
return cameraBoundariesMin;
}
glm::vec3 ComponentCamera::getCameraBoundariesMax()
{
return cameraBoundariesMax;
}
glm::vec3 ComponentCamera::getCameraPosition()
{
return position;
}
glm::vec3 ComponentCamera::getCameraSize()
{
return cameraSize;
}
bool ComponentCamera::getlockParallax()
{
return lockParallax;
}
void ComponentCamera::setCameraBoundariesMin(glm::vec3 boundaries)
{
cameraBoundariesMin = boundaries;
}
void ComponentCamera::setCameraBoundariesMax(glm::vec3 boundaries)
{
cameraBoundariesMax = boundaries;
}
void ComponentCamera::setCameraPosition(glm::vec3 P)
{
position = P;
}
void ComponentCamera::setCameraSize(glm::vec3 S)
{
cameraSize = S;
}
void ComponentCamera::setCameraSpeed(float speedX, float speedY)
{
cameraSpeed[0] = speedX;
cameraSpeed[1] = speedY;
}
void ComponentCamera::setCameraSpeedVec(glm::vec3 speed)
{
cameraSpeed = speed;
}
void ComponentCamera::setMVPmatrix(glm::mat4 matrix)
{
MVPmatrix = matrix;
}
void ComponentCamera::setlockParallax(bool value)
{
lockParallax = value;
}