Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

GeometryTextureCoordinates.cpp

Go to the documentation of this file.
00001 
00002 /*
00003     TEDDY - General graphics application library
00004     Copyright (C) 1999-2002  Timo Suoranta
00005     tksuoran@cc.helsinki.fi
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Lesser General Public
00009     License as published by the Free Software Foundation; either
00010     version 2.1 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     Lesser General Public License for more details.
00016 
00017     You should have received a copy of the GNU Lesser General Public
00018     License along with this library; if not, write to the Free Software
00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 
00021     $Id: GeometryTextureCoordinates.cpp,v 1.4 2002/01/11 14:35:02 tksuoran Exp $
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     //  If the old vertex has no texture coordinate set, place new coordinate there
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         //  Otherwise if the old texture coordinate is different,
00124         //  make a new Vertex and replace the Vertex pointer in
00125         //  Face's Vertex list
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             //new_vertex->debug();
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             //  Otherwise, the old texture coordinate is the same
00152             //  as the new, and we do nothing about it.
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     //  For each Face Element in the Geometry
00230     list<Element*>::iterator e_it = elements.begin();
00231     while( e_it != elements.end() ){
00232         Element *e = (*e_it);
00233         element_count++;
00234 
00235         //  For each Vertex in the Face
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             //  Calculate texture coordinate from (x, y, z)
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; //fract( s );
00266             v = t; //fract( 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         }  //  vertex iterator v_it
00283         dmsg( M_TMAP, "Element ready, %ld vertices", element_vertices );
00284 
00285         e_it++;
00286     }  //  element iterator e_it;
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             //  if( widthTiling != 1 ) lon = fract(lon) * widthTiling;
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             //lon = 1.0 - lon / M_2_PI;
00500             lon = lon / M_2_PI;
00501             lat = 0.5 - lat / M_PI;
00502             //  if( widthTiling  != 1 ) lon = fract(lon) * widthTiling;
00503             //  if( heightTiling != 1 ) lat = fract(lat) * heightTiling;
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     //  For each Face Element in the Geometry
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         //  For each Vertex in the element
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             //  Calculate texture coordinate from (x, y, z)
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; //fract( s );
00619             v = t; //fract( 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         }  //  vertex iterator v_it
00636         dmsg( M_TMAP, "Element ready, %ld vertices", element_vertices );
00637 
00638         e_it++;
00639     }  //  element iterator e_it;
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 };  //  namespace Imports
00651 };  //  namespace Teddy
00652