Jump to content

  • Log In with Google      Sign In   
  • Create Account


Scene Graph Resources


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
15 replies to this topic

#1 snk_kid   Members   -  Reputation: 1312

Like
0Likes
Like

Posted 06 October 2005 - 01:28 AM

As scene graphs are a such an important and frequently questioned topic here (and else where) i decided to begin compiling a comprehensive listing of resource links about them for those interested in implementing/using them. Hopefully this will become a sticky for all to find of great use. To those who have not done so already and are new to the topic of scene graphs i recommend reading up on some/all design patterns in particular:
  • Composite - reason being that scene graphs are typically implementated with this pattern
  • Decorator - reason being it's related to Composite and is in fact a degenerate form/case of Composite where decorators only have a single or fixed number of children. It is also frequently used with the Composite pattern. In the case of scene graphs implementated via the Composite pattern we have Grouping node types (they are the Composites) typically there will be an instantiable base Group node type who's sole purpose is child containment and child management, this instantiable base is just a plain instance of the composite pattern and the most general grouping node type of all in a scene graph. Then we add more specific kinds of grouping nodes, like transforms, switch nodes, LOD nodes etc these are sub-types of the base group node type thus inherit child containment and child management (code-reuse) but also adding new behaviours/state to internal nodes of a tree/DAG (the reason why i emphasis this is it does not make sense to have something like a Switch/LOD node who's sole purpose is to select/switch between other nodes as terminating/leaf nodes of a tree/DAG). The specific kinds of grouping node types are Composites aswell they are also instances of the decorator pattern too!.
  • Interpreter - reason being it's related to composite but the main point is the idea of a "global" context i.e SG could have global state or rendering context.
  • Observer - Scene Graphs are/use the Observer pattern implicitly without the developer realizing it but it can be used explicitly when scene graphs are DAGs because there maybe occasions where leaf nodes need to notify state changes to all parents (and there parent's parents and so on all the way upto the root/roots if necessary). Therefore leaf node types are subjects and grouping node types are the observers (they are also subjects when viewed in a different context since grouping node types typically share a common base with leaf node types).
  • flyweight - reason being you can permit node sharing in an n-ary tree without resorting to use a directed acyclic graph (DAG) which are harder to deal with but more flexible.
  • Visitor - reason being seperating the operation and data of scene graphs, it will beome more apparent when this pattern is read

Caveat: The main point/advantage of the composite pattern is the distinction between internal (non-terminal) and leaf (terminal) node types (yet they have a common super-type), Composite intances are internal nodes of a tree/DAG, concreate component instances are terminating, leaf nodes of a tree/DAG. The advantage of this there is no need todo a run-time check whether a node is a leaf/terminal, there is no redundant data of child containment in leaf node types (aswell as other state/behaviour that should only ever be in internal nodes of a tree/DAG). Here is the Caveat, Composite pattern is generally applied to OO designs indeed Gang Of Four (GOF) design patterns are concise & general designs/concepts to recurring solutions that arise in OO systems/languages. As such Composite pattern is implementated in-terms/via sub-type polymorphism (the type of polymorphism most widely known). However there is another method to achieve virtually the same (that is making a distinction between leafs and internal nodes) thing without sub-type polymorphism, without the need of a common polymorphic base, even no need for pointers & heap allocation by using something called recursive variants. Virtually all Functional programming languages (i don't mean imperative but some of them do also) natively support variants AKA disjoint disjoint (discriminated) unions, one value - finite set of types, they also can also be recursive (this is the key here). For example in SML we can describe a binary tree as such:
datatype 'a tree = Leaf of 'a | Node of (('a tree) * ('a tree));
This just basically says that a "tree" is either leaf of some type or an internal node. It's what we want. We can do this in C/C++, in C++ the best method is by using boost::variant, we an use boost::variant to achieve what the composite does and implement the basic structure of a typical scene graph interms of it:
#include <deque>
#include <boost/variant.hpp>

typedef boost::variant<
    struct leaf,
    struct leaf2,
    struct leaf3,
    boost::recursive_wrapper<struct group>,
> scene_node;

//...

struct leaf { /*...*/ };
struct leaf2 { /*...*/ };
struct leaf3 { /*...*/ };

struct group {
  
  typedef std::deque<scene_node> child_list; // notice recursive composition

private:  

  child_list kids;

public:

   void add_child(const scene_node& sn) { kids.push_back(sn); }
};

int main() {

    group root;

    root.add_child(leaf());
    root.add_child(leaf2());
    root.add_child(leaf3());
    root.add_child(group());

    group& inner_grp = boost::get<group>(grp.kids.back());

    inner_grp.add_child(leaf());
    inner_grp.add_child(leaf2());

}
You get the idea, read boost::variant docs on how to use it properly, use boost::static/apply_visitor etc. The interesting thing about this method you will still end up using inheritance but not for sub-type polymorphism or interfaces but purely for code reuse, no need for virtual destructors, not only that you will end up replacing sub-type polymorphism with static polymorphism using Curiously Recurring Template Pattern (CRTP). This idea is even possible in standard C (with some extra work) because C/C++ have union user-defined types but it is not a discriminated union (like boost::variant is) though, in C you can simulate discriminated unions using a simple technique called a tagged unions and enforcing state invariants through an interface. All tagged unions is is a union plus a type tag identifier, in pure standard C it will look like this:
typedef enum tag_type { FOO, BAR, .... } tag_type; // enumrated set of types

typedef struct my_variant_ {

    tag_type type_id;

    union { foo f, bar b, ... } var;

} my_variant;
Many C compilers have a non-standard extension that make this slightly less verbose:
typedef enum tag_type { FOO, BAR, .... } tag_type; // enumrated set of types

typedef struct my_variant_ {

    tag_type type_id;

    union { foo f, bar b, ... };

} my_variant;
Now we have variants in C we can apply this again to implement the composite pattern in C with recursive variants:
#include <stddef.h> // size_t
typedef enum tag_type { LEAF, LEAF2, GROUP };

typedef struct scene_node {
    tag_type type_id;
     union {
        struct leaf*   l1;
        struct leaf2*  l2;
        struct group*  grp;
     };
} scene_node;

typedef struct group {
     scene_node* kids; // pointer to an array of scene_node,
                       // notice recursive composition again
     size_t num_of_kids;
} group;

typedef struct leaf {} leaf;
typedef struct leaf2 {} leaf2;
Another advantage of this specifically to C it's slightly more type-safe, you can (almost) completely avoid void pointer syndrome. The obvious disadvantage to using recursive variants in C/C++ is the lack of pattern matching that statically typed functional languages enjoy aswell as the method completely automated, and type-checked. Saying that though its not to bad with boost::variant's static/apply_visitor. Lastly i'm not suggesting this method to be best/better than the traditional OO method of the Composite. i'm just stating it's not the only method. You could probably get the best of both worlds in OCaml.
I'll continuously add/update this, please PM me if you have any more links and i'll stick up here for all to see [smile]. [Edited by - snk_kid on November 4, 2005 6:29:34 AM]

Sponsor:

#2 dimebolt   Members   -  Reputation: 440

Like
0Likes
Like

Posted 06 October 2005 - 01:47 AM

Excellent. I'm not a big fan of stickies however and would suggest moving it to the FAQ right away (as in my view it belongs there).

Tom

#3 Emmanuel Deloget   Members   -  Reputation: 1381

Like
0Likes
Like

Posted 06 October 2005 - 01:50 AM

Maybe this one? Official OpenInventor site @ SGI

Regards,

#4 paic   Members   -  Reputation: 645

Like
0Likes
Like

Posted 06 October 2005 - 01:51 AM

Hi,

very good initiative ^^

I would add this really good thread http://www.gamedev.net/community/forums/topic.asp?topic_id=110342

#5 snk_kid   Members   -  Reputation: 1312

Like
0Likes
Like

Posted 06 October 2005 - 01:54 AM

Quote:
Original post by paic
Hi,

very good initiative ^^

I would add this really good thread http://www.gamedev.net/community/forums/topic.asp?topic_id=110342


Thanks i'm in the process of adding links to gamdev forum threads (including Yann's stuff) into relevant sections.

#6 demonkoryu   Members   -  Reputation: 976

Like
0Likes
Like

Posted 06 October 2005 - 01:55 AM

Very cool! You guys make my day! [lol]


#7 dmatter   Crossbones+   -  Reputation: 2979

Like
0Likes
Like

Posted 06 October 2005 - 05:25 AM

Yay, I wrote most of that Wikipedia entry only the other week! - nice to see that its getting some publicity, the article only just hinges on some of the things that make up a good scene-graph but I think it is quite good as read-first article - thanks snk_kid [smile].

#8 Cypher19   Members   -  Reputation: 768

Like
0Likes
Like

Posted 06 October 2005 - 05:28 AM

Thumbs up to the #graphicsdev logs! (except for the Iain one simply because I was such a newbie back then :-P)

#9 superpig   Staff Emeritus   -  Reputation: 1825

Like
0Likes
Like

Posted 06 October 2005 - 12:47 PM

I'll sticky this until I get around to integrating it into the FAQ. Nice work.

#10 demonkoryu   Members   -  Reputation: 976

Like
0Likes
Like

Posted 08 October 2005 - 03:23 AM

Hey, not directly scenegraph-related, but perhaps you'll make another thread about shaders: Generating Shaders From HLSL Fragments, a very interesting read!

#11 snk_kid   Members   -  Reputation: 1312

Like
0Likes
Like

Posted 10 October 2005 - 03:47 AM

New! added a "Caveat" section + stuff [wink].

[Edited by - snk_kid on October 10, 2005 10:47:12 AM]

#12 dimebolt   Members   -  Reputation: 440

Like
0Likes
Like

Posted 10 October 2005 - 09:42 PM

Quote:
Original post by snk_kid
New! added a "Caveat" section + stuff [wink].


Man, you should write an article. If you continue in this rate, it will be way too big for the FAQ :)

Tom

#13 acid2   Members   -  Reputation: 451

Like
0Likes
Like

Posted 15 October 2005 - 12:29 AM

THANK YOU! This is possibly one of the most valuable posts I've seen on gamedev. I can't thank you enough ^_^

#14 Qrikko   Members   -  Reputation: 134

Like
0Likes
Like

Posted 27 October 2005 - 08:33 PM

Quote:
Original post by acid2
THANK YOU! This is possibly one of the most valuable posts I've seen on gamedev. I can't thank you enough ^_^


and I would move for "my most wanted" post in any forum! thank you so much this will certainly come in handy!
"Who ever put in this magic number should die, in the face" - found documented in the code of TGE

#15 LilBudyWizer   Members   -  Reputation: 495

Like
0Likes
Like

Posted 10 November 2005 - 04:18 AM

Nice work and seems a good idea.

#16 jon723   Members   -  Reputation: 168

Like
0Likes
Like

Posted 30 November 2005 - 07:52 AM

I once wrote a scene graph when I worked at a VR company (based on some articles I read on GameDev). When I left the company I wanted to write my own from scratch but couldn't seem to wrap my head around the various design concepts (and i couldnt use things I did for a company). None the less thank you for all of the topics you've compiled I'm pretty sure I'll be able to tackle this problem once and for all.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS