212 lines
8.7 KiB
C++
212 lines
8.7 KiB
C++
// Filename: builder.h
|
|
// Created by: drose (09Sep97)
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// PANDA 3D SOFTWARE
|
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
|
//
|
|
// All use of this software is subject to the terms of the Panda 3d
|
|
// Software license. You should have received a copy of this license
|
|
// along with this source code; you will also find a current copy of
|
|
// the license at http://www.panda3d.org/license.txt .
|
|
//
|
|
// To contact the maintainers of this program write to
|
|
// panda3d@yahoogroups.com .
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef BUILDER_H
|
|
#define BUILDER_H
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Builder
|
|
//
|
|
// The builder accepts as input a loose collection of polygons with
|
|
// various attributes, sizes, and shapes, and does all the work of
|
|
// grouping relating polygons and creating triangle strips, etc.,
|
|
// ultimately storing the resulting optimized geometry into one or
|
|
// more GeomNodes.
|
|
//
|
|
// It is intended that the builder should be the single entry point
|
|
// for all code wishing to create geometry in the scene graph. The
|
|
// builder can know about the kinds of geometry that are optimal for a
|
|
// particular platform, or even about the kinds of geometry that are
|
|
// available for a given platform. (For instance, perhaps on some
|
|
// bizarre platform, triangle strips do not exist, but quadstrips are
|
|
// really fast. User code should not create triangle strips
|
|
// directly.)
|
|
//
|
|
// Actually, there are two fairly separate pieces in this package.
|
|
// The first is the builder itself, which handles the interface to
|
|
// user code, and is responsible for collecting polygons from the
|
|
// caller, sorting them according to their attributes, and creating
|
|
// Geoms that represent the resulting geometry. The second piece is
|
|
// the mesher, which receives geometry from the builder and tries to
|
|
// create optimal triangle strips (or whichever kind of higher-level
|
|
// structure is most appropriate) from them, which it hands back to
|
|
// the builder.
|
|
//
|
|
// It is possible to use the builder without invoking the mesher, in
|
|
// which case the builder will create Geoms with the individual prims
|
|
// exactly as the user passed them in. It is not possible to use the
|
|
// mesher without first going through the builder.
|
|
//
|
|
//
|
|
// The general system of using the builder is as follows:
|
|
//
|
|
// (a) Create a Builder object.
|
|
//
|
|
// (b) Iterate through the polygons. For each polygon:
|
|
//
|
|
// (c) Create a BuilderBucket object and assign to it the
|
|
// scene-graph level attributes, such as texture, lighting,
|
|
// etc. for your polygon. If several polygons share the same
|
|
// attributes, they can of course use the same bucket. But
|
|
// there's no reason to be afraid of creating a new bucket
|
|
// object each time, if that's more convenient.
|
|
//
|
|
// (d) Create a BuilderPrim object to describe the polygon. If
|
|
// the polygon is to have a polygon color or polygon normal,
|
|
// set these on the BuilderPrim.
|
|
//
|
|
// (e) Iterate through the polygon vertices, in counterclockwise
|
|
// order when viewed from the front of the polygon. For each
|
|
// vertex:
|
|
//
|
|
// (f) Create a BuilderVertex object. If the vertex has a
|
|
// texture coordinate, normal, or color, set this on the
|
|
// BuilderVertex.
|
|
//
|
|
// (g) Add the BuilderVertex to the BuilderPrim.
|
|
//
|
|
// (h) Add the BuilderPrim to the Builder.
|
|
//
|
|
// (i) Call Builder::build() and receive your new geometry!
|
|
//
|
|
// All of these objects--BuilderBucket, BuilderPrim, and
|
|
// BuilderVertex--can, and probably should, be ordinary local
|
|
// variables. When they are added into their respective data
|
|
// structures they are copied, not referenced, so there's no need to
|
|
// try to keep them around after that.
|
|
//
|
|
// The BuilderBucket is the builder's system for grouping polygons
|
|
// that share similar characteristings. Polygons that were added to
|
|
// the builder with equivalent (though not necessarily identical)
|
|
// buckets may be candidates for joining together into triangle strips
|
|
// when possible.
|
|
//
|
|
//
|
|
// That's the basic operation. There are lots of fancy features on
|
|
// top of that.
|
|
//
|
|
// * Other kinds of geometry than polygons are supported. Presently,
|
|
// these are light points and line segments. To add these kinds of
|
|
// geometry, call set_type() on your BuilderPrim with either
|
|
// BPT_point or BPT_line.
|
|
//
|
|
// * Indexed geometry is supported as well as nonindexed. Indexed
|
|
// geometry means that the vertices, UV's, etc. are referenced
|
|
// indirectly; an index number into a table is stored instead of
|
|
// the actual coordinate values. Indexed geometry may be freely
|
|
// mixed in with nonindexed geometry; the builder will sort them
|
|
// out (although each polygon must be either entirely indexed or
|
|
// entirely nonindexed). To create indexed geometry, use a
|
|
// BuilderPrimI object, and assign to it a number of BuilderVertexI
|
|
// vertices. The coordinate values you will assign are ushort
|
|
// array index numbers. Store the array pointers these refer to in
|
|
// the BuilderBucket, via set_coords(), set_normals(), etc.
|
|
//
|
|
// * The builder is to a certain extent scene-graph aware. In the
|
|
// normal usage, you give it a bunch of polygons which are all
|
|
// lumped together, and when you call build() it allocates and
|
|
// returns a GeomNode which has all of your geometry in it.
|
|
// However, you can also ask it to distribute the geometry
|
|
// throughout a pre-existing scene graph. To do this, assign the
|
|
// _node pointer of your BuilderBucket to point to the node each
|
|
// polygon belongs under, as you create the polygons. Now when you
|
|
// call build(), the builder will create all the polygons under the
|
|
// nodes you indicated, creating new GeomNodes whenever necessary.
|
|
// The advantage to this method is that you don't have to process
|
|
// your polygons in scene-graph order; the builder can sort them
|
|
// out for you. Another advantage is it allows the builder to set
|
|
// up the state for you, see the next point:
|
|
//
|
|
// * It is only when you are taking advantage of the scene-graph
|
|
// awareness of the builder that the builder can assign the state
|
|
// transitions (like texturing, etc.) you specify to the geometry
|
|
// it builds. This is because the state transitions are stored on
|
|
// the arcs of the scene graph, and in non-scene graph mode there
|
|
// are no arcs!
|
|
//
|
|
// * You can fine-tune the mesher behavior via a number of parameters
|
|
// on the BuilderBucket. Look in builderProperties.h for these
|
|
// parameters (BuilderBucket inherits from BuilderProperties).
|
|
// This is also where you turn the mesher off if you don't want it.
|
|
//
|
|
// * You can set global properties on all buckets easily either by
|
|
// creating your own default BuilderBucket that you use to
|
|
// initialize each individual BuilderBucket you create, or by
|
|
// changing the parameters stored in the bucket pointed to by
|
|
// BuilderBucket::get_default_bucket(), which is what is used to
|
|
// initialize any BuilderBucket created with a default constructor.
|
|
// It is suggested that the get_default_bucket() pointer be used to
|
|
// define global defaults at applications start-up, while a local
|
|
// default BuilderBucket should be used for local defaults.
|
|
//
|
|
// * You can also control the binning behavior, if you have some
|
|
// particular user-specific parameters you want your geometry to be
|
|
// grouped on. To do this, subclass from BuilderBucket and
|
|
// redefine the comparison operator (it's a virtual function), as
|
|
// well as the make_copy() function.
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#include "pandabase.h"
|
|
|
|
#include "builderAttrib.h"
|
|
#include "builderBucketNode.h"
|
|
|
|
#include "pointerTo.h"
|
|
|
|
#include "pset.h"
|
|
|
|
|
|
class GeomNode;
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
// Class : Builder
|
|
// Description : The main driver class to the builder package. See
|
|
// the comments above.
|
|
////////////////////////////////////////////////////////////////////
|
|
class EXPCL_PANDAEGG Builder {
|
|
public:
|
|
Builder();
|
|
~Builder();
|
|
|
|
INLINE bool add_prim(const BuilderBucket &bucket,
|
|
const BuilderPrim &prim);
|
|
INLINE bool add_prim(const BuilderBucket &bucket,
|
|
const BuilderPrimI &prim);
|
|
INLINE bool add_prim_nonindexed(const BuilderBucket &bucket,
|
|
const BuilderPrimI &prim);
|
|
|
|
GeomNode *build(const string &default_name = "");
|
|
|
|
protected:
|
|
void add_bucket(const BuilderBucket &bucket);
|
|
|
|
typedef pset<BuilderBucketNode> Buckets;
|
|
|
|
Buckets _buckets;
|
|
Buckets::iterator _bi;
|
|
};
|
|
|
|
#include "builder.I"
|
|
|
|
#endif
|