|
@@ -0,0 +1,384 @@
|
|
|
|
|
+// Filename: eggToC.cxx
|
|
|
|
|
+// Created by: drose (03Aug01)
|
|
|
|
|
+//
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+//
|
|
|
|
|
+// 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
|
|
|
|
|
+// [email protected] .
|
|
|
|
|
+//
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+
|
|
|
|
|
+#include "eggToC.h"
|
|
|
|
|
+
|
|
|
|
|
+#include "eggVertexPool.h"
|
|
|
|
|
+#include "eggVertex.h"
|
|
|
|
|
+#include "eggPolygon.h"
|
|
|
|
|
+#include "eggPrimitive.h"
|
|
|
|
|
+#include "eggGroupNode.h"
|
|
|
|
|
+#include "eggPolysetMaker.h"
|
|
|
|
|
+#include "eggBin.h"
|
|
|
|
|
+#include "string_utils.h"
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: EggToC::Constructor
|
|
|
|
|
+// Access: Public
|
|
|
|
|
+// Description:
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+EggToC::
|
|
|
|
|
+EggToC() :
|
|
|
|
|
+ EggToSomething("C", ".c", true, true)
|
|
|
|
|
+{
|
|
|
|
|
+ set_program_description
|
|
|
|
|
+ ("This program reads Egg files and outputs code that will almost "
|
|
|
|
|
+ "compile as a C or C++ program. You get to define the data structures "
|
|
|
|
|
+ "for the program after the fact; the program only generates tables "
|
|
|
|
|
+ "of vertices and polygons.");
|
|
|
|
|
+
|
|
|
|
|
+ // -f is always in effect for egg2c. It doesn't make sense to
|
|
|
|
|
+ // provide it as an option to the user.
|
|
|
|
|
+ remove_option("f");
|
|
|
|
|
+
|
|
|
|
|
+ add_option
|
|
|
|
|
+ ("v", "", 0,
|
|
|
|
|
+ "Generate a table of vertex positions.",
|
|
|
|
|
+ &EggToC::dispatch_none, &_vertices);
|
|
|
|
|
+
|
|
|
|
|
+ add_option
|
|
|
|
|
+ ("u", "", 0,
|
|
|
|
|
+ "Generate a table of UV's per each vertex.",
|
|
|
|
|
+ &EggToC::dispatch_none, &_uvs);
|
|
|
|
|
+
|
|
|
|
|
+ add_option
|
|
|
|
|
+ ("vn", "", 0,
|
|
|
|
|
+ "Generate a table of normals per each vertex.",
|
|
|
|
|
+ &EggToC::dispatch_none, &_vertex_normals);
|
|
|
|
|
+
|
|
|
|
|
+ add_option
|
|
|
|
|
+ ("vc", "", 0,
|
|
|
|
|
+ "Generate a table of colors per each vertex.",
|
|
|
|
|
+ &EggToC::dispatch_none, &_vertex_colors);
|
|
|
|
|
+
|
|
|
|
|
+ add_option
|
|
|
|
|
+ ("pn", "", 0,
|
|
|
|
|
+ "Generate a table of normals per each polygon.",
|
|
|
|
|
+ &EggToC::dispatch_none, &_polygon_normals);
|
|
|
|
|
+
|
|
|
|
|
+ add_option
|
|
|
|
|
+ ("pc", "", 0,
|
|
|
|
|
+ "Generate a table of colors per each polygon.",
|
|
|
|
|
+ &EggToC::dispatch_none, &_polygon_colors);
|
|
|
|
|
+
|
|
|
|
|
+ add_option
|
|
|
|
|
+ ("p", "", 0,
|
|
|
|
|
+ "Generate a table of polygons that index into the above tables.",
|
|
|
|
|
+ &EggToC::dispatch_none, &_polygons);
|
|
|
|
|
+
|
|
|
|
|
+ add_option
|
|
|
|
|
+ ("t", "", 0,
|
|
|
|
|
+ "Output only triangles by subdividing higher-order polygons.",
|
|
|
|
|
+ &EggToC::dispatch_none, &_triangulate_polygons);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: EggToC::run
|
|
|
|
|
+// Access: Public
|
|
|
|
|
+// Description:
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void EggToC::
|
|
|
|
|
+run() {
|
|
|
|
|
+ nout << "Removing invalid primitives.\n";
|
|
|
|
|
+ int num_removed = _data.remove_invalid_primitives();
|
|
|
|
|
+ nout << " (" << num_removed << " removed.)\n";
|
|
|
|
|
+
|
|
|
|
|
+ if (_triangulate_polygons) {
|
|
|
|
|
+ nout << "Triangulating polygons.\n";
|
|
|
|
|
+ int num_produced = _data.triangulate_polygons(true);
|
|
|
|
|
+ nout << " (" << num_produced << " triangles produced.)\n";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ _data.apply_texmats();
|
|
|
|
|
+ _data.flatten_transforms();
|
|
|
|
|
+ _data.remove_unused_vertices();
|
|
|
|
|
+
|
|
|
|
|
+ // Collect all the polygons together into polysets.
|
|
|
|
|
+ EggPolysetMaker pmaker;
|
|
|
|
|
+ pmaker.set_properties(0);
|
|
|
|
|
+ pmaker.make_bins(&_data);
|
|
|
|
|
+
|
|
|
|
|
+ get_output()
|
|
|
|
|
+ << "/*\n"
|
|
|
|
|
+ << " * Generated by:\n"
|
|
|
|
|
+ << " * " << get_exec_command() << "\n"
|
|
|
|
|
+ << " *\n"
|
|
|
|
|
+ << " */\n\n";
|
|
|
|
|
+
|
|
|
|
|
+ _next_vpool_index = 0;
|
|
|
|
|
+ _next_bin_index = 0;
|
|
|
|
|
+ traverse(&_data);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: EggToC::traverse
|
|
|
|
|
+// Access: Public
|
|
|
|
|
+// Description:
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void EggToC::
|
|
|
|
|
+traverse(EggNode *node) {
|
|
|
|
|
+ if (node->is_of_type(EggVertexPool::get_class_type())) {
|
|
|
|
|
+ write_vertex_pool(DCAST(EggVertexPool, node));
|
|
|
|
|
+
|
|
|
|
|
+ } else if (node->is_of_type(EggBin::get_class_type())) {
|
|
|
|
|
+ write_bin(DCAST(EggBin, node));
|
|
|
|
|
+
|
|
|
|
|
+ } else if (node->is_of_type(EggGroupNode::get_class_type())) {
|
|
|
|
|
+ EggGroupNode *group = DCAST(EggGroupNode, node);
|
|
|
|
|
+
|
|
|
|
|
+ EggGroupNode::const_iterator ci;
|
|
|
|
|
+ for (ci = group->begin(); ci != group->end(); ++ci) {
|
|
|
|
|
+ traverse(*ci);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: EggToC::write_vertex_pool
|
|
|
|
|
+// Access: Public
|
|
|
|
|
+// Description:
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void EggToC::
|
|
|
|
|
+write_vertex_pool(EggVertexPool *vpool) {
|
|
|
|
|
+ int highest_index = vpool->get_highest_index();
|
|
|
|
|
+ int i;
|
|
|
|
|
+
|
|
|
|
|
+ ostream &out = get_output();
|
|
|
|
|
+ out << "/* Vertex pool index " << _next_vpool_index
|
|
|
|
|
+ << ": " << vpool->get_name() << " */\n";
|
|
|
|
|
+ _vertex_pools[vpool] = _next_vpool_index;
|
|
|
|
|
+ _next_vpool_index++;
|
|
|
|
|
+
|
|
|
|
|
+ if (_vertices) {
|
|
|
|
|
+ out << "/* Vertex definition for " << vpool->get_name() << " */\n"
|
|
|
|
|
+ << "vertex vertices_" << vpool->get_name() << "[" << highest_index
|
|
|
|
|
+ << "] = {\n";
|
|
|
|
|
+ for (i = 0; i < highest_index; i++) {
|
|
|
|
|
+ EggVertex *vert = vpool->get_vertex(i);
|
|
|
|
|
+ if (vert == (EggVertex *)NULL) {
|
|
|
|
|
+ out << " vertex(), /* " << i << " */\n";
|
|
|
|
|
+ } else {
|
|
|
|
|
+ LPoint4d p = vert->get_pos4();
|
|
|
|
|
+ switch (vert->get_num_dimensions()) {
|
|
|
|
|
+ case 1:
|
|
|
|
|
+ out << " vertex(" << p[0] << "), /* " << i << " */\n";
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ case 2:
|
|
|
|
|
+ out << " vertex(" << p[0] << ", " << p[1]
|
|
|
|
|
+ << "), /* " << i << " */\n";
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ case 3:
|
|
|
|
|
+ out << " vertex(" << p[0] << ", " << p[1] << ", " << p[2]
|
|
|
|
|
+ << "), /* " << i << " */\n";
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ case 4:
|
|
|
|
|
+ out << " vertex(" << p[0] << ", " << p[1] << ", " << p[2]
|
|
|
|
|
+ << ", " << p[3] << "), /* " << i << " */\n";
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ default:
|
|
|
|
|
+ out << " vertex(), /* error */\n";
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ out << "};\n\n";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (_uvs) {
|
|
|
|
|
+ out << "/* UV's for " << vpool->get_name() << " */\n"
|
|
|
|
|
+ << "uv uvs_" << vpool->get_name() << "[" << highest_index
|
|
|
|
|
+ << "] = {\n";
|
|
|
|
|
+ for (i = 0; i < highest_index; i++) {
|
|
|
|
|
+ EggVertex *vert = vpool->get_vertex(i);
|
|
|
|
|
+ if (vert == (EggVertex *)NULL || !vert->has_uv()) {
|
|
|
|
|
+ out << " uv(), /* " << i << " */\n";
|
|
|
|
|
+ } else {
|
|
|
|
|
+ TexCoordd uv = vert->get_uv();
|
|
|
|
|
+ out << " uv(" << uv[0] << ", " << uv[1]
|
|
|
|
|
+ << "), /* " << i << " */\n";
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ out << "};\n\n";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (_vertex_normals) {
|
|
|
|
|
+ out << "/* Vertex normals for " << vpool->get_name() << " */\n"
|
|
|
|
|
+ << "normal normals_" << vpool->get_name() << "[" << highest_index
|
|
|
|
|
+ << "] = {\n";
|
|
|
|
|
+ for (i = 0; i < highest_index; i++) {
|
|
|
|
|
+ EggVertex *vert = vpool->get_vertex(i);
|
|
|
|
|
+ if (vert == (EggVertex *)NULL || !vert->has_normal()) {
|
|
|
|
|
+ out << " normal(), /* " << i << " */\n";
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Normald n = vert->get_normal();
|
|
|
|
|
+ out << " normal(" << n[0] << ", " << n[1] << ", " << n[2]
|
|
|
|
|
+ << "), /* " << i << " */\n";
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ out << "};\n\n";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (_vertex_colors) {
|
|
|
|
|
+ out << "/* Vertex colors for " << vpool->get_name() << " */\n"
|
|
|
|
|
+ << "color colors_" << vpool->get_name() << "[" << highest_index
|
|
|
|
|
+ << "] = {\n";
|
|
|
|
|
+ for (i = 0; i < highest_index; i++) {
|
|
|
|
|
+ EggVertex *vert = vpool->get_vertex(i);
|
|
|
|
|
+ if (vert == (EggVertex *)NULL || !vert->has_color()) {
|
|
|
|
|
+ out << " color(), /* " << i << " */\n";
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Colorf c = vert->get_color();
|
|
|
|
|
+ out << " color(" << c[0] << ", " << c[1] << ", " << c[2]
|
|
|
|
|
+ << ", " << c[3] << "), /* " << i << " */\n";
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ out << "};\n\n";
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: EggToC::write_bin
|
|
|
|
|
+// Access: Public
|
|
|
|
|
+// Description:
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void EggToC::
|
|
|
|
|
+write_bin(EggBin *bin) {
|
|
|
|
|
+ ostream &out = get_output();
|
|
|
|
|
+ string bin_name = bin->get_name();
|
|
|
|
|
+ if (bin_name.empty()) {
|
|
|
|
|
+ bin_name = format_string(_next_bin_index);
|
|
|
|
|
+ _next_bin_index++;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ out << "/* Polygon group " << bin_name << " */\n";
|
|
|
|
|
+
|
|
|
|
|
+ size_t num_children = bin->size();
|
|
|
|
|
+
|
|
|
|
|
+ if (_polygons) {
|
|
|
|
|
+ out << "/* Polygon definitions for " << bin_name << " */\n";
|
|
|
|
|
+ string prim_type = "polygon";
|
|
|
|
|
+ if (_triangulate_polygons) {
|
|
|
|
|
+ prim_type = "triangle";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ out << prim_type << " polys_" << bin_name << "[" << num_children
|
|
|
|
|
+ << "] = {\n";
|
|
|
|
|
+
|
|
|
|
|
+ if (_triangulate_polygons) {
|
|
|
|
|
+ out << " /* vpool index, vertex0, vertex1, vertex2 */\n";
|
|
|
|
|
+ } else {
|
|
|
|
|
+ out << " /* vpool index, num vertices, vertex0, vertex1, vertex2, ... */\n";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ EggGroupNode::const_iterator ci;
|
|
|
|
|
+ size_t prim_index = 0;
|
|
|
|
|
+ for (ci = bin->begin(); ci != bin->end(); ++ci) {
|
|
|
|
|
+ EggNode *child = (*ci);
|
|
|
|
|
+ if (!child->is_of_type(EggPrimitive::get_class_type())) {
|
|
|
|
|
+ out << " " << prim_type << "(), /* error */\n";
|
|
|
|
|
+ } else {
|
|
|
|
|
+ EggPrimitive *prim = DCAST(EggPrimitive, child);
|
|
|
|
|
+ EggVertexPool *vpool = prim->get_pool();
|
|
|
|
|
+ int vpool_index = -1;
|
|
|
|
|
+ VertexPools::const_iterator pi = _vertex_pools.find(vpool);
|
|
|
|
|
+ if (pi != _vertex_pools.end()) {
|
|
|
|
|
+ vpool_index = (*pi).second;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ out << " " << prim_type << "(" << vpool_index;
|
|
|
|
|
+ if (!_triangulate_polygons) {
|
|
|
|
|
+ out << ", " << prim->size();
|
|
|
|
|
+ }
|
|
|
|
|
+ EggPrimitive::const_iterator vi;
|
|
|
|
|
+ for (vi = prim->begin(); vi != prim->end(); ++vi) {
|
|
|
|
|
+ EggVertex *vert = (*vi);
|
|
|
|
|
+ out << ", " << vert->get_index();
|
|
|
|
|
+ }
|
|
|
|
|
+ out << "), /* " << prim_index << " */\n";
|
|
|
|
|
+ prim_index++;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ out << "};\n\n";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (_polygon_normals) {
|
|
|
|
|
+ ostream &out = get_output();
|
|
|
|
|
+ out << "/* Polygon normals for " << bin_name << " */\n";
|
|
|
|
|
+ out << "normal polys_" << bin_name << "[" << num_children
|
|
|
|
|
+ << "] = {\n";
|
|
|
|
|
+
|
|
|
|
|
+ EggGroupNode::const_iterator ci;
|
|
|
|
|
+ size_t prim_index = 0;
|
|
|
|
|
+ for (ci = bin->begin(); ci != bin->end(); ++ci) {
|
|
|
|
|
+ EggNode *child = (*ci);
|
|
|
|
|
+ if (!child->is_of_type(EggPrimitive::get_class_type())) {
|
|
|
|
|
+ out << " normal(), /* error */\n";
|
|
|
|
|
+ } else {
|
|
|
|
|
+ EggPrimitive *prim = DCAST(EggPrimitive, child);
|
|
|
|
|
+ if (!prim->has_normal()) {
|
|
|
|
|
+ out << " normal(), /* " << prim_index << " */\n";
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Normald n = prim->get_normal();
|
|
|
|
|
+ out << " normal(" << n[0] << ", " << n[1] << ", " << n[2]
|
|
|
|
|
+ << "), /* " << prim_index << " */\n";
|
|
|
|
|
+ }
|
|
|
|
|
+ prim_index++;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ out << "};\n\n";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (_polygon_colors) {
|
|
|
|
|
+ ostream &out = get_output();
|
|
|
|
|
+ out << "/* Polygon colors for " << bin_name << " */\n";
|
|
|
|
|
+ out << "color polys_" << bin_name << "[" << num_children
|
|
|
|
|
+ << "] = {\n";
|
|
|
|
|
+
|
|
|
|
|
+ EggGroupNode::const_iterator ci;
|
|
|
|
|
+ size_t prim_index = 0;
|
|
|
|
|
+ for (ci = bin->begin(); ci != bin->end(); ++ci) {
|
|
|
|
|
+ EggNode *child = (*ci);
|
|
|
|
|
+ if (!child->is_of_type(EggPrimitive::get_class_type())) {
|
|
|
|
|
+ out << " color(), /* error */\n";
|
|
|
|
|
+ } else {
|
|
|
|
|
+ EggPrimitive *prim = DCAST(EggPrimitive, child);
|
|
|
|
|
+ if (!prim->has_color()) {
|
|
|
|
|
+ out << " color(), /* " << prim_index << " */\n";
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Colorf c = prim->get_color();
|
|
|
|
|
+ out << " color(" << c[0] << ", " << c[1] << ", " << c[2]
|
|
|
|
|
+ << ", " << c[3] << "), /* " << prim_index << " */\n";
|
|
|
|
|
+ }
|
|
|
|
|
+ prim_index++;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ out << "};\n\n";
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+int main(int argc, char *argv[]) {
|
|
|
|
|
+ EggToC prog;
|
|
|
|
|
+ prog.parse_command_line(argc, argv);
|
|
|
|
|
+ prog.run();
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|