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/Models/Face.h"
00026 #include "Teddy/Models/Geometry.h"
00027 #include "Teddy/Models/Vertex.h"
00028 #include "Teddy/SysSupport/Messages.h"
00029 #include "Teddy/SysSupport/StdMaths.h"
00030 #include "Teddy/SysSupport/StdIO.h"
00031 using namespace Teddy::SysSupport;
00032 
00033 
00034 namespace Teddy  {
00035 namespace Models {
00036 
00037 
00038 #define TC_EPSILON (double)(0.0009) // texturecoordinate face epsilon
00039 
00040 
00042 static void xyz_to_h( const float x, const float y, const float z, float &h ){
00043     if( x == 0 && z == 0){
00044         h = 0;
00045     }else{
00046         if( z == 0 ){
00047             h = (x < 0) ? M_HALF_PI : -M_HALF_PI;
00048         }else if (z < 0){
00049             h = -atan(x / z) + M_PI;
00050         }else{
00051             h = -atan(x / z);
00052         }
00053     }
00054 }
00055 
00056 
00058 static void xyz_to_hp( float x, float y, float z, float &h, float &p ){
00059     
00060     if( x == 0 && z == 0 ){
00061         h = 0;
00062         
00063         if( y != 0 ){
00064             p = (y<0) ? -M_HALF_PI : M_HALF_PI;
00065         }else{
00066             p = 0;
00067         }
00068     
00069     }else{
00070         if( z == 0 ){
00071             h = (x < 0) ? M_HALF_PI : -M_HALF_PI;
00072         }else if( z < 0){
00073             h = -atan( x/z ) + M_PI;
00074         }else{
00075             h = -atan( x/z );
00076         }
00077         
00078         x = sqrt( x*x + z*z );
00079         
00080         if( x == 0 ){
00081             p = (y<0) ? -M_HALF_PI : M_HALF_PI;
00082         }else{
00083             p = atan( y/x );
00084         }
00085     }
00086 }
00087 
00088 
00090 static float fract( float f ){
00091     float val = (float)(f - floor( f ) );
00092 
00093     return val;
00094 }
00095 
00096 
00098 
00105 void Geometry::setTextureCoordinate( Element *e, list<Vertex*>::iterator v_it, float s, float t ){
00106     Vertex *vx = *v_it;
00107 
00108     Vector new_tc = Vector( s, t, 0.0f );
00109 
00110     
00111     if( vx->isDisabled(Element::VX_HAS_TEXTURE) ){
00112         dmsg( M_TMAP,
00113             "Vertex %ld had no old texture coordinate, setting (%.8f, %.8f)",
00114             (unsigned long)vx,
00115             s, 
00116             t
00117         );
00118         vx->setTexture( new_tc );
00119         if( vx->isDisabled(Element::VX_HAS_TEXTURE) ){
00120             dmsg( M_TMAP, "Vertex tc problem" );
00121         }
00122     }else{
00123         
00124         
00125         
00126         Vector old_tc = vx->getTexture();
00127         float ds = fabs( old_tc.v[0] - new_tc.v[0] );
00128         float dt = fabs( old_tc.v[1] - new_tc.v[1] );
00129         if( ds > TC_EPSILON || dt > TC_EPSILON ){
00130             dmsg( M_TMAP,
00131                 "Vertex %ld had a different texture coordinate delta = (%.8f, %.8f), making copy new tc = (%.8f, %.8f)",
00132                 (unsigned long)vx,
00133                 ds,
00134                 dt,
00135                 s, 
00136                 t
00137             );
00138             Vertex *new_vertex = new Vertex( vx );
00139             new_vertex->setTexture( new_tc );
00140             *v_it = new_vertex;
00141             
00142         }else{
00143             dmsg( M_TMAP,
00144                 "Vertex %ld had the same texture coordinate delta = (%.8f, %.8f), tc = (%.8f, %.8f)",
00145                 (unsigned long)vx,
00146                 ds,
00147                 dt,
00148                 s, 
00149                 t
00150             );
00151             
00152             
00153         }
00154     }
00155 }
00156 
00157 
00205 void Geometry::makePlanarTextureCoordinates( Vector center, Vector size, int axis ){
00206     float s = 0;
00207     float t = 0;
00208     float u;
00209     float v;
00210     float x, y, z;
00211 
00212     dmsg( M_TMAP, "Planar Image Map, Axis %d", axis );
00213     dmsg( M_TMAP,
00214         "Texture center (%.1f, %.1f, %.1f )",
00215         center.v[0],
00216         center.v[1],
00217         center.v[2]
00218     );
00219     dmsg( M_TMAP,
00220         "Texture size (%.1f, %.1f, %.1f )",
00221         size.v[0],
00222         size.v[1],
00223         size.v[2]
00224     );
00225 
00226     int element_count = 0;
00227     int vertex_count  = 0;
00228 
00229     
00230     list<Element*>::iterator e_it = elements.begin();
00231     while( e_it != elements.end() ){
00232         Element *e = (*e_it);
00233         element_count++;
00234 
00235         
00236         int element_vertices = 0;
00237         list<Vertex*>::iterator v_it = e->vertices.begin();
00238         while( v_it != e->vertices.end() ){
00239             Vertex *vx = *v_it;
00240             if( vx == NULL ){
00241                 dmsg( M_TMAP, "Found NULL vertex" );
00242                 v_it++;
00243                 continue;
00244             }
00245         
00246             vertex_count++;
00247             element_vertices++;
00248 
00249             x = vx->getVertex().v[0];
00250             y = vx->getVertex().v[1];
00251             z = vx->getVertex().v[2];
00252 
00253             
00254             x -= center.v[0];
00255             y -= center.v[1];
00256             z -= center.v[2];
00257 
00258             switch( axis ){
00259             case TEXTURE_AXIS_X: s = ( z / size.v[2]) + .5; t = (-y / size.v[1]) + .5; break;
00260             case TEXTURE_AXIS_Y: s = ( x / size.v[0]) + .5; t = (-z / size.v[2]) + .5; break;
00261             case TEXTURE_AXIS_Z: s = ( x / size.v[0]) + .5; t = (-y / size.v[1]) + .5; break;
00262             default: dmsg( M_TMAP, "Bad axis %d", axis ); break;
00263             }
00264 
00265             u = s; 
00266             v = t; 
00267             if( fabs(u)<TC_EPSILON && fabs(v)<TC_EPSILON ){
00268                 dmsg( M_TMAP,
00269                     "x = %.5f, y = %.5f, z = %.5f, size.v[0] = %.5f size.v[1] = %.5f size.v[2] = %.5f",
00270                     x,
00271                     y,
00272                     z,
00273                     size.v[0],
00274                     size.v[1],
00275                     size.v[2]
00276                 );
00277                 dmsg( M_TMAP, "Problem" );
00278             }
00279             setTextureCoordinate( e, v_it, u, v );
00280 
00281             v_it++;
00282         }  
00283         dmsg( M_TMAP, "Element ready, %ld vertices", element_vertices );
00284 
00285         e_it++;
00286     }  
00287 
00288     dmsg( M_TMAP,
00289         "Texture coordinates ready, %d elements %d vertices",
00290         element_count,
00291         vertex_count
00292     );
00293 
00294 }
00295 
00296 
00332 void Geometry::makeCylindricalTextureCoordinates( Vector center, Vector size, int axis ){
00333     float t = 0;
00334     float u;
00335     float v;
00336     float lon;
00337     float x,y,z;
00338 
00339     dmsg( M_TMAP, "Cylindrical Image Map, Axis %d", axis );
00340     dmsg( M_TMAP,
00341         "Texture center (%.1f, %.1f, %.1f )",
00342         center.v[0],
00343         center.v[1],
00344         center.v[2]
00345     );
00346     dmsg( M_TMAP,
00347         "Texture size (%.1f, %.1f, %.1f )",
00348         size.v[0],
00349         size.v[1],
00350         size.v[2]
00351     );
00352 
00353     int element_count = 0;
00354     int vertex_count  = 0;
00355 
00356     list<Element*>::iterator e_it = elements.begin();
00357     while( e_it != elements.end() ){
00358         Element *e = (*e_it);
00359         element_count++;
00360 
00361         list<Vertex*>::iterator v_it = e->vertices.begin();
00362         while( v_it != e->vertices.end() ){
00363             Vertex *vx = (*v_it);
00364             if( vx == NULL ){
00365                 dmsg( M_TMAP, "Found NULL vertex" );
00366                 v_it++;
00367                 continue;
00368             }
00369 
00370             vertex_count++;
00371 
00372             x = vx->getVertex().v[0];
00373             y = vx->getVertex().v[1];
00374             z = vx->getVertex().v[2];
00375 
00376             x -= center.v[0];
00377             y -= center.v[1];
00378             z -= center.v[2];
00379 
00380             switch( axis ){
00381             case TEXTURE_AXIS_X: xyz_to_h(  z,  x, -y, lon ); t = -x / size.v[0] + .5; break;
00382             case TEXTURE_AXIS_Y: xyz_to_h( -x,  y,  z, lon ); t = -y / size.v[1] + .5; break;
00383             case TEXTURE_AXIS_Z: xyz_to_h( -x,  z, -y, lon ); t = -z / size.v[2] + .5; break;
00384             default: dmsg( M_TMAP, "Bad axis %d", axis ); break;
00385             }
00386 
00387             lon = 1 - lon / M_2_PI;
00388             
00389             u = fract( lon );
00390             v = fract( t   );
00391 
00392             setTextureCoordinate( e, v_it, u, v );
00393 
00394             v_it++;
00395         }
00396 
00397         e_it++;
00398     }
00399 
00400     dmsg( M_TMAP,
00401         "Texture coordinates ready, %d elements %d vertices",
00402         element_count,
00403         vertex_count
00404     );
00405 
00406 }
00407 
00408 
00444 void Geometry::makeSphericalTextureCoordinates( Vector center, Vector size, int axis ){
00445     float lon;
00446     float lat;
00447     float u;
00448     float v;
00449     float x,y,z;
00450 
00451     dmsg( M_TMAP, "Spherical Image Map, Axis %d", axis );
00452     dmsg( M_TMAP,
00453         "Texture center (%.1f, %.1f, %.1f )",
00454         center.v[0],
00455         center.v[1],
00456         center.v[2]
00457     );
00458     dmsg( M_TMAP,
00459         "Texture size (%.1f, %.1f, %.1f )",
00460         size.v[0],
00461         size.v[1],
00462         size.v[2]
00463     );
00464 
00465     int element_count = 0;
00466     int vertex_count  = 0;
00467 
00468     list<Element*>::iterator e_it = elements.begin();
00469     while( e_it != elements.end() ){
00470         Element *e = (*e_it);
00471         element_count++;
00472 
00473         list<Vertex*>::iterator v_it = e->vertices.begin();
00474         while( v_it != e->vertices.end() ){
00475             Vertex *vx = (*v_it);
00476             if( vx == NULL ){
00477                 dmsg( M_TMAP, "Found NULL vertex" );
00478                 v_it++;
00479                 continue;
00480             }
00481 
00482             vertex_count++;
00483 
00484             x = vx->getVertex().v[0];
00485             y = vx->getVertex().v[1];
00486             z = vx->getVertex().v[2];
00487 
00488             x -= center.v[0];
00489             y -= center.v[1];
00490             z -= center.v[2];
00491 
00492             switch( axis ){
00493             case TEXTURE_AXIS_X: xyz_to_hp(  z,  x, -y, lon, lat ); break;
00494             case TEXTURE_AXIS_Y: xyz_to_hp( -x,  y,  z, lon, lat ); break;
00495             case TEXTURE_AXIS_Z: xyz_to_hp( -x,  z, -y, lon, lat ); break;
00496             default: dmsg( M_TMAP, "Bad axis %d", axis ); break;
00497             }
00498 
00499             
00500             lon = lon / M_2_PI;
00501             lat = 0.5 - lat / M_PI;
00502             
00503             
00504             u = fract( lon );
00505             v = fract( lat );
00506 
00507             setTextureCoordinate( e, v_it, u, v );
00508 
00509             v_it++;
00510         }
00511 
00512         e_it++;
00513     }
00514 
00515     dmsg( M_TMAP,
00516         "Texture coordinates ready, %d elements %d vertices",
00517         element_count,
00518         vertex_count
00519     );
00520 }
00521 
00522 
00549 void Geometry::makeCubicTextureCoordinates( Vector center, Vector size ){
00550     float s = 0;
00551     float t = 0;
00552     float u;
00553     float v;
00554     float x, y, z;
00555 
00556     dmsg( M_TMAP, "Cubic Image Map" );
00557     dmsg( M_TMAP,
00558         "Texture center (%.1f, %.1f, %.1f )",
00559         center.v[0],
00560         center.v[1],
00561         center.v[2]
00562     );
00563     dmsg( M_TMAP,
00564         "Texture size (%.1f, %.1f, %.1f )",
00565         size.v[0],
00566         size.v[1],
00567         size.v[2]
00568     );
00569 
00570     int element_count = 0;
00571     int vertex_count  = 0;
00572 
00573     
00574     list<Element*>::iterator e_it = elements.begin();
00575     while( e_it != elements.end() ){
00576         Element *e = (*e_it);
00577         element_count++;
00578 
00579         if( e->isDisabled(Element::EL_HAS_ELEMENT_NORMAL) ){
00580             e->makeNormal();
00581         }
00582 
00583         Vector en   = e->getNormal();
00584         int    axis = TEXTURE_AXIS_X;
00585         if( fabs(en.v[1]) >= fabs(en.v[0]) && fabs(en.v[1]) >= fabs(en.v[2]) ) axis = TEXTURE_AXIS_Y;
00586         if( fabs(en.v[2]) >= fabs(en.v[0]) && fabs(en.v[2]) >= fabs(en.v[1]) ) axis = TEXTURE_AXIS_Z;
00587 
00588         
00589         int element_vertices = 0;
00590         list<Vertex*>::iterator v_it = e->vertices.begin();
00591         while( v_it != e->vertices.end() ){
00592             Vertex *vx = *v_it;
00593             if( vx == NULL ){
00594                 dmsg( M_TMAP, "Found NULL vertex" );
00595                 v_it++;
00596                 continue;
00597             }
00598         
00599             vertex_count++;
00600             element_vertices++;
00601 
00602             x = vx->getVertex().v[0];
00603             y = vx->getVertex().v[1];
00604             z = vx->getVertex().v[2];
00605 
00606             
00607             x -= center.v[0];
00608             y -= center.v[1];
00609             z -= center.v[2];
00610 
00611             switch( axis ){
00612             case TEXTURE_AXIS_X: s = ( z / size.v[2]) + .5; t = (-y / size.v[1]) + .5; break;
00613             case TEXTURE_AXIS_Y: s = ( x / size.v[0]) + .5; t = (-z / size.v[2]) + .5; break;
00614             case TEXTURE_AXIS_Z: s = ( x / size.v[0]) + .5; t = (-y / size.v[1]) + .5; break;
00615             default: dmsg( M_TMAP, "Bad axis %d", axis ); break;
00616             }
00617 
00618             u = s; 
00619             v = t; 
00620             if( fabs(u)<TC_EPSILON && fabs(v)<TC_EPSILON ){
00621                 dmsg( M_TMAP,
00622                     "x = %.5f, y = %.5f, z = %.5f, size.v[0] = %.5f size.v[1] = %.5f size.v[2] = %.5f",
00623                     x,
00624                     y,
00625                     z,
00626                     size.v[0],
00627                     size.v[1],
00628                     size.v[2]
00629                 );
00630                 dmsg( M_TMAP, "Problem" );
00631             }
00632             setTextureCoordinate( e, v_it, u, v );
00633 
00634             v_it++;
00635         }  
00636         dmsg( M_TMAP, "Element ready, %ld vertices", element_vertices );
00637 
00638         e_it++;
00639     }  
00640 
00641     dmsg( M_TMAP,
00642         "Texture coordinates ready, %d elements %d vertices",
00643         element_count,
00644         vertex_count
00645     );
00646 
00647 }
00648 
00649 
00650 };  
00651 };  
00652