00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "lwoToEggConverter.h"
00020 #include "cLwoLayer.h"
00021 #include "cLwoClip.h"
00022 #include "cLwoPoints.h"
00023 #include "cLwoPolygons.h"
00024 #include "cLwoSurface.h"
00025
00026 #include "eggData.h"
00027 #include "lwoHeader.h"
00028 #include "lwoLayer.h"
00029 #include "lwoClip.h"
00030 #include "lwoPoints.h"
00031 #include "lwoPolygons.h"
00032 #include "lwoVertexMap.h"
00033 #include "lwoDiscontinuousVertexMap.h"
00034 #include "lwoTags.h"
00035 #include "lwoPolygonTags.h"
00036 #include "lwoInputFile.h"
00037 #include "dcast.h"
00038
00039
00040
00041
00042
00043
00044
00045 LwoToEggConverter::
00046 LwoToEggConverter() {
00047 _generic_layer = (CLwoLayer *)NULL;
00048 _make_materials = true;
00049 }
00050
00051
00052
00053
00054
00055
00056 LwoToEggConverter::
00057 LwoToEggConverter(const LwoToEggConverter ©) :
00058 SomethingToEggConverter(copy)
00059 {
00060 }
00061
00062
00063
00064
00065
00066
00067 LwoToEggConverter::
00068 ~LwoToEggConverter() {
00069 cleanup();
00070 }
00071
00072
00073
00074
00075
00076
00077 SomethingToEggConverter *LwoToEggConverter::
00078 make_copy() {
00079 return new LwoToEggConverter(*this);
00080 }
00081
00082
00083
00084
00085
00086
00087
00088 string LwoToEggConverter::
00089 get_name() const {
00090 return "Lightwave";
00091 }
00092
00093
00094
00095
00096
00097
00098
00099 string LwoToEggConverter::
00100 get_extension() const {
00101 return "lwo";
00102 }
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 bool LwoToEggConverter::
00117 convert_file(const Filename &filename) {
00118 LwoInputFile in;
00119
00120 nout << "Reading " << filename << "\n";
00121 if (!in.open_read(filename)) {
00122 nout << "Unable to open " << filename << "\n";
00123 return false;
00124 }
00125
00126 PT(IffChunk) chunk = in.get_chunk();
00127 if (chunk == (IffChunk *)NULL) {
00128 nout << "Unable to read " << filename << "\n";
00129 return false;
00130 }
00131
00132 if (!chunk->is_of_type(LwoHeader::get_class_type())) {
00133 nout << "File " << filename << " is not a Lightwave Object file.\n";
00134 return false;
00135 }
00136
00137 LwoHeader *header = DCAST(LwoHeader, chunk);
00138 if (!header->is_valid()) {
00139 nout << "File " << filename
00140 << " is not recognized as a Lightwave Object file. "
00141 << "Perhaps the version is too recent.\n";
00142 return false;
00143 }
00144
00145 return convert_lwo(header);
00146 }
00147
00148
00149
00150
00151
00152
00153
00154 bool LwoToEggConverter::
00155 convert_lwo(const LwoHeader *lwo_header) {
00156 if (_egg_data->get_coordinate_system() == CS_default) {
00157 _egg_data->set_coordinate_system(CS_yup_left);
00158 }
00159
00160 _error = false;
00161 _lwo_header = lwo_header;
00162
00163 collect_lwo();
00164 make_egg();
00165 connect_egg();
00166
00167 _egg_data->remove_unused_vertices();
00168 cleanup();
00169
00170 return !_error;
00171 }
00172
00173
00174
00175
00176
00177
00178
00179 CLwoLayer *LwoToEggConverter::
00180 get_layer(int number) const {
00181 if (number >= 0 && number < (int)_layers.size()) {
00182 return _layers[number];
00183 }
00184 return (CLwoLayer *)NULL;
00185 }
00186
00187
00188
00189
00190
00191
00192
00193 CLwoClip *LwoToEggConverter::
00194 get_clip(int number) const {
00195 if (number >= 0 && number < (int)_clips.size()) {
00196 return _clips[number];
00197 }
00198 return (CLwoClip *)NULL;
00199 }
00200
00201
00202
00203
00204
00205
00206
00207 CLwoSurface *LwoToEggConverter::
00208 get_surface(const string &name) const {
00209 Surfaces::const_iterator si;
00210 si = _surfaces.find(name);
00211 if (si != _surfaces.end()) {
00212 return (*si).second;
00213 }
00214 return (CLwoSurface *)NULL;
00215 }
00216
00217
00218
00219
00220
00221
00222
00223
00224 void LwoToEggConverter::
00225 cleanup() {
00226 _lwo_header.clear();
00227
00228 if (_generic_layer != (CLwoLayer *)NULL) {
00229 delete _generic_layer;
00230 _generic_layer = (CLwoLayer *)NULL;
00231 }
00232
00233 Layers::iterator li;
00234 for (li = _layers.begin(); li != _layers.end(); ++li) {
00235 CLwoLayer *layer = (*li);
00236 if (layer != (CLwoLayer *)NULL) {
00237 delete layer;
00238 }
00239 }
00240 _layers.clear();
00241
00242 Clips::iterator ci;
00243 for (ci = _clips.begin(); ci != _clips.end(); ++ci) {
00244 CLwoClip *clip = (*ci);
00245 if (clip != (CLwoClip *)NULL) {
00246 delete clip;
00247 }
00248 }
00249 _clips.clear();
00250
00251 Points::iterator pi;
00252 for (pi = _points.begin(); pi != _points.end(); ++pi) {
00253 CLwoPoints *points = (*pi);
00254 delete points;
00255 }
00256 _points.clear();
00257
00258 Polygons::iterator gi;
00259 for (gi = _polygons.begin(); gi != _polygons.end(); ++gi) {
00260 CLwoPolygons *polygons = (*gi);
00261 delete polygons;
00262 }
00263 _polygons.clear();
00264
00265 Surfaces::iterator si;
00266 for (si = _surfaces.begin(); si != _surfaces.end(); ++si) {
00267 CLwoSurface *surface = (*si).second;
00268 delete surface;
00269 }
00270 _surfaces.clear();
00271 }
00272
00273
00274
00275
00276
00277
00278
00279 void LwoToEggConverter::
00280 collect_lwo() {
00281 CLwoLayer *last_layer = (CLwoLayer *)NULL;
00282 CLwoPoints *last_points = (CLwoPoints *)NULL;
00283 CLwoPolygons *last_polygons = (CLwoPolygons *)NULL;
00284
00285 const LwoTags *tags = (const LwoTags *)NULL;
00286
00287 int num_chunks = _lwo_header->get_num_chunks();
00288 for (int i = 0; i < num_chunks; i++) {
00289 const IffChunk *chunk = _lwo_header->get_chunk(i);
00290
00291 if (chunk->is_of_type(LwoLayer::get_class_type())) {
00292 const LwoLayer *lwo_layer = DCAST(LwoLayer, chunk);
00293 CLwoLayer *layer = new CLwoLayer(this, lwo_layer);
00294 int number = layer->get_number();
00295 slot_layer(number);
00296
00297 if (_layers[number] != (CLwoLayer *)NULL) {
00298 nout << "Warning: multiple layers with number " << number << "\n";
00299 }
00300 _layers[number] = layer;
00301 last_layer = layer;
00302 last_points = (CLwoPoints *)NULL;
00303 last_polygons = (CLwoPolygons *)NULL;
00304
00305 } else if (chunk->is_of_type(LwoClip::get_class_type())) {
00306 const LwoClip *lwo_clip = DCAST(LwoClip, chunk);
00307 CLwoClip *clip = new CLwoClip(this, lwo_clip);
00308
00309 int index = clip->get_index();
00310 slot_clip(index);
00311
00312 if (_clips[index] != (CLwoClip *)NULL) {
00313 nout << "Warning: multiple clips with index " << index << "\n";
00314 }
00315 _clips[index] = clip;
00316
00317 } else if (chunk->is_of_type(LwoPoints::get_class_type())) {
00318 if (last_layer == (CLwoLayer *)NULL) {
00319 last_layer = make_generic_layer();
00320 }
00321
00322 const LwoPoints *lwo_points = DCAST(LwoPoints, chunk);
00323 CLwoPoints *points = new CLwoPoints(this, lwo_points, last_layer);
00324 _points.push_back(points);
00325 last_points = points;
00326
00327 } else if (chunk->is_of_type(LwoVertexMap::get_class_type())) {
00328 if (last_points == (CLwoPoints *)NULL) {
00329 nout << "Vertex map chunk encountered without a preceding points chunk.\n";
00330 } else {
00331 const LwoVertexMap *lwo_vmap = DCAST(LwoVertexMap, chunk);
00332 last_points->add_vmap(lwo_vmap);
00333 }
00334
00335 } else if (chunk->is_of_type(LwoDiscontinuousVertexMap::get_class_type())) {
00336 if (last_polygons == (CLwoPolygons *)NULL) {
00337 nout << "Discontinous vertex map chunk encountered without a preceding polygons chunk.\n";
00338 } else {
00339 const LwoDiscontinuousVertexMap *lwo_vmad = DCAST(LwoDiscontinuousVertexMap, chunk);
00340 last_polygons->add_vmad(lwo_vmad);
00341 }
00342
00343 } else if (chunk->is_of_type(LwoTags::get_class_type())) {
00344 tags = DCAST(LwoTags, chunk);
00345
00346 } else if (chunk->is_of_type(LwoPolygons::get_class_type())) {
00347 if (last_points == (CLwoPoints *)NULL) {
00348 nout << "Polygon chunk encountered without a preceding points chunk.\n";
00349 } else {
00350 const LwoPolygons *lwo_polygons = DCAST(LwoPolygons, chunk);
00351 CLwoPolygons *polygons =
00352 new CLwoPolygons(this, lwo_polygons, last_points);
00353 _polygons.push_back(polygons);
00354 last_polygons = polygons;
00355 }
00356
00357 } else if (chunk->is_of_type(LwoPolygonTags::get_class_type())) {
00358 if (last_polygons == (CLwoPolygons *)NULL) {
00359 nout << "Polygon tags chunk encountered without a preceding polygons chunk.\n";
00360 } else if (tags == (LwoTags *)NULL) {
00361 nout << "Polygon tags chunk encountered without a preceding tags chunk.\n";
00362 } else {
00363 const LwoPolygonTags *lwo_ptags = DCAST(LwoPolygonTags, chunk);
00364 last_polygons->add_ptags(lwo_ptags, tags);
00365 }
00366
00367 } else if (chunk->is_of_type(LwoSurface::get_class_type())) {
00368 if (last_layer == (CLwoLayer *)NULL) {
00369 last_layer = make_generic_layer();
00370 }
00371
00372 const LwoSurface *lwo_surface = DCAST(LwoSurface, chunk);
00373 CLwoSurface *surface = new CLwoSurface(this, lwo_surface);
00374
00375 bool inserted = _surfaces.insert(Surfaces::value_type(surface->get_name(), surface)).second;
00376 if (!inserted) {
00377 nout << "Multiple surface definitions named " << surface->get_name() << "\n";
00378 delete surface;
00379 }
00380 }
00381 }
00382 }
00383
00384
00385
00386
00387
00388
00389
00390 void LwoToEggConverter::
00391 make_egg() {
00392 if (_generic_layer != (CLwoLayer *)NULL) {
00393 _generic_layer->make_egg();
00394 }
00395
00396 Layers::iterator li;
00397 for (li = _layers.begin(); li != _layers.end(); ++li) {
00398 CLwoLayer *layer = (*li);
00399 if (layer != (CLwoLayer *)NULL) {
00400 layer->make_egg();
00401 }
00402 }
00403
00404 Points::iterator pi;
00405 for (pi = _points.begin(); pi != _points.end(); ++pi) {
00406 CLwoPoints *points = (*pi);
00407 points->make_egg();
00408 }
00409
00410 Polygons::iterator gi;
00411 for (gi = _polygons.begin(); gi != _polygons.end(); ++gi) {
00412 CLwoPolygons *polygons = (*gi);
00413 polygons->make_egg();
00414 }
00415 }
00416
00417
00418
00419
00420
00421
00422 void LwoToEggConverter::
00423 connect_egg() {
00424 if (_generic_layer != (CLwoLayer *)NULL) {
00425 _generic_layer->connect_egg();
00426 }
00427
00428 Layers::iterator li;
00429 for (li = _layers.begin(); li != _layers.end(); ++li) {
00430 CLwoLayer *layer = (*li);
00431 if (layer != (CLwoLayer *)NULL) {
00432 layer->connect_egg();
00433 }
00434 }
00435
00436 Points::iterator pi;
00437 for (pi = _points.begin(); pi != _points.end(); ++pi) {
00438 CLwoPoints *points = (*pi);
00439 points->connect_egg();
00440 }
00441
00442 Polygons::iterator gi;
00443 for (gi = _polygons.begin(); gi != _polygons.end(); ++gi) {
00444 CLwoPolygons *polygons = (*gi);
00445 polygons->connect_egg();
00446 }
00447 }
00448
00449
00450
00451
00452
00453
00454
00455 void LwoToEggConverter::
00456 slot_layer(int number) {
00457 nassertv(number - (int)_layers.size() < 1000);
00458 while (number >= (int)_layers.size()) {
00459 _layers.push_back((CLwoLayer *)NULL);
00460 }
00461 nassertv(number >= 0 && number < (int)_layers.size());
00462 }
00463
00464
00465
00466
00467
00468
00469
00470 void LwoToEggConverter::
00471 slot_clip(int number) {
00472 nassertv(number - (int)_clips.size() < 1000);
00473 while (number >= (int)_clips.size()) {
00474 _clips.push_back((CLwoClip *)NULL);
00475 }
00476 nassertv(number >= 0 && number < (int)_clips.size());
00477 }
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488 CLwoLayer *LwoToEggConverter::
00489 make_generic_layer() {
00490 nassertr(_generic_layer == (CLwoLayer *)NULL, _generic_layer);
00491
00492 PT(LwoLayer) layer = new LwoLayer;
00493 layer->make_generic();
00494
00495 _generic_layer = new CLwoLayer(this, layer);
00496 return _generic_layer;
00497 }