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