[xinf] Xinfinity scenegraph

Daniel Cassidy xinf at danielcassidy.me.uk
Fri Dec 22 12:37:19 CET 2006


Hi Dan (and list),

Here, for your perusal, is a summary of my initial plans for
Xinfinity's scenegraph implementation. Its aims are simplicity to
implement, simplicity to use, flexibility and similarity to Flash's
implementation.

There's at least one glaring flaw with it, for which I already have a
planned resolution. But, I'm willing to bet that there are even worse
problems. If you should happen to spot them, please point them out.
You're welcome to laugh, too, if you feel the need.

The following interfaces and classes will be made available:
interface Scene;
interface Plane extends Scene;
class Group implements Scene;
class Canvas implements Plane, Group;


Scene represents a node in the scenegraph. Each node will have
associated with it a 4x3 transformation matrix:

[ x_x, x_y, x_z, t_x ]
[ y_x, y_y, y_z, t_y ]
[ z_x, z_y, z_z, t_z ]

If the current backend supports only 2D rendering, some elements in
the matrix are fixed as follows:

[ x_x, x_y, 0, t_x ]
[ y_x, y_y, 0, t_y ]
[ 0,   0,   1,   t_z ]

If, on a 2D-only implementation, an application attempts to modify
fixed matrix elements, either an exception will be thrown or nothing
will happen; I haven't decided. Note that the z-axis is retained in
order to provide a draw order. Translations along z therefore remain
possible, but rotation, shearing, scaling, etc. of z are impossible
since they aren't meaningful for 2D.

Note that Scene is just an interface and doesn't provide any
implementation. All the usual things that you expect, such as 3D
models, will eventually be provided as classes implementing Scene.


Group is a class implementing Scene whose function is simply to
contain other Scenes (it is therefore quite similar to MovieClip in
Flash). Contained Scenes are rendered directly to the Group's
enclosing context, but are affected by the Group's transformation
matrix in addition to their own.


Plane is an interface extending scene, and provides for 2D objects
which may be manipulated within the 3D environment; for example an
Image would implement Plane, and may then be added directly to a scene
and transformed exactly as if it were a (very flat) 3D object. It is
my intention that once texture mapped polygons are implemented, it
will be possible to efficiently use any Plane as a texture.


Canvas is an implementation of both Plane and Group that renders its
(2D *or* 3D) contents to a 2D buffer, and then exposes that buffer to
the containing Scene as a Plane. Dynamic texturing thereby becomes
almost transparent.

A Canvas, in addition to its transformation matrix, has a projection
matrix associated with it, which defaults to an orthographic
projection. In a 2D-only implementation, any attempt to use a
projection matrix which is not orthographic results in either an
exception or silent failure (as above, for translation matrices).

The root node of the scenegraph is implemented as a Canvas, except
that it renders directly to the main context rather than to a buffer.


So, the (simplified) steps required to render the complete scene are as follows:
1. Set the view matrix to the identity matrix.
2. Step to the root node.
3. Push the view matrix to the stack.
4. Multiply the view matrix by the current node's transformation matrix.
5. Do some custom class-specific stuff, e.g. drawing operations.
6. If the node has any children which haven't yet been visited, step
to the next child and continue from step 3.
7. Do some more custom class-specific stuff.
8. Pop the previous view matrix from the stack.
9. If we're at the root node, stop. Otherwise, step back to the parent
node and continue from step 6.


Comments?

Dan C


More information about the xinf mailing list