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