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

pandatool/src/lwoegg/cLwoPolygons.cxx

Go to the documentation of this file.
00001 // Filename: cLwoPolygons.cxx
00002 // Created by:  drose (25Apr01)
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 "cLwoPolygons.h"
00020 #include "lwoToEggConverter.h"
00021 #include "cLwoPoints.h"
00022 #include "cLwoLayer.h"
00023 #include "cLwoSurface.h"
00024 
00025 #include <lwoPolygonTags.h>
00026 #include <lwoTags.h>
00027 #include <lwoDiscontinuousVertexMap.h>
00028 #include <eggData.h>
00029 #include <eggPolygon.h>
00030 #include <eggPoint.h>
00031 #include <deg_2_rad.h>
00032 
00033 ////////////////////////////////////////////////////////////////////
00034 //     Function: CLwoPolygons::add_ptags
00035 //       Access: Public
00036 //  Description: Associates the indicated PolygonTags and Tags with
00037 //               the polygons in this chunk.  This may define features
00038 //               such as per-polygon surfaces, parts, and smoothing
00039 //               groups.
00040 ////////////////////////////////////////////////////////////////////
00041 void CLwoPolygons::
00042 add_ptags(const LwoPolygonTags *lwo_ptags, const LwoTags *tags) {
00043   if (_tags != (LwoTags *)NULL && _tags != tags) {
00044     nout << "Multiple Tags fields in effect on the same polygons.\n";
00045   }
00046   _tags = tags;
00047 
00048   IffId type = lwo_ptags->_tag_type;
00049 
00050   bool inserted = _ptags.insert(PTags::value_type(type, lwo_ptags)).second;
00051   if (!inserted) {
00052     nout << "Multiple polygon tags on the same polygons of type "
00053          << type << "\n";
00054 
00055   } else {
00056     if (type == IffId("SURF")) {
00057       _surf_ptags = lwo_ptags;
00058     }
00059   }
00060 }
00061 
00062 ////////////////////////////////////////////////////////////////////
00063 //     Function: CLwoPolygons::add_vmad
00064 //       Access: Public
00065 //  Description: Associates the indicated DiscontinousVertexMap with
00066 //               the polygons.  This can be used in conjunction with
00067 //               (or in place of) the VertexMap associated with the
00068 //               points set, to define per-polygon UV's etc.
00069 ////////////////////////////////////////////////////////////////////
00070 void CLwoPolygons::
00071 add_vmad(const LwoDiscontinuousVertexMap *lwo_vmad) {
00072   IffId map_type = lwo_vmad->_map_type;
00073   const string &name = lwo_vmad->_name;
00074 
00075   bool inserted;
00076   if (map_type == IffId("TXUV")) {
00077     inserted =
00078       _txuv.insert(VMad::value_type(name, lwo_vmad)).second;
00079 
00080   } else {
00081     return;
00082   }
00083 
00084   if (!inserted) {
00085     nout << "Multiple discontinous vertex maps on the same polygons of type "
00086          << map_type << " named " << name << "\n";
00087   }
00088 }
00089 
00090 ////////////////////////////////////////////////////////////////////
00091 //     Function: CLwoPolygons::get_surface
00092 //       Access: Public
00093 //  Description: Returns the surface associated with the given
00094 //               polygon, or NULL if no surface is associated.
00095 ////////////////////////////////////////////////////////////////////
00096 CLwoSurface *CLwoPolygons::
00097 get_surface(int polygon_index) const {
00098   if (_surf_ptags == (LwoPolygonTags *)NULL) {
00099     // No surface definitions.
00100     return (CLwoSurface *)NULL;
00101   }
00102 
00103   if (!_surf_ptags->has_tag(polygon_index)) {
00104     // The polygon isn't tagged.
00105     return (CLwoSurface *)NULL;
00106   }
00107 
00108   int tag_index = _surf_ptags->get_tag(polygon_index);
00109   if (_tags == (LwoTags *)NULL || tag_index < 0 ||
00110       tag_index >= _tags->get_num_tags()) {
00111     // The tag index is out-of-bounds.
00112     nout << "Invalid polygon tag index " << tag_index << "\n";
00113     return (CLwoSurface *)NULL;
00114   }
00115 
00116   string tag = _tags->get_tag(tag_index);
00117 
00118   // Now look up the surface name in the header.
00119   CLwoSurface *surface = _converter->get_surface(tag);
00120   if (surface == (CLwoSurface *)NULL) {
00121     nout << "Unknown surface " << tag << "\n";
00122     return (CLwoSurface *)NULL;
00123   }
00124 
00125   return surface;
00126 }
00127 
00128 ////////////////////////////////////////////////////////////////////
00129 //     Function: CLwoPolygons::get_uv
00130 //       Access: Public
00131 //  Description: Returns true if there is a UV of the indicated name
00132 //               associated with the given vertex of the indicated
00133 //               polygon, false otherwise.  If true, fills in uv with
00134 //               the value.
00135 //
00136 //               This performs a lookup in the optional
00137 //               "discontinuous" vertex mapping, which provides the
00138 //               ability to map different UV's per each polygon for
00139 //               the same vertex.  If the UV is not defined here, it
00140 //               may also be defined in the standard vertex map, which
00141 //               is associated with the points themselves.
00142 ////////////////////////////////////////////////////////////////////
00143 bool CLwoPolygons::
00144 get_uv(const string &uv_name, int pi, int vi, LPoint2f &uv) const {
00145   VMad::const_iterator ni = _txuv.find(uv_name);
00146   if (ni == _txuv.end()) {
00147     return false;
00148   }
00149 
00150   const LwoDiscontinuousVertexMap *vmad = (*ni).second;
00151   if (vmad->_dimension != 2) {
00152     nout << "Unexpected dimension of " << vmad->_dimension
00153          << " for discontinuous UV map " << uv_name << "\n";
00154     return false;
00155   }
00156 
00157   if (!vmad->has_value(pi, vi)) {
00158     return false;
00159   }
00160 
00161   PTA_float value = vmad->get_value(pi, vi);
00162 
00163   uv.set(value[0], value[1]);
00164   return true;
00165 }
00166 
00167 ////////////////////////////////////////////////////////////////////
00168 //     Function: CLwoPolygons::make_egg
00169 //       Access: Public
00170 //  Description: Creates the egg structures associated with this
00171 //               Lightwave object.
00172 ////////////////////////////////////////////////////////////////////
00173 void CLwoPolygons::
00174 make_egg() {
00175   // First, we need a temporary group to hold all of the polygons
00176   // we'll create.
00177   _egg_group = new EggGroup;
00178 
00179   if (_polygons->_polygon_type == IffId("CURV")) {
00180     nout << "Ignoring Catmull-Rom splines.\n";
00181 
00182   } else if (_polygons->_polygon_type == IffId("PTCH")) {
00183     nout << "Treating subdivision patches as ordinary polygons.\n";
00184     make_faces();
00185 
00186   } else if (_polygons->_polygon_type == IffId("MBAL")) {
00187     nout << "Ignoring metaballs.\n";
00188 
00189   } else if (_polygons->_polygon_type == IffId("BONE")) {
00190     nout << "Ignoring bones.\n";
00191 
00192   } else if (_polygons->_polygon_type == IffId("FACE")) {
00193     make_faces();
00194 
00195   } else {
00196     nout << "Ignoring unknown geometry type " << _polygons->_polygon_type
00197          << ".\n";
00198   }
00199 }
00200 
00201 ////////////////////////////////////////////////////////////////////
00202 //     Function: CLwoPolygons::connect_egg
00203 //       Access: Public
00204 //  Description: Connects all the egg structures together.
00205 ////////////////////////////////////////////////////////////////////
00206 void CLwoPolygons::
00207 connect_egg() {
00208   nassertv(_points->_layer->_egg_group != (EggGroup *)NULL);
00209   nassertv(_egg_group != (EggGroup *)NULL);
00210   _points->_layer->_egg_group->steal_children(*_egg_group);
00211 }
00212 
00213 
00214 ////////////////////////////////////////////////////////////////////
00215 //     Function: CLwoPolygons::make_faces
00216 //       Access: Public
00217 //  Description: Generates "face" polygons, i.e. actual polygons.
00218 ////////////////////////////////////////////////////////////////////
00219 void CLwoPolygons::
00220 make_faces() {
00221   float smooth_angle = -1.0;
00222 
00223   int num_polygons = _polygons->get_num_polygons();
00224   for (int pindex = 0; pindex < num_polygons; pindex++) {
00225     LwoPolygons::Polygon *poly = _polygons->get_polygon(pindex);
00226     CLwoSurface *surface = get_surface(pindex);
00227 
00228     bool is_valid = true;
00229 
00230     // Set up the vertices.
00231     const LwoPoints *points = _points->_points;
00232     int num_points = points->get_num_points();
00233     EggVertexPool *egg_vpool = _points->_egg_vpool;
00234 
00235     // We reverse the vertex ordering to compensate for Lightwave's
00236     // clockwise ordering convention.  We also want to start with the
00237     // last vertex, so that the first convex angle is the first angle
00238     // in the EggPolygon (for determining correct normals).
00239     PT(EggPrimitive) egg_prim;
00240 
00241     if (poly->_vertices.size() == 1) {
00242       egg_prim = new EggPoint;
00243     } else {
00244       egg_prim = new EggPolygon;
00245     }
00246 
00247     // First, we have to create a temporary vector of vertices for the
00248     // polygon, so we can possibly adjust the properties of these
00249     // vertices (like the UV's) in the shader before we create them.
00250     vector_PT_EggVertex egg_vertices;
00251 
00252     int num_vertices = poly->_vertices.size();
00253     for (int vi = num_vertices; vi > 0; vi--) {
00254       int vindex = poly->_vertices[vi % num_vertices];
00255       if (vindex < 0 || vindex >= num_points) {
00256         nout << "Invalid vertex index " << vindex << " in polygon.\n";
00257         is_valid = false;
00258       } else {
00259         PT(EggVertex) egg_vertex = new EggVertex;
00260         LPoint3d pos = LCAST(double, points->get_point(vindex));
00261         egg_vertex->set_pos(pos);
00262 
00263         // Does the vertex used named UV's?
00264         if (surface != (CLwoSurface *)NULL && surface->has_named_uvs()) {
00265           string uv_name = surface->get_uv_name();
00266           LPoint2f uv;
00267           if (get_uv(uv_name, pindex, vindex, uv)) {
00268             // This UV is defined in a "discontinuous" map, that
00269             // associated a particular UV per each polygon.
00270             egg_vertex->set_uv(LCAST(double, uv));
00271 
00272           } else if (_points->get_uv(uv_name, vindex, uv)) {
00273             // The UV does not appear in a discontinuous map, but it
00274             // is defined in the points set.
00275             egg_vertex->set_uv(LCAST(double, uv));
00276           }
00277         }
00278 
00279         egg_vertices.push_back(egg_vertex);
00280       }
00281     }
00282 
00283     if (is_valid) {
00284       if (surface != (CLwoSurface *)NULL) {
00285         surface->apply_properties(egg_prim, egg_vertices, smooth_angle);
00286       }
00287 
00288       // Now add all the vertices officially to the primitive.
00289       vector_PT_EggVertex::const_iterator evi;
00290       for (evi = egg_vertices.begin(); evi != egg_vertices.end(); ++evi) {
00291         EggVertex *egg_vertex = (*evi);
00292         EggVertex *new_vertex = egg_vpool->create_unique_vertex(*egg_vertex);
00293         egg_prim->add_vertex(new_vertex);
00294       }
00295 
00296       // And add the primitive to its parent.
00297       _egg_group->add_child(egg_prim.p());
00298     }
00299   }
00300 
00301   CoordinateSystem cs = _converter->get_egg_data().get_coordinate_system();
00302   if (smooth_angle > 0.0) {
00303     _egg_group->recompute_vertex_normals(rad_2_deg(smooth_angle), cs);
00304   } else {
00305     _egg_group->recompute_polygon_normals(cs);
00306   }
00307 }
00308 

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