From: Mikko Rasa Date: Tue, 4 Jun 2019 07:39:17 +0000 (+0300) Subject: Add a class to unify loading coordinate transforms X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=9e384cddaf641f25ce6714327e1b4fadfea4632d;p=libs%2Fgl.git Add a class to unify loading coordinate transforms It will also be useful for animations. Euler angles are not the ideal way of storing rotations but they are relatively easy to understand and work with. Other rotation types will be added in the future. --- diff --git a/source/animatedobject.cpp b/source/animatedobject.cpp index 257e1368..3a781100 100644 --- a/source/animatedobject.cpp +++ b/source/animatedobject.cpp @@ -6,6 +6,7 @@ #include "programdata.h" #include "renderer.h" #include "technique.h" +#include "transform.h" using namespace std; @@ -79,6 +80,9 @@ void AnimatedObject::setup_render(Renderer &renderer, const Tag &) const AnimatedObject::Loader::Loader(AnimatedObject &o): DataFile::ObjectLoader(o) { + add("transform", &Loader::transform); + + // Deprecated; Use the transform statement instead add("position", &Loader::position); add("rotation", &Loader::rotation); add("scale", &Loader::scale); @@ -105,5 +109,12 @@ void AnimatedObject::Loader::scale_uniform(float s) obj.matrix.scale(s); } +void AnimatedObject::Loader::transform() +{ + Transform trn; + load_sub(trn); + obj.matrix = trn.to_matrix(); +} + } // namespace GL } // namespace Msp diff --git a/source/animatedobject.h b/source/animatedobject.h index 74e59fc8..73c39e2c 100644 --- a/source/animatedobject.h +++ b/source/animatedobject.h @@ -26,6 +26,7 @@ public: void rotation(float, float, float, float); void scale(float, float, float); void scale_uniform(float); + void transform(); }; private: diff --git a/source/keyframe.cpp b/source/keyframe.cpp index dd4adf16..708fa22b 100644 --- a/source/keyframe.cpp +++ b/source/keyframe.cpp @@ -1,6 +1,7 @@ #include #include "keyframe.h" #include "pose.h" +#include "transform.h" using namespace std; @@ -52,11 +53,14 @@ void KeyFrame::Loader::init() { add("pose", &Loader::pose); add("pose", &Loader::pose_inline); + add("transform", &Loader::transform); + add("uniforms", &Loader::uniforms); + + // Deprecated; use the transform statement instead add("position", &Loader::position); add("rotation", &Loader::rotation); add("scaling", &Loader::scaling_uniform); add("scaling", &Loader::scaling); - add("uniforms", &Loader::uniforms); } void KeyFrame::Loader::pose(const string &n) @@ -92,6 +96,13 @@ void KeyFrame::Loader::scaling(float x, float y, float z) obj.matrix.scale(x, y, z); } +void KeyFrame::Loader::transform() +{ + Transform trn; + load_sub(trn); + obj.matrix = trn.to_matrix(); +} + void KeyFrame::Loader::uniforms() { UniformsLoader ldr(obj); diff --git a/source/keyframe.h b/source/keyframe.h index 7854a928..88e85214 100644 --- a/source/keyframe.h +++ b/source/keyframe.h @@ -30,6 +30,7 @@ public: void rotation(float, float, float, float); void scaling_uniform(float); void scaling(float, float, float); + void transform(); void uniforms(); }; diff --git a/source/transform.cpp b/source/transform.cpp new file mode 100644 index 00000000..9660c2c4 --- /dev/null +++ b/source/transform.cpp @@ -0,0 +1,80 @@ +#include "transform.h" + +namespace Msp { +namespace GL { + +Transform::Transform(): + position(0.0f, 0.0f, 0.0f), + euler(Angle::zero(), Angle::zero(), Angle::zero()), + scale(1.0f, 1.0f, 1.0f) +{ } + +void Transform::set_position(const Vector3 &p) +{ + position = p; +} + +void Transform::set_euler(const AngleVector3 &e) +{ + euler = e; +} + +void Transform::set_scale(const Vector3 &s) +{ + scale = s; +} + +Matrix Transform::to_matrix() const +{ + Matrix result; + result.translate(position); + result.rotate(euler.z, Vector3(0.0f, 0.0f, 1.0f)); + result.rotate(euler.y, Vector3(0.0f, 1.0f, 0.0f)); + result.rotate(euler.x, Vector3(1.0f, 0.0f, 0.0f)); + result.scale(scale); + return result; +} + + +Transform::Loader::Loader(Transform &t): + DataFile::ObjectLoader(t) +{ + add("position", &Loader::position); + add("euler", &Loader::euler); + add("rotation", &Loader::rotation); + add("scale_uniform", &Loader::scale_uniform); + add("scale", &Loader::scale); +} + +void Transform::Loader::position(float x, float y, float z) +{ + obj.position = Vector3(x, y, z); +} + +void Transform::Loader::euler(float x, float y, float z) +{ + obj.euler = AngleVector3(Angle::from_degrees(x), Angle::from_degrees(y), Angle::from_degrees(z)); +} + +void Transform::Loader::rotation(float a, float x, float y, float z) +{ + Matrix matrix = Matrix::rotation(Angle::from_degrees(a), Vector3(x, y, z)); + obj.euler.z = Geometry::atan2(matrix(1, 0), matrix(0, 0)); + matrix = Matrix::rotation(-obj.euler.z, Vector3(0.0f, 0.0f, 1.0f))*matrix; + obj.euler.y = Geometry::atan2(matrix(2, 0), matrix(0, 0)); + matrix = Matrix::rotation(-obj.euler.y, Vector3(0.0f, 1.0f, 0.0f))*matrix; + obj.euler.x = Geometry::atan2(matrix(2, 1), matrix(1, 1)); +} + +void Transform::Loader::scale_uniform(float s) +{ + obj.scale = Vector3(s, s, s); +} + +void Transform::Loader::scale(float x, float y, float z) +{ + obj.scale = Vector3(x, y, z); +} + +} // namespace GL +} // namespace Msp diff --git a/source/transform.h b/source/transform.h new file mode 100644 index 00000000..ee821ce1 --- /dev/null +++ b/source/transform.h @@ -0,0 +1,55 @@ +#ifndef MSP_GL_TRANSFORM_H_ +#define MSP_GL_TRANSFORM_H_ + +#include +#include "matrix.h" + +namespace Msp { +namespace GL { + +/** +Stores a coordinate space transform as individual components. Primarily +intended for loading data from external sources. At runtime transforms +should generally be stored as matrices. +*/ +class Transform +{ +public: + class Loader: public DataFile::ObjectLoader + { + public: + Loader(Transform &); + + private: + void position(float, float, float); + void euler(float, float, float); + void rotation(float, float, float, float); + void scale_uniform(float); + void scale(float, float, float); + }; + + typedef Geometry::Angle Angle; + typedef LinAl::Vector AngleVector3; + +private: + Vector3 position; + AngleVector3 euler; + Vector3 scale; + +public: + Transform(); + + void set_position(const Vector3 &); + void set_euler(const AngleVector3 &); + void set_scale(const Vector3 &); + const Vector3 &get_position() const { return position; } + const AngleVector3 &get_euler() const { return euler; } + const Vector3 &get_scale() const { return scale; } + + Matrix to_matrix() const; +}; + +} // namespace GL +} // namespace Msp + +#endif