void Transform::set_values(const TransformValues &v)
{
- write().values = v;
+ Data &d = write();
+ d.values = v;
+ d.world_values = false;
+}
+
+void Transform::set_world_values(const TransformValues &v)
+{
+ Data &d = write();
+ d.values = v;
+ d.world_values = true;
}
void Transform::set_position(const LinAl::Vector<float, 3> &p)
{
- write().values.position = p;
+ Data &d = write();
+ if(d.world_values)
+ throw invalid_state("Transform::set_position");
+ d.values.position = p;
}
void Transform::set_rotation(const Geometry::Quaternion<float> &r)
{
- write().values.rotation = normalize(r);
+ Data &d = write();
+ if(d.world_values)
+ throw invalid_state("Transform::set_position");
+ d.values.rotation = normalize(r);
}
void Transform::set_scale(const LinAl::Vector<float, 3> &s)
{
- write().values.scale = s;
+ Data &d = write();
+ if(d.world_values)
+ throw invalid_state("Transform::set_position");
+ d.values.scale = s;
}
void Transform::update_world_transform(const Transform *parent)
d.local_transform = Affine::translation(d.values.position)*
Affine::rotation(d.values.rotation)*Affine::scaling(d.values.scale);
if(parent)
- d.world_transform = parent->get_world_transform()*d.local_transform;
+ {
+ if(d.world_values)
+ {
+ d.world_transform = d.local_transform;
+ d.local_transform = invert(parent->get_world_transform())*d.world_transform;
+ d.values = TransformValues::from_matrix(d.local_transform);
+ }
+ else
+ d.world_transform = parent->get_world_transform()*d.local_transform;
+ }
else
d.world_transform = d.local_transform;
+ d.world_values = false;
}
} // namespace Msp::Game
struct TransformData
{
TransformValues values;
+ bool world_values = false;
Geometry::AffineTransform<float, 3> local_transform;
Geometry::AffineTransform<float, 3> world_transform;
};
Transform(Handle<Entity> e): BufferedComponent(e) { }
void set_values(const TransformValues &);
+ void set_world_values(const TransformValues &);
void set_position(const LinAl::Vector<float, 3> &);
void set_rotation(const Geometry::Quaternion<float> &);
void set_scale(const LinAl::Vector<float, 3> &);