diff --git a/examples/model_loading/main.cpp b/examples/model_loading/main.cpp index 0ec4612..1db6552 100644 --- a/examples/model_loading/main.cpp +++ b/examples/model_loading/main.cpp @@ -72,6 +72,8 @@ int main(int argc, char** argv) oglu::Enable(GL_DEPTH_TEST); oglu::Camera camera(45.0f, 1.0f, 0.1f, 100.0f); + camera.Move(0.0f, -5.0f, -10.0f); + camera.LookAt(glm::value_ptr(glm::make_vec3(utah.GetPosition()) + glm::vec3(0.0f, 2.0f, 0.0f))); float t = 0.0f; @@ -82,8 +84,7 @@ int main(int argc, char** argv) oglu::ClearScreen(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, oglu::Color(0.29f, 0.13f, 0.23f)); - camera.SetPosition(10.0f * cosf(t), -5.0f, 10.0f * sinf(t)); - camera.LookAt(utah); + utah.Rotate(0.0f, 10.0f, 0.0f); shader->Use(); shader->SetUniform("model", utah); diff --git a/include/transformable.hpp b/include/transformable.hpp index 165faf7..ce71386 100644 --- a/include/transformable.hpp +++ b/include/transformable.hpp @@ -10,6 +10,8 @@ #define TRANSFORMABLE_HPP #include +#include +#include namespace oglu { @@ -258,12 +260,13 @@ namespace oglu protected: // TODO: Separate translation, rotation and scaling matrices. // Combine them only when the user wants the transformation matrix - float* position; ///< Position vector - float* rotation; ///< Rotation matrix - float* scaling; ///< Scaling vector + glm::mat4 transformation; - float* transformation; - bool calculateMatrix; ///< Wether GetMatrix() needs to re-calculate the transformation matrix + glm::vec3 scale; + glm::quat orientation; + glm::vec3 translation; + glm::vec3 skew; + glm::vec4 perspective; }; } diff --git a/src/camera.cpp b/src/camera.cpp index 4e7ee94..f0c49d3 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -53,32 +53,8 @@ namespace oglu void Camera::LookAt(GLfloat x, GLfloat y, GLfloat z) { - glm::mat4 newTransform = glm::lookAt(glm::make_vec3(position), glm::vec3(x, y, z), glm::vec3(0.0f, 1.0f, 0.0f)); - glm::vec3 scale; - glm::vec3 pos; - glm::quat rot; - glm::vec3 skew; - glm::vec4 pers; - glm::decompose(newTransform, scale, rot, pos, skew, pers); - - memcpy( - position, - glm::value_ptr(pos), - 3 * sizeof(float) - ); - - memcpy( - rotation, - glm::value_ptr(glm::toMat4(rot)), - 16 * sizeof(float) - ); - - memcpy( - scaling, - glm::value_ptr(scale), - 3 * sizeof(float) - ); - calculateMatrix = true; + transformation = glm::lookAt(translation, glm::vec3(x, y, z), glm::vec3(0.0f, 1.0f, 0.0f)); + glm::decompose(transformation, scale, orientation, translation, skew, perspective); } void Camera::LookAt(const GLfloat* target) diff --git a/src/transformable.cpp b/src/transformable.cpp index b12110c..70e2853 100644 --- a/src/transformable.cpp +++ b/src/transformable.cpp @@ -2,266 +2,150 @@ #include -#include #include +#include +#include #include namespace oglu { oglu::Transformable::Transformable() : - position(new float[3]{ 0.f }), rotation(new float[16]), scaling(new float[3]{ 1.f, 1.f, 1.f }), transformation(new float[16]), calculateMatrix(false) + transformation(glm::mat4(1.0f)) { - glm::mat4 identity(1.0f); - memcpy( - rotation, - glm::value_ptr(identity), - 16 * sizeof(float) - ); - memcpy( - transformation, - glm::value_ptr(identity), - 16 * sizeof(float) - ); + glm::decompose(transformation, scale, orientation, translation, skew, perspective); } Transformable::Transformable(const Transformable& other) : - position(new float[3]), rotation(new float[16]), scaling(new float[3]), transformation(new float[16]), calculateMatrix(true) + transformation(other.transformation) { - memcpy( - this->position, - other.position, - 3 * sizeof(float) - ); - - memcpy( - this->rotation, - other.rotation, - 16 * sizeof(float) - ); - - memcpy( - this->scaling, - other.scaling, - 3 * sizeof(float) - ); + glm::decompose(transformation, scale, orientation, translation, skew, perspective); } Transformable::~Transformable() { - delete[] scaling; - delete[] rotation; - delete[] position; } void Transformable::SetPosition(float x, float y, float z) { - this->position[0] = x; - this->position[1] = y; - this->position[2] = z; - calculateMatrix = true; + glm::decompose(transformation, scale, orientation, translation, skew, perspective); + translation = glm::vec3(x, y, z) - translation; + transformation = glm::translate(transformation, translation); } void Transformable::SetPosition(const float* translation) { - memcpy( - this->position, - translation, - 3 * sizeof(float) - ); - calculateMatrix = true; + glm::decompose(transformation, scale, orientation, this->translation, skew, perspective); + this->translation = glm::make_vec3(translation) - this->translation; + transformation = glm::translate(transformation, this->translation); } void Transformable::SetRotation(float rotX, float rotY, float rotZ) { - // TODO: Using rotation matrices is stupid. Eventually this could (should) be done with quaternions - // For now we'll just risk gimbal locking the model - memcpy( - this->rotation, - glm::value_ptr( - glm::rotate( - glm::rotate( - glm::rotate( - glm::mat4(1.0f), glm::radians(rotX), glm::vec3(1.0f, 0.0f, 0.0f) - ), glm::radians(rotY), glm::vec3(0.0f, 1.0f, 0.0f) - ), glm::radians(rotZ), glm::vec3(0.0f, 0.0f, 1.0f) - ) - ), - 16 * sizeof(float) - ); - calculateMatrix = true; + glm::decompose(transformation, scale, orientation, translation, skew, perspective); + orientation = glm::quat(glm::vec3(rotX, rotY, rotZ)) - orientation; + transformation = glm::rotate(transformation, orientation.w, glm::vec3(orientation.x, orientation.y, orientation.z)); } void Transformable::SetRotation(const float* rotation) { - memcpy( - this->rotation, - glm::value_ptr( - glm::rotate( - glm::rotate( - glm::rotate( - glm::mat4(1.0f), glm::radians(rotation[0]), glm::vec3(1.0f, 0.0f, 0.0f) - ), glm::radians(rotation[1]), glm::vec3(0.0f, 1.0f, 0.0f) - ), glm::radians(rotation[2]), glm::vec3(0.0f, 0.0f, 1.0f) - ) - ), - 16 * sizeof(float) - ); - calculateMatrix = true; + glm::decompose(transformation, scale, orientation, translation, skew, perspective); + orientation = glm::quat(glm::make_vec3(rotation)) - orientation; + transformation = glm::rotate(transformation, orientation.w, glm::vec3(orientation.x, orientation.y, orientation.z)); } void Transformable::SetRotation(float angle, float xAxis, float yAxis, float zAxis) { - memcpy( - this->rotation, - glm::value_ptr(glm::rotate(glm::mat4(1.0f), glm::radians(angle), glm::vec3(xAxis, yAxis, zAxis))), - 16 * sizeof(float) - ); - calculateMatrix = true; + glm::decompose(transformation, scale, orientation, translation, skew, perspective); + orientation = glm::quat(glm::vec4(xAxis, yAxis, zAxis, angle)) - orientation; + transformation = glm::rotate(transformation, orientation.w, glm::vec3(orientation.x, orientation.y, orientation.z)); } void Transformable::SetRotation(float angle, const float* axis) { - memcpy( - this->rotation, - glm::value_ptr(glm::rotate(glm::mat4(1.0f), glm::radians(angle), glm::make_vec3(axis))), - 16 * sizeof(float) - ); - calculateMatrix = true; + glm::decompose(transformation, scale, orientation, translation, skew, perspective); + orientation = glm::quat(glm::vec4(axis[0], axis[1], axis[2], angle)) - orientation; + transformation = glm::rotate(transformation, orientation.w, glm::vec3(orientation.x, orientation.y, orientation.z)); } void Transformable::SetScale(float scaleX, float scaleY, float scaleZ) { - this->scaling[0] = scaleX; - this->scaling[1] = scaleY; - this->scaling[2] = scaleZ; - calculateMatrix = true; + glm::decompose(transformation, scale, orientation, translation, skew, perspective); + scale = glm::vec3(scaleX, scaleY, scaleZ) - scale; + transformation = glm::scale(transformation, scale); } void Transformable::SetScale(const float* scale) { - memcpy( - this->scaling, - scale, - 3 * sizeof(float) - ); - calculateMatrix = true; + glm::decompose(transformation, this->scale, orientation, translation, skew, perspective); + this->scale = glm::make_vec3(scale) - this->scale; + transformation = glm::scale(transformation, this->scale); } void Transformable::Move(float x, float y, float z) { - this->position[0] += x; - this->position[1] += y; - this->position[2] += z; - calculateMatrix = true; + transformation = glm::translate(transformation, glm::vec3(x, y, z)); + glm::decompose(transformation, scale, orientation, translation, skew, perspective); } void Transformable::Move(const float* translation) { - this->position[0] += translation[0]; - this->position[1] += translation[1]; - this->position[2] += translation[2]; - calculateMatrix = true; + transformation = glm::translate(transformation, glm::make_vec3(translation)); + glm::decompose(transformation, scale, orientation, this->translation, skew, perspective); } void Transformable::Rotate(float rotX, float rotY, float rotZ) { - memcpy( - this->rotation, - glm::value_ptr( - glm::rotate( - glm::rotate( - glm::rotate( - glm::make_mat4(this->rotation), glm::radians(rotX), glm::vec3(1.0f, 0.0f, 0.0f) - ), glm::radians(rotY), glm::vec3(0.0f, 1.0f, 0.0f) - ), glm::radians(rotZ), glm::vec3(0.0f, 0.0f, 1.0f) - ) - ), - 16 * sizeof(float) - ); - calculateMatrix = true; + transformation = glm::rotate(transformation, glm::radians(1.0f), glm::vec3(rotX, rotY, rotZ)); + glm::decompose(transformation, scale, orientation, translation, skew, perspective); } void Transformable::Rotate(const float* rotation) { - memcpy( - this->rotation, - glm::value_ptr( - glm::rotate( - glm::rotate( - glm::rotate( - glm::make_mat4(this->rotation), glm::radians(rotation[0]), glm::vec3(1.0f, 0.0f, 0.0f) - ), glm::radians(rotation[1]), glm::vec3(0.0f, 1.0f, 0.0f) - ), glm::radians(rotation[2]), glm::vec3(0.0f, 0.0f, 1.0f) - ) - ), - 16 * sizeof(float) - ); - calculateMatrix = true; + transformation = glm::rotate(transformation, 1.0f, glm::make_vec3(rotation)); + glm::decompose(transformation, scale, orientation, translation, skew, perspective); } void Transformable::Rotate(float angle, float xAxis, float yAxis, float zAxis) { - memcpy( - this->rotation, - glm::value_ptr(glm::rotate(glm::make_mat4(this->rotation), glm::radians(angle), glm::vec3(xAxis, yAxis, zAxis))), - 16 * sizeof(float) - ); - calculateMatrix = true; + transformation = glm::rotate(transformation, angle, glm::vec3(xAxis, yAxis, zAxis)); + glm::decompose(transformation, scale, orientation, translation, skew, perspective); } void Transformable::Rotate(float angle, const float* axis) { - memcpy( - this->rotation, - glm::value_ptr(glm::rotate(glm::make_mat4(this->rotation), glm::radians(angle), glm::make_vec3(axis))), - 16 * sizeof(float) - ); - calculateMatrix = true; + transformation = glm::rotate(transformation, angle, glm::make_vec3(axis)); + glm::decompose(transformation, scale, orientation, translation, skew, perspective); } void Transformable::Scale(float scaleX, float scaleY, float scaleZ) { - this->scaling[0] += scaleX; - this->scaling[1] += scaleY; - this->scaling[2] += scaleZ; - calculateMatrix = true; + transformation = glm::scale(transformation, glm::vec3(scaleX, scaleY, scaleZ)); + glm::decompose(transformation, scale, orientation, translation, skew, perspective); } void Transformable::Scale(const float* scale) { - this->scaling[0] += scale[0]; - this->scaling[1] += scale[1]; - this->scaling[2] += scale[2]; - calculateMatrix = true; + transformation = glm::scale(transformation, glm::make_vec3(scale)); + glm::decompose(transformation, this->scale, orientation, translation, skew, perspective); } const float* Transformable::GetMatrix() { - if (calculateMatrix) - { - memcpy( - transformation, - glm::value_ptr(glm::translate(glm::mat4(1.0f), glm::make_vec3(position)) * glm::make_mat4(rotation) * glm::scale(glm::mat4(1.0f), glm::make_vec3(scaling))), - 16 * sizeof(float) - ); - calculateMatrix = false; - } - - return transformation; + return glm::value_ptr(transformation); } const float* Transformable::GetPosition() const { - return position; + return glm::value_ptr(translation); } const float* Transformable::GetRotation() const { - return rotation; + return glm::value_ptr(orientation); } const float* Transformable::GetScaling() const { - return scaling; + return glm::value_ptr(scale); } }