aesop-client/tool/physicsFromModel/main.cpp

Go to the documentation of this file.
00001 /*
00002  * main.cpp
00003  *
00004  * Copyright (C) 2009  Thomas A. Vaughan
00005  * All rights reserved.
00006  *
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *     * Redistributions of source code must retain the above copyright
00011  *       notice, this list of conditions and the following disclaimer.
00012  *     * Redistributions in binary form must reproduce the above copyright
00013  *       notice, this list of conditions and the following disclaimer in the
00014  *       documentation and/or other materials provided with the distribution.
00015  *     * Neither the name of the <organization> nor the
00016  *       names of its contributors may be used to endorse or promote products
00017  *       derived from this software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THOMAS A. VAUGHAN ''AS IS'' AND ANY
00020  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00021  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00022  * DISCLAIMED. IN NO EVENT SHALL THOMAS A. VAUGHAN BE LIABLE FOR ANY
00023  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00024  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00025  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00026  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00027  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  *
00030  *
00031  * Program that creates triangle meshes from glut-models.  Mostly used for
00032  * physics models.
00033  */
00034 
00035 // includes --------------------------------------------------------------------
00036 #include <fstream>
00037 #include <iostream>
00038 
00039 #include "common/wave_ex.h"
00040 #include "glut-model/glut-model.h"
00041 #include "perf/perf.h"
00042 #include "util/token_stream.h"
00043 
00044 
00045 ////////////////////////////////////////////////////////////////////////////////
00046 ///
00047 /// \ingroup aesop_tool
00048 /// \defgroup tool_physics_from_model AESOP Tool: physicsFromModel
00049 ///
00050 /// \n
00051 /// The physicsFromModel utility lets storytellers create physics models from
00052 /// 3D models.  Right now, the tool only supports mapping from a \ref glut_model
00053 /// to a triangle mesh shape (see \ref aesop_physics).  However, that is also
00054 /// the most general case and is expected to be the most useful.
00055 ////////////////////////////////////////////////////////////////////////////////
00056 
00057 // statics and typedefs --------------------------------------------------------
00058 
00059 class DummyRegistry : public glut::MaterialRegistry {
00060 public:
00061         DummyRegistry(void) {
00062                         m_material = new glut::material_t;
00063                         ASSERT(m_material, "out of memory");
00064                 }
00065 
00066         ~DummyRegistry(void) throw() { }
00067 
00068         virtual smart_ptr<glut::material_t> getMaterial(IN const char * id) {
00069                         ASSERT(id, "null");
00070                         DPRINTF("Ignoring request to load material '%s'", id);
00071                         return m_material;
00072                 }
00073 
00074 private:
00075         smart_ptr<glut::material_t>     m_material;
00076 };
00077 
00078 
00079 
00080 struct triangle_t {
00081         int     index[3];               // 3 vertex indices per triangle
00082 };
00083 
00084 typedef std::vector<triangle_t> vec_triangle_t;
00085 
00086 
00087 
00088 ////////////////////////////////////////////////////////////////////////////////
00089 //
00090 //      static helper methods
00091 //
00092 ////////////////////////////////////////////////////////////////////////////////
00093 
00094 static void
00095 writeVertices
00096 (
00097 IO std::ostream& stream,
00098 IN const glut::model_t& model
00099 )
00100 {
00101         stream << "# vertex count and listing\n";
00102         stream << "nVertices " << model.nVertices << "\n";
00103         for (int i = 0; i < model.nVertices; ++i) {
00104                 const point3d_t& p = model.vertices[i];
00105                 stream << "v\t" << p.x << "\t";
00106                 stream << p.y << "\t";
00107                 stream << p.z << "\n";
00108         }
00109         stream << "\n";
00110 }
00111 
00112 
00113 
00114 static void
00115 writeTriangles
00116 (
00117 IO std::ostream& stream,
00118 IN const glut::model_t& model
00119 )
00120 {
00121         // accumulate triangles first
00122         vec_triangle_t vec;
00123         for (int i = 0; i < model.nPolygons; ++i) {
00124                 const glut::polygon_t& poly = model.polygons[i];
00125                 int nTriangles = poly.nVertices - 2;
00126 
00127                 // construct a triangle fan from given polygon
00128                 for (int j = 0; j < nTriangles; ++j) {
00129                         triangle_t t;
00130                         t.index[0] = poly.indices[0];
00131                         t.index[1] = poly.indices[j + 1];
00132                         t.index[2] = poly.indices[j + 2];
00133                         vec.push_back(t);
00134                 }
00135         }
00136 
00137         // now write
00138         stream << "# triangle count and listing\n";
00139         stream << "nTriangles " << vec.size() << "\n";
00140         for (int i = 0; i < (int) vec.size(); ++i) {
00141                 const triangle_t& t = vec[i];
00142                 stream << "t\t";
00143                 stream << t.index[0] << "\t";
00144                 stream << t.index[1] << "\t";
00145                 stream << t.index[2] << "\n";
00146         }
00147         stream << "\n";
00148 }
00149 
00150 
00151 
00152 ////////////////////////////////////////////////////////////////////////////////
00153 //
00154 //      entry point
00155 //
00156 ////////////////////////////////////////////////////////////////////////////////
00157 
00158 int
00159 main
00160 (
00161 IN int argc,
00162 IN const char * argv[]
00163 )
00164 {
00165         ASSERT(2 == argc, "usage: physicsFromModel <model-file>");
00166         const char * filename = argv[1];
00167 
00168         int retval = 0;
00169 
00170         try {
00171                 perf::Timer timer("overall timer");
00172                 glut::lod_model_t lod_model;
00173 
00174                 std::ifstream infile(filename);
00175                 if (!infile.good()) {
00176                         WAVE_EX(wex);
00177                         wex << "Failed to open model file: " << filename;
00178                 }
00179                 expectToken(infile, "modelFormat");
00180                 expectToken(infile, "model-0.1");
00181                 expectToken(infile, "type");
00182                 expectToken(infile, "lod-model");
00183 //              expectToken(infile, "lodModel");
00184 
00185                 DummyRegistry reg;
00186                 glut::parseLodModel(&reg, infile, lod_model);
00187                 DPRINTF("Loaded model from %s", filename);
00188 
00189                 if (lod_model.nEntries < 1) {
00190                         WAVE_EX(wex);
00191                         wex << "level-of-detail model contains no models?";
00192                 }
00193 
00194                 glut::model_t& model = lod_model.entries[0].model;
00195 
00196                 std::cout << "# Autogenerated triangle mesh.\n";
00197                 std::cout << "\n";
00198 
00199                 writeVertices(std::cout, model);
00200                 writeTriangles(std::cout, model);
00201 
00202         } catch (std::exception& e) {
00203                 DPRINTF("Exception: %s", e.what());
00204                 retval = 1;
00205         }
00206 
00207         // dump timers and leave
00208         perf::dumpTimingSummary(std::cerr);
00209         return retval;
00210 }
00211