+Transform::Transform():
+ position(0.0f, 0.0f, 0.0f),
+ euler(Angle::zero(), Angle::zero(), Angle::zero()),
+ scale(1.0f, 1.0f, 1.0f)
+{ }
+
+Transform Transform::from_matrix(const Matrix &matrix)
+{
+ Transform trn;
+ trn.position = matrix.column(3).slice<3>(0);
+
+ trn.euler.z = Geometry::atan2<float>(matrix(1, 0), matrix(0, 0));
+ Matrix m = Matrix::rotation(-trn.euler.z, Vector3(0.0f, 0.0f, 1.0f))*matrix;
+ trn.euler.y = Geometry::atan2<float>(m(2, 0), m(0, 0));
+ m = Matrix::rotation(-trn.euler.y, Vector3(0.0f, 1.0f, 0.0f))*m;
+ trn.euler.x = Geometry::atan2<float>(m(2, 1), m(1, 1));
+ m = Matrix::rotation(-trn.euler.x, Vector3(1.0f, 0.0f, 0.0f))*m;
+
+ trn.scale = Vector3(m(0, 0), m(1, 1), m(2, 2));
+
+ return trn;
+}
+
+void Transform::set_position(const Vector3 &p)
+{
+ position = p;
+}
+
+void Transform::set_euler(const AngleVector3 &e)
+{
+ euler = e;
+}
+
+void Transform::set_rotation(const Angle &angle, const Vector3 &axis)
+{
+ euler = from_matrix(Matrix::rotation(angle, axis)).euler;
+}
+
+void Transform::set_scale(float s)
+{
+ set_scale(Vector3(s, s, s));
+}
+
+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<Transform>(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.set_position(Vector3(x, y, z));
+}
+
+void Transform::Loader::euler(float x, float y, float z)