00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "eggToC.h"
00020
00021 #include "eggVertexPool.h"
00022 #include "eggVertex.h"
00023 #include "eggPolygon.h"
00024 #include "eggPrimitive.h"
00025 #include "eggGroupNode.h"
00026 #include "eggPolysetMaker.h"
00027 #include "eggBin.h"
00028 #include "string_utils.h"
00029
00030
00031
00032
00033
00034
00035 EggToC::
00036 EggToC() :
00037 EggToSomething("C", ".c", true, true)
00038 {
00039 set_program_description
00040 ("This program reads Egg files and outputs code that will almost "
00041 "compile as a C or C++ program. You get to define the data structures "
00042 "for the program after the fact; the program only generates tables "
00043 "of vertices and polygons.");
00044
00045
00046
00047 remove_option("f");
00048
00049 add_option
00050 ("v", "", 0,
00051 "Generate a table of vertex positions.",
00052 &EggToC::dispatch_none, &_vertices);
00053
00054 add_option
00055 ("u", "", 0,
00056 "Generate a table of UV's per each vertex.",
00057 &EggToC::dispatch_none, &_uvs);
00058
00059 add_option
00060 ("vn", "", 0,
00061 "Generate a table of normals per each vertex.",
00062 &EggToC::dispatch_none, &_vertex_normals);
00063
00064 add_option
00065 ("vc", "", 0,
00066 "Generate a table of colors per each vertex.",
00067 &EggToC::dispatch_none, &_vertex_colors);
00068
00069 add_option
00070 ("p", "", 0,
00071 "Generate a table of polygons that index into the above tables.",
00072 &EggToC::dispatch_none, &_polygons);
00073
00074 add_option
00075 ("pn", "", 0,
00076 "Generate a table of normals per each polygon.",
00077 &EggToC::dispatch_none, &_polygon_normals);
00078
00079 add_option
00080 ("pc", "", 0,
00081 "Generate a table of colors per each polygon.",
00082 &EggToC::dispatch_none, &_polygon_colors);
00083
00084 add_option
00085 ("t", "", 0,
00086 "Output only triangles by subdividing higher-order polygons.",
00087 &EggToC::dispatch_none, &_triangulate_polygons);
00088 }
00089
00090
00091
00092
00093
00094
00095 void EggToC::
00096 run() {
00097 nout << "Removing invalid primitives.\n";
00098 int num_removed = _data.remove_invalid_primitives();
00099 nout << " (" << num_removed << " removed.)\n";
00100
00101 if (_triangulate_polygons) {
00102 nout << "Triangulating polygons.\n";
00103 int num_produced = _data.triangulate_polygons(true);
00104 nout << " (" << num_produced << " triangles produced.)\n";
00105 }
00106
00107 _data.apply_texmats();
00108 _data.flatten_transforms();
00109 _data.remove_unused_vertices();
00110
00111
00112 EggPolysetMaker pmaker;
00113 pmaker.set_properties(0);
00114 pmaker.make_bins(&_data);
00115
00116 get_output()
00117 << "/*\n"
00118 << " * Generated by:\n"
00119 << " * " << get_exec_command() << "\n"
00120 << " *\n"
00121 << " */\n\n";
00122
00123 _next_vpool_index = 0;
00124 _next_bin_index = 0;
00125 traverse(&_data);
00126 }
00127
00128
00129
00130
00131
00132
00133 void EggToC::
00134 traverse(EggNode *node) {
00135 if (node->is_of_type(EggVertexPool::get_class_type())) {
00136 write_vertex_pool(DCAST(EggVertexPool, node));
00137
00138 } else if (node->is_of_type(EggBin::get_class_type())) {
00139 write_bin(DCAST(EggBin, node));
00140
00141 } else if (node->is_of_type(EggGroupNode::get_class_type())) {
00142 EggGroupNode *group = DCAST(EggGroupNode, node);
00143
00144 EggGroupNode::const_iterator ci;
00145 for (ci = group->begin(); ci != group->end(); ++ci) {
00146 traverse(*ci);
00147 }
00148 }
00149 }
00150
00151
00152
00153
00154
00155
00156 void EggToC::
00157 write_vertex_pool(EggVertexPool *vpool) {
00158 int highest_index = vpool->get_highest_index();
00159 int i;
00160
00161 ostream &out = get_output();
00162 out << "/* Vertex pool index " << _next_vpool_index
00163 << ": " << vpool->get_name() << " */\n";
00164 _vertex_pools[vpool] = _next_vpool_index;
00165 _next_vpool_index++;
00166
00167 if (_vertices) {
00168 out << "/* Vertex definition for " << vpool->get_name() << " */\n"
00169 << "vertex vertices_" << vpool->get_name() << "[" << highest_index
00170 << "] = {\n";
00171 for (i = 0; i < highest_index; i++) {
00172 EggVertex *vert = vpool->get_vertex(i);
00173 if (vert == (EggVertex *)NULL) {
00174 out << " vertex(), /* " << i << " */\n";
00175 } else {
00176 LPoint4d p = vert->get_pos4();
00177 switch (vert->get_num_dimensions()) {
00178 case 1:
00179 out << " vertex(" << p[0] << "), /* " << i << " */\n";
00180 break;
00181
00182 case 2:
00183 out << " vertex(" << p[0] << ", " << p[1]
00184 << "), /* " << i << " */\n";
00185 break;
00186
00187 case 3:
00188 out << " vertex(" << p[0] << ", " << p[1] << ", " << p[2]
00189 << "), /* " << i << " */\n";
00190 break;
00191
00192 case 4:
00193 out << " vertex(" << p[0] << ", " << p[1] << ", " << p[2]
00194 << ", " << p[3] << "), /* " << i << " */\n";
00195 break;
00196
00197 default:
00198 out << " vertex(), /* error */\n";
00199 }
00200 }
00201 }
00202 out << "};\n\n";
00203 }
00204
00205 if (_uvs) {
00206 out << "/* UV's for " << vpool->get_name() << " */\n"
00207 << "uv uvs_" << vpool->get_name() << "[" << highest_index
00208 << "] = {\n";
00209 for (i = 0; i < highest_index; i++) {
00210 EggVertex *vert = vpool->get_vertex(i);
00211 if (vert == (EggVertex *)NULL || !vert->has_uv()) {
00212 out << " uv(), /* " << i << " */\n";
00213 } else {
00214 TexCoordd uv = vert->get_uv();
00215 out << " uv(" << uv[0] << ", " << uv[1]
00216 << "), /* " << i << " */\n";
00217 }
00218 }
00219 out << "};\n\n";
00220 }
00221
00222 if (_vertex_normals) {
00223 out << "/* Vertex normals for " << vpool->get_name() << " */\n"
00224 << "normal normals_" << vpool->get_name() << "[" << highest_index
00225 << "] = {\n";
00226 for (i = 0; i < highest_index; i++) {
00227 EggVertex *vert = vpool->get_vertex(i);
00228 if (vert == (EggVertex *)NULL || !vert->has_normal()) {
00229 out << " normal(), /* " << i << " */\n";
00230 } else {
00231 Normald n = vert->get_normal();
00232 out << " normal(" << n[0] << ", " << n[1] << ", " << n[2]
00233 << "), /* " << i << " */\n";
00234 }
00235 }
00236 out << "};\n\n";
00237 }
00238
00239 if (_vertex_colors) {
00240 out << "/* Vertex colors for " << vpool->get_name() << " */\n"
00241 << "color colors_" << vpool->get_name() << "[" << highest_index
00242 << "] = {\n";
00243 for (i = 0; i < highest_index; i++) {
00244 EggVertex *vert = vpool->get_vertex(i);
00245 if (vert == (EggVertex *)NULL || !vert->has_color()) {
00246 out << " color(), /* " << i << " */\n";
00247 } else {
00248 Colorf c = vert->get_color();
00249 out << " color(" << c[0] << ", " << c[1] << ", " << c[2]
00250 << ", " << c[3] << "), /* " << i << " */\n";
00251 }
00252 }
00253 out << "};\n\n";
00254 }
00255 }
00256
00257
00258
00259
00260
00261
00262
00263 void EggToC::
00264 write_bin(EggBin *bin) {
00265 ostream &out = get_output();
00266 string bin_name = bin->get_name();
00267 if (bin_name.empty()) {
00268 bin_name = format_string(_next_bin_index);
00269 _next_bin_index++;
00270 }
00271
00272 out << "/* Polygon group " << bin_name << " */\n";
00273
00274 size_t num_children = bin->size();
00275
00276 if (_polygons) {
00277 out << "/* Polygon definitions for " << bin_name << " */\n";
00278 string prim_type = "polygon";
00279 if (_triangulate_polygons) {
00280 prim_type = "triangle";
00281 }
00282
00283 out << prim_type << " polys_" << bin_name << "[" << num_children
00284 << "] = {\n";
00285
00286 if (_triangulate_polygons) {
00287 out << " /* vpool index, vertex0, vertex1, vertex2 */\n";
00288 } else {
00289 out << " /* vpool index, num vertices, vertex0, vertex1, vertex2, ... */\n";
00290 }
00291
00292 EggGroupNode::const_iterator ci;
00293 size_t prim_index = 0;
00294 for (ci = bin->begin(); ci != bin->end(); ++ci) {
00295 EggNode *child = (*ci);
00296 if (!child->is_of_type(EggPrimitive::get_class_type())) {
00297 out << " " << prim_type << "(), /* error */\n";
00298 } else {
00299 EggPrimitive *prim = DCAST(EggPrimitive, child);
00300 EggVertexPool *vpool = prim->get_pool();
00301 int vpool_index = -1;
00302 VertexPools::const_iterator pi = _vertex_pools.find(vpool);
00303 if (pi != _vertex_pools.end()) {
00304 vpool_index = (*pi).second;
00305 }
00306
00307 out << " " << prim_type << "(" << vpool_index;
00308 if (!_triangulate_polygons) {
00309 out << ", " << prim->size();
00310 }
00311 EggPrimitive::const_iterator vi;
00312 for (vi = prim->begin(); vi != prim->end(); ++vi) {
00313 EggVertex *vert = (*vi);
00314 out << ", " << vert->get_index();
00315 }
00316 out << "), /* " << prim_index << " */\n";
00317 prim_index++;
00318 }
00319 }
00320 out << "};\n\n";
00321 }
00322
00323 if (_polygon_normals) {
00324 ostream &out = get_output();
00325 out << "/* Polygon normals for " << bin_name << " */\n";
00326 out << "normal polys_" << bin_name << "[" << num_children
00327 << "] = {\n";
00328
00329 EggGroupNode::const_iterator ci;
00330 size_t prim_index = 0;
00331 for (ci = bin->begin(); ci != bin->end(); ++ci) {
00332 EggNode *child = (*ci);
00333 if (!child->is_of_type(EggPrimitive::get_class_type())) {
00334 out << " normal(), /* error */\n";
00335 } else {
00336 EggPrimitive *prim = DCAST(EggPrimitive, child);
00337 if (!prim->has_normal()) {
00338 out << " normal(), /* " << prim_index << " */\n";
00339 } else {
00340 Normald n = prim->get_normal();
00341 out << " normal(" << n[0] << ", " << n[1] << ", " << n[2]
00342 << "), /* " << prim_index << " */\n";
00343 }
00344 prim_index++;
00345 }
00346 }
00347 out << "};\n\n";
00348 }
00349
00350 if (_polygon_colors) {
00351 ostream &out = get_output();
00352 out << "/* Polygon colors for " << bin_name << " */\n";
00353 out << "color polys_" << bin_name << "[" << num_children
00354 << "] = {\n";
00355
00356 EggGroupNode::const_iterator ci;
00357 size_t prim_index = 0;
00358 for (ci = bin->begin(); ci != bin->end(); ++ci) {
00359 EggNode *child = (*ci);
00360 if (!child->is_of_type(EggPrimitive::get_class_type())) {
00361 out << " color(), /* error */\n";
00362 } else {
00363 EggPrimitive *prim = DCAST(EggPrimitive, child);
00364 if (!prim->has_color()) {
00365 out << " color(), /* " << prim_index << " */\n";
00366 } else {
00367 Colorf c = prim->get_color();
00368 out << " color(" << c[0] << ", " << c[1] << ", " << c[2]
00369 << ", " << c[3] << "), /* " << prim_index << " */\n";
00370 }
00371 prim_index++;
00372 }
00373 }
00374 out << "};\n\n";
00375 }
00376 }
00377
00378
00379 int main(int argc, char *argv[]) {
00380 EggToC prog;
00381 prog.parse_command_line(argc, argv);
00382 prog.run();
00383 return 0;
00384 }