Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

pandatool/src/eggprogs/eggToC.cxx

Go to the documentation of this file.
00001 // Filename: eggToC.cxx
00002 // Created by:  drose (03Aug01)
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 #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 //     Function: EggToC::Constructor
00032 //       Access: Public
00033 //  Description:
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   // -f is always in effect for egg2c.  It doesn't make sense to
00046   // provide it as an option to the user.
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 //     Function: EggToC::run
00092 //       Access: Public
00093 //  Description:
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   // Collect all the polygons together into polysets.
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 //     Function: EggToC::traverse
00130 //       Access: Public
00131 //  Description:
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 //     Function: EggToC::write_vertex_pool
00153 //       Access: Public
00154 //  Description:
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 //     Function: EggToC::write_bin
00260 //       Access: Public
00261 //  Description:
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 }

Generated on Fri May 2 03:18:53 2003 for Panda-Tool by doxygen1.3