diff --git a/CMakeLists.txt b/CMakeLists.txt index 663acfe..6f007df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,7 +48,9 @@ set(SOURCE_FILES src/Engine/Camera/Perspective.cpp src/Engine/Camera/Perspective.h src/Engine/Camera/Ortho.cpp src/Engine/Camera/Ortho.h src/Examples/Tangram3D/Triangle3D.cpp src/Examples/Tangram3D/Triangle3D.h - src/Examples/Tangram3D/Parallelogram3D.h src/Examples/Tangram3D/Parallelogram3D.cpp src/Engine/Math/Quat.cpp src/Engine/Math/Quat.h) + src/Examples/Tangram3D/Parallelogram3D.h src/Examples/Tangram3D/Parallelogram3D.cpp src/Engine/Math/Quat.cpp src/Engine/Math/Quat.h + src/Examples/Quaternion/CameraControllerRot.cpp src/Examples/Quaternion/CameraControllerRot.h + src/Examples/Quaternion/Quaternion.cpp src/Examples/Quaternion/Quaternion.h) set(TESTS_SOURCE_FILES src/Tests/catch.hpp src/Tests/tests.cpp src/Tests/VectorTests.h src/Tests/MatrixTests.h) diff --git a/src/Engine/Camera/Camera.cpp b/src/Engine/Camera/Camera.cpp index 8bdc4b6..debc2b8 100644 --- a/src/Engine/Camera/Camera.cpp +++ b/src/Engine/Camera/Camera.cpp @@ -10,52 +10,6 @@ namespace ThreeEngine { -// const glMatrix I = { -// 1.0f, 0.0f, 0.0f, 0.0f, -// 0.0f, 1.0f, 0.0f, 0.0f, -// 0.0f, 0.0f, 1.0f, 0.0f, -// 0.0f, 0.0f, 0.0f, 1.0f -// }; -// -// const glMatrix ModelMatrix = { -// 1.0f, 0.0f, 0.0f, 0.0f, -// 0.0f, 1.0f, 0.0f, 0.0f, -// 0.0f, 0.0f, 1.0f, 0.0f, -// -0.5f, -0.5f, -0.5f, 1.0f -// }; // Column Major -// -// // Eye(5,5,5) Center(0,0,0) Up(0,1,0) -// const glMatrix ViewMatrix1 = { -// 0.70f, -0.41f, 0.58f, 0.00f, -// 0.00f, 0.82f, 0.58f, 0.00f, -// -0.70f, -0.41f, 0.58f, 0.00f, -// 0.00f, 0.00f, -8.70f, 1.00f -// }; // Column Major -// -// // Eye(-5,-5,-5) Center(0,0,0) Up(0,1,0) -// const glMatrix ViewMatrix2 = { -// -0.70f, -0.41f, -0.58f, 0.00f, -// 0.00f, 0.82f, -0.58f, 0.00f, -// 0.70f, -0.41f, -0.58f, 0.00f, -// 0.00f, 0.00f, -8.70f, 1.00f -// }; // Column Major -// -// // Orthographic LeftRight(-2,2) TopBottom(-2,2) NearFar(1,10) -// const glMatrix ProjectionMatrix1 = { -// 0.50f, 0.00f, 0.00f, 0.00f, -// 0.00f, 0.50f, 0.00f, 0.00f, -// 0.00f, 0.00f, -0.22f, 0.00f, -// 0.00f, 0.00f, -1.22f, 1.00f -// }; // Column Major -// -// // Perspective Fovy(30) Aspect(640/480) NearZ(1) FarZ(10) -// const glMatrix ProjectionMatrix2 = { -// 2.79f, 0.00f, 0.00f, 0.00f, -// 0.00f, 3.73f, 0.00f, 0.00f, -// 0.00f, 0.00f, -1.22f, -1.00f, -// 0.00f, 0.00f, -2.22f, 0.00f -// }; // Column Majors - Camera::Camera() : Camera(0) { } Camera::Camera(GLuint uniformBlockBidingID) : Camera(uniformBlockBidingID, @@ -65,7 +19,7 @@ namespace ThreeEngine { {0, 1, 0})) { } Camera::Camera(GLuint uniformBlockBidingID, Matrix* projection, Matrix* view) - : uniformBlockBidingID(uniformBlockBidingID), projection(projection), view(view) { } + : projection(projection), view(view), uniformBlockBidingID(uniformBlockBidingID) { } Camera::~Camera() { glDeleteBuffers(1, &vboId); @@ -99,4 +53,42 @@ namespace ThreeEngine { glBindBuffer(GL_UNIFORM_BUFFER, 0); CheckOpenGLError("Could not draw camera."); } + + Matrix* Camera::getProjection() const { + return projection; + } + + void Camera::SetProjection(Matrix* projection) { + if (this->projection == projection) { + return; + } + delete this->projection; + this->projection = projection; + } + + void Camera::SetProjection(Matrix const& projection) { + if (!this->projection) { + return; + } + *this->projection = projection; + } + + Matrix* Camera::GetView() const { + return view; + } + + void Camera::SetView(Matrix* view) { + if (this->view == view) { + return; + } + delete this->view; + this->view = view; + } + + void Camera::SetView(Matrix const& view) { + if (!this->view) { + return; + } + *this->view = view; + } } /* namespace Divisaction */ \ No newline at end of file diff --git a/src/Engine/Camera/Camera.h b/src/Engine/Camera/Camera.h index a345de7..b614712 100644 --- a/src/Engine/Camera/Camera.h +++ b/src/Engine/Camera/Camera.h @@ -14,10 +14,10 @@ namespace ThreeEngine { class Camera : public IActor { private: GLuint vaoId, vboId; - public: - GLuint uniformBlockBidingID; Matrix* projection, * view; + public: + GLuint uniformBlockBidingID; Camera(); @@ -30,6 +30,18 @@ namespace ThreeEngine { void Init() override; void Draw() override; + + Matrix* getProjection() const; + + void SetProjection(Matrix* projection); + + void SetProjection(Matrix const& projection); + + Matrix* GetView() const; + + void SetView(Matrix* view); + + void SetView(Matrix const& view); }; } /* namespace Divisaction */ diff --git a/src/Examples/Quaternion/CameraControllerRot.cpp b/src/Examples/Quaternion/CameraControllerRot.cpp new file mode 100644 index 0000000..a3309fb --- /dev/null +++ b/src/Examples/Quaternion/CameraControllerRot.cpp @@ -0,0 +1,68 @@ +/* + * File CameraController.cpp in project ThreeEngine + * + * Copyright (C) Ricardo Rodrigues 2017 - All Rights Reserved + */ +#include "CameraControllerRot.h" +#include "../../Engine/Camera/Ortho.h" +#include "../../Engine/Camera/Perspective.h" + +namespace ThreeEngine { + + CameraControllerRot::CameraControllerRot() : engine(Engine::Instance()), inPerspective(true), + useQuat(false), previousMouseLocation(), + yawPitch(), translation(Matrix::IdentityMatrix()), + rotation(Matrix::IdentityMatrix()), + quat({1, 0, 0, 0}) { } + + CameraControllerRot::~CameraControllerRot() = default; + + void CameraControllerRot::Update() { + if (engine) { + const Vector2 mouse = engine->input.GetMouseScreenLocation(); + Camera* camera = engine->camera; + + // Toggle between Ortho and Perspective + if (engine->input.Click('p')) { + if (inPerspective) { + camera->SetProjection(new Ortho(-2, 2, -2, 2, 1, 100)); + inPerspective = false; + } else { + number width = engine->config["window"]["x"]; + number height = engine->config["window"]["y"]; + number aspect = width / height; + camera->SetProjection(new Perspective(30, aspect, 1, 100)); + inPerspective = true; + } + } + // Toggle between using Quaternions or Euler Angles for rotations + if (engine->input.Click('g')) { + useQuat = !useQuat; + } + + if (engine->input[MouseKeys::LEFT] || engine->input[MouseKeys::RIGHT]) { + float sensitivity = 0.05f; + Vector2 delta = {(mouse.X - previousMouseLocation.X) * sensitivity, + (previousMouseLocation.Y - mouse.Y) * sensitivity}; + + // Always calculate the updated quaternion to even if it is not being used + // otherwise it will break the toggling. + quat = (Quat::FromAngleAxis(delta.X, Vector(0, 1, 0)) * + Quat::FromAngleAxis(-delta.Y, Vector(1, 0, 0))).Normalize() * quat; + + if (useQuat) { + camera->SetView(Matrix::TranslationMatrix(Vector(0, 0, -10)) * quat.ToMatrix()); + } else { + + Matrix rotation = Matrix(Matrix3::RotationMatrix(Maths::Axis::Y, -delta.X)) * + Matrix(Matrix3::RotationMatrix(Maths::Axis::X, -delta.Y)); + camera->SetView(*camera->GetView() * rotation); + } + } + + previousMouseLocation = mouse; + } + + } + +} /* namespace Divisaction */ \ No newline at end of file diff --git a/src/Examples/Quaternion/CameraControllerRot.h b/src/Examples/Quaternion/CameraControllerRot.h new file mode 100644 index 0000000..8eceabe --- /dev/null +++ b/src/Examples/Quaternion/CameraControllerRot.h @@ -0,0 +1,37 @@ +/* + * File CameraController.h in project ThreeEngine + * + * Copyright (C) Ricardo Rodrigues 2017 - All Rights Reserved + */ +#ifndef THREEENGINE_CAMERACONTROLLERROT_H +#define THREEENGINE_CAMERACONTROLLERROT_H + +#include "../../Engine/Engine.h" +#include "../../Engine/Math/Quat.h" + +namespace ThreeEngine { + + class CameraControllerRot { + private: + Engine* engine; + + bool inPerspective, useQuat; + + Vector2 previousMouseLocation, yawPitch; + + Matrix translation, rotation; + + Quat quat; + + public: + + CameraControllerRot(); + + virtual ~CameraControllerRot(); + + void Update(); + }; + +} /* namespace Divisaction */ + +#endif //THREEENGINE_CAMERACONTROLLERROT_H diff --git a/src/Examples/Quaternion/Quaternion.cpp b/src/Examples/Quaternion/Quaternion.cpp new file mode 100644 index 0000000..58f8829 --- /dev/null +++ b/src/Examples/Quaternion/Quaternion.cpp @@ -0,0 +1,151 @@ +/* + * File Tangram.cpp in project ThreeEngine + * + * Copyright (C) Ricardo Rodrigues 2017 - All Rights Reserved + */ +#include "Quaternion.h" +#include "../../Engine/Camera/Perspective.h" +#include "../../Engine/Camera/LookAt.h" +#include "../Tangram3D/Triangle3D.h" +#include "../Tangram3D/Cube.h" +#include "../Tangram3D/Parallelogram3D.h" + +#define VERTICES 0 +#define COLORS 1 + +using json = nlohmann::json; + +namespace ThreeEngine { + + + Quaternion::Quaternion() : Engine(), shapeToShow(CUBE), controller() { } + + Quaternion::~Quaternion() = default; + + void Quaternion::OnInit() { + switch (shapeToShow) { + case CUBE: + CubeScene(); + break; + } + } + + void Quaternion::CubeScene() { + auto colorProgram = std::make_shared("shaders/Color3D/program.json"); + colorProgram->Init(); + + Debug::Log(*colorProgram); + + { // Camera handling + delete camera; + + number width = config["window"]["x"]; + number height = config["window"]["y"]; + number aspect = width / height; + camera = new Camera( + static_cast(colorProgram->GetUniformBlockBidingId("SharedMatrices")), + new Perspective(30, aspect, 1, 100), + new Matrix(Matrix::TranslationMatrix(Vector(0, 0, -10))) +// new LookAt({5, 0.5f, 0}, {0, 0.5f, 0}, {0, 1, 0}) + ); + } + + float triangleSize = 0.7071f; + + { // Big triangle to the Left + auto* triangle = new Triangle3D(); + Matrix2 transform2D = + (TMatrix<2, 2>) Matrix2::RotationMatrix(135) * + Matrix2::ScaleMatrix(triangleSize * 2, triangleSize * 2); + triangle->transform = + Matrix::TranslationMatrix({0.0f, 0.0f, 0, 0}) * + Matrix(transform2D); + actors.push_back((IActor*) triangle); + + triangle->shaderProgram = colorProgram; + triangle->color[0] = .5f; + } + { // Big triangle to the Top + auto* triangle = new Triangle3D(); + Matrix2 transform2D = + (TMatrix<2, 2>) Matrix2::RotationMatrix(45) * + Matrix2::ScaleMatrix(triangleSize * 2, triangleSize * 2); + triangle->transform = Matrix::TranslationMatrix({0.0f, 0.0f, .5f, 0}) * + Matrix(transform2D); + actors.push_back((IActor*) triangle); + + triangle->shaderProgram = colorProgram; + triangle->color[1] = .5f; + } + { // Small triangle at the center + auto* triangle = new Triangle3D(); + Matrix2 transform2D = (TMatrix<2, 2>) Matrix2::RotationMatrix(-135) * + Matrix2::ScaleMatrix(triangleSize, triangleSize); + triangle->transform = + Matrix::TranslationMatrix({0.0f, 0.0f, -.5f, 0}) * Matrix(transform2D); + actors.push_back((IActor*) triangle); + + triangle->shaderProgram = colorProgram; + } + { // Small triangle at the top right + auto* triangle = new Triangle3D(); + Matrix2 transform2D = (TMatrix<2, 2>) Matrix2::RotationMatrix(-45) * + Matrix2::ScaleMatrix(triangleSize, triangleSize); + triangle->transform = + Matrix::TranslationMatrix({0.5f, 0.5f, 0.2f, 0}) * + Matrix(transform2D); + actors.push_back((IActor*) triangle); + + triangle->shaderProgram = colorProgram; + triangle->color[0] = .5f; + triangle->color[1] = .5f; + } + { // Medium triangle to the bottom right + auto* triangle = new Triangle3D(); + Matrix2 transform2D = + (TMatrix<2, 2>) Matrix2::RotationMatrix(90); + triangle->transform = + Matrix::TranslationMatrix({1.0f, -1.0f, -0.2f, 0}) * Matrix(transform2D); + actors.push_back((IActor*) triangle); + + triangle->shaderProgram = colorProgram; + triangle->color[0] = .2f; + triangle->color[1] = .7f; + } + { // Square + auto* square = new Cube(); + Matrix2 transform2D = + (TMatrix<2, 2>) Matrix2::RotationMatrix(-45) * + Matrix2::ScaleMatrix(triangleSize, triangleSize); + square->transform = Matrix(transform2D); + actors.push_back((IActor*) square); + + square->shaderProgram = colorProgram; + } + { // Parallelogram + auto* parallelogram = new Parallelogram3D(); + parallelogram->transform = + Matrix::TranslationMatrix({0.0f, 0.0f, -1, 0}) * + Matrix::TranslationMatrix(Vector({-1, -1, 0})); + actors.push_back((IActor*) parallelogram); + + parallelogram->shaderProgram = colorProgram; + } + + } + + void Quaternion::OnReshape(int, int) { +// number aspect = (number) w / (number) h, +// angle = Maths::ToRadians(30.0f / 2.0f), +// d = 1.0f / tanf(angle); +// camera->projection.M[0][0] = d / aspect; + } + + void Quaternion::PreDraw() { + if (input.Click(27)) { + Exit(); + } + controller.Update(); + } + +} /* namespace Divisaction */ \ No newline at end of file diff --git a/src/Examples/Quaternion/Quaternion.h b/src/Examples/Quaternion/Quaternion.h new file mode 100644 index 0000000..19c00dc --- /dev/null +++ b/src/Examples/Quaternion/Quaternion.h @@ -0,0 +1,43 @@ +/* + * File Tangram.h in project ThreeEngine + * + * Copyright (C) Ricardo Rodrigues 2017 - All Rights Reserved + */ +#ifndef THREEENGINE_QUATERNION_H +#define THREEENGINE_QUATERNION_H + +#include "../../Engine/Engine.h" +#include "../../Engine/Shader/ShaderProgram.h" +#include "../../Engine/IActor.h" +#include "CameraControllerRot.h" + +namespace ThreeEngine { + + class Quaternion : public Engine { + public: + Quaternion(); + + ~Quaternion() override; + + enum ShapeType3D { + CUBE + }; + + ShapeType3D shapeToShow; + + CameraControllerRot controller; + + protected: + + void OnInit() override; + + void CubeScene(); + + void OnReshape(int w, int h) override; + + void PreDraw() override; + }; + +} /* namespace Divisaction */ + +#endif //THREEENGINE_QUATERNION_H diff --git a/src/Examples/Tangram3D/CameraController.cpp b/src/Examples/Tangram3D/CameraController.cpp index 57784a1..3120074 100644 --- a/src/Examples/Tangram3D/CameraController.cpp +++ b/src/Examples/Tangram3D/CameraController.cpp @@ -24,21 +24,20 @@ namespace ThreeEngine { Camera* camera = engine->camera; if (engine->input.Click('p')) { - delete camera->projection; if (inPerspective) { - camera->projection = new Ortho(-2, 2, -2, 2, 1, 100); + camera->SetProjection(new Ortho(-2, 2, -2, 2, 1, 100)); inPerspective = false; } else { number width = engine->config["window"]["x"]; number height = engine->config["window"]["y"]; number aspect = width / height; - camera->projection = new Perspective(30, aspect, 1, 100); + camera->SetProjection(new Perspective(30, aspect, 1, 100)); inPerspective = true; } } - auto lookAt = static_cast(camera->view); + auto lookAt = static_cast(camera->GetView()); if (engine->input['w'] || engine->input[SpecialKeys::UP_KEY]) { // translation = Matrix::TranslationMatrix({0, 0, 0.1f, 0}) * translation; diff --git a/src/main.cpp b/src/main.cpp index 3d72c47..042a816 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,7 +3,7 @@ // #include -#include "Examples/Tangram3D/Tangram3D.h" +#include "Examples/Quaternion/Quaternion.h" #include "Engine/Math/Quat.h" using namespace ThreeEngine; @@ -23,8 +23,8 @@ int main(int argc, char* argv[]) { Quat r = q * Quat(v) * qi; Debug::Log(r); - Tangram3D engine; - engine.shapeToShow = Tangram3D::ShapeType3D::CUBE; + Quaternion engine; + engine.shapeToShow = Quaternion::ShapeType3D::CUBE; engine.Init(argc, argv); engine.Run(); }