Hello again,

As there seems to be currently not much activity in 3D gnoming, I
collected together pieces I've until now written into the following
preliminary RFC.

The code can be found at:

It does not differ much from other scene graph libraries, but uses Gtk
types. As a consequence, it requires C geometric libraries...

It does not compile into libraries yet, but instead into some simple
programs, you can tweak with. The most important is 'floyd', which you can
test, executing it from toplevel source directory, with 'samples/a.wrl' as
a parameter. It probably does not behave well without 3D accelerator, and
may not behave well with accelerator too... Sorry.


Gnome 3D API RFC


Version 0 - a list of ideas

1. Should we use OpenInventor (OI), or separate Gnome3D (G3D) API?
(All mentioned library names are subject to change)
Currently I've divided (or plan to do it) things into separate modular

1.1. libfl - low level library of geometric primitives, such as 2,3,4D points
and vectors, quaternions, colors, matrixes ...
Handles basic transformations, creation and testing, vector math ...

1.2. libflg - library of 3D objects, such as: vertices, polygons,
polygon-sets, shapes ...
Handles complex tasks, such as normal computation, polygon decomposing,
intersection tests ...

1.3. libfloyd - Gnome 3D canvas
A child of GtkGLArea, handling state-preserving 3D objects, such as boxes,
spheres, arbirary-shaped objects, cameras, lights...
Also nonspacious objects, such as textures, moving objects...

1.4. libginventor - an openinventor clone, usign C and Gtk types, built on
top of libfloyd

1.5. libvrml? - useful for reading 3D scenes, similar to libglade reading
of widget descriptions/callback signals

2. libfl
Completely NonOO, using simple structure types:

 - FLPoint2, FLVector2, FLPoint3, FLVector3, FLPoint4, FLVector4
   Vectors and points ARE different datatypes - you cannot add 2 points...
 - FLColor3, FLColor4
 - RGB and RGBA versions. Maybe also HSV, YUV...
 - FLQuaternion, FLRotation, FLDirection
 - 3 different methods for specifying rotation matrixes - quaternions,
   axis/angle pairs and euler angles
 - FLMatrix4 - 4x4 transformation matrix
 - FLCuboid3, FLSphere - Basically intended for binding volume computation

Also libfl has array versions of these types, such as:

 - FLPoint3Array...

to implement highly-optimized block transforms. Here we can use 3DNow, KNI,

The most important parts of libfl are done.

3. libflg
NonOO, complex data structures:
- a list of 4D points, 3D normals, 2D (3D?) texture coords, RGBA
  colors ,FaceIndexes?, ...
- an array of indexes, referring to FLGVertexList
- an array of index triplets, referring to FLGVertexList
- structure, representing a face (FLColor, Normal...)

nothing done

4. libfloyd
A big part is done, needs massive rewrite & rethinking...

GnomeFloyd - an OpenGL widget, deriving from GtkGLArea

Hierarchical tree of physical bodies + flat list of 3D objects:


An implementation logic should be similar to the GnomeCanvas one:

object = floyd_object_new (parent, FLOYD_TYPE, args..., NULL);

floyd_object_set (FLOYD_OBJECT (object), args..., NULL);

- abstract base class. One object may belong to several other objects,
  allowing to share OpenGL lists.
::render method - is noramlly called by object owner during it's
  own rendering - if object specifies some OpenGL behaviour (texture,
  lighting params...)
  '::render' is also responsible for updating half (display part) of 
  object's internal state, if delayed updating is requested. (FloydItems
  have in addition 'update' method, but this is reserved strictly for
  physical bodies and changes in physical paremters)

FloydItem - geometric body, with meaningful local coordinate system,
  usually also with position, volume & other physical paremters.
- physical objects
- lights. [0,0,0] in local coords is position of pointlight
          [0,0,-1] is the direction of directionallights
- views. [0,0,0] is the viewer location, [0,0,-1] is viewing direction
- groups of items
::update method - is called in similar way to GnomeCanvas update method,
  whenever object requests it, or it's parent thinks it is appropriate
  to force children to update themselves (parent's transformation matrix
NB! although '::update' is invoked whenever object's transformation
  changes, it is usually not a good idea to recompile GLList during it.
  Instead,  during rendering, physical body pushes transformation matrix
  to OpenGL transformation stack and invokes '::render' method of it's
  geometry object.
Items may have binding cuboids, which should be updated during ::update.
  Cuboids are used to eliminate as much intersection testing, as possible
::intersect method - tests object intersection against other item.
  If, due to update, object has any reason to believe, it can intersect
  with other items, it can call floyd_item_request_intersect. It ensures,
  that, before rendering, intersection will be tested.
If intersect gives positive result and both items share at least one
  collision flag ((a->cflags & b->cflags) != 0), '::collision' method is
  invoked. Typically this invokes object's "collision" signal.

FloydGroup - group of FloydItems
Probably has it's own flat FloydObjects list - limiting the scope of
  those - lights, fog... Objects needing global scope should assign
  themselves to root group

FloydShape - physical instantiation of FloydGeometry
  Making difference between geometry defs and instances allow us to share
  glLists, probably resulting in much faster rendering

FloydBinder - an abstract parent of groups, having one member with special
  geometry rules. For example - an object, which stays in one place, but
  looks always at other object...

FloydView - an object, implementing glProjection matrix. There can be many
  views, only one of whose is currently active. For multiview floyd,
  different views can be active on different vieports

FloydLight - an light. Floyd takes care of allocating OpenGL available 
  light sources to active lights.

FloydInertialBody - a moving group, with fixed linear and rotational

Time model

Floyd has its own global time, which is usually synchronized with system
An object (and user?) can request timeout events:
- preferred timeout. Occurs at specified time, or ASAP later. Floyd
collects together all timeouts, whose requested time is earlier than
current timestamp, and executes these with timestamp set to current time.
- exact timeout - if floyd cannot process it in time, it stills world time
and executes it with requested timestamp.
- idle timeout - will be executed only, if floyd has idle time
There can be at most 1 update and intersection test for any timestamp.

Collision prediction
Probably need separate method.

Floyd serves as dictionary for it's objects, so, for example, if it is
  created from VRML, we can pick out separate items via names.

Lauris Kaplinski

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]