The high-level scene graph tuning tools discussed in Chapter 3 and Chapter 6 provide convenient interfaces, and probably meet most of your needs for manipulating triangles in a scene graph. However, if you want lower-level control, for example, to develop your own scene graph tuning application, you need the tools discussed in this chapter.
These are the sections in this chapter:
The low-level geometry-building tools work with csGeoSets; they do not manipulate a scene graph. They decompose csGeoSets into constituent triangles, or collect vertices and triangles, and then rebuild the triangles into new csGeoSets. These tools are the basic procedures of opSpatialize, which is discussed in the section “Spatialization Tool: opSpatialize”. You can control color attributes of new csGeoSets by specifying them for each primitive or triangle.
To apply these tools to a scene graph, incorporate them in a traversal; see Chapter 12, “Traversing a Large Scene Graph” and Chapter 14, “Managing Multiple Processors.”
Figure 13-1 shows how the geometry-building classes fit into a class hierarchy.
The class hierarchy of opGeoBuilder and its children mimics the Cosmo3D hierarchy of csGeoSet and its children, which are the classes for vertex-based geometries. The methods in opGeoBuilder manipulate a vertex array developed from a csGeoSet. The methods in its children manipulate objects in the corresponding descendents of csGeoSet by using common functionality in opGeoBuilder.
You can therefore derive a class from opGeoBuilder to build a subclass of csGeoSet; for models, use the classes opTriSetBuilder, opTriFanSetBuilder, and opTriStripSetBuilder.
This chapter discusses
Also, this chapter discusses in more detail opGeoConverter and opColorGenerator, which were briefly mentioned in Chapter 3.
The classes opTriFanner and opTriStripper, which appear in Figure 13-1, were discussed in “Creating OpenGL Connected Primitives”.
You are likely to have csGeoSets whose triangles you want to reorganize when, for example, you want to organize them spatially (see Chapter 6, “Organizing the Scene Graph Spatially”). To reorganize a scene graph based on its renderable content, it is valuable to have a database that provides convenient access to triangles, and avoids the complexities of manipulating attributes.
The necessary data management is performed by the class opGeoConverter. It provides methods to take the important csGeoSets csTriSet, csTriStripSet, and csTriFanSet and develop data structures—mainly hash tables—that hold the defining features of the individual component triangles: vertices, normals, and colors. opGeoConverter represents a set of input csGeoSets as concatenated lists of unique triangles.
The triangles from an opGeoConverter are used as inputs to opTriFanner and opTriStripper (discussed in “Creating OpenGL Connected Primitives”) and to the tools discussed below: opTriSetBuilder, opTriFanSetBuilder, and opTriStripSetBuilder.
The class has the following main methods:
class opGeoConverter
{
opGeoConverter(csGeoSet::NormalBindEnum nb = csGeoSet::NO_NORMAL,
csGeoSet::ColorBindEnum cb = csGeoSet::NO_COLOR,
csGeoSet::TexCoordBindEnum tb = csGeoSet::NO_TEX_COORD);
opGeoConverter(csGeoSet *g,
csGeoSet::NormalBindEnum nb = csGeoSet::NO_NORMAL,
csGeoSet::ColorBindEnum cb = csGeoSet::NO_COLOR,
csGeoSet::TexCoordBindEnum tb = csGeoSet::NO_TEX_COORD);
~opGeoConverter();
void addGeoSet(csGeoSet *g);
void done();
static bool isConvertable(csGeometry *g);
int getNTriangles() const;
opTriangle *getTriangle(int i) const;
int getNVertices() const;
csGeoSet::NormalBindEnum getNBind() const;
csGeoSet::ColorBindEnum getCBind() const;
csGeoSet::TexCoordBindEnum getTBind() const;
csVec3f *getOverallNormal() const;
csVec4f *getOverallColor() const;
csContext::CullFaceEnum getOverallCullFace() const;
void setNormalTolerance(float norm_tol);
float getNormalTolerance() const);
};
|
| opGeoConverter() |
| |
| addGeoSet(g) | Adds the triangles in g to the data structure maintained by opGeoConverter. |
The accessor functions retrieve the numbers of triangles and vertices, and the normal, color, and texture bindings of the first csGeoSet included in the hash tables. You can also test whether a given csGeoSet can be converted; that is whether it is a csTriSet, a csTriFanSet, or a csTriStripSet.
Because instances of opGeoConverter maintain tables of hashed attributes, you can reduce memory consumption by destroying opGeoConverters that you no longer need.
If you use an opGeoConverter to break down csGeoSets, when you rebuild them you can control the coloring of the new primitives by supplying an opColorGenerator to the geometry building tools.
The class has the following main methods:
class opColorGenerator
{
public:
opColorGenerator(const csVec4f *color=NULL);
void genOverallColor(const csVec4f *color=NULL);
void genPrimColor();
csGeoSet::ColorBindEnum getCBind() const;
const csVec4f *getOverallColor();
const csVec4f *getPrimColor();
static opColorGenerator* noColors();
};
|
Given the data held in an opGeoConverter, you can rebuild csGeoSets with the tools discussed in this section. You can also use the tools to build csGeoSets from individual vertices and triangles.
The class opGeoBuilder provides the common functionality needed by its children to build csGeoSets. You are unlikely to use opGeoBuilder to build a csGeoSet, but rather one of its children, opTriSetBuilder, opTriFanSetBuilder, or opTriStripSetBuilder.
opGeoBuilder is derived from the base class opGeoTool, which provides basic accessor functions used by all geometry building classes, but which you should not use.
The class has the following main methods:
class opGeoBuilder : public opGeoTool
{
public:
opGeoBuilder(const opGeoConverter *gc=NULL);
virtual ~opGeoBuilder();
void setColorBind(csGeoSet::ColorBindEnum cBind);
void setNormalBind(csGeoSet::NormalBindEnum nBind);
void setTexCoordBind(csGeoSet::TexCoordBindEnum tBind);
void addVertex(const opVertex *v);
void finishPrim(const csVec4f *color,
const csVec3f *normal);
void finishSet( csGeoSet *geoSet,
const csVec4f *color,
const csVec3f *normal);
};
|
Children of opGeoBuilder can use the following low-level methods:
| addVertex() | Adds a vertex to a primitive | |
| setColorBind(), setNormalBind(), and setTexCoordBind() |
| |
| finishPrim() | Indicates when a set of vertices provided by addVertex() defines a primitive. Optional arguments allow you to specify color and normals. | |
| finishSet() | Is called when a set of primitives defined by calls to finishPrim() is complete. The function builds the new csGeoSet. Optional arguments allow you to specify overall color and normals for the new csGeoSet. |
If you have developed triangle data with an opGeoConverter, you can use it to supply vertex data or default attribute settings to an opGeoBuilder.
The class opTriSetBuilder is an opGeoBuilder that provides the necessary tools to build a csTriSet from a set of triangles along with per-triangle attributes, or from the data in an opGeoConverter.
The following are the main methods in the class:
class opTriSetBuilder : public opGeoBuilder
{
public:
opTriSetBuilder(const opGeoConverter *gc=NULL);
virtual ~opTriSetBuilder();
// Add triangle with optional PER_PRIMITIVE
// attribute values.
void addTriangle( const opTriangle *t, const csVec3f *normal);
void addTriangle( const opTriangle *t, const csVec4f *color=NULL,
const csVec3f *normal=NULL);
// Finish set with option of passing OVERALL attribute values.
csTriSet *done( const csVec3f *normal);
csTriSet *done( const csVec4f *color=NULL, const csVec3f *normal=NULL);
static csTriSet *convert( const opGeoConverter *gc,
opColorGenerator *cg = opColorGenerator::noColors());
static csTriSet *convert( csGeometry *geom,
opColorGenerator *cg = opColorGenerator::noColors());
};
|
In addition to the inherited methods, opTriSetBuilder has the following methods:
| addTriangle() | Is overloaded to allow you to specify normal and color bindings, or just normal bindings, for each triangle included in the csTriSet. | |
| done() | Completes the process of making a csTriSet from the triangles brought in by addTriangle(). This function is overloaded to allow you to specify overall normal and color bindings, or just normal bindings. | |
| convert() | Is a convenience function that takes a set of triangles from either of two sources, an opGeoConverter or a csGeometry, and develops a csTriSet. | |
| addTriangle() | Is overloaded to allow you to specify normal and color bindings, or just normal bindings, for each triangle included in the csTriSet. | |
| done() | Completes the process of making a csTriSet from the triangles brought in by addTriangle(). This function is overloaded to allow you to specify overall normal and color bindings, or just normal bindings. | |
| convert() | Is a convenience function that takes a set of triangles from either an opGeoConverter or a csGeometry, and develops a csTriSet. |
The class opTriFanSetBuilder is an opGeoBuilder that provides the necessary tools to build a csTriFanSet from a set of triangles along with per-triangle attributes or from the data in an opGeoConverter.
The class has the following main methods:
class opTriFanSetBuilder : public opGeoBuilder
{
public:
opTriFanSetBuilder(const opGeoConverter *gc=NULL);
virtual ~opTriFanSetBuilder();
// Add triangle with optional PER_PRIMITIVE attribute values.
void addTriangle(const opTriangle *t, const csVec3f *normal);
void addTriangle(const opTriangle *t, const csVec4f *color=NULL,
const csVec3f *normal=NULL);
// Finish fan with option of passing OVERALL attribute values.
void finishFan(const csVec3f *normal=NULL);
void finishFan(const csVec4f *color,const csVec3f *normal=NULL);
// Finish set with option of passing OVERALL attribute values.
csTriFanSet *done( const csVec3f *normal);
csTriFanSet *done( const csVec4f *color=NULL,
const csVec3f *normal=NULL);
};
|
opTriFanSetBuilder is similar to opTriSetBuilder. However, it requires an intermediate function to build primitives, which are no longer individual triangles but trifans.
| finishFan() | Defines data structures for each csTriFan that you build from a set of triangles developed with calls to addTriangle() or from an opGeoConverter. | |
| done() | Assembles the csTriFans into an output csTriFanSet. |
The class opTriStripSetBuilder is an opGeoBuilder that provides the necessary tools to build a csTriStripSet either from a set of triangles along with per-triangle attributes or from the data in an opGeoConverter.
With obvious differences in names, opTriStripSetBuilder has the same methods as opTriFanSetBuilder, and the following additional methods.
| finishStrip() | Defines the data structures for each csTriStrip that you build from a set of triangles added by calls to addTriangle(). | |
| flipStrip() | Sets a flag so that the vertices of subsequently added triangles are re-ordered to change triangle orientation. |