00001 // Filename: builder.h 00002 // Created by: drose (09Sep97) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved 00008 // 00009 // All use of this software is subject to the terms of the Panda 3d 00010 // Software license. You should have received a copy of this license 00011 // along with this source code; you will also find a current copy of 00012 // the license at http://www.panda3d.org/license.txt . 00013 // 00014 // To contact the maintainers of this program write to 00015 // panda3d@yahoogroups.com . 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 #ifndef BUILDER_H 00020 #define BUILDER_H 00021 00022 //////////////////////////////////////////////////////////////////// 00023 // 00024 // Builder 00025 // 00026 // The builder accepts as input a loose collection of polygons with 00027 // various attributes, sizes, and shapes, and does all the work of 00028 // grouping relating polygons and creating triangle strips, etc., 00029 // ultimately storing the resulting optimized geometry into one or 00030 // more GeomNodes. 00031 // 00032 // It is intended that the builder should be the single entry point 00033 // for all code wishing to create geometry in the scene graph. The 00034 // builder can know about the kinds of geometry that are optimal for a 00035 // particular platform, or even about the kinds of geometry that are 00036 // available for a given platform. (For instance, perhaps on some 00037 // bizarre platform, triangle strips do not exist, but quadstrips are 00038 // really fast. User code should not create triangle strips 00039 // directly.) 00040 // 00041 // Actually, there are two fairly separate pieces in this package. 00042 // The first is the builder itself, which handles the interface to 00043 // user code, and is responsible for collecting polygons from the 00044 // caller, sorting them according to their attributes, and creating 00045 // Geoms that represent the resulting geometry. The second piece is 00046 // the mesher, which receives geometry from the builder and tries to 00047 // create optimal triangle strips (or whichever kind of higher-level 00048 // structure is most appropriate) from them, which it hands back to 00049 // the builder. 00050 // 00051 // It is possible to use the builder without invoking the mesher, in 00052 // which case the builder will create Geoms with the individual prims 00053 // exactly as the user passed them in. It is not possible to use the 00054 // mesher without first going through the builder. 00055 // 00056 // 00057 // The general system of using the builder is as follows: 00058 // 00059 // (a) Create a Builder object. 00060 // 00061 // (b) Iterate through the polygons. For each polygon: 00062 // 00063 // (c) Create a BuilderBucket object and assign to it the 00064 // scene-graph level attributes, such as texture, lighting, 00065 // etc. for your polygon. If several polygons share the same 00066 // attributes, they can of course use the same bucket. But 00067 // there's no reason to be afraid of creating a new bucket 00068 // object each time, if that's more convenient. 00069 // 00070 // (d) Create a BuilderPrim object to describe the polygon. If 00071 // the polygon is to have a polygon color or polygon normal, 00072 // set these on the BuilderPrim. 00073 // 00074 // (e) Iterate through the polygon vertices, in counterclockwise 00075 // order when viewed from the front of the polygon. For each 00076 // vertex: 00077 // 00078 // (f) Create a BuilderVertex object. If the vertex has a 00079 // texture coordinate, normal, or color, set this on the 00080 // BuilderVertex. 00081 // 00082 // (g) Add the BuilderVertex to the BuilderPrim. 00083 // 00084 // (h) Add the BuilderPrim to the Builder. 00085 // 00086 // (i) Call Builder::build() and receive your new geometry! 00087 // 00088 // All of these objects--BuilderBucket, BuilderPrim, and 00089 // BuilderVertex--can, and probably should, be ordinary local 00090 // variables. When they are added into their respective data 00091 // structures they are copied, not referenced, so there's no need to 00092 // try to keep them around after that. 00093 // 00094 // The BuilderBucket is the builder's system for grouping polygons 00095 // that share similar characteristings. Polygons that were added to 00096 // the builder with equivalent (though not necessarily identical) 00097 // buckets may be candidates for joining together into triangle strips 00098 // when possible. 00099 // 00100 // 00101 // That's the basic operation. There are lots of fancy features on 00102 // top of that. 00103 // 00104 // * Other kinds of geometry than polygons are supported. Presently, 00105 // these are light points and line segments. To add these kinds of 00106 // geometry, call set_type() on your BuilderPrim with either 00107 // BPT_point or BPT_line. 00108 // 00109 // * Indexed geometry is supported as well as nonindexed. Indexed 00110 // geometry means that the vertices, UV's, etc. are referenced 00111 // indirectly; an index number into a table is stored instead of 00112 // the actual coordinate values. Indexed geometry may be freely 00113 // mixed in with nonindexed geometry; the builder will sort them 00114 // out (although each polygon must be either entirely indexed or 00115 // entirely nonindexed). To create indexed geometry, use a 00116 // BuilderPrimI object, and assign to it a number of BuilderVertexI 00117 // vertices. The coordinate values you will assign are ushort 00118 // array index numbers. Store the array pointers these refer to in 00119 // the BuilderBucket, via set_coords(), set_normals(), etc. 00120 // 00121 // * The builder is to a certain extent scene-graph aware. In the 00122 // normal usage, you give it a bunch of polygons which are all 00123 // lumped together, and when you call build() it allocates and 00124 // returns a GeomNode which has all of your geometry in it. 00125 // However, you can also ask it to distribute the geometry 00126 // throughout a pre-existing scene graph. To do this, assign the 00127 // _node pointer of your BuilderBucket to point to the node each 00128 // polygon belongs under, as you create the polygons. Now when you 00129 // call build(), the builder will create all the polygons under the 00130 // nodes you indicated, creating new GeomNodes whenever necessary. 00131 // The advantage to this method is that you don't have to process 00132 // your polygons in scene-graph order; the builder can sort them 00133 // out for you. Another advantage is it allows the builder to set 00134 // up the state for you, see the next point: 00135 // 00136 // * It is only when you are taking advantage of the scene-graph 00137 // awareness of the builder that the builder can assign the state 00138 // transitions (like texturing, etc.) you specify to the geometry 00139 // it builds. This is because the state transitions are stored on 00140 // the arcs of the scene graph, and in non-scene graph mode there 00141 // are no arcs! 00142 // 00143 // * You can fine-tune the mesher behavior via a number of parameters 00144 // on the BuilderBucket. Look in builderProperties.h for these 00145 // parameters (BuilderBucket inherits from BuilderProperties). 00146 // This is also where you turn the mesher off if you don't want it. 00147 // 00148 // * You can set global properties on all buckets easily either by 00149 // creating your own default BuilderBucket that you use to 00150 // initialize each individual BuilderBucket you create, or by 00151 // changing the parameters stored in the bucket pointed to by 00152 // BuilderBucket::get_default_bucket(), which is what is used to 00153 // initialize any BuilderBucket created with a default constructor. 00154 // It is suggested that the get_default_bucket() pointer be used to 00155 // define global defaults at applications start-up, while a local 00156 // default BuilderBucket should be used for local defaults. 00157 // 00158 // * You can also control the binning behavior, if you have some 00159 // particular user-specific parameters you want your geometry to be 00160 // grouped on. To do this, subclass from BuilderBucket and 00161 // redefine the comparison operator (it's a virtual function), as 00162 // well as the make_copy() function. 00163 // 00164 //////////////////////////////////////////////////////////////////// 00165 00166 00167 00168 #include <pandabase.h> 00169 00170 #include "builderAttrib.h" 00171 #include "builderBucketNode.h" 00172 00173 #include <pointerTo.h> 00174 00175 #include "pset.h" 00176 00177 00178 class GeomNode; 00179 00180 00181 /////////////////////////////////////////////////////////////////// 00182 // Class : Builder 00183 // Description : The main driver class to the builder package. See 00184 // the comments above. 00185 //////////////////////////////////////////////////////////////////// 00186 class EXPCL_PANDAEGG Builder { 00187 public: 00188 Builder(); 00189 ~Builder(); 00190 00191 INLINE bool add_prim(const BuilderBucket &bucket, 00192 const BuilderPrim &prim); 00193 INLINE bool add_prim(const BuilderBucket &bucket, 00194 const BuilderPrimI &prim); 00195 INLINE bool add_prim_nonindexed(const BuilderBucket &bucket, 00196 const BuilderPrimI &prim); 00197 00198 GeomNode *build(const string &default_name = ""); 00199 00200 protected: 00201 void add_bucket(const BuilderBucket &bucket); 00202 00203 typedef pset<BuilderBucketNode> Buckets; 00204 00205 Buckets _buckets; 00206 Buckets::iterator _bi; 00207 }; 00208 00209 #include "builder.I" 00210 00211 #endif