Skip to content

Commit

Permalink
Merge pull request #2 from festivaledu/adv-rotation
Browse files Browse the repository at this point in the history
Merge branch adv-rotation
  • Loading branch information
vainamov committed Feb 25, 2020
2 parents 6cd1584 + 61996a5 commit d80d7a0
Show file tree
Hide file tree
Showing 5 changed files with 209 additions and 57 deletions.
133 changes: 94 additions & 39 deletions QubGL/src/Logic/Cube.cpp
Expand Up @@ -19,47 +19,73 @@ Cube::Cube(const ShaderProgram* shader)
}

void Cube::Draw() {
if (m_rotateSide != Side::None && a != m_rotateAngle) {
if (m_rotateDirection == Direction::Clockwise) {
a -= 1.F;
} else {
a += 1.F;
}
if ((m_rotateSide != Side::None || m_rotateAxis != Axis::None) && a != m_rotateAngle) {
a += (m_rotateDirection == Direction::Clockwise) ? -1.F : 1.F;

if (a > 360.F) a = 0;
if (a > 360.F) a = 0.F;
if (a < 0.F) a = 360.F;

for (auto p : GetSide(m_rotateSide)) {
auto& tf = p->GetTransform();
auto r = tf.GetRotation();

glm::vec3 m(p->Position);

switch (m_rotateSide) {
case Side::Left:
case Side::Right:
tf.SetRotation(a, r.y, r.z);
m = glm::vec3(p->Position) * RotateX(glm::radians(a));
break;
case Side::Bottom:
case Side::Top:
tf.SetRotation(r.x, a, r.z);
m = glm::vec3(p->Position) * RotateY(glm::radians(a));
break;
case Side::Back:
case Side::Front:
tf.SetRotation(r.x, r.y, a);
m = glm::vec3(p->Position) * RotateZ(glm::radians(a));
break;
default:
a = 0.F;
}

tf.SetTranslation(m.x, m.y, m.z);
}

FinishRotate();
} else {

if (m_rotateSide != Side::None) {
for (auto p : GetSide(m_rotateSide)) {
auto& tf = p->GetTransform();
auto r = tf.GetRotation();

glm::vec3 m(p->Position);

switch (m_rotateSide) {
case Side::Left:
case Side::Right:
tf.SetRotation(a, r.y, r.z);
m = glm::vec3(p->Position) * RotateX(glm::radians(a));
break;
case Side::Bottom:
case Side::Top:
tf.SetRotation(r.x, a, r.z);
m = glm::vec3(p->Position) * RotateY(glm::radians(a));
break;
case Side::Back:
case Side::Front:
tf.SetRotation(r.x, r.y, a);
m = glm::vec3(p->Position) * RotateZ(glm::radians(a));
break;
default:
a = 0.F;
}

tf.SetTranslation(m.x, m.y, m.z);
}

FinishRotate();
} else if (m_rotateAxis != Axis::None) {
for (auto p : m_pointers) {
auto& tf = p->GetTransform();
auto r = tf.GetRotation();

glm::vec3 m(p->Position);

switch (m_rotateAxis) {
case Axis::Y:
tf.SetRotation(a, r.y, r.z);
m = glm::vec3(p->Position) * RotateX(glm::radians(a));
break;
case Axis::Z:
tf.SetRotation(r.x, a, r.z);
m = glm::vec3(p->Position) * RotateY(glm::radians(a));
break;
case Axis::X:
tf.SetRotation(r.x, r.y, a);
m = glm::vec3(p->Position) * RotateZ(glm::radians(a));
break;
default:
a = 0.F;
}

tf.SetTranslation(m.x, m.y, m.z);
}

FinishRotate();
}
} else {
for (auto p : m_pointers) {
auto& tf = p->GetTransform();
tf.SetTranslation(p->Position.x, p->Position.y, p->Position.z);
Expand Down Expand Up @@ -158,6 +184,7 @@ void Cube::FinishRotate() {
}

m_isRotating = false;
m_rotateAxis = Axis::None;
m_rotateSide = Side::None;
}

Expand Down Expand Up @@ -297,6 +324,34 @@ void Cube::Rotate(Side side, Direction direction) {
m_isRotating = true;
}

void Cube::Rotate(Axis axis, Direction direction) {
if (axis == Axis::None) return;

auto rotation = m_pointers.front()->GetTransform().GetRotation();

switch (axis) {
case Axis::Y:
a = rotation.x;
break;
case Axis::Z:
a = rotation.y;
break;
case Axis::X:
a = rotation.z;
break;
default:
a = 0.F;
}

m_rotateAngle = a + (int)direction;
if (m_rotateAngle < 0) m_rotateAngle += 360.F;
if (m_rotateAngle >= 360.F) m_rotateAngle -= 360.F;

m_rotateDirection = direction;
m_rotateAxis = axis;
m_isRotating = true;
}

glm::mat3 Cube::RotateX(const float angle) {
return glm::mat3(1, 0, 0, 0, cos(angle), -sin(angle), 0, sin(angle), cos(angle));
}
Expand Down
10 changes: 10 additions & 0 deletions QubGL/src/Logic/Cube.hpp
Expand Up @@ -25,6 +25,14 @@ enum class Side {
Top,
};

/// Note: https://developer.valvesoftware.com/w/images/6/6c/Hammer_Axis_visual_guide.png
enum class Axis {
None,
X,
Y,
Z
};

class Cube {
public:
Cube(const ShaderProgram* shader);
Expand All @@ -34,6 +42,7 @@ class Cube {
void GenerateModels(const Mesh mesh);
bool GetIsRotating() const;
void Rotate(Side side, Direction direction = Direction::Clockwise);
void Rotate(Axis axis, Direction direction = Direction::Clockwise);
void SetShader(const ShaderProgram* shader);

private:
Expand All @@ -48,6 +57,7 @@ class Cube {
std::list<Model> m_models;
std::vector<Model*> m_pointers;
float m_rotateAngle = 0.F;
Axis m_rotateAxis = Axis::None;
Direction m_rotateDirection = Direction::Clockwise;
Side m_rotateSide = Side::None;
const ShaderProgram* m_shader;
Expand Down
120 changes: 104 additions & 16 deletions QubGL/src/Rendering/OpenGlWindow.cpp
Expand Up @@ -11,15 +11,25 @@
#include "Model.hpp"
#include "ShaderProgram.hpp"

glm::vec3 m_cameraPosition = glm::vec3(0.F, 0.F, 5.F);
glm::vec3 m_cameraFront = glm::vec3(0.F, 0.F, -1.F);
glm::vec3 m_cameraUp = glm::vec3(0.F, 1.F, 0.F);

bool m_mouseDidMove = false;
float m_cameraSensitivity = .15F;
float m_cameraYaw = -90.F;
float m_cameraPitch = 0.F;
float m_cameraPreviousX = 800.F / 2.F;
float m_cameraPreviousY = 600.F / 2.F;
float m_cameraFieldOfView = 45.F;

Cube cube(nullptr);

void OnKey(GLFWwindow* window, int key, int scancode, int action, int mods) {
if (action != GLFW_PRESS) return;
if (cube.GetIsRotating()) return;

auto d = Direction::Clockwise;
if (key == GLFW_KEY_ESCAPE) glfwDestroyWindow(window);
if (action != GLFW_PRESS || cube.GetIsRotating()) return;

if ((mods && GLFW_MOD_SHIFT) == GLFW_MOD_SHIFT) d = Direction::CounterClockwise;
auto d = ((mods && GLFW_MOD_SHIFT) == GLFW_MOD_SHIFT) ? Direction::CounterClockwise : Direction::Clockwise;

if (key == GLFW_KEY_B) {
cube.Rotate(Side::Back, d);
Expand All @@ -34,6 +44,67 @@ void OnKey(GLFWwindow* window, int key, int scancode, int action, int mods) {
} else if (key == GLFW_KEY_U) {
cube.Rotate(Side::Bottom, d);
}

switch (key) {
/// Note: https://developer.valvesoftware.com/w/images/6/6c/Hammer_Axis_visual_guide.png
// Cube controls
case GLFW_KEY_KP_8:
cube.Rotate(Axis::Y, Direction::Clockwise);
break;
case GLFW_KEY_KP_2:
cube.Rotate(Axis::Y, Direction::CounterClockwise);
break;
case GLFW_KEY_KP_4:
cube.Rotate(Axis::Z, Direction::Clockwise);
break;
case GLFW_KEY_KP_6:
cube.Rotate(Axis::Z, Direction::CounterClockwise);
break;

// Cube section controls
case GLFW_KEY_KP_7:
cube.Rotate(Side::Left, Direction::Clockwise);
break;
case GLFW_KEY_KP_1:
cube.Rotate(Side::Left, Direction::CounterClockwise);
break;
case GLFW_KEY_KP_9:
cube.Rotate(Side::Right, Direction::Clockwise);
break;
case GLFW_KEY_KP_3:
cube.Rotate(Side::Right, Direction::CounterClockwise);
break;
default: break;
}
}

void OnMouseMove(GLFWwindow* window, double xPos, double yPos) {
if (!m_mouseDidMove)
{
m_cameraPreviousX = xPos;
m_cameraPreviousY = yPos;
m_mouseDidMove = true;
}

float xOffset = xPos - m_cameraPreviousX;
float yOffset = m_cameraPreviousY - yPos;
m_cameraPreviousX = xPos;
m_cameraPreviousY = yPos;

xOffset *= m_cameraSensitivity;
yOffset *= m_cameraSensitivity;

m_cameraYaw += xOffset;
m_cameraPitch += yOffset;

if (m_cameraPitch > 89.F) m_cameraPitch = 89.F;
if (m_cameraPitch < -89.F) m_cameraPitch = -89.F;

glm::vec3 front;
front.x = cos(glm::radians(m_cameraYaw)) * cos(glm::radians(m_cameraPitch));
front.y = sin(glm::radians(m_cameraPitch));
front.z = sin(glm::radians(m_cameraYaw)) * cos(glm::radians(m_cameraPitch));
m_cameraFront = glm::normalize(front);
}

OpenGlWindow::OpenGlWindow(const std::string& title, unsigned int width, unsigned int height)
Expand Down Expand Up @@ -61,8 +132,10 @@ OpenGlWindow::OpenGlWindow(const std::string& title, unsigned int width, unsigne

std::cout << "Open GL Version: " << glGetString(GL_VERSION) << std::endl;
std::cout << "Vendor: " << glGetString(GL_VENDOR) << std::endl;
std::cout << "Renderer: " << glGetString(GL_RENDERER) << std::endl;

glfwSetKeyCallback(m_window, OnKey);
glfwSetCursorPosCallback(m_window, OnMouseMove);

glClearColor(0.F, 0.F, 0.F, 1.F);
}
Expand All @@ -79,6 +152,25 @@ unsigned int OpenGlWindow::GetWidth() const {
return m_width;
}

void OpenGlWindow::ProcessInput(GLFWwindow* window) {
float cameraSpeed = .25F;

if (glfwGetKey(window, GLFW_KEY_LEFT_ALT) == GLFW_PRESS) {
cameraSpeed = .1F;
} else if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) {
cameraSpeed = .5F;
}

if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
m_cameraPosition += cameraSpeed * m_cameraFront;
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
m_cameraPosition -= cameraSpeed * m_cameraFront;
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
m_cameraPosition -= glm::normalize(glm::cross(m_cameraFront, m_cameraUp)) * cameraSpeed;
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
m_cameraPosition += glm::normalize(glm::cross(m_cameraFront, m_cameraUp)) * cameraSpeed;
}

void OpenGlWindow::Show() {
ShaderProgram program("resources/BasicVertex.shader", "resources/BasicFragment.shader");
program.Bind();
Expand All @@ -96,9 +188,7 @@ void OpenGlWindow::Show() {
glm::mat4 projection = glm::perspective(glm::radians(55.F), aspectRatio, .1F, 100.F);
program.SetProjectionMatrix(projection);

glm::mat4 camera = glm::lookAt(glm::vec3(0.F, 0.F, 5.F), glm::vec3(0.F, 0.F, -1.F), glm::vec3(0.F, 1.F, 0.F));
program.SetViewMatrix(camera);

glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
glEnable(GL_DEPTH_TEST);

DirectionalLight dirLight;
Expand All @@ -109,16 +199,14 @@ void OpenGlWindow::Show() {

program.SetDirectionalLight(dirLight);

auto angle = 0.F;

while (!glfwWindowShouldClose(m_window)) {
angle += .05F;

if (angle > 360) {
angle = 0;
}

ProcessInput(m_window);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glm::mat4 camera = glm::lookAt(m_cameraPosition, m_cameraPosition + m_cameraFront, m_cameraUp);
// glm::mat4 camera = glm::lookAt(m_cameraPosition, m_cameraCenter, glm::vec3(0.F, 1.F, 0.F));
program.SetViewMatrix(camera);

cube.Draw();

Expand Down
1 change: 1 addition & 0 deletions QubGL/src/Rendering/OpenGlWindow.hpp
Expand Up @@ -11,6 +11,7 @@ class OpenGlWindow : public Window {
virtual unsigned int GetHeight() const override;
virtual std::string GetTitle() const override;
virtual unsigned int GetWidth() const override;
virtual void OpenGlWindow::ProcessInput(GLFWwindow* window);
virtual void Show() override;

private:
Expand Down
2 changes: 0 additions & 2 deletions QubGL/src/main.cpp
Expand Up @@ -5,8 +5,6 @@
#include "Rendering/WindowFactory.hpp"

int main(void) {
std::cout << "Hello World!" << std::endl;

Window* window = WindowFactory::CreateWindow("QubGL - Jonas tinkt", 1920, 1080);
window->Show();

Expand Down

0 comments on commit d80d7a0

Please sign in to comment.