Transformable now uses a matrix
This commit is contained in:
parent
30736781ab
commit
3e6884356f
|
@ -72,6 +72,8 @@ int main(int argc, char** argv)
|
||||||
oglu::Enable(GL_DEPTH_TEST);
|
oglu::Enable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
oglu::Camera camera(45.0f, 1.0f, 0.1f, 100.0f);
|
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;
|
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));
|
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));
|
utah.Rotate(0.0f, 10.0f, 0.0f);
|
||||||
camera.LookAt(utah);
|
|
||||||
|
|
||||||
shader->Use();
|
shader->Use();
|
||||||
shader->SetUniform("model", utah);
|
shader->SetUniform("model", utah);
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#define TRANSFORMABLE_HPP
|
#define TRANSFORMABLE_HPP
|
||||||
|
|
||||||
#include <core.hpp>
|
#include <core.hpp>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtx/quaternion.hpp>
|
||||||
|
|
||||||
namespace oglu
|
namespace oglu
|
||||||
{
|
{
|
||||||
|
@ -258,12 +260,13 @@ namespace oglu
|
||||||
protected:
|
protected:
|
||||||
// TODO: Separate translation, rotation and scaling matrices.
|
// TODO: Separate translation, rotation and scaling matrices.
|
||||||
// Combine them only when the user wants the transformation matrix
|
// Combine them only when the user wants the transformation matrix
|
||||||
float* position; ///< Position vector
|
glm::mat4 transformation;
|
||||||
float* rotation; ///< Rotation matrix
|
|
||||||
float* scaling; ///< Scaling vector
|
|
||||||
|
|
||||||
float* transformation;
|
glm::vec3 scale;
|
||||||
bool calculateMatrix; ///< Wether GetMatrix() needs to re-calculate the transformation matrix
|
glm::quat orientation;
|
||||||
|
glm::vec3 translation;
|
||||||
|
glm::vec3 skew;
|
||||||
|
glm::vec4 perspective;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,32 +53,8 @@ namespace oglu
|
||||||
|
|
||||||
void Camera::LookAt(GLfloat x, GLfloat y, GLfloat z)
|
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));
|
transformation = glm::lookAt(translation, glm::vec3(x, y, z), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
glm::vec3 scale;
|
glm::decompose(transformation, scale, orientation, translation, skew, perspective);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::LookAt(const GLfloat* target)
|
void Camera::LookAt(const GLfloat* target)
|
||||||
|
|
|
@ -2,266 +2,150 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include <glm/gtx/matrix_decompose.hpp>
|
||||||
|
#include <glm/gtx/quaternion.hpp>
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
namespace oglu
|
namespace oglu
|
||||||
{
|
{
|
||||||
oglu::Transformable::Transformable() :
|
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);
|
glm::decompose(transformation, scale, orientation, translation, skew, perspective);
|
||||||
memcpy(
|
|
||||||
rotation,
|
|
||||||
glm::value_ptr(identity),
|
|
||||||
16 * sizeof(float)
|
|
||||||
);
|
|
||||||
memcpy(
|
|
||||||
transformation,
|
|
||||||
glm::value_ptr(identity),
|
|
||||||
16 * sizeof(float)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Transformable::Transformable(const Transformable& other) :
|
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(
|
glm::decompose(transformation, scale, orientation, translation, skew, perspective);
|
||||||
this->position,
|
|
||||||
other.position,
|
|
||||||
3 * sizeof(float)
|
|
||||||
);
|
|
||||||
|
|
||||||
memcpy(
|
|
||||||
this->rotation,
|
|
||||||
other.rotation,
|
|
||||||
16 * sizeof(float)
|
|
||||||
);
|
|
||||||
|
|
||||||
memcpy(
|
|
||||||
this->scaling,
|
|
||||||
other.scaling,
|
|
||||||
3 * sizeof(float)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Transformable::~Transformable()
|
Transformable::~Transformable()
|
||||||
{
|
{
|
||||||
delete[] scaling;
|
|
||||||
delete[] rotation;
|
|
||||||
delete[] position;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transformable::SetPosition(float x, float y, float z)
|
void Transformable::SetPosition(float x, float y, float z)
|
||||||
{
|
{
|
||||||
this->position[0] = x;
|
glm::decompose(transformation, scale, orientation, translation, skew, perspective);
|
||||||
this->position[1] = y;
|
translation = glm::vec3(x, y, z) - translation;
|
||||||
this->position[2] = z;
|
transformation = glm::translate(transformation, translation);
|
||||||
calculateMatrix = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transformable::SetPosition(const float* translation)
|
void Transformable::SetPosition(const float* translation)
|
||||||
{
|
{
|
||||||
memcpy(
|
glm::decompose(transformation, scale, orientation, this->translation, skew, perspective);
|
||||||
this->position,
|
this->translation = glm::make_vec3(translation) - this->translation;
|
||||||
translation,
|
transformation = glm::translate(transformation, this->translation);
|
||||||
3 * sizeof(float)
|
|
||||||
);
|
|
||||||
calculateMatrix = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transformable::SetRotation(float rotX, float rotY, float rotZ)
|
void Transformable::SetRotation(float rotX, float rotY, float rotZ)
|
||||||
{
|
{
|
||||||
// TODO: Using rotation matrices is stupid. Eventually this could (should) be done with quaternions
|
glm::decompose(transformation, scale, orientation, translation, skew, perspective);
|
||||||
// For now we'll just risk gimbal locking the model
|
orientation = glm::quat(glm::vec3(rotX, rotY, rotZ)) - orientation;
|
||||||
memcpy(
|
transformation = glm::rotate(transformation, orientation.w, glm::vec3(orientation.x, orientation.y, orientation.z));
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transformable::SetRotation(const float* rotation)
|
void Transformable::SetRotation(const float* rotation)
|
||||||
{
|
{
|
||||||
memcpy(
|
glm::decompose(transformation, scale, orientation, translation, skew, perspective);
|
||||||
this->rotation,
|
orientation = glm::quat(glm::make_vec3(rotation)) - orientation;
|
||||||
glm::value_ptr(
|
transformation = glm::rotate(transformation, orientation.w, glm::vec3(orientation.x, orientation.y, orientation.z));
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transformable::SetRotation(float angle, float xAxis, float yAxis, float zAxis)
|
void Transformable::SetRotation(float angle, float xAxis, float yAxis, float zAxis)
|
||||||
{
|
{
|
||||||
memcpy(
|
glm::decompose(transformation, scale, orientation, translation, skew, perspective);
|
||||||
this->rotation,
|
orientation = glm::quat(glm::vec4(xAxis, yAxis, zAxis, angle)) - orientation;
|
||||||
glm::value_ptr(glm::rotate(glm::mat4(1.0f), glm::radians(angle), glm::vec3(xAxis, yAxis, zAxis))),
|
transformation = glm::rotate(transformation, orientation.w, glm::vec3(orientation.x, orientation.y, orientation.z));
|
||||||
16 * sizeof(float)
|
|
||||||
);
|
|
||||||
calculateMatrix = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transformable::SetRotation(float angle, const float* axis)
|
void Transformable::SetRotation(float angle, const float* axis)
|
||||||
{
|
{
|
||||||
memcpy(
|
glm::decompose(transformation, scale, orientation, translation, skew, perspective);
|
||||||
this->rotation,
|
orientation = glm::quat(glm::vec4(axis[0], axis[1], axis[2], angle)) - orientation;
|
||||||
glm::value_ptr(glm::rotate(glm::mat4(1.0f), glm::radians(angle), glm::make_vec3(axis))),
|
transformation = glm::rotate(transformation, orientation.w, glm::vec3(orientation.x, orientation.y, orientation.z));
|
||||||
16 * sizeof(float)
|
|
||||||
);
|
|
||||||
calculateMatrix = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transformable::SetScale(float scaleX, float scaleY, float scaleZ)
|
void Transformable::SetScale(float scaleX, float scaleY, float scaleZ)
|
||||||
{
|
{
|
||||||
this->scaling[0] = scaleX;
|
glm::decompose(transformation, scale, orientation, translation, skew, perspective);
|
||||||
this->scaling[1] = scaleY;
|
scale = glm::vec3(scaleX, scaleY, scaleZ) - scale;
|
||||||
this->scaling[2] = scaleZ;
|
transformation = glm::scale(transformation, scale);
|
||||||
calculateMatrix = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transformable::SetScale(const float* scale)
|
void Transformable::SetScale(const float* scale)
|
||||||
{
|
{
|
||||||
memcpy(
|
glm::decompose(transformation, this->scale, orientation, translation, skew, perspective);
|
||||||
this->scaling,
|
this->scale = glm::make_vec3(scale) - this->scale;
|
||||||
scale,
|
transformation = glm::scale(transformation, this->scale);
|
||||||
3 * sizeof(float)
|
|
||||||
);
|
|
||||||
calculateMatrix = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transformable::Move(float x, float y, float z)
|
void Transformable::Move(float x, float y, float z)
|
||||||
{
|
{
|
||||||
this->position[0] += x;
|
transformation = glm::translate(transformation, glm::vec3(x, y, z));
|
||||||
this->position[1] += y;
|
glm::decompose(transformation, scale, orientation, translation, skew, perspective);
|
||||||
this->position[2] += z;
|
|
||||||
calculateMatrix = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transformable::Move(const float* translation)
|
void Transformable::Move(const float* translation)
|
||||||
{
|
{
|
||||||
this->position[0] += translation[0];
|
transformation = glm::translate(transformation, glm::make_vec3(translation));
|
||||||
this->position[1] += translation[1];
|
glm::decompose(transformation, scale, orientation, this->translation, skew, perspective);
|
||||||
this->position[2] += translation[2];
|
|
||||||
calculateMatrix = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transformable::Rotate(float rotX, float rotY, float rotZ)
|
void Transformable::Rotate(float rotX, float rotY, float rotZ)
|
||||||
{
|
{
|
||||||
memcpy(
|
transformation = glm::rotate(transformation, glm::radians(1.0f), glm::vec3(rotX, rotY, rotZ));
|
||||||
this->rotation,
|
glm::decompose(transformation, scale, orientation, translation, skew, perspective);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transformable::Rotate(const float* rotation)
|
void Transformable::Rotate(const float* rotation)
|
||||||
{
|
{
|
||||||
memcpy(
|
transformation = glm::rotate(transformation, 1.0f, glm::make_vec3(rotation));
|
||||||
this->rotation,
|
glm::decompose(transformation, scale, orientation, translation, skew, perspective);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transformable::Rotate(float angle, float xAxis, float yAxis, float zAxis)
|
void Transformable::Rotate(float angle, float xAxis, float yAxis, float zAxis)
|
||||||
{
|
{
|
||||||
memcpy(
|
transformation = glm::rotate(transformation, angle, glm::vec3(xAxis, yAxis, zAxis));
|
||||||
this->rotation,
|
glm::decompose(transformation, scale, orientation, translation, skew, perspective);
|
||||||
glm::value_ptr(glm::rotate(glm::make_mat4(this->rotation), glm::radians(angle), glm::vec3(xAxis, yAxis, zAxis))),
|
|
||||||
16 * sizeof(float)
|
|
||||||
);
|
|
||||||
calculateMatrix = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transformable::Rotate(float angle, const float* axis)
|
void Transformable::Rotate(float angle, const float* axis)
|
||||||
{
|
{
|
||||||
memcpy(
|
transformation = glm::rotate(transformation, angle, glm::make_vec3(axis));
|
||||||
this->rotation,
|
glm::decompose(transformation, scale, orientation, translation, skew, perspective);
|
||||||
glm::value_ptr(glm::rotate(glm::make_mat4(this->rotation), glm::radians(angle), glm::make_vec3(axis))),
|
|
||||||
16 * sizeof(float)
|
|
||||||
);
|
|
||||||
calculateMatrix = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transformable::Scale(float scaleX, float scaleY, float scaleZ)
|
void Transformable::Scale(float scaleX, float scaleY, float scaleZ)
|
||||||
{
|
{
|
||||||
this->scaling[0] += scaleX;
|
transformation = glm::scale(transformation, glm::vec3(scaleX, scaleY, scaleZ));
|
||||||
this->scaling[1] += scaleY;
|
glm::decompose(transformation, scale, orientation, translation, skew, perspective);
|
||||||
this->scaling[2] += scaleZ;
|
|
||||||
calculateMatrix = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transformable::Scale(const float* scale)
|
void Transformable::Scale(const float* scale)
|
||||||
{
|
{
|
||||||
this->scaling[0] += scale[0];
|
transformation = glm::scale(transformation, glm::make_vec3(scale));
|
||||||
this->scaling[1] += scale[1];
|
glm::decompose(transformation, this->scale, orientation, translation, skew, perspective);
|
||||||
this->scaling[2] += scale[2];
|
|
||||||
calculateMatrix = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const float* Transformable::GetMatrix()
|
const float* Transformable::GetMatrix()
|
||||||
{
|
{
|
||||||
if (calculateMatrix)
|
return glm::value_ptr(transformation);
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const float* Transformable::GetPosition() const
|
const float* Transformable::GetPosition() const
|
||||||
{
|
{
|
||||||
return position;
|
return glm::value_ptr(translation);
|
||||||
}
|
}
|
||||||
|
|
||||||
const float* Transformable::GetRotation() const
|
const float* Transformable::GetRotation() const
|
||||||
{
|
{
|
||||||
return rotation;
|
return glm::value_ptr(orientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
const float* Transformable::GetScaling() const
|
const float* Transformable::GetScaling() const
|
||||||
{
|
{
|
||||||
return scaling;
|
return glm::value_ptr(scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue