d.values.scale = s;
}
-void Transform::update_world_transform(const Transform *parent)
+const Geometry::AffineTransform<float, 3> &Transform::update_world_transform(const Geometry::AffineTransform<float, 3> *parent)
{
using Affine = Geometry::AffineTransform<float, 3>;
if(d.world_values)
{
d.world_transform = d.local_transform;
- d.local_transform = invert(parent->get_world_transform())*d.world_transform;
+ d.local_transform = invert(*parent)*d.world_transform;
d.values = TransformValues::from_matrix(d.local_transform);
}
else
- d.world_transform = parent->get_world_transform()*d.local_transform;
+ d.world_transform = (*parent)*d.local_transform;
}
else
d.world_transform = d.local_transform;
d.world_values = false;
+
+ return d.world_transform;
}
} // namespace Msp::Game
const LinAl::Vector<float, 3> &get_scale() const { return read().values.scale; }
const Geometry::AffineTransform<float, 3> &get_world_transform() const { return read().world_transform; }
- void update_world_transform(const Transform *);
+ const Geometry::AffineTransform<float, 3> &update_world_transform(const Geometry::AffineTransform<float, 3> *);
};
} // namespace Msp::Game
update_children = transforms.size();
}
+ vector<const Geometry::AffineTransform<float, 3> *> world_transforms(max_level);
+
for(ParentedTransform &t: transforms)
if(t.transform->was_written() || update_children>0)
{
- t.transform->update_world_transform(t.parent.get());
+ const Geometry::AffineTransform<float, 3> *parent_wt = (t.level>0 ? world_transforms[t.level-1] : nullptr);
+ const Geometry::AffineTransform<float, 3> &wt = t.transform->update_world_transform(parent_wt);
+ if(t.child_count>0)
+ world_transforms[t.level] = &wt;
+
if(t.child_count>update_children)
update_children = t.child_count;
else if(update_children>0)
{
transforms_dirty = false;
transforms.clear();
+ max_level = 0;
for(Handle<Entity> c: stage.get_root()->get_children())
- rebuild_transform_order(c, nullptr);
+ rebuild_transform_order(c, nullptr, 0);
}
-void TransformPropagator::rebuild_transform_order(Handle<Entity> entity, Handle<Transform> parent_trans)
+void TransformPropagator::rebuild_transform_order(Handle<Entity> entity, Handle<Transform> parent_trans, unsigned level)
{
size_t index = static_cast<size_t>(-1);
if(Handle<Transform> trans = entity->get_transform())
{
+ max_level = max(level, max_level);
index = transforms.size();
- transforms.emplace_back(trans, parent_trans);
+ transforms.emplace_back(trans, parent_trans, level);
parent_trans = trans;
+ ++level;
}
for(Handle<Entity> c: entity->get_children())
- rebuild_transform_order(c, parent_trans);
+ rebuild_transform_order(c, parent_trans, level);
if(index<transforms.size())
transforms[index].child_count = transforms.size()-1-index;
{
Handle<Transform> transform;
Handle<Transform> parent;
+ unsigned level = 0;
unsigned child_count = 0;
};
EventObserver observer;
std::vector<ParentedTransform> transforms;
+ unsigned max_level = 0;
bool transforms_dirty = true;
public:
private:
void rebuild_transform_order();
- void rebuild_transform_order(Handle<Entity>, Handle<Transform>);
+ void rebuild_transform_order(Handle<Entity>, Handle<Transform>, unsigned);
};
} // namespace Msp::Game