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