00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "Teddy/TeddyConfig.h"
00026 #if defined( TEDDY_INCLUDE_LW_SCENE )
00027
00028
00029 #include "Teddy/Imports/LWClip.h"
00030 #include "Teddy/Imports/LWEnvelope.h"
00031 #include "Teddy/Imports/LWFile.h"
00032 #include "Teddy/Imports/LWLayer.h"
00033 #include "Teddy/Imports/LWModel.h"
00034 #include "Teddy/Imports/LWSurface.h"
00035 #include "Teddy/Models/Model.h"
00036 #include "Teddy/Models/Face.h"
00037 #include "Teddy/Models/Geometry.h"
00038 #include "Teddy/Models/Vertex.h"
00039 #include "Teddy/SysSupport/Exception.h"
00040 #include "Teddy/SysSupport/Messages.h"
00041 #include "Teddy/SysSupport/StdMaths.h"
00042 #include "Teddy/SysSupport/StdIO.h"
00043
00044 #ifndef SWIG
00045 #include <algorithm>
00046 using namespace std;
00047 #endif
00048 using namespace Teddy::SysSupport;
00049
00050
00051 #define USE_LIGHTWAVE_SCALE 1
00052 #define SCALE 1
00053
00054
00055 namespace Teddy {
00056 namespace Imports {
00057
00058
00060 LWLayer::LWLayer( LWModel *model, const std::string &name, U2 flags, Vector pivot, int parent )
00061 :
00062 Model( name )
00063 {
00064 this->f = model->getFile();
00065 this->model = model;
00066 this->pivot = pivot;
00067 this->flags = flags;
00068 this->parent_layer = parent;
00069 num_vertices = 0;
00070 num_faces = 0;
00071 num_surfaces = 0;
00072 num_envelopes = 0;
00073 num_clips = 0;
00074 current_surface = 0;
00075 bbox_min = Vector(0,0,0);
00076 bbox_max = Vector(0,0,0);
00077
00078 dmsg( M_LWO, "LWLayer constructor" );
00079 }
00080
00081 void LWLayer::processLayer(){
00082
00083 while( f->bytesRead()-8 < f->getLen() ){
00084 dmsg( M_LWO, "calling processChunk()" );
00085 bool next_layer = processChunk();
00086 if( next_layer == true ){
00087 break;
00088 }
00089
00090 }
00091
00092
00093
00094 list<Model*>::iterator m_it;
00095 m_it = children.begin();
00096 while( m_it != children.end() ){
00097 Model *model = *m_it;
00098 Material *mat = model->getMaterial();
00099
00100 model->getGeometry()->smooth( mat->getMaxSmoothingAngle() );
00101 m_it++;
00102 }
00103
00104 }
00105
00106
00108 LWLayer::~LWLayer(){
00109
00110 }
00111
00112
00114 bool LWLayer::processChunk(){
00115 dmsg( M_LWO, "processChunk() @ %lu", f->bytesRead() );
00116 bool next_layer = false;
00117 U4 chunk_id = f->read_ID4();
00118 U4 chunk_length = f->read_U4();
00119
00120 dmsg( M_LWO,
00121 "%s::%s (%lu) (%lu bytes)",
00122 did( f->getType() ),
00123 did( chunk_id ),
00124 chunk_id,
00125 chunk_length
00126 );
00127
00128 f->pushDomain( chunk_length );
00129
00130 switch( f->getType() ){
00131 case ID_LWOB:
00132 case ID_LWLO:
00133 switch( chunk_id ){
00134 case ID_PNTS: pointList (); break;
00135 case ID_SRFS: surfaceList(); break;
00136 case ID_POLS: faceList (); break;
00137 case ID_CRVS: curveList (); break;
00138 case ID_PCHS: patchList (); break;
00139 case ID_SURF: surface_sc (); break;
00140 default: break;
00141 }
00142 break;
00143 case ID_LWO2:
00144 switch( chunk_id ){
00145 case ID_PNTS: pointList (); break;
00146 case ID_VMAP: vertexMapping_ID4_U2_S0_d(); break;
00147 case ID_POLS: polygonList (); break;
00148 case ID_TAGS: model->tags_d (); break;
00149 case ID_PTAG: polygonTags_ID4_d (); break;
00150 case ID_ENVL: envelope_U4_sc (); break;
00151 case ID_CLIP: clip_U4_sc (); break;
00152 case ID_SURF: surf_S0_S0_sc (); break;
00153 case ID_BBOX: boundingBox_VEC12_VEC12 (); break;
00154 case ID_DESC: descriptionLine_S0 (); break;
00155 case ID_TEXT: comments_S0 (); break;
00156 case ID_ICON: thumbnail_U2_U2_d (); break;
00157 default: break;
00158 }
00159 break;
00160 default: break;
00161 }
00162
00163 if( chunk_id == ID_LAYR ){
00164 next_layer = true;
00165 switch( f->getType() ){
00166 case ID_LWLO: model->layer_U2_U2_S0 (); break;
00167 case ID_LWO2: model->layer_U2_U2_VEC12_S0_U2(); break;
00168 default: break;
00169 }
00170 }else{
00171
00172 f->popDomain( true );
00173
00174 }
00175
00176 return next_layer;
00177
00178 }
00179
00180
00181 LWModel *LWLayer::getModel(){
00182 return model;
00183 }
00184
00185
00186 LWClip *LWLayer::getClip( VX clip_index ){
00187 U4_to_LWClip::iterator c_it = clips.find( clip_index );
00188 LWClip *clip = NULL;
00189
00190 if( c_it != clips.end() ){
00191 clip = (*c_it).second;
00192 }
00193 return clip;
00194 }
00195
00196
00219 void LWLayer::pointList(){
00220 Vertex *vertex;
00221 U4 current_v_index = 0;
00222 U4 i;
00223
00224 num_vertices = f->domainLeft()/12;
00225
00226 for( i=0; i<num_vertices; i++ ){
00227 if( f->domainLeft()<3*4 ){
00228 emsg( M_LWO, "Not enough floats found in chunk for point" );
00229 break;
00230 }
00231
00232 Vector vec = f->read_VEC12();
00233 vec += pivot;
00234 vec[2] = -vec[2];
00235
00236 vertex = new Vertex( vec );
00237
00238 # ifdef USE_LIGHTWAVE_SCALE
00239 *vertex *= SCALE;
00240 # endif
00241
00242
00243 this->vertices.insert( std::make_pair(current_v_index,vertex) );
00244 current_v_index++;
00245 }
00246 dmsg( M_LWO, "pointList() done through %d vertices", i-1 );
00247 }
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 void LWLayer::surfaceList(){
00267 std::string surface_name;
00268 LWSurface *surface;
00269 Model *model;
00270 char *buffer;
00271
00272 while( f->domainLeft() > 0 ){
00273 num_surfaces++;
00274 surface_name = f->read_S0();
00275 model = new Model ( surface_name );
00276 surface = new LWSurface( this, model, surface_name );
00277 add( model );
00278 buffer = new char[16];
00279 sprintf( buffer, "SURFACE %d", (int)(num_surfaces) );
00280 surfaces.insert( std::make_pair(surface_name,surface) );
00281 models .insert( std::make_pair(buffer, model ) );
00282 model->setMaterial( surface );
00283 }
00284 }
00285
00286
00321 void LWLayer::faceList(){
00322 Face *face = NULL;
00323 Vertex *vertex = NULL;
00324 Model *model = NULL;
00325 U4 num_vertices;
00326 U4 surface_index;
00327 U4 vertex_index;
00328 U4 i;
00329 bool good;
00330 U4 bad_count = 0;
00331 U4 point_count = 0;
00332 U4 line_count = 0;
00333
00334 while( f->domainLeft() > 0 ){
00335 num_vertices = f->read_U2();
00336
00337 if( num_vertices<3 ){
00338 bad_count++;
00339 switch( num_vertices ){
00340 case 0: bad_count ++; emsg( M_LWO, "Bad polygon - 0 vertices" ); break;
00341 case 1: bad_count ++; point_count++; break;
00342 case 2: bad_count ++; line_count ++; break;
00343 }
00344 for( i=0; i<num_vertices; i++ ){
00345 vertex_index = f->read_U2();
00346 }
00347 f->read_U2();
00348 continue;
00349 }
00350
00351 face = new Face();
00352 good = true;
00353
00354 for( i=0; i<num_vertices; i++ ){
00355 if( f->domainLeft()<2 ){
00356 emsg( M_LWO, "Not enough shorts found in chunk" );
00357 good = false;
00358 break;
00359 }
00360 vertex_index = f->read_U2();
00361
00362 if( (vertex_index > this->num_vertices) ){
00363 emsg( M_LWO, "Not understood as vertex index %ld > %ld", vertex_index, num_vertices );
00364 good = false;
00365 break;
00366 }
00367
00368
00369 U4_to_Vertex::iterator v_it = vertices.find( vertex_index );
00370 if( v_it!=vertices.end() ){
00371 vertex = (*v_it).second;
00372 if( vertex != NULL ){
00373 face->add( vertex );
00374 }else{
00375 emsg( M_LWO, "Vertex %ld pointer is NULL", vertex_index );
00376 good = false;
00377 }
00378 }else{
00379 emsg( M_LWO, "Vertex %ld not found", vertex_index );
00380 good = false;
00381 }
00382
00383 }
00384
00385 if( good ){
00386 surface_index = f->read_U2();
00387 if( surface_index > num_surfaces ){
00388 bad_count++;
00389 delete face;
00390 continue;
00391
00392 }
00393
00394 string_to_Model::iterator m_it;
00395 char surface_name[16];
00396
00397 sprintf( surface_name, "SURFACE %d", (int)(surface_index) );
00398
00399 m_it = models.find( surface_name );
00400 if( m_it!=models.end() ){
00401 model = (*m_it).second;
00402 if( model==NULL ){
00403 emsg( M_LWO, "Model-surface %s found as NULL", surface_name );
00404 bad_count++;
00405 delete face;
00406 continue;
00407 }
00408 face->makeNormal();
00409 model->add( face );
00410 faces.insert( std::make_pair(num_faces,face) );
00411 num_faces++;
00412 }else{
00413 emsg( M_LWO, "Model-surface %s not found", surface_name );
00414 bad_count++;
00415 delete face;
00416 continue;
00417 }
00418 }else{
00419 bad_count++;
00420 delete face;
00421 }
00422 }
00423
00424 if( bad_count > 0 ){
00425 dmsg( M_LWO, "%ld good polygons read %ld bad polygons skipped", num_faces, bad_count );
00426 if( point_count>0 ){
00427 dmsg( M_LWO, "%ld points, not yet supported", point_count );
00428 }
00429 if( line_count>0 ){
00430 dmsg( M_LWO, "%ld lines, not yet supported", line_count );
00431 }
00432 }
00433 }
00434
00435
00437 void LWLayer::curveList(){
00438
00439 }
00440
00441
00443 void LWLayer::patchList(){
00444
00445 }
00446
00447
00460 void LWLayer::surface_sc(){
00461 string_to_LWSurface::iterator s_it;
00462 std::string surface_name;
00463 LWSurface *surface;
00464
00465 surface_name = f->read_S0();
00466
00467 s_it = surfaces.find( surface_name );
00468 if( s_it != surfaces.end() ){
00469 surface = (*s_it).second;
00470 if( surface == NULL ){
00471 emsg( M_LWO, "NULL surface %s in surfacelist", surface_name.c_str() );
00472 return;
00473 }
00474 }else{
00475 surface = new LWSurface( this, this, surface_name );
00476 }
00477
00478 while( f->domainLeft() > 0 ){
00479 surface->processSubChunk();
00480 }
00481 surface->endSurface();
00482 }
00483
00484
00500 void LWLayer::vertexMapping_ID4_U2_S0_d(){
00501 ID4 vmap_type = f->read_ID4();
00502 U2 vmap_dim = f->read_U2();
00503 std::string vmap_name = f->read_S0();
00504
00505 dmsg( M_LWO, "%s Vertex map %s", did(vmap_type), vmap_name.c_str() );
00506
00507 while( f->domainLeft() > 0 ){
00508 VX vertex_id = f->read_VX();
00509 for( int i=0; i<vmap_dim; i++ ){
00510 F4 value = f->read_F4();
00511 }
00512 switch( vmap_type ){
00513 case ID_TXUV:
00514 case ID_MNUW:
00515 case ID_MORF:
00516 case ID_SPOT:
00517 case ID_RGBA:
00518 default:
00519 break;
00520 }
00521
00522 }
00523
00524 }
00525
00526
00552 void LWLayer::polygonList(){
00553 Face *face;
00554 Vertex *vertex;
00555 ID4 polygons_type = f->read_ID4();
00556 U4 vertex_index;
00557 int i;
00558 bool good;
00559 int bad_count = 0;
00560 int point_count = 0;
00561 int line_count = 0;
00562
00563 while( f->domainLeft() > 0 ){
00564 U2 data = f->read_U2();
00565 U2 numvert = data & 0x03ff;
00566 U2 flags = (data & ~numvert) >> 10;
00567
00568 if( numvert<3 ){
00569 bad_count++;
00570 switch( num_vertices ){
00571 case 0: bad_count++; emsg( M_LWO, "Bad polygon - 0 vertices" ); break;
00572 case 1: bad_count++; point_count++; break;
00573 case 2: bad_count++; line_count++; break;
00574 }
00575 for( i=0; i<numvert; i++ ){
00576 vertex_index = f->read_VX();
00577 }
00578 continue;
00579 }
00580
00581 face = new Face();
00582 good = true;
00583
00584 for( i=0; i<numvert; i++ ){
00585
00586 if( f->domainLeft()<2 ){
00587 emsg( M_LWO, "Not enough bytes left in chunk" );
00588 good = false;
00589 break;
00590 }
00591
00592 vertex_index = f->read_VX();
00593 if( vertex_index > this->num_vertices ){
00594 emsg( M_LWO, "Not understood as vertex index %ld > %ld", vertex_index, num_vertices );
00595 good = false;
00596 break;
00597 }
00598
00599 U4_to_Vertex::iterator v_it = vertices.find( vertex_index);
00600 if( v_it!=vertices.end() ){
00601 vertex = (*v_it).second;
00602 if( vertex != NULL ){
00603 face->add( vertex );
00604 }else{
00605 emsg( M_LWO, "Vertex %ld pointer is NULL", vertex_index );
00606 good = false;
00607 }
00608 }else{
00609 emsg( M_LWO, "Vertex %ld not found", vertex_index );
00610 good = false;
00611 }
00612 }
00613 if( good ){
00614 face->makeNormal();
00615 faces.insert( pair<U4,Face*>(num_faces,face) );
00616 num_faces++;
00617 }else{
00618 bad_count++;
00619 delete face;
00620 }
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631 }
00632
00633 if( bad_count > 0 ){
00634 dmsg( M_LWO, "%ld good polygons read %d bad polygons skipped", num_faces, bad_count );
00635 if( point_count>0 ){
00636 dmsg( M_LWO, "%d points, not yet supported", point_count );
00637 }
00638 if( line_count>0 ){
00639 dmsg( M_LWO, "%d lines, not yet supported", line_count );
00640 }
00641 }
00642 }
00643
00644
00676 void LWLayer::polygonTags_ID4_d(){
00677 string_to_LWSurface::iterator s_it;
00678 string_to_Model ::iterator m_it;
00679 U4_to_Face ::iterator f_it;
00680
00681 Face *face;
00682 LWSurface *surface;
00683 LWModel *root_model;
00684 Model *model;
00685 VX polygon_index;
00686 U4 tag_index;
00687 ID4 tag_type;
00688 std::string tag_value;
00689
00690 root_model = this->model;
00691 if( root_model == NULL ){
00692 emsg( M_LWO, "Can not access root Model" );
00693 return;
00694 }
00695
00696 if( (f->getOptions() & LWFILE_OPTION_SKIP_MATERIAL_M) == LWFILE_OPTION_SKIP_MATERIAL_M ){
00697 surface = new LWSurface( this, this, "skipped materials" );
00698 model = this;
00699 model->setMaterial( surface );
00700 }
00701
00702
00703 tag_type = f->read_ID4();
00704
00705 while( f->domainLeft() > 0 ){
00706
00707 polygon_index = f->read_VX();
00708 tag_index = f->read_U2();
00709 tag_value = root_model->getTag( tag_index );
00710
00711 switch( tag_type ){
00712 case ID_SURF:
00713 f_it = faces .find( polygon_index );
00714 s_it = surfaces.find( tag_value );
00715 m_it = models .find( tag_value );
00716
00717
00718 if( f_it != faces.end() ){
00719 face = (*f_it).second;
00720 if( face == NULL ){
00721 emsg( M_LWO, "FACE FOUND AS NULL" );
00722 break;
00723 }
00724 }else{
00725 emsg( M_LWO, "FACE NOT FOUND" );
00726 break;
00727 }
00728
00729
00730
00731 if( !((f->getOptions() & LWFILE_OPTION_SKIP_MATERIAL_M) == LWFILE_OPTION_SKIP_MATERIAL_M) ){
00732 if( s_it == surfaces.end() ){
00733 surface = new LWSurface( this, NULL, tag_value );
00734 surfaces.insert( std::make_pair(tag_value,surface) );
00735 }else{
00736 surface = (*s_it).second;
00737 }
00738
00739
00740 if( m_it == models.end() ){
00741 model = new Model( tag_value );
00742 models.insert( std::make_pair(tag_value,model) );
00743 model->setMaterial( surface );
00744 this->add( model );
00745 }else{
00746 model = (*m_it).second;
00747 }
00748
00749
00750 surface->setModel( model );
00751 }
00752 model->add( face );
00753
00754 break;
00755
00756 default:
00757 dmsg( M_LWO, "UNKNOWN TAG" );
00758 break;
00759 }
00760 }
00761 }
00762
00763
00779 void LWLayer::envelope_U4_sc(){
00780 U4 envelope_index = f->read_U4();
00781 LWEnvelope *envelope = new LWEnvelope( f );
00782
00783 envelopes.insert( make_pair(num_envelopes,envelope) );
00784 num_envelopes++;
00785 while( f->domainLeft() > 0 ){
00786 envelope->processEnvelope();
00787 }
00788 }
00789
00790
00803 void LWLayer::clip_U4_sc(){
00804 U4 clip_index = f->read_U4();
00805 LWClip *clip = new LWClip( f );
00806
00807 if( clip_index >= 0x1000000 ){
00808 emsg( M_LWO, "Clip index not below 0x1000000" );
00809 }
00810
00811 clips.insert( make_pair(clip_index,clip) );
00812 num_clips++;
00813 while( f->domainLeft() > 0 ){
00814 clip->processClip();
00815 }
00816 }
00817
00818
00833 void LWLayer::surf_S0_S0_sc(){
00834 string_to_LWSurface::iterator s_it;
00835 std::string surface_name;
00836 std::string surface_source;
00837 LWSurface *surface;
00838
00839 surface_name = f->read_S0();
00840 surface_source = f->read_S0();
00841
00842 s_it = surfaces.find( surface_name );
00843 if( s_it != surfaces.end() ){
00844 surface = (*s_it).second;
00845 if( surface == NULL ){
00846 emsg( M_LWO, "NULL surface %s in surfacelist", surface_name.c_str() );
00847 return;
00848 }
00849 }else{
00850 dmsg( M_LWO, "New SURF" );
00851 surface = new LWSurface( this, NULL, surface_name.c_str() );
00852 }
00853
00854 if( surface_source.length() > 0 ){
00855 dmsg( M_LWO, "LW Object loader: No material inheritance yet" );
00856
00857 }
00858 while( f->domainLeft() > 0 ){
00859 surface->processSubChunk();
00860 }
00861 surface->endSurface();
00862 }
00863
00864
00874 void LWLayer::boundingBox_VEC12_VEC12(){
00875 bbox_min = f->read_VEC12();
00876 bbox_max = f->read_VEC12();
00877 }
00878
00879
00891 void LWLayer::descriptionLine_S0(){
00892 description_line = f->read_S0();
00893 }
00894
00895
00905 void LWLayer::comments_S0(){
00906 commentary_text = f->read_S0();
00907 }
00908
00909
00923 void LWLayer::thumbnail_U2_U2_d(){
00924 U2 encoding = f->read_U2();
00925 U2 width = f->read_U2();
00926
00927 if( encoding != 0 ){
00928 dmsg( M_LWO, "Unknown thumbnail encoding" );
00929 return;
00930 }
00931
00932 while( f->domainLeft() > 0 ){
00933 for( int x=0; x<width; x++ ){
00934 U1 red = f->read_U1();
00935 U1 green = f->read_U1();
00936 U1 blue = f->read_U1();
00937
00938 }
00939 }
00940 }
00941
00942
00943 };
00944 };
00945
00946
00947 #endif // TEDDY_INCLUDE_LW_SCENE
00948