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

Author Topic: Scene graph (transformation tree) with SFML  (Read 6489 times)

0 Members and 1 Guest are viewing this topic.

BurrickSlayer

  • Newbie
  • *
  • Posts: 5
    • View Profile
Scene graph (transformation tree) with SFML
« on: October 09, 2013, 06:44:33 pm »
Hello all,

for a game I'm working on I would like to have a simple scene graph. Nothing fancy: it should just describe the transformation hierarchies of my drawables. The drawables are kept in a separate data structure.

I've found two examples on how a scene graph could be implemented using SFML:


In both examples the scene nodes not only contain a transformation but also drawables and render logic. As my drawables are not drawn in the order as they appear in the scene graph, it's unfavorable for me to have them being part of the scene nodes. It also seems to me somewhat redundant to have a transformable scene node that holds a transformable sprite (or some other drawable).

So I would like to get the drawables out of the scene graph but, as you might guessed, I'm not sure about how to do this properly.

Let's assume my game consists of sprites only. With this setup I would like to organize the sprites and scene nodes like that (pseudo code):

Code: [Select]
SceneNode : Transformable
    vector<SceneNode*> children
    SceneNode*         parent
end
   
// This sprite is a Drawable but not a Transformable.   
Sprite : Drawable
    SceneNode* sceneNode
end
   
// Somewhere in the World class:
SceneNode      root
vector<Sprite> drawables

I already toyed with the idea of writing my own sprite class so I can customize it the way that suits me. I could just copy sf::Sprite and apply my changes.

What do you think? Is writing a custom sprite class reasonable or do you think this would be overkill? Do you have other/better ideas on what I could do?

Thanks in advance for your help.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Scene graph (transformation tree) with SFML
« Reply #1 on: October 13, 2013, 02:40:16 pm »
You could consider an approach where you head more towards separation of graphics and logics. That is, the scene graph itself isn't drawable, but rather contains transformable properties, and a pointer to some drawable object (e.g. std::unique_ptr<DrawableObject>). Like this, you can extract the rendering task from the scene graph.

To fix the problem of a different rendering order, you can either build your scene graph in a way such that objects are traversed in the correct order. Or, you iterate through all nodes and store the respective drawables in a std::set<DrawableObject*, MyCustomOrder>. DrawableObject can be a custom class with a Z coordinate, and MyCustomOrder is a functor that sorts by this Z component. After traversing the scene graph, you iterate through the set and draw all objects.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

BurrickSlayer

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Scene graph (transformation tree) with SFML
« Reply #2 on: October 15, 2013, 10:23:56 am »
Quote
You could consider an approach where you head more towards separation of graphics and logics. That is, the scene graph itself isn't drawable, but rather contains transformable properties, and a pointer to some drawable object (e.g. std::unique_ptr<DrawableObject>). Like this, you can extract the rendering task from the scene graph.
Yes, that's exactly the idea that I wanted to convey in the pseudo code.My plan was to have a transformation tree and a separate list of drawables with each drawable storing a pointer to the transformation node it's attached to.

I've now settled for just leaving the drawables in the tree for various reasons. I'm fine with that. This doesn't make the tree drawable, though. As you suggested, the drawables are extracted from the tree and then passed to a renderer in a render queue. So luckily I've achieved separation of concerns at least in that regard.

Quote
To fix the problem of a different rendering order, you can either build your scene graph in a way such that objects are traversed in the correct order. Or, you iterate through all nodes and store the respective drawables in a std::set<DrawableObject*, MyCustomOrder>. DrawableObject can be a custom class with a Z coordinate, and MyCustomOrder is a functor that sorts by this Z component. After traversing the scene graph, you iterate through the set and draw all objects.
The rendering order is my current problem. Sorting the render queue is much more difficult than I expected it to be. The issue is explained in more detail on Stack Overflow. I'm afraid I'll have to sort the scene nodes directly. I don't like this approach too much because in my opinion the renderer should be responsible for sorting the drawables, not the scene tree. But if there's no other way to get the right rendering order, then I guess I have no choice.

Thanks for your suggestions, Nexus.

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Scene graph (transformation tree) with SFML
« Reply #3 on: October 15, 2013, 10:40:54 am »
Maybe I'm misunderstanding how the whole scene graph thing works, but why not just store some kind of depth value/z-coordinate in each of your drawable objects, and use that to sort them as they get inserted into the render queue? iirc that has a better time complexity than inserting them all and sorting the whole queue afterward.

BurrickSlayer

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Scene graph (transformation tree) with SFML
« Reply #4 on: October 16, 2013, 06:05:32 pm »
This won't work because each group of sibling nodes has to be sorted individually. Otherwise nodes of different hierarchies would be mixed up.

But never mind, I might have found an adequate solution: I'll just split the scene tree up into a transformation tree and a render tree. The transformation tree will only take care of the transformation hierarchy while the render tree will contain all the drawables. This way the renderer can sort the drawables in the render tree like crazy without me having objections. ;)

Thank you anyway!

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Scene graph (transformation tree) with SFML
« Reply #5 on: October 16, 2013, 06:20:02 pm »
This won't work because each group of sibling nodes has to be sorted individually. Otherwise nodes of different hierarchies would be mixed up.
Why don't you keep the children of a node locally sorted? Either by sorting std::vector, or by directly using std::set to store child nodes...
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

BurrickSlayer

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Scene graph (transformation tree) with SFML
« Reply #6 on: October 17, 2013, 12:39:22 am »
This is exactly how it is done now in the render tree (with a sorted std::vector<std::unique_ptr<RenderNode>>). I could have done the sorting in the scene tree (which is nor more) as well or even in the transformation tree, but as I'm striving for separation of concerns this would have been a step backwards.

Now the transformations and drawables (or any other kind of objects that can be attached to transformation nodes) are clearly separated. The transformation tree isn't even aware of any attachable objects. I like this approach pretty much and I'm happy that I finally got a solution.

Now I can finally start making my Pong clone.
j/k ;)