PLIB 1.8.5+ r2173 from http://plib.svn.sourceforge.net/svnroot/plib/trunk
This commit is contained in:
233
doc/ssg/ssgBase.html
Normal file
233
doc/ssg/ssgBase.html
Normal file
@@ -0,0 +1,233 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<TITLE>A Simple Scene Graph API for OpenGL.</TITLE>
|
||||
</HEAD>
|
||||
<BODY text="#B5A642" link="#8FFF8F" vlink="#18A515" alink="#20336B"
|
||||
bgcolor="#005000" background="../marble.png">
|
||||
|
||||
<H2><code>class ssgBase</code> - The Universal Abstract Base Class.</H2>
|
||||
All significant SSG classes are derived from ssgBase - which offers a type testing
|
||||
mechanism and a means to print out the tree hierarchy in human-readable form,
|
||||
or to save/load it to/from disk.
|
||||
<pre>
|
||||
|
||||
class ssgBase
|
||||
{
|
||||
void ref () ;
|
||||
void deRef () ;
|
||||
int getRef () ;
|
||||
|
||||
int isA ( int ty ) ;
|
||||
int isAKindOf ( int ty ) ;
|
||||
|
||||
int getType (void) ;
|
||||
virtual char *getTypeName(void) ;
|
||||
|
||||
ssgBase *getUserData () ;
|
||||
void setUserData ( ssgBase *user_data ) ;
|
||||
|
||||
void setName ( char *nm ) ;
|
||||
char *getName () ;
|
||||
const char *getPrintableName () ;
|
||||
|
||||
virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ;
|
||||
virtual int load ( FILE *fd ) ;
|
||||
virtual int save ( FILE *fd = stderr ) ;
|
||||
|
||||
ssgBase *clone ( int clone_flags ) ;
|
||||
} ;
|
||||
|
||||
</pre>
|
||||
|
||||
<H3>Reference Counting.</H3>
|
||||
All SSG classes are reference counted - that means that whenever you
|
||||
connect a node into the scene graph with <code>ssgBranch::addKid()</code>, we
|
||||
increment its reference count and each time we remove a node from
|
||||
the graph with <code>ssgBranch::removeKid()</code>, we decrement the count -
|
||||
and if it's zero, we'll delete the node to recover memory.
|
||||
<p>
|
||||
Sometimes, you need a node to stay in memory even though it may be
|
||||
be disconnected from the scene graph. You can achieve that by
|
||||
calling <code>ssgBase::ref()</code> to increment the reference count.
|
||||
If you later find you don't need that node anymore then you may
|
||||
<code>ssgBase::deRef()</code> it. If you <code>ssgBase::deRef()</code>
|
||||
a node to zero, SSG won't automatically delete it - you still need to use
|
||||
<code>delete</code> to do that. Since such deletions are recursive,
|
||||
you may delete an entire sub-branch with a single call.
|
||||
<p>
|
||||
Instead of using <code>ssgBase::deRef()</code> directly, you should use
|
||||
<code>ssgDeRefDelete()</code> which automatically deletes the node if
|
||||
the reference count drops to zero.
|
||||
<p>
|
||||
You can read the current ref count for a node
|
||||
using <code>ssgBase::getRef()</code>.
|
||||
<H3>Names.</H3>
|
||||
It's often useful to attach an ASCII name to a node in the
|
||||
scene graph - this is often derived from a name field in
|
||||
whatever modelling tool was used to create the object.
|
||||
<code>ssgBase::setName(s)</code> sets the name,
|
||||
<code>ssgBase::getName()</code> returns it.
|
||||
|
||||
<H3>User Data</H3>
|
||||
Although one can derive a new C++ class from an SSG class and thereby customise
|
||||
it's behavior, it's often more convenient to simply attach application-specific
|
||||
data structures to a basic entity. Two functions are provided:
|
||||
<code>ssgBase::getUserData()</code> and <code>ssgBase::setUserData(data)</code>.
|
||||
<p>
|
||||
Notice that user data is of class ssgBase - which means that user data
|
||||
can be named, ref-counted - and can in turn have user data of it's own.
|
||||
This allows user data to be formed into linked lists when multiple
|
||||
user data items need to be attached to a single node.
|
||||
|
||||
<H3>Destructor Functions</H3>
|
||||
When an SSG entity is NOT connected into the scene graph in any
|
||||
way, then the correct way to get rid of it and free up memory
|
||||
is to call it's destructor function. However, when the entity
|
||||
is included into the scene graph, you should disconnect it
|
||||
from the tree and let the reference count mechanism take care
|
||||
of the cleanup.
|
||||
<H3>Type Names</H3>
|
||||
SSG frequently needs to know what kind of an object an ssgBase is.
|
||||
Since C++ programs may create new classes that inherit from SSG
|
||||
classes, we provide several functions to make run time type determination
|
||||
possible. There is an external function for each type that
|
||||
returns the type token for that type:
|
||||
<pre>
|
||||
|
||||
int ssgTypeBase () ;
|
||||
int ssgTypeEntity () ;
|
||||
int ssgTypeLeaf () ;
|
||||
int ssgTypeVTable () ;
|
||||
int ssgTypeVtxTable () ;
|
||||
int ssgTypeDisplayList() ;
|
||||
int ssgTypeBranch () ;
|
||||
int ssgTypeBaseTransform ();
|
||||
int ssgTypeTransform () ;
|
||||
int ssgTypeTexTrans () ;
|
||||
int ssgTypeSelector () ;
|
||||
int ssgTypeTimedSelector () ;
|
||||
int ssgTypeRangeSelector () ;
|
||||
int ssgTypeRoot () ;
|
||||
int ssgTypeCutout () ;
|
||||
|
||||
</pre>
|
||||
Now, you can use the <code>ssgBase::isA(type)</code> or <code>ssgBase::isAKindOf</code>
|
||||
to test the type of the node. For example, if you want to test
|
||||
whether a node is a Leaf node or a Branch node, you can do this:
|
||||
<pre>
|
||||
|
||||
if ( mynode -> isAKindOf ( ssgTypeLeaf() ) )
|
||||
printf ( "Leaf node\n" ) ;
|
||||
else
|
||||
if ( mynode -> isAKindOf ( ssgTypeBranch() ) )
|
||||
printf ( "Branch node\n" ) ;
|
||||
else
|
||||
printf ( "Something else\n" ) ;
|
||||
|
||||
</pre>
|
||||
Notice that if you ran that code on (say) an ssgSelector, then it'll
|
||||
print "Branch node" since the Selector class is derived from the Branch
|
||||
class. If you wanted to tell if a node was *exactly* a Branch node -
|
||||
and not from a derived class, then you could use:
|
||||
<pre>
|
||||
|
||||
if ( mynode -> isA ( ssgTypeBranch() ) )
|
||||
printf ( "Branch node\n" ) ;
|
||||
|
||||
</pre>
|
||||
Finally, you can actually read the type of a node - either as a
|
||||
token (using <code>ssgBase::getType()</code>) or as an ASCII string
|
||||
(using <code>ssgBase::getTypeName()</code>). The latter is very useful
|
||||
for debug routines:
|
||||
<pre>
|
||||
|
||||
printf ( "ERROR - something wrong with my '%s' node.\n",
|
||||
mynode -> getTypeName () ) ;
|
||||
|
||||
</pre>
|
||||
|
||||
<H3>Printing</H3>
|
||||
It's sometimes useful during debug to print a section of the
|
||||
scene graph so you can examine it. <code>ssgBase::print(fd, indent, how_much)</code>
|
||||
does that for you - it prints out the node itself - and anything
|
||||
connected beneath it in the scene graph. <code>fd</code> is the
|
||||
file descriptor to print to (defaults to stderr) and
|
||||
<code>indent</code> is a string that will prefix all output lines
|
||||
- and is used internally within SSG to make printout of tree
|
||||
structures more legible by indenting them.
|
||||
<p>
|
||||
The values for the parameter <code>how_much</code> may be 0,1,2,3 or 4
|
||||
and determine how much is printed, with 0 meaning little
|
||||
and 4 meaning much.
|
||||
<BR>
|
||||
For how_much = 0, basic information of the branches is printed
|
||||
<BR>
|
||||
For 1, additionally there is: basic leaf info, state pointers
|
||||
<BR>
|
||||
For 2, additionally there is: states, user data, number of parents,
|
||||
bSphere
|
||||
<BR>
|
||||
For 3, additionally there is: Reference count
|
||||
<BR>
|
||||
For 4, additionally there is: contents of vertex-, normal-, colour-,
|
||||
texCoord- and index-arrays
|
||||
<BR>
|
||||
Experience tells that for <code>how_much = 0</code> you get very little
|
||||
out put, with 1, 2 and 3 a manageable amount and with 4 a huge amount,
|
||||
up to 100 MB for a medium sized model.
|
||||
|
||||
|
||||
<p>
|
||||
It would be unwise
|
||||
to attempt to parse the output of <code>ssgBase::print</code> into another
|
||||
program since it is only intended for human consumption and the
|
||||
format may change dramatically between revisions of SSG.
|
||||
|
||||
<H3>Cloning:</H3>
|
||||
All classes derived from ssgBase have a member function
|
||||
<code>ssgBase *clone(int clone_flags)</code> which new's a
|
||||
new object of that class as a copy of the calling object.
|
||||
<p>
|
||||
The 'clone_flags' is a set of tokens that you 'OR' together to
|
||||
specify how 'deep' you want the cloning to go. By default
|
||||
(with clone_flags==0), only the object itself is cloned and
|
||||
the clone will simply point to the same child structures as
|
||||
the original object. However, if you OR in 'SSG_CLONE_RECURSIVE',
|
||||
then all ssgEntities beneath this one will also be cloned.
|
||||
ORing in SSG_CLONE_GEOMETRY will cause all the per-vertex data
|
||||
at the leaf nodes to also be cloned. SSG_CLONE_STATE causes
|
||||
ssgState objects to be cloned also, SSG_CLONE_STATE_RECURSIVE
|
||||
also causes states pointed to by other states to be copied,
|
||||
SSG_CLONE_USERDATA causes user data attached to
|
||||
the original node to be referenced (NOT copied) by the clone -
|
||||
otherwise, user data for the clone is set to NULL. Finally,
|
||||
SSG_CLONE_TEXTURE causes texture maps to be replicated also.
|
||||
<p>
|
||||
Most copy operations will typically use either zero, SSG_CLONE_RECURSIVE
|
||||
or (SSG_CLONE_RECURSIVE | SSG_CLONE_GEOMETRY)
|
||||
|
||||
<hr>
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td width="33%" align="left"><a href="index.html"><= previous =</a></td>
|
||||
<td width="34%" align="center"><a href="index.html">Return to SSG Index</a></td>
|
||||
<td width="33%" align="right"><a href="ssgEntity.html">= next =></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="http://validator.w3.org/check/referer"><img border="0" src="../valid-html40.png" alt="Valid HTML 4.0!" height="31" width="88"></a>
|
||||
<td>
|
||||
<ADDRESS>
|
||||
<A HREF="http://www.sjbaker.org">
|
||||
Steve J. Baker.</A>
|
||||
<<A HREF="mailto:sjbaker1@airmail.net">sjbaker1@airmail.net</A>>
|
||||
</ADDRESS>
|
||||
</table>
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
||||
Reference in New Issue
Block a user