craftworkgames / MonoGame.Extended

Extensions to make MonoGame more awesome
http://www.monogameextended.net/
Other
1.42k stars 324 forks source link

[SceneGraph] Replace the scene graph with the Entity Component System #305

Closed craftworkgames closed 7 years ago

craftworkgames commented 7 years ago

I had a conversation with @LithiumToast the other day about potentially replacing the scene graph system with the entity component system.

Lucas Girouard-Stranks @LithiumToast Nov 11 10:36 But in essence attaching a Transform2D to another Transform2D has the exact behaviour as a scene graph They both solve the same problem

Dylan Wilson @craftworkgames Nov 11 10:37 So do you think there's any benefit in having both?

Lucas Girouard-Stranks @LithiumToast Nov 11 10:37 Not really

Dylan Wilson @craftworkgames Nov 11 10:37 Maybe we should consolodate that functionality into one concept.

Lucas Girouard-Stranks @LithiumToast Nov 11 10:37 We could do without SceneGraph perhaps

Dylan Wilson @craftworkgames Nov 11 10:37 Yeah, that'd be fine with me.

Lucas Girouard-Stranks @LithiumToast Nov 11 10:37 Each Entity is basically a SceneNode and every Entity can have a parent which may or may not be null

Dylan Wilson @craftworkgames Nov 11 10:38 Maybe we can remove SceneGraph and rebuild the scene graph demo out of entities?

Lucas Girouard-Stranks @LithiumToast Nov 11 10:38 looping through the parents of an Entity you can easily find the hierarchy The only thing is that each Entity doesn’t know its children really

Dylan Wilson @craftworkgames Nov 11 10:39 Is that a problem?

Lucas Girouard-Stranks @LithiumToast Nov 11 10:39 Not really... Just that functionality was there with SceneGraph and it’s not there with Transform2D for overhead reasons of course

Dylan Wilson @craftworkgames Nov 11 10:40 How would you search the graph for a particular node?

Lucas Girouard-Stranks @LithiumToast Nov 11 10:40 You would loop through all the components in a system The only difference like I said before is that it’s harder to find all the children entities given an entity. Like given this Entity, what are its children? That information is just not there

Dylan Wilson @craftworkgames Nov 11 10:42 As I said, if we can rebuild the scene graph demo, we're probably in a good place.

Lucas Girouard-Stranks @LithiumToast Nov 11 10:42 It would have be found the long way by looping through all entities Yeah Actually what is funny... I changed the SceneNode use Transform2D The code is already there https://github.com/craftworkgames/MonoGame.Extended/blob/develop/Source/MonoGame.Extended/SceneGraphs/SceneNode.cs

Dylan Wilson @craftworkgames Nov 11 10:45 Hmm.. maybe it's actually a good thing to keep SceneNode? Like, it makes sense for entities to have children, does it really make sense for say, a sprite to have children?

Lucas Girouard-Stranks @LithiumToast Nov 11 10:47 Well We could just add an EntityCollection class and have a Children property on Entity Then Entity would be exactly the same as a SceneNode

Dylan Wilson @craftworkgames Nov 11 10:48 Yeah, that'd work I guess. If we need it.

Lucas Girouard-Stranks @LithiumToast Nov 11 10:49 Downside is, Entity is no longer this dummy holder; it actually has data The only true thing SceneGraph has is the ability to query for nodes by location In this sense SceneGraph is more like a spatial partition collection similiar to a QuadTree or OctTree

Dylan Wilson @craftworkgames Nov 11 10:51 I'm sure we can come up with a solution that gives us the best of both worlds.

Lucas Girouard-Stranks @LithiumToast Nov 11 10:51 Transform2D can’t query for children, it’s not designed for that

Dylan Wilson @craftworkgames Nov 11 10:53 That's okay.. we probably only care about querying for child Entity

Lucas Girouard-Stranks @LithiumToast Nov 11 10:53 well in collisions for example we do care But then we wouldn’t use SceneGraph, but a type of a SceneGraph a special type of SceneGraph like a QuadTree so yeah, I think SceneGraph is a cool concept, but not entirely useful

Dylan Wilson @craftworkgames Nov 11 10:57 Yeah, that's fine with me.. it was an experiment.

Lucas Girouard-Stranks @LithiumToast Nov 11 10:57 although… does your GUI code use SceneGraph?

Dylan Wilson @craftworkgames Nov 11 10:57 I think we're at a point now that it makes more sense to get rid of it I think. No. I tried using it in the GUI but it was problematic.

Lucas Girouard-Stranks @LithiumToast Nov 11 10:57 How so?

Dylan Wilson @craftworkgames Nov 11 10:57 Besides, we have Nuclex now.

Lucas Girouard-Stranks @LithiumToast Nov 11 10:57 Fair enough I’m sure there is something like a SceneGraph inside NuclexGUI

Dylan Wilson @craftworkgames Nov 11 10:58 I'm still working on the GUI code, but I'm happy for it to keep evolving. Don't let it be a blocker.

Lucas Girouard-Stranks @LithiumToast Nov 11 10:58 Controls can have children, which can also have their own children and we want child controls to inherit the position of their parents

Dylan Wilson @craftworkgames Nov 11 10:59 Even though a GUI is a bit like a scene graph, it's not really the same thing. It just happens to also be a tree structure.

Lucas Girouard-Stranks @LithiumToast Nov 11 10:59 atleast I would assume so Yeah, that’s why I think the concept of a scene graph is important

Dylan Wilson @craftworkgames Nov 11 10:59 being able to attach a GuiButton to an entity? Maybe, probably not that useful though.

Lucas Girouard-Stranks @LithiumToast Nov 11 11:00 but having a generic scene graph is probably too much overhead?

Dylan Wilson @craftworkgames Nov 11 11:00 For now I'm just going to keep the concepts separate. Let's just move forward with the ECS.

Lucas Girouard-Stranks @LithiumToast Nov 11 11:00 I would definitely consider SceneGraph on a dead watch but yeah

lithiumtoast commented 7 years ago

Also see, https://www.reddit.com/r/gamedev/comments/5exges/scene_graph_just_a_question/

craftworkgames commented 7 years ago

Interesting read. I'm going to paste some of it here for reference.

A Scene Graph is essentially a method of rendering where you place your entire world into this big graph or tree with all the information needed to render it, and then point a renderer at it. The renderer traverses the graph and draws the items. Often, the edges between the nodes attempt to describe some sort of minimal state changes. The idea is fairly simple - we're computer scientists, so we should use fancy data structures. A tree or graph is a really cool structure, and it's great for all sorts of things, so surely it's going to be good for rendering, right?

It's a great theory, but sadly it's completely wrong. The world is not a big tree - a coffee mug on a desk is not a child of the desk, or a sibling of any other mug, or a child of the house it's in or the parent of the coffee it contains or anything - it's just a mug. It sits there, bolted to nothing. Putting the entire world into a big tree is not an obvious thing to do as far as the real world is concerned.

Now, I'm not going to be a total luddite and claim that trees are not useful in graphics - of course they are. There's loads of tree and graph structures all over the place - BSP trees, portal graphs, skeletal animation trees, spatial octrees, partitioning of meshes into groups that will fit in memory (bone-related or otherwise), groups of meshes that are lit by particular lights, lists of objects that use the same shader/texture/post-processing effect/rendertarget/shadowbuffer/etc. Tons of hierarchical and node/edge structures all over the place.

And that's the point - there's tons of them, they all mean different things, and (and this is the important bit) they don't match each other. If you try to put them all into one big graph, you will get a complete bloody mess. The list of meshes that use shadowbuffer X are completely unrelated to the list of meshes that use skeleton Y. I've seen many Scene Graphs over the years, and typically they have a bunch of elegant accessors and traversers, and then they have a gigantic list of unholy hacks and loopholes and workarounds and suchlike that people have had to add to get them to do even the simplest demos. Try and put them in a big, real, complex game and you have a graph with everything linked to everything. Either that, or you have a root node with fifty bazillion direct children in a big flat array and a bunch of highly specialised links between those children. Those links are the other structures that I mentioned above - but now they're hard to access and traverse and they clutter up everything.

I think the take away from this is that scene graphs can be useful sometimes, but we shouldn't try to force everything into one basket.

lithiumtoast commented 7 years ago

With the new ECS, TransformableComponent2D is basically a scene node of sorts for the purposes of affine transformations; the scene graph doesn't really exist formally in that context.

Scene graphs are probably going to be very specific for specific problems such as spatial partitioning. Like that guy said, trying to generalize the pattern into code is probably not a good idea.

craftworkgames commented 7 years ago

Now that we've split these into different packages this is not really relevant anymore. Once the ECS is fleshed out a bit more the SceneGraphs package will likely become obsolete.