Are you interested in SceneGraph? Seeking public submissions:
I was playing around with some code I wrote for loading entire scene hierarchies from an XFile, and simultaneously thinking about Scene Graphs and hierarchical OSP. It occurred to me that XFiles just don't support the special nodes which exist in a SceneGraph. I decided I'd better implement my OWN version of an XFile in order to support the various kinds of nodes I had in mind.
Without a thought, I opened an ASCII version of an XFile, and noticed that it contains a basic scene hierarchy with lumps of data for meshes etc.
I unashamedly ripped off the XFile syntax for the hierarchy (simply a system of nested curly brackets), and implemented the Frame and FrameTransformMatrix templates in a real, working loader. I thought to myself "Great !! Now I can specify the exact hierarchy of nodes which the Loader will construct !" but it wasn't enought. I replaced the wads of mesh data in the XFile with a single line reference to the name of the xfile object to be loaded in its place. Then I implemented the Mesh template in the Loader, using my CMesh class as a base. Now I could contruct genuine object hierarchies from script, but still it wasn't enough. Next I encapsulated CMesh in another class called CMeshCache, which keeps a linkedlist of names of loaded Meshes along with a ptr to their CMesh instance. Now I had implemented referenced mesh, and thats as far as I got that day.
Next will be to rework the Texture loading code of CMesh to use my CTexture class, and to wrap CTexture in a CTextureCache manager class so that Textures are referenced in a similar way to Meshes and only ever loaded once.
After that I'll write Update and Render code just to make sure everything is working properly, before going on to add some of the more complex nodes which unlock the power of SceneGraphs. Later I'll write code to SAVE the loaded SceneGraph in binary and not Ascii format, and then modify the Loader to handle the Binary format as well... from thereon, the Ascii version will be developer-only.

For the curious, heres the current script language test script:


Frame SceneRoot{
FrameTransformMatrix{
1.0,0.0,0.0,0.0,
0.0,1.0,0.0,0.0,
0.0,0.0,1.0,0.0,
0.0,0.0,0.0,1.0
}
Frame Tank{
FrameTransformMatrix{
1.0,0.0,0.0,0.0,
0.0,1.0,0.0,0.0,
0.0,0.0,1.0,0.0,
0.0,0.0,0.0,1.0
}
Mesh TankBody.x
Frame TankTurret{
FrameTransformMatrix{
1.0,0.0,0.0,0.0,
0.0,1.0,0.0,0.0,
0.0,0.0,1.0,0.0,
0.0,0.0,0.0,1.0
}
Mesh TankTurret.x
}
Frame TankLeftTrack{
FrameTransformMatrix{
1.0,0.0,0.0,0.0,
0.0,1.0,0.0,0.0,
0.0,0.0,1.0,0.0,
0.0,0.0,0.0,1.0
}
Mesh TankTrack.x
}
Frame TankRightTrack{
FrameTransformMatrix{
1.0,0.0,0.0,0.0,
0.0,1.0,0.0,0.0,
0.0,0.0,1.0,0.0,
0.0,0.0,0.0,1.0
}
Mesh TankTrack.x
}
}
}
Posted on 2004-01-27 04:37:52 by Homer
While you're at it, you can also add movement operators (eg splines) at each node, and bounding volumes etc.
And you can re-use the movement operators for other things, such as cameras and lights.
I also assign shaders, texture/samplerstates and things on a per-mesh basis, along with the textures. Also a flag for the cull-order (CW, CCW or NONE, can aid mirroring or other special effects), and a flag to indicate whether a mesh is translucent or not (they have to be handled separately).
Posted on 2004-01-27 05:38:05 by Henk-Jan
BoundingBoxes will be calculated only for nodes which contain geometry and will as such be kept in a CMesh object, rather than the CFrame object which forms the bulk of the hierarchy.
Thanks to Ultrano, I now have a method of identifying a node TYPE without needing to keep an identifier in any nodes. This will allow me to mix different nodes in the main tree in order to create a "true" scenegraph with such obscure node types as "switch", and I guess next will be writing the tree walk/render code for a BASIC tree before I attempt to add a Named Attribute node to allow for data interdependancy chains and positive and negative feedback. I'll probably be using the "child notifies parent" method for negative feedback, and not processing changes until the next time we walk the tree. This prevents data dependancy problems due to late changes in the data of already-processed nodes, at the expense of a single potentially flawed frame at the beginning of rendering. Thoughts?
Posted on 2004-01-27 09:20:50 by Homer
Forgot to mention - found a way to encapsulate a linkedlist manager for a class within the SAME class - we now no longer need CMeshCache to manage CMesh instances, because CMesh manages its OWN instances, including returning pExisting in response to attempts to load a previously loaded mesh, and zeroing its own rootpointer when the last instance is killed.
Posted on 2004-01-27 09:26:11 by Homer
BoundingBoxes will be calculated only for nodes which contain geometry and will as such be kept in a CMesh object, rather than the CFrame object which forms the bulk of the hierarchy.


I thought you might have wanted to store them in the file, rather than generating them at runtime.

This prevents data dependancy problems due to late changes in the data of already-processed nodes, at the expense of a single potentially flawed frame at the beginning of rendering. Thoughts?


I generally render in multiple stages. Selecting candidates for rendering, applying animation/other dynamic parameters, rendering opaque, rendering translucent.

The scenegraph works like a database, the 'renderables' are extracted, the necessary dynamic stuff is applied, and then they can be rendered without the need of hierarchy. Each renderable will simply contain its entire state (you can also sort on these states to improve rendering. Sort on texture for example, or shader).
Posted on 2004-01-27 09:44:19 by Henk-Jan
A basic SceneGraph is nothing much more than a way to database the scene frame hierarchy - but more progressive Scenegraphs contain nodes which control node data as well as controlling the way in which the hierarchy is walked at rendertime - it makes sense then to walk the hierarchy just once at rendertime, making any calculations immediately that act on data in a node or its children (positive feedback), or flagging the results of such calculations in the targetnode(s) (negative feedback). I gave the example of a Switch Node. This is maybe the most basic of the "advanced" scenegraph nodes, it has N children, and contains a constraint which forces only one child to be selected. We can think of this in terms of a storyboard with several possible outcomes, only one of which is active.
An example where we might want to use this in gamecoding is for something like rendering one of N possible meshes for the door of a car, which causes it to visually become progressively damaged. Obviously in this case, the constraint causes pNext to be based on the amount of damage the door has taken.
Yes, these kinds of constraints can be hardcoded, however I see SceneGraph in terms of a kind of pseudo execution at runtime, much more than a mere database. I think of it in terms of softcoded logic. I'm using a plaintext script at the moment, but the idea is to 1)write code to save the entire scenegraph to a binary file 2)rewrite the loader to handle plain or binary files 3)use plaintext scripts only as a development tool, with only binary "scripts" to be shipped.
The final scenegraph will be reminiscent of Maya in topology, for it should allow constraint associations of arbitrary data of arbitrary nodes.
For example, we should be able to associate the rotation angle(s) of a jetplane's landing gear with the height of the jetplane above ground, and limit the rotation to a predetermined range. Now the landing gear will extend and retract automatically as the jetplane lands and takes off. Thus SceneGaph becomes a way to automate and aid various tasks in the game engine such as animation. Think "Driven Key" ;)
That's where I'd like to be heading with this project - if I only wanted a hierarchy loader I could have almost stuck with XFile.
Posted on 2004-01-27 10:03:28 by Homer
An example where we might want to use this in gamecoding is for something like rendering one of N possible meshes for the door of a car, which causes it to visually become progressively damaged. Obviously in this case, the constraint causes pNext to be based on the amount of damage the door has taken


I would just use a damage-parameter that vertexblends between good and damaged door :)

I see SceneGraph in terms of a kind of pseudo execution at runtime


I see a scenegraph as a way to optimize the rendering speed :)

But yes, you can and should extend it to be a tool in animation, as I already said, have 'movable' data in it.
Posted on 2004-01-27 10:21:45 by Henk-Jan