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

Author Topic: Nested drawables to manipulate them toghether, sf hierarchy?  (Read 6192 times)

0 Members and 1 Guest are viewing this topic.

toglia

  • Newbie
  • *
  • Posts: 8
    • View Profile
Nested drawables to manipulate them toghether, sf hierarchy?
« on: September 25, 2009, 10:09:45 am »
I'm trying to do some kind of generic class made of different sorts of drawables so I can manipulate them all at once, (like ogre's scenenodes that can be attached in a hierarchy way)

Example:
Child is attached to Father:
a) father moves/rotates/etc child moves/rotates/etc.
b) child moves/rotates/etc father doesn't move.

To keep it simple I've decided to do a vector of drawables, and to have an empty sprite to be the "father" of all, so the draw method is like:

Code: [Select]
   iterator = mDrawables.begin();
    while( iterator != mDrawables.end() ) {
        renderWindow->Draw(

            /*This is the messy part, how do I change its position/rotation to mantain the relative distance
            but adding its father position (without accumulating) (got it?)*/
            /*This obviously doesn't work but it shows the idea.*/
            (*mDrawables) + father->GetPosition()
            (*mDrawables) + father->GetRotacion()
        );
        ++iteradorDibujables;
    }

Can somebody help me with that?, the problem I'm getting is that I can't do a momentary change of position/rotation just to render...

Is there a better way of doing this supported by sfml?

Thanks

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Nested drawables to manipulate them toghether, sf hierarchy?
« Reply #1 on: September 25, 2009, 10:28:07 am »
You have the solution in your title: nested drawables.

In SFML, if you draw a child Drawable while drawing a parent one (ie. in its Render function), the child automatically inherits its transformations (and color in SFML 2).
Plus, you can inherit from sf::Drawable, so that you don't have to use a dummy sprite or whatever.

Code: [Select]
class Layer : public sf::Drawable
{
    virtual void Render(sf::RenderTarget& target) const
    {
        for (iterator = mDrawables.begin(); iterator != mDrawables.end(); ++iterator)
            target.Draw(*iterator);
    }
};

Layer layer;
... add drawables to layer ...
layer.SetPosition(...);
layer.SetRotation(...);

window.Draw(layer);
Laurent Gomila - SFML developer

toglia

  • Newbie
  • *
  • Posts: 8
    • View Profile
Nested drawables to manipulate them toghether, sf hierarchy?
« Reply #2 on: September 25, 2009, 09:21:29 pm »
Thanks a lot. It was not even sfml related, just simple c++ inheritance feature... :oops:

toglia

  • Newbie
  • *
  • Posts: 8
    • View Profile
Nested drawables to manipulate them toghether, sf hierarchy?
« Reply #3 on: September 26, 2009, 12:19:42 am »
I found a "layer" class in the wiki, which I copy pasted, and did some testing but I'm not getting the inherited translation.

This is layer class:
Code: [Select]
#include <vector>
#include <SFML/Graphics.hpp>

typedef std::vector<sf::Drawable*> FrameSet;
typedef FrameSet::const_iterator itFrame;

class Layer : public sf::Drawable, public FrameSet {
 public :
Layer(  const sf::Vector2f& Position = sf::Vector2f(0, 0),
                const sf::Vector2f& Scale = sf::Vector2f(1, 1),
                float Rotation = 0.f,
                const sf::Color& Col = sf::Color(255, 255, 255, 255));
virtual ~Layer();

virtual void Render(sf::RenderTarget& Target) const;
};

Layer::Layer(   const sf::Vector2f& Position,
                const sf::Vector2f& Scale,
                float Rotation,
                const sf::Color& Col) : sf::Drawable(Position,Scale,Rotation,Col) {
};
 
Layer::~Layer(){
};

void Layer::Render(sf::RenderTarget& Target) const {
    for( itFrame i = begin() ;i!=end();i++)
            Target.Draw(*(*i));
};


The main:
Code: [Select]

int main(){
    sf::RenderWindow App(sf::VideoMode(800, 600, 32), "X");

    sf::Image image;
    image.LoadFromFile("x.png");

    sf::Sprite * sp = new sf::Sprite();
    sp->SetImage(image);

    Layer layer;
    layer.push_back(sp);
    layer.SetPosition(10,10); //<-Should move the sprite right?

    while (true){
        App.Clear();
        layer.Render(App);        
        App.Display();
    }
}


The layer doesn't seem to move the sprite...

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Nested drawables to manipulate them toghether, sf hierarchy?
« Reply #4 on: September 26, 2009, 10:08:23 am »
Which version of SFML are you using?
Laurent Gomila - SFML developer

toglia

  • Newbie
  • *
  • Posts: 8
    • View Profile
Nested drawables to manipulate them toghether, sf hierarchy?
« Reply #5 on: September 26, 2009, 07:30:23 pm »
I downloaded the stable 1.5 like a month ago.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Nested drawables to manipulate them toghether, sf hierarchy?
« Reply #6 on: September 26, 2009, 07:41:48 pm »
You're directly calling the Render function, so you don't get all the stuff that SFML does automatically.

Look at my example twice, I wrote
Code: [Select]
window.Draw(layer);
not
Code: [Select]
layer.Render(window);
Laurent Gomila - SFML developer

Fuzzy_Wuzzy.bmp

  • Newbie
  • *
  • Posts: 5
    • View Profile
Nested drawables to manipulate them toghether, sf hierarchy?
« Reply #7 on: September 27, 2009, 03:39:06 am »
I have a similar problem. I'm currently using a std::list<sf::Shape> to draw concave shapes, but since I have to rotate each sf::Shape separately, I'm worried that I'm wasting resources recalculating the transformation matrix each time. Any ideas how to do this efficiently?

Also, I don't understand what you mean by
Quote from: "Laurent"
In SFML, if you draw a child Drawable while drawing a parent one (ie. in its Render function), the child automatically inherits its transformations (and color in SFML 2).

Do you mean that if I do this:
Code: [Select]
class Sprites : public sf::Drawable
{
    void Draw(sf::RenderWindow& targetScreen)
    {
        for(iterator = sprites.begin(); iterator != sprites.end(); iterator++)
            targetScreen.Draw(*iterator);
    }
    std::vector<sf::Sprite> sprites;
};

And then this:
Code: [Select]
Sprites someSprites;
someSprites.SetRotation(75.f);
someSprites.Draw(someWindow);

It'll magically draw all the sprites with a rotation of 75 degrees?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Nested drawables to manipulate them toghether, sf hierarchy?
« Reply #8 on: September 27, 2009, 11:30:03 am »
Quote
It'll magically draw all the sprites with a rotation of 75 degrees?

If you override the Drawable::Render virtual function instead of providing your own Draw function, yes. See the example above.
Laurent Gomila - SFML developer

Silence

  • Newbie
  • *
  • Posts: 1
    • View Profile
Nested drawables to manipulate them toghether, sf hierarchy?
« Reply #9 on: June 30, 2010, 05:42:56 pm »
Hi, sorry for bumping an old thread. But i've tried this code (using SFML 1.6)  and it works (SetPostion, SetRotation) beautifull but with one exception.

layer.SetCenter() doesn't seem to work ?  It always seem to rotate from the point 0,0 no matter what I write.  Is there some reason for that ?

EDIt: nvmind there must be a bug somewhere in my program as in my small demo app it seems to work fine.