00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "cLwoPolygons.h"
00016 #include "lwoToEggConverter.h"
00017 #include "cLwoPoints.h"
00018 #include "cLwoLayer.h"
00019 #include "cLwoSurface.h"
00020
00021 #include "lwoPolygonTags.h"
00022 #include "lwoTags.h"
00023 #include "lwoDiscontinuousVertexMap.h"
00024 #include "eggData.h"
00025 #include "eggPolygon.h"
00026 #include "eggPoint.h"
00027 #include "deg_2_rad.h"
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 void CLwoPolygons::
00038 add_ptags(const LwoPolygonTags *lwo_ptags, const LwoTags *tags) {
00039 if (_tags != (LwoTags *)NULL && _tags != tags) {
00040 nout << "Multiple Tags fields in effect on the same polygons.\n";
00041 }
00042 _tags = tags;
00043
00044 IffId type = lwo_ptags->_tag_type;
00045
00046 bool inserted = _ptags.insert(PTags::value_type(type, lwo_ptags)).second;
00047 if (!inserted) {
00048 nout << "Multiple polygon tags on the same polygons of type "
00049 << type << "\n";
00050
00051 } else {
00052 if (type == IffId("SURF")) {
00053 _surf_ptags = lwo_ptags;
00054 }
00055 }
00056 }
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 void CLwoPolygons::
00067 add_vmad(const LwoDiscontinuousVertexMap *lwo_vmad) {
00068 IffId map_type = lwo_vmad->_map_type;
00069 const string &name = lwo_vmad->_name;
00070
00071 bool inserted;
00072 if (map_type == IffId("TXUV")) {
00073 inserted =
00074 _txuv.insert(VMad::value_type(name, lwo_vmad)).second;
00075
00076 } else {
00077 return;
00078 }
00079
00080 if (!inserted) {
00081 nout << "Multiple discontinous vertex maps on the same polygons of type "
00082 << map_type << " named " << name << "\n";
00083 }
00084 }
00085
00086
00087
00088
00089
00090
00091
00092 CLwoSurface *CLwoPolygons::
00093 get_surface(int polygon_index) const {
00094 if (_surf_ptags == (LwoPolygonTags *)NULL) {
00095
00096 return (CLwoSurface *)NULL;
00097 }
00098
00099 if (!_surf_ptags->has_tag(polygon_index)) {
00100
00101 return (CLwoSurface *)NULL;
00102 }
00103
00104 int tag_index = _surf_ptags->get_tag(polygon_index);
00105 if (_tags == (LwoTags *)NULL || tag_index < 0 ||
00106 tag_index >= _tags->get_num_tags()) {
00107
00108 nout << "Invalid polygon tag index " << tag_index << "\n";
00109 return (CLwoSurface *)NULL;
00110 }
00111
00112 string tag = _tags->get_tag(tag_index);
00113
00114
00115 CLwoSurface *surface = _converter->get_surface(tag);
00116 if (surface == (CLwoSurface *)NULL) {
00117 nout << "Unknown surface " << tag << "\n";
00118 return (CLwoSurface *)NULL;
00119 }
00120
00121 return surface;
00122 }
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139 bool CLwoPolygons::
00140 get_uv(const string &uv_name, int pi, int vi, LPoint2 &uv) const {
00141 VMad::const_iterator ni = _txuv.find(uv_name);
00142 if (ni == _txuv.end()) {
00143 return false;
00144 }
00145
00146 const LwoDiscontinuousVertexMap *vmad = (*ni).second;
00147 if (vmad->_dimension != 2) {
00148 nout << "Unexpected dimension of " << vmad->_dimension
00149 << " for discontinuous UV map " << uv_name << "\n";
00150 return false;
00151 }
00152
00153 if (!vmad->has_value(pi, vi)) {
00154 return false;
00155 }
00156
00157 PTA_stdfloat value = vmad->get_value(pi, vi);
00158
00159 uv.set(value[0], value[1]);
00160 return true;
00161 }
00162
00163
00164
00165
00166
00167
00168
00169 void CLwoPolygons::
00170 make_egg() {
00171
00172
00173 _egg_group = new EggGroup;
00174
00175 if (_polygons->_polygon_type == IffId("CURV")) {
00176 nout << "Ignoring Catmull-Rom splines.\n";
00177
00178 } else if (_polygons->_polygon_type == IffId("PTCH")) {
00179 nout << "Treating subdivision patches as ordinary polygons.\n";
00180 make_faces();
00181
00182 } else if (_polygons->_polygon_type == IffId("MBAL")) {
00183 nout << "Ignoring metaballs.\n";
00184
00185 } else if (_polygons->_polygon_type == IffId("BONE")) {
00186 nout << "Ignoring bones.\n";
00187
00188 } else if (_polygons->_polygon_type == IffId("FACE")) {
00189 make_faces();
00190
00191 } else {
00192 nout << "Ignoring unknown geometry type " << _polygons->_polygon_type
00193 << ".\n";
00194 }
00195 }
00196
00197
00198
00199
00200
00201
00202 void CLwoPolygons::
00203 connect_egg() {
00204 nassertv(_points->_layer->_egg_group != (EggGroup *)NULL);
00205 nassertv(_egg_group != (EggGroup *)NULL);
00206 _points->_layer->_egg_group->steal_children(*_egg_group);
00207 }
00208
00209
00210
00211
00212
00213
00214
00215 void CLwoPolygons::
00216 make_faces() {
00217 PN_stdfloat smooth_angle = -1.0;
00218
00219 int num_polygons = _polygons->get_num_polygons();
00220 for (int pindex = 0; pindex < num_polygons; pindex++) {
00221 LwoPolygons::Polygon *poly = _polygons->get_polygon(pindex);
00222 CLwoSurface *surface = get_surface(pindex);
00223
00224 bool is_valid = true;
00225
00226
00227 const LwoPoints *points = _points->_points;
00228 int num_points = points->get_num_points();
00229 EggVertexPool *egg_vpool = _points->_egg_vpool;
00230
00231
00232
00233
00234
00235 PT(EggPrimitive) egg_prim;
00236
00237 if (poly->_vertices.size() == 1) {
00238 egg_prim = new EggPoint;
00239 } else {
00240 egg_prim = new EggPolygon;
00241 }
00242
00243
00244
00245
00246 vector_PT_EggVertex egg_vertices;
00247
00248 int num_vertices = poly->_vertices.size();
00249 for (int vi = num_vertices; vi > 0; vi--) {
00250 int vindex = poly->_vertices[vi % num_vertices];
00251 if (vindex < 0 || vindex >= num_points) {
00252 nout << "Invalid vertex index " << vindex << " in polygon.\n";
00253 is_valid = false;
00254 } else {
00255 PT(EggVertex) egg_vertex = new EggVertex;
00256 LPoint3d pos = LCAST(double, points->get_point(vindex));
00257 egg_vertex->set_pos(pos);
00258
00259
00260 if (surface != (CLwoSurface *)NULL && surface->has_named_uvs()) {
00261 string uv_name = surface->get_uv_name();
00262 LPoint2 uv;
00263 if (get_uv(uv_name, pindex, vindex, uv)) {
00264
00265
00266 egg_vertex->set_uv(LCAST(double, uv));
00267
00268 } else if (_points->get_uv(uv_name, vindex, uv)) {
00269
00270
00271 egg_vertex->set_uv(LCAST(double, uv));
00272 }
00273 }
00274
00275 egg_vertices.push_back(egg_vertex);
00276 }
00277 }
00278
00279 if (is_valid) {
00280 if (surface != (CLwoSurface *)NULL) {
00281 surface->apply_properties(egg_prim, egg_vertices, smooth_angle);
00282 }
00283
00284
00285 vector_PT_EggVertex::const_iterator evi;
00286 for (evi = egg_vertices.begin(); evi != egg_vertices.end(); ++evi) {
00287 EggVertex *egg_vertex = (*evi);
00288 EggVertex *new_vertex = egg_vpool->create_unique_vertex(*egg_vertex);
00289 egg_prim->add_vertex(new_vertex);
00290 }
00291
00292
00293 _egg_group->add_child(egg_prim.p());
00294 }
00295 }
00296
00297 CoordinateSystem cs = _converter->get_egg_data()->get_coordinate_system();
00298 if (smooth_angle > 0.0) {
00299 _egg_group->recompute_vertex_normals(rad_2_deg(smooth_angle), cs);
00300 } else {
00301 _egg_group->recompute_polygon_normals(cs);
00302 }
00303 }
00304