Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Why not decouple transform \ render?  (Read 2029 times)

0 Members and 1 Guest are viewing this topic.

Blader

  • Newbie
  • *
  • Posts: 5
    • View Profile
Why not decouple transform \ render?
« on: September 22, 2016, 08:17:08 am »
Hey guys, I would like to start a discussion about why all things drawable inherit from transformable. To me it makes sense to use composition to give drawables a transform. E.g. sf::Sprite HAS A transform rather than sf::Sprite IS A transform.

First my use case:

  • I want to have a hierarchy of transforms for my sprites or drawables.
  • But I don't want that hierarchy to control the draw order

To that end I re-wrote those classes into what I call 'SmartDrawables and SmartTransformables'. They aren't really smart they just allow me to write this:


sf::SmartTransformable rootTransform;
sf::SmartTransformable someTransform;

sf::Sprite rootSprite(rootTransform, texture);
sf::Sprite someSprite(someTransform, texture);

rootTransform.addChild(someTransform);

// In an update somewhere.
rootTransform.rotate(0.1f);
rootTransform.updateTransforms(); // Goes through the heirarchy.

window.draw(someSprite); // Draw in whatever order we want, regardless of parent->child relationship.
window.draw(rootSprite);
 

So my questions:

  • Is this a dumb idea and have I missed something obvious?
  • Are there better ways to do this?
  • Should SFML follow the 'Prefer composition over inheritance rule' in this situation?

A pic is attached, the blue one represents the child and is being rendered below the parent.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Why not decouple transform \ render?
« Reply #1 on: September 22, 2016, 09:31:10 am »
Hi

SFML doesn't force any design. You can perfectly use external transforms (in sf::RenderState) and leave the internal ones to identity. This is the typical solution for hierarchies, and it is even shown in tutorials:

http://www.sfml-dev.org/tutorials/2.4/graphics-transform.php#object-hierarchies-scene-graph
Laurent Gomila - SFML developer

Blader

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Why not decouple transform \ render?
« Reply #2 on: September 23, 2016, 02:27:23 am »
Quote
SFML doesn't force any design

The given drawables are given a design choice and that is to inherit from Transformable rather than contain one, why is that? I assume it's purely from ease of use perspective rather than good coding perspective.


Quote
You can perfectly use external transforms (in sf::RenderState) and leave the internal ones to identity.

Yes, I do this in my code now. Yeah the typical solution creates a situation of a set rendering order in the hierarchies, something I don't want. That's why I started this discussion on a non-typical implementation.

So I guess a simplified question would be: Using that node class as an example, is it better to do my implementation (Making a transformable directly have parent\child relationships and removing the inheritance usage of Transformable) or use that node class and changing it to separate where the combinedTransform is calculated and the drawing occurs?
« Last Edit: September 23, 2016, 02:34:52 am by Blader »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Why not decouple transform \ render?
« Reply #3 on: September 23, 2016, 07:44:59 am »
Quote
The given drawables are given a design choice
It doesn't force you to use the built-in transform if you don't want to. If you want maximum power and flexibility you can use the render-state's transform, and manage the link with the drawable as you want.

Quote
inherit from Transformable rather than contain one, why is that?
What would the API look like if entities contained a transform rather than being transformable? Something like entity.setTransform(sf::Transform)?

Quote
So I guess a simplified question would be: Using that node class as an example, is it better to do my implementation (Making a transformable directly have parent\child relationships and removing the inheritance usage of Transformable) or use that node class and changing it to separate where the combinedTransform is calculated and the drawing occurs?
I'd say it's easier to calculate the transform elsewhere. You can also collect the nodes and reorder them as you want for rendering. There are many possible implementations.
Laurent Gomila - SFML developer

Blader

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Why not decouple transform \ render?
« Reply #4 on: September 23, 2016, 08:03:16 am »
Quote
inherit from Transformable rather than contain one, why is that?
What would the API look like if entities contained a transform rather than being transformable? Something like entity.setTransform(sf::Transform)?

I don't see a reason to set a transform after creation although there might be a use case, I prefer to force it as a dependency as it is required. Although I may be wrong! E.g this is my code copy-pasted:

SmartDrawable::SmartDrawable(SmartTransformable& transformable) : sf::Drawable(),
                m_smartTransformable(transformable)
{
}



Quote
So I guess a simplified question would be: Using that node class as an example, is it better to do my implementation (Making a transformable directly have parent\child relationships and removing the inheritance usage of Transformable) or use that node class and changing it to separate where the combinedTransform is calculated and the drawing occurs?
I'd say it's easier to calculate the transform elsewhere. You can also collect the nodes and reorder them as you want for rendering. There are many possible implementations.

Unless you split the transform calculation and node drawing you can't reorder nodes as that might mess up some specific child->parent relationship. E.g an orb that hovers in front of \ behind a character while also inheriting it's transform wouldn't want to be re-ordered to be the characters parent.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Why not decouple transform \ render?
« Reply #5 on: September 23, 2016, 08:29:11 am »
Quote
I don't see a reason to set a transform after creation although there might be a use case, I prefer to force it as a dependency as it is required
So the transform is kept external, the entity doesn't own it? I see a lot of problems associated to this, and I don't see any benefit.

Quote
Unless you split the transform calculation and node drawing you can't reorder nodes as that might mess up some specific child->parent relationship. E.g an orb that hovers in front of \ behind a character while also inheriting it's transform wouldn't want to be re-ordered to be the characters parent.
I was just talking about drawing order. That's what most scene-graphs do: they traverse the hierarchy and collect all relevant nodes, and then reorder the collected drawable entities to optimize rendering (mostly to create batches of geometry that use the same render-states).
Laurent Gomila - SFML developer