00001
00002 #include "Types.h"
00003 #include "Util.h"
00004 #include "Error.h"
00005 #include "Plane.h"
00006 #include "RelationalNode.h"
00007 #include "Rendergroup.h"
00008 #include "Vertexbuffer.h"
00009
00011 #include "Rendernode.h"
00013 #include "Program.h"
00014 #include "Stateset.h"
00015 #include "Sampler.h"
00016
00017 #include <sys/stat.h>
00018
00019 namespace RenderTools{
00020
00021 vector<string> s_rootDirs;
00022 vector<string> s_subDirs;
00023 string s_lastSuccessfulPrefix = "";
00024
00025 void addSearchRoot( string dir ){
00026 if( dir.size() ){
00028 replace( dir.begin(), dir.end(), '\\', '/' );
00029 if( dir[ dir.size() - 1 ] != '/' ){
00030 dir += "/";
00031 }
00032 s_rootDirs.push_back( dir );
00033 }
00034 }
00035
00036 void addSearchDir( string dir ){
00037 if( dir.size() ){
00039 replace( dir.begin(), dir.end(), '\\', '/' );
00040 if( dir[ dir.size() - 1 ] != '/' ){
00041 dir += "/";
00042 }
00043 s_subDirs.push_back( dir );
00044 }
00045 }
00046
00047 string findFile( string name, bool verbose ){
00048 struct stat results;
00049
00051 if( stat( name.c_str(), & results ) == 0 ){
00052 if( verbose ){
00053 cout << "found: " << name << endl;
00054 }
00055 return( name );
00056 }
00057
00059 if( s_lastSuccessfulPrefix != "" ){
00060 string fullname = s_lastSuccessfulPrefix + name;
00061 if( stat( fullname.c_str(), & results ) == 0 ){
00062 if( verbose ){
00063 cout << "found: " << fullname << endl;
00064 }
00065 return( fullname );
00066 }
00067 }
00068
00070 replace( name.begin(), name.end(), '\\', '/' );
00071
00073 for( int i = -2; i < (int)s_subDirs.size(); i++ ){
00074 for( unsigned int j = 0; j < s_rootDirs.size(); j++ ){
00075 string prefix = s_rootDirs[ j ];
00076
00078 if( i == - 1 ){
00080 prefix += "rsrc/";
00081 }
00082 else if( i >= 0 ){
00084 prefix += s_subDirs[ i ];
00085 }
00086
00088 string fullname = prefix + name;
00089
00090 if( verbose ){
00091 cout << "looking for: " << fullname << endl;
00092 }
00093
00095 if( stat( fullname.c_str(), & results ) == 0 ){
00096 if( verbose ){
00097 cout << "found: " << fullname << endl;
00098 }
00099
00101 s_lastSuccessfulPrefix = prefix;
00102 return( fullname );
00103 }
00104 }
00105 }
00108 Error::warning( Error::FILE_NOT_FOUND, __FILE__, __LINE__ );
00109 return( "" );
00110 }
00111
00112 void erase( const string & subString, string & fromThis ){
00113 size_t pos = fromThis.find( subString );
00114 while( pos != string::npos ){
00115 fromThis.erase( pos, subString.size() );
00116 pos = fromThis.find( subString );
00117 }
00118 }
00119
00120 void replace( string & context, const string & from, const string & to ){
00121 size_t lookHere = 0;
00122 size_t foundHere;
00123 while( ( foundHere = context.find( from, lookHere ) ) != string::npos ){
00124 context.replace( foundHere, from.size(), to );
00125 lookHere = foundHere + to.size();
00126 }
00127 }
00128
00129 Vec3 NAABB::getCorner( int i ) const {
00130 switch( i ){
00131 case 0: return( Vec3( m_lo[0], m_lo[1], m_lo[2] ) );
00132 case 1: return( Vec3( m_hi[0], m_lo[1], m_lo[2] ) );
00133 case 2: return( Vec3( m_hi[0], m_hi[1], m_lo[2] ) );
00134 case 3: return( Vec3( m_lo[0], m_hi[1], m_lo[2] ) );
00135 case 4: return( Vec3( m_lo[0], m_lo[1], m_hi[2] ) );
00136 case 5: return( Vec3( m_hi[0], m_lo[1], m_hi[2] ) );
00137 case 6: return( Vec3( m_hi[0], m_hi[1], m_hi[2] ) );
00138 case 7: return( Vec3( m_lo[0], m_hi[1], m_hi[2] ) );
00139 }
00140 Error::error( Error::INDEX_OUT_OF_BOUNDS, __FILE__, __LINE__ );
00141 return( Vec3( 0,0,0 ) );
00142 }
00143
00144 void NAABB::adjust( const Vec3 & vct ){
00145 if( vct[0] < m_lo[0] )m_lo[0] = vct[0];
00146 if( vct[1] < m_lo[1] )m_lo[1] = vct[1];
00147 if( vct[2] < m_lo[2] )m_lo[2] = vct[2];
00148 if( vct[0] > m_hi[0] )m_hi[0] = vct[0];
00149 if( vct[1] > m_hi[1] )m_hi[1] = vct[1];
00150 if( vct[2] > m_hi[2] )m_hi[2] = vct[2];
00151 }
00152
00153 void NAABB::adjust( const NAABB & box ){
00154 for( int i = 0; i < 8; i++ ){
00155 adjust( box.getCorner( i ) );
00156 }
00157 }
00158
00159 Vec3 NAABB::getCenter() const {
00160 Vec3 r = ( m_lo + m_hi );
00161 return( r / float( 2.0 ) );
00162 }
00163
00164 Vec3 NAABB::getSize() const {
00165 return( m_hi - m_lo );
00166 }
00167
00168 void cmyk_rgb( const Vec4 & cmyk, Vec3 & rgb ){
00169 rgb[ 0 ] = 1.0f - ( cmyk[ 0 ] * ( 1.0 - cmyk[ 3 ] ) + cmyk[ 3 ] );
00170 rgb[ 1 ] = 1.0f - ( cmyk[ 1 ] * ( 1.0 - cmyk[ 3 ] ) + cmyk[ 3 ] );
00171 rgb[ 2 ] = 1.0f - ( cmyk[ 2 ] * ( 1.0 - cmyk[ 3 ] ) + cmyk[ 3 ] );
00172 }
00173
00174 void rgb_cmyk( const Vec3 & rgb, Vec4 & cmyk ){
00175 float r_ = 1.0f - rgb[ 0 ];
00176 float g_ = 1.0f - rgb[ 1 ];
00177 float b_ = 1.0f - rgb[ 2 ];
00178
00179 cmyk[ 3 ] = min( min( r_, g_ ), b_ );
00180 cmyk[ 0 ] = ( r_ - cmyk[ 3 ] ) / ( 1.0 - cmyk[ 3 ] );
00181 cmyk[ 1 ] = ( g_ - cmyk[ 3 ] ) / ( 1.0 - cmyk[ 3 ] );
00182 cmyk[ 2 ] = ( b_ - cmyk[ 3 ] ) / ( 1.0 - cmyk[ 3 ] );
00183 }
00184
00186 void rgb_hsl( const Vec3 & rgb, Vec3 & hsl ){
00187 float r = rgb[ 0 ];
00188 float g = rgb[ 1 ];
00189 float b = rgb[ 2 ];
00190 double v;
00191 double m;
00192 double vm;
00193 double r2, g2, b2;
00194
00195 v = largest( r, g );
00196 v = largest( v, b );
00197 m = smallest( r, g );
00198 m = smallest( m, b );
00199
00200 hsl = Vec3();
00201
00202 if( ( hsl[ 2 ] = ( m + v ) / 2.0 ) <= 0.0 ){
00203 return;
00204 }
00205 if( ( hsl[ 1 ] = vm = v - m ) > 0.0 ){
00206 hsl[ 1 ] /= ( hsl[ 2 ] <= 0.5 ) ? ( v + m ) : (2.0 - v - m );
00207 }
00208 else{
00209 return;
00210 }
00211
00212 r2 = ( v - r ) / vm;
00213 g2 = ( v - g ) / vm;
00214 b2 = ( v - b ) / vm;
00215
00216 if( r == v ){
00217 hsl[ 0 ] = ( g == m ? 5.0 + b2 : 1.0 - g2 );
00218 }
00219 else if( g == v ){
00220 hsl[ 0 ] = ( b == m ? 1.0 + r2 : 3.0 - b2 );
00221 }
00222 else{
00223 hsl[ 0 ] = ( r == m ? 3.0 + g2 : 5.0 - r2 );
00224 }
00225 hsl[ 0 ] *= 0.1666667;
00226 }
00227
00228 void hsl_rgb( const Vec3 & hsl, Vec3 & rgb ){
00229 float h = hsl[ 0 ];
00230 float sl = hsl[ 1 ];
00231 float l = hsl[ 2 ];
00232 float v;
00233
00234 v = ( l <= 0.5 ) ? ( l * ( 1.0 + sl ) ) : ( l + sl - l * sl );
00235 if( v <= 0.0f ) {
00236 rgb = Vec3();
00237 }
00238 else {
00239 double m;
00240 double sv;
00241 int sextant;
00242 double fract, vsf, mid1, mid2;
00243
00244 m = l + l - v;
00245 sv = ( v - m ) / v;
00246 h *= 6.0;
00247 sextant = h;
00248 fract = h - sextant;
00249 vsf = v * sv * fract;
00250 mid1 = m + vsf;
00251 mid2 = v - vsf;
00252 switch( sextant ) {
00253 case 0: rgb[ 0 ] = v; rgb[ 1 ] = mid1; rgb[ 2 ] = m; break;
00254 case 1: rgb[ 0 ] = mid2; rgb[ 1 ] = v; rgb[ 2 ] = m; break;
00255 case 2: rgb[ 0 ] = m; rgb[ 1 ] = v; rgb[ 2 ] = mid1; break;
00256 case 3: rgb[ 0 ] = m; rgb[ 1 ] = mid2; rgb[ 2 ] = v; break;
00257 case 4: rgb[ 0 ] = mid1; rgb[ 1 ] = m; rgb[ 2 ] = v; break;
00258 case 5: rgb[ 0 ] = v; rgb[ 1 ] = m; rgb[ 2 ] = mid2; break;
00259 }
00260 }
00261 }
00262
00263 #ifndef RT_AS3
00264 void NAABB::render( GLenum method ) const {
00265 # ifndef RT_GLES
00266 Vec3 corner[8];
00267 for( int i = 0; i < 8; i++ ){
00268 corner[i] = getCorner( i );
00269 }
00270 glBegin( method );
00271 glVertex3fv( *corner[0] );
00272 glVertex3fv( *corner[1] );
00273 glVertex3fv( *corner[2] );
00274 glVertex3fv( *corner[3] );
00275 glEnd();
00276 glBegin( method );
00277 glVertex3fv( *corner[4] );
00278 glVertex3fv( *corner[5] );
00279 glVertex3fv( *corner[6] );
00280 glVertex3fv( *corner[7] );
00281 glEnd();
00282 glBegin( method );
00283 glVertex3fv( *corner[0] );
00284 glVertex3fv( *corner[1] );
00285 glVertex3fv( *corner[5] );
00286 glVertex3fv( *corner[4] );
00287 glEnd();
00288 glBegin( method );
00289 glVertex3fv( *corner[1] );
00290 glVertex3fv( *corner[2] );
00291 glVertex3fv( *corner[6] );
00292 glVertex3fv( *corner[5] );
00293 glEnd();
00294 glBegin( method );
00295 glVertex3fv( *corner[2] );
00296 glVertex3fv( *corner[3] );
00297 glVertex3fv( *corner[7] );
00298 glVertex3fv( *corner[6] );
00299 glEnd();
00300 glBegin( method );
00301 glVertex3fv( *corner[3] );
00302 glVertex3fv( *corner[0] );
00303 glVertex3fv( *corner[4] );
00304 glVertex3fv( *corner[7] );
00305 glEnd();
00306 # endif
00307 }
00308 #endif
00309
00310 Vec3 AABB::getCorner( int i ) const {
00311 switch( i ){
00312 case 0: return( Vec3( -m_size[0], -m_size[1], -m_size[2] ) );
00313 case 1: return( Vec3( +m_size[0], -m_size[1], -m_size[2] ) );
00314 case 2: return( Vec3( +m_size[0], +m_size[1], -m_size[2] ) );
00315 case 3: return( Vec3( -m_size[0], +m_size[1], -m_size[2] ) );
00316 case 4: return( Vec3( -m_size[0], -m_size[1], +m_size[2] ) );
00317 case 5: return( Vec3( +m_size[0], -m_size[1], +m_size[2] ) );
00318 case 6: return( Vec3( +m_size[0], +m_size[1], +m_size[2] ) );
00319 case 7: return( Vec3( -m_size[0], +m_size[1], +m_size[2] ) );
00320 }
00321 Error::error( Error::INDEX_OUT_OF_BOUNDS, __FILE__, __LINE__ );
00322 return( Vec3( 0,0,0 ) );
00323 }
00324
00325 #ifndef RT_AS3
00326 void AABB::render( const Mat4 & mat, GLenum method ) const {
00327 # ifndef RT_GLES
00328 Vec3 corner[8];
00329 for( int i = 0; i < 8; i++ ){
00330 corner[i] = ( mat * Vec4( getCorner( i ), 1.0 ) ).xyz();
00331 }
00332
00333 glBegin( method );
00334 glVertex3fv( *corner[0] );
00335 glVertex3fv( *corner[1] );
00336 glVertex3fv( *corner[2] );
00337 glVertex3fv( *corner[3] );
00338 glEnd();
00339 glBegin( method );
00340 glVertex3fv( *corner[4] );
00341 glVertex3fv( *corner[5] );
00342 glVertex3fv( *corner[6] );
00343 glVertex3fv( *corner[7] );
00344 glEnd();
00345 glBegin( method );
00346 glVertex3fv( *corner[0] );
00347 glVertex3fv( *corner[1] );
00348 glVertex3fv( *corner[5] );
00349 glVertex3fv( *corner[4] );
00350 glEnd();
00351 glBegin( method );
00352 glVertex3fv( *corner[1] );
00353 glVertex3fv( *corner[2] );
00354 glVertex3fv( *corner[6] );
00355 glVertex3fv( *corner[5] );
00356 glEnd();
00357 glBegin( method );
00358 glVertex3fv( *corner[2] );
00359 glVertex3fv( *corner[3] );
00360 glVertex3fv( *corner[7] );
00361 glVertex3fv( *corner[6] );
00362 glEnd();
00363 glBegin( method );
00364 glVertex3fv( *corner[3] );
00365 glVertex3fv( *corner[0] );
00366 glVertex3fv( *corner[4] );
00367 glVertex3fv( *corner[7] );
00368 glEnd();
00369 # endif
00370 }
00371 #endif
00372
00373 void AABB::adjust( const Vec3 & vct ){
00374 if( fabs( vct[0] ) > m_size[0] )m_size[0] = fabs( vct[0] );
00375 if( fabs( vct[1] ) > m_size[1] )m_size[1] = fabs( vct[1] );
00376 if( fabs( vct[2] ) > m_size[2] )m_size[2] = fabs( vct[2] );
00377 }
00378
00379 #ifndef RT_AS3
00380 # if GLUquadricObj
00381
00382 GLUquadricObj * initQuadObj( void ){
00383 static GLUquadricObj *quadObj = NULL;
00384 if( ! quadObj ){
00385 quadObj = gluNewQuadric();
00386 }
00387 return( quadObj );
00388 }
00389
00390 void wireSphere( GLfloat radius, GLint slices, GLint stacks ){
00391 GLUquadricObj *quadObj = initQuadObj();
00392 gluQuadricDrawStyle( quadObj, GLU_LINE );
00393 gluQuadricNormals( quadObj, GLU_SMOOTH );
00394 gluSphere( quadObj, radius, slices, stacks );
00395 }
00396
00397 void solidSphere( GLfloat radius, GLint slices, GLint stacks ){
00398 GLUquadricObj *quadObj = initQuadObj();
00399 gluQuadricDrawStyle( quadObj, GLU_FILL );
00400 gluQuadricNormals( quadObj, GLU_SMOOTH );
00401 gluSphere( quadObj, radius, slices, stacks );
00402 }
00403
00404 void wireCylinder( GLfloat base, GLfloat top, GLfloat height, GLint slices, GLint stacks ){
00405 GLUquadricObj *quadObj = initQuadObj();
00406 gluQuadricDrawStyle( quadObj, GLU_LINE );
00407 gluQuadricNormals( quadObj, GLU_SMOOTH );
00408 gluCylinder( quadObj, base, top, height, slices, stacks );
00409 }
00410
00411 void solidCylinder( GLfloat base, GLfloat top, GLfloat height, GLint slices, GLint stacks ){
00412 GLUquadricObj *quadObj = initQuadObj();
00413 gluQuadricDrawStyle( quadObj, GLU_FILL );
00414 gluQuadricNormals( quadObj, GLU_SMOOTH );
00415 gluCylinder( quadObj, base, top, height, slices, stacks );
00416 }
00417
00418 void wireCone( GLfloat base, GLfloat height, GLint slices, GLint stacks ){
00419 GLUquadricObj *quadObj = initQuadObj();
00420 gluQuadricDrawStyle( quadObj, GLU_LINE );
00421 gluQuadricNormals( quadObj, GLU_SMOOTH );
00422 gluCylinder( quadObj, base, 0.0, height, slices, stacks );
00423 }
00424
00425 void solidCone( GLfloat base, GLfloat height, GLint slices, GLint stacks ){
00426 GLUquadricObj *quadObj = initQuadObj();
00427 gluQuadricDrawStyle( quadObj, GLU_FILL );
00428 gluQuadricNormals( quadObj, GLU_SMOOTH );
00429 gluCylinder( quadObj, base, 0.0, height, slices, stacks );
00430 }
00431
00432 # else
00433
00434 void solidSphere( GLfloat radius, GLint slices, GLint stacks ){
00435 }
00436
00437 void wireSphere( GLfloat radius, GLint slices, GLint stacks ){
00438 }
00439
00440 void solidCone( GLfloat base, GLfloat height, GLint slices, GLint stacks ){
00441 }
00442
00443 void wireCone( GLfloat base, GLfloat height, GLint slices, GLint stacks ){
00444 }
00445
00446 void solidCylinder( GLfloat base, GLfloat top, GLfloat height, GLint slices, GLint stacks ){
00447 }
00448
00449 void wireCylinder( GLfloat base, GLfloat top, GLfloat height, GLint slices, GLint stacks ){
00450 }
00451
00452 # endif
00453
00454 void drawBox( GLfloat size, GLenum type ){
00455 # ifndef RT_GLES
00456 static GLint faces[6][4] =
00457 {
00458 {0, 1, 2, 3},
00459 {3, 2, 6, 7},
00460 {7, 6, 5, 4},
00461 {4, 5, 1, 0},
00462 {5, 6, 2, 1},
00463 {7, 4, 0, 3}
00464 };
00465 GLfloat v[8][3];
00466
00467 v[0][0] = v[1][0] = v[2][0] = v[3][0] = -size / 2;
00468 v[4][0] = v[5][0] = v[6][0] = v[7][0] = size / 2;
00469 v[0][1] = v[1][1] = v[4][1] = v[5][1] = -size / 2;
00470 v[2][1] = v[3][1] = v[6][1] = v[7][1] = size / 2;
00471 v[0][2] = v[3][2] = v[4][2] = v[7][2] = -size / 2;
00472 v[1][2] = v[2][2] = v[5][2] = v[6][2] = size / 2;
00473
00474 for( int i = 5; i >= 0; i-- ){
00475 glBegin(type);
00476 # if glNormal3fv
00477 static GLfloat n[6][3] =
00478 {
00479 {-1.0, 0.0, 0.0},
00480 {0.0, 1.0, 0.0},
00481 {1.0, 0.0, 0.0},
00482 {0.0, -1.0, 0.0},
00483 {0.0, 0.0, 1.0},
00484 {0.0, 0.0, -1.0}
00485 };
00486 glNormal3fv(&n[i][0]);
00487 # endif
00488 glVertex3fv(&v[faces[i][0]][0]);
00489 glVertex3fv(&v[faces[i][1]][0]);
00490 glVertex3fv(&v[faces[i][2]][0]);
00491 glVertex3fv(&v[faces[i][3]][0]);
00492 glEnd();
00493 }
00494 # endif
00495 }
00496
00497 void drawAxes(){
00498 # ifndef RT_GLES
00499 glBegin( GL_LINES );
00500 glColor3f( 1.0, 0.0, 0.0 );
00501 glVertex3f( 0.0, 0.0, 0.0 );
00502 glVertex3f( 10.0, 0.0, 0.0 );
00503 glColor3f( 0.0, 1.0, 0.0 );
00504 glVertex3f( 0.0, 0.0, 0.0 );
00505 glVertex3f( 0.0, 10.0, 0.0 );
00506 glColor3f( 0.0, 0.0, 1.0 );
00507 glVertex3f( 0.0, 0.0, 0.0 );
00508 glVertex3f( 0.0, 0.0, 10.0 );
00509 glEnd();
00510 # endif
00511 }
00512
00513
00514 void solidCube( GLfloat size ){
00515 # ifdef GL_QUADS
00516 drawBox( size, GL_QUADS );
00517 # endif
00518 }
00519
00520 void wireCube( GLfloat size ){
00521 drawBox( size, GL_LINE_LOOP );
00522 }
00523
00524 #endif //RT_AS3
00525
00526
00527 bool unique( const Vec3List & list, const Vec3 & p, float epsilon ){
00528 for( int i = 0; i < (int)list.size(); i++ ){
00529 if( list[ i ].equals( p, epsilon ) ){
00530 return( false );
00531 }
00532 }
00533 return( true );
00534 }
00535
00536 bool unique( const Vec2List & list, const Vec2 & p, float epsilon ){
00537 for( int i = 0; i < (int)list.size(); i++ ){
00538 if( list[ i ].equals( p, epsilon ) ){
00539 return( false );
00540 }
00541 }
00542 return( true );
00543 }
00544
00545 float rnd( float minimum, float maximum ){
00546 return( minimum + ( (float)( rand() % 32767 ) / 32767.0f ) * ( maximum - minimum ) );
00547 }
00548
00549 bool pointOnPoint( const Vec2 & p1, const Vec2 & p2, float epsilon ){
00550 return( length2( p1 - p2 ) <= ( epsilon * epsilon ) );
00551 }
00552
00553 bool pointOnLine( const Vec2 & p1, const Vec2 & p2, const Vec2 & p, float epsilon ){
00554 Vec2 t = p2 - p1;
00555 Vec2 n( -t[1], t[0] );
00556 Vec2 r = p - p1;
00557 return( fabs( normalize( n ).dot( r ) ) <= epsilon );
00558 }
00559
00560 float distanceToLine( const Vec2 & p1, const Vec2 & p2, const Vec2 & p ){
00561 Vec2 t = p2 - p1;
00562 Vec2 n( -t[1], t[0] );
00563 Vec2 r = p - p1;
00564 return( fabs( normalize( n ).dot( r ) ) );
00565 }
00566
00567 float distanceToLinesegment( const Vec2 & p1, const Vec2 & p2, const Vec2 & p ){
00568 Vec2 t = normalize( p2 - p1 );
00569 Vec2 n( -t[1], t[0] );
00570 Vec2 r = p - p1;
00571
00572 float f = dot( r, t );
00573
00574 if( f < 0.0f ){
00575 return( length( p - p1 ) );
00576 }
00577 else if( f > length( p2 - p1 ) ){
00578 return( length( p - p2 ) );
00579 }
00580 return( fabs( n.dot( r ) ) );
00581 }
00582
00583 bool pointOnLinesegment( const Vec2 & p1, const Vec2 & p2, const Vec2 & p, float epsilon ){
00585 if( length2( p - p1 ) <= ( epsilon * epsilon ) || \
00586 length2( p - p2 ) <= ( epsilon * epsilon ) ){
00587 return( true );
00588 }
00589
00590 Vec2 t = p2 - p1;
00591 Vec2 n( -t[1], t[0] );
00592 Vec2 r = p - p1;
00593 if( fabs( normalize( n ).dot( r ) ) <= epsilon ){
00595 float tr = normalize( t ).dot( r );
00597 return( tr >= 0.0f && tr * tr <= length2( t ) );
00598 }
00599 return( false );
00600 }
00601
00630 IntersectionMask intersect( const Vec2 & p1, const Vec2 & p2, const Vec2 & p3, const Vec2 & p4, Vec2 & poi, float epsilon ){
00631
00633 bool p1Touches3 = pointOnPoint( p1, p3, epsilon );
00634 bool p1Touches4 = pointOnPoint( p1, p4, epsilon );
00635 bool p2Touches3 = pointOnPoint( p2, p3, epsilon );
00636 bool p2Touches4 = pointOnPoint( p2, p4, epsilon );
00637
00639 if( ( p1Touches3 && p2Touches4 ) || ( p1Touches4 && p2Touches3 ) ){
00640 return( COINCIDENT | OVERLAP | PARALLEL | COLLINEAR );
00641 }
00642
00643 Vec2 p12 = p2 - p1;
00644 Vec2 p34 = p4 - p3;
00645 float lp12 = length( p12 );
00646 float lp34 = length( p34 );
00647
00649 bool p1Touches2 = ( lp12 <= epsilon );
00650 if( p1Touches2 ){
00651 if( pointOnLinesegment( p3, p4, p1, epsilon ) ){
00652 return( OVERLAP | PARALLEL | COLLINEAR );
00653 }
00654 else{
00655 return( DISJOINT );
00656 }
00657 }
00658
00660 bool p3Touches4 = ( lp34 <= epsilon );
00661 if( p3Touches4 ){
00663 if( pointOnLinesegment( p1, p2, p3, epsilon ) ){
00664 return( OVERLAP | PARALLEL | COLLINEAR );
00665 }
00666 else{
00667 return( DISJOINT );
00668 }
00669 }
00670
00671 IntersectionMask result = UNDETERMINED;
00672
00674 float dn = ( p4[ 1 ] - p3[ 1 ] ) * ( p2[ 0 ] - p1[ 0 ] ) - ( p4[ 0 ] - p3[ 0 ] ) * ( p2[ 1 ] - p1[ 1 ] );
00675 float ua = ( p4[ 0 ] - p3[ 0 ] ) * ( p1[ 1 ] - p3[ 1 ] ) - ( p4[ 1 ] - p3[ 1 ] ) * ( p1[ 0 ] - p3[ 0 ] );
00676 float ub = ( p2[ 0 ] - p1[ 0 ] ) * ( p1[ 1 ] - p3[ 1 ] ) - ( p2[ 1 ] - p1[ 1 ] ) * ( p1[ 0 ] - p3[ 0 ] );
00677
00679 if( fabs( dn ) <= epsilon ){
00680
00682 result |= PARALLEL;
00683
00685 if( fabs( ua ) <= epsilon && fabs( ub ) <= epsilon ){
00686
00688 result |= COLLINEAR;
00689
00691 if( lp12 == 0.0f || lp34 == 0.0f ){
00692 Error::error( Error::DIVISION_BY_ZERO, __FILE__, __LINE__ );
00693 }
00694
00696 Vec2 p12n = p12 / lp12;
00697 Vec2 p34n = p34 / lp34;
00698
00700 float p3on12 = dot( p3 - p1, p12n );
00701 float p4on12 = dot( p4 - p1, p12n );
00702
00704 float p1on34 = dot( p1 - p3, p34n );
00705 float p2on34 = dot( p2 - p3, p34n );
00706
00708 if( p1on34 > epsilon && p1on34 < ( lp34 - epsilon ) ){
00710 poi = p1;
00711 result |= OVERLAP;
00712 }
00713 else if( p2on34 > epsilon && p2on34 < ( lp34 - epsilon ) ){
00715 poi = p2;
00716 result |= OVERLAP;
00717 }
00718 else if( p3on12 > epsilon && p3on12 < ( lp12 - epsilon ) ){
00720 poi = p3;
00721 result |= OVERLAP;
00722 }
00723 else if( p4on12 > epsilon && p4on12 < ( lp12 - epsilon ) ){
00725 poi = p4;
00726 result |= OVERLAP;
00727 }
00728 else if( p1Touches3 && p4on12 <= 0.0f ){
00730 poi = p1;
00731 result |= ADJOINT;
00732 }
00733 else if( p2Touches3 && p4on12 >= lp12 ){
00735 poi = p2;
00736 result |= ADJOINT;
00737 }
00738 else if( p1Touches4 && p3on12 <= 0.0f ){
00740 poi = p1;
00741 result |= ADJOINT;
00742 }
00743 else if( p2Touches4 && p3on12 >= lp12 ){
00745 poi = p2;
00746 result |= ADJOINT;
00747 }
00748 else{
00749 result |= DISJOINT;
00750 }
00751 }
00752 }
00753 else{
00754 ua /= dn;
00755 ub /= dn;
00756
00758 poi = p1 + ( p2 - p1 ) * ua;
00759
00761 if( ua > 0.0f && ua < 1.0f && ub > 0.0f && ub < 1.0f ){
00762 result = INTERSECT;
00763 }
00764 else if( p1Touches3 || p1Touches4 || p2Touches3 || p2Touches4 ){
00766 result = ADJOINT;
00767 }
00768 else {
00770 ua *= lp12;
00771 ub *= lp34;
00772
00773 if( fabs( ua ) <= epsilon || fabs( lp12 - ua ) <= epsilon || fabs( ub ) <= epsilon || fabs( lp34 - ub ) <= epsilon ){
00775 result = TOUCH;
00776 }
00777 else{
00778 result = DISJOINT;
00779 }
00780 }
00781 }
00782
00783 return( result );
00784 }
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849 IntersectionMask intersect( const Plane & plane, const Mat4 & planeWorld, const Vec3 & worldP1, const Vec3 & worldP2, Vec3List & results, float epsilon ){
00850 Vec3 origin = planeWorld.getCol( 3 ).xyz();
00851 Vec3 cp1 = worldP1 - origin;
00852 Vec3 cp2 = worldP2 - origin;
00853 Vec3 normal = plane.getNormal();
00854
00855 float d1 = dot( normal, cp1 );
00856 float d2 = dot( normal, cp2 );
00857
00858 results.resize( 0 );
00859
00860 if( d1 * d2 <= 0.0f ){
00861 Vec3 x;
00862 d1 = fabs( d1 );
00863 d2 = fabs( d2 );
00864
00865 if( ( d1 + d2 ) > 0.0f ){
00866 float f = ( d1 / ( d1 + d2 ) );
00867 x = worldP1 * ( 1.0f - f ) + worldP2 * f;
00868 results.push_back( x );
00869 return( INTERSECT );
00870 }
00871 else{
00872 results.push_back( worldP1 );
00873 results.push_back( worldP2 );
00874 return( COPLANAR );
00875 }
00876 }
00877 return( DISJOINT );
00878 }
00879
00880 #ifndef RT_AS3
00881
00882 IntersectionMask intersect( const Plane & plane, const Mat4 & planeGlobal, const Rendernode & node, const Mat4 & nodeGlobal, Vec3List & results, float epsilon ){
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01026 return( DISJOINT );
01027 }
01028 #endif
01029
01030
01031 bool sortLowestY( const Vec3 & a, const Vec3 & b ){
01032 return( a[1] < b[1] );
01033 }
01034
01035 bool convexHull( const Vec2List & points, Vec2List & results ){
01036 results.clear();
01037
01038 if( points.size() > 2 ){
01039 int i, j;
01040
01041
01042
01043 Vec2List contour;
01044 for( i = 0; i < (int)points.size(); i++ ){
01045 if( unique( contour, points[ i ] ) ){
01046 contour.push_back( points[ i ] );
01047 }
01048 }
01049
01050 vector<int>index;
01051
01052
01053 Vec2 center( 0.0, 0.0 );
01054 for( i = 0; i < (int)contour.size(); i++ ){
01055 center += contour[ i ];
01056 }
01057
01058 center /= (float)contour.size();
01059
01060
01061 Vec2List copy = contour;
01062
01063
01064 int lowest = 0;
01065 for( i = 1; i < (int)contour.size(); i++ ){
01066 if( contour[ i ][1] == contour[ i - 1 ][1] ){
01067 lowest = i;
01068 }
01069 else{
01070 break;
01071 }
01072 }
01073
01074
01075
01076 Vec2 x = normalize( contour[ lowest ] - center );
01077 Vec2 y( -x[ 1 ], x[ 0 ] );
01078
01079
01080 index.push_back( lowest );
01081
01082 for( i = 0; i < (int)contour.size(); i++ ){
01083 float smallestAngle = FLT_MAX;
01084 int smallest = -1;
01085 for( j = 0; j < (int)contour.size(); j++ ){
01086
01087 if( find( index.begin(), index.end(), j ) != index.end() )continue;
01088
01089
01090 Vec3 r = normalize( contour[ j ] - contour[ lowest ] );
01091
01092 float angle = r.getAngle( x, y );
01093
01094 if( angle < smallestAngle ){
01095 smallestAngle = angle;
01096 smallest = j;
01097 }
01098 }
01099 if( smallest >= 0 ){
01100 index.push_back( smallest );
01101 }
01102 }
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114 vector<int>stack;
01115 stack.push_back( index[ 0 ] );
01116 stack.push_back( index[ 1 ] );
01117 stack.push_back( index[ 2 ] );
01118
01119 for( i = 3; i < (int)index.size(); i++ ){
01120
01121 int head = index[ i ];
01122 if( stack.size() == 0 ){
01123 Error::warning( Error::STACK_UNDERFLOW, __FILE__, __LINE__ );
01124 break;
01125 }
01126 int middle = stack[ stack.size() - 1 ];
01127 stack.pop_back();
01128 if( stack.size() == 0 ){
01129 Error::warning( Error::STACK_UNDERFLOW, __FILE__, __LINE__ );
01130 break;
01131 }
01132 int tail = stack[ stack.size() - 1 ];
01133 stack.pop_back();
01134
01135 Vec2 p1 = contour[ head ] - contour[ middle ];
01136 Vec2 p2 = contour[ middle ] - contour[ tail ];
01137 float c = cross( p1, p2 );
01138 if( c <= 0.0f ){
01139 stack.push_back( tail );
01140 stack.push_back( middle );
01141 stack.push_back( head );
01142 }
01143 else {
01144 stack.push_back( tail );
01145 i--;
01146 }
01147 }
01148
01149
01150 for( i = 0; i < (int)stack.size(); i++ ){
01151 int j = stack[ i ];
01152 if( j < (int)copy.size() ){
01153 results.push_back( copy[ j ] );
01154 }
01155 }
01156 }
01157
01158 return( results.size() != 0 );
01159 }
01160
01161 bool convexHull( const Vec3List & points, const Vec3 & normal, Vec3List & results, vector<int> & indices ){
01162
01163 results.resize( 0 );
01164
01165 if( points.size() > 2 ){
01166 int i, j;
01167
01168
01169
01170 Vec3List contour;
01171 for( i = 0; i < (int)points.size(); i++ ){
01172 if( unique( contour, points[ i ] ) ){
01173 contour.push_back( points[ i ] );
01174 }
01175 }
01176
01177 vector<int>index;
01178
01179
01180 Vec3 center( 0.0, 0.0, 0.0 );
01181 for( i = 0; i < (int)contour.size(); i++ ){
01182 center += contour[ i ];
01183 }
01184
01185 center /= (float)contour.size();
01186
01187
01188 sort( contour.begin(), contour.end() );
01189
01190 sort( contour.begin(), contour.end() );
01191
01192
01193 Vec3List copy = contour;
01194
01195
01196
01197 Vec3 x = normalize( contour[ 0 ] - center );
01198 Vec3 y = normalize( cross( normal, x ) );
01199
01200
01201 index.push_back( 0 );
01202
01203 for( i = 0; i < (int)contour.size(); i++ ){
01204 float smallestAngle = FLT_MAX;
01205 int smallest = -1;
01206 for( j = 0; j < (int)contour.size(); j++ ){
01207
01208 if( find( index.begin(), index.end(), j ) != index.end() )continue;
01209
01210
01211 Vec3 r = normalize( contour[ j ] - contour[ 0 ] );
01212
01213 float angle = r.getAngle( x, y );
01214
01215 if( angle < smallestAngle ){
01216 smallestAngle = angle;
01217 smallest = j;
01218 }
01219 }
01220 if( smallest >= 0 ){
01221 index.push_back( smallest );
01222 }
01223 }
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235 vector<int>stack;
01236 stack.push_back( index[ 0 ] );
01237 stack.push_back( index[ 1 ] );
01238 stack.push_back( index[ 2 ] );
01239
01240 for( i = 3; i < (int)index.size(); i++ ){
01241
01242 int head = index[ i ];
01243 if( stack.size() == 0 ){
01244 Error::warning( Error::STACK_UNDERFLOW, __FILE__, __LINE__ );
01245 break;
01246 }
01247 int middle = stack[ stack.size() - 1 ]; stack.pop_back();;
01248 if( stack.size() == 0 ){
01249 Error::warning( Error::STACK_UNDERFLOW, __FILE__, __LINE__ );
01250 break;
01251 }
01252 int tail = stack[ stack.size() - 1 ]; stack.pop_back();
01253
01254 Vec3 p1 = contour[ head ] - contour[ middle ];
01255 Vec3 p2 = contour[ middle ] - contour[ tail ];
01256 Vec3 c = cross( p1, p2 );
01257
01258 float d = dot( c, normal );
01259 if( d <= 0.0 ){
01260 stack.push_back( tail );
01261 stack.push_back( middle );
01262 stack.push_back( head );
01263 }
01264 else {
01265 stack.push_back( tail );
01266 i--;
01267 }
01268 }
01269
01270
01271 for( i = 0; i < (int)stack.size(); i++ ){
01272 results.push_back( copy[ stack[ i ] ] );
01273 indices.push_back( stack[ i ] );
01274 }
01275 }
01276
01277 return( results.size() != 0 );
01278 }
01279
01280 float getAngle( const Vec2List & list, unsigned int atIndex ){
01281 unsigned int i = ( atIndex + list.size() - 1 ) % list.size();
01282 unsigned int j = atIndex % list.size();
01283 unsigned int k = ( atIndex + 1 ) % list.size();
01284
01285 return( dot( normalize( list[ j ] - list[ i ] ), normalize( list[ k ] - list[ j ] ) ) );
01286 }
01287
01288 #ifndef RT_AS3
01289 GLint glGetTexParameteri( GLenum target, GLenum pname) {
01290 GLint result;
01291 glGetTexParameteriv(target, pname, &result);
01292 return result;
01293 }
01294
01295 GLint glGetInteger( GLenum which ){
01296 GLint result[32];
01297 glGetIntegerv(which, result);
01298 return result[0];
01299 }
01300
01301 GLvoid * glGetPointer( GLenum which ){
01302 GLvoid * result = 0;
01303 # ifdef RT_GLES1
01304 glGetPointerv(which, &result);
01305 # else
01306 Error::warning( Error::NULL_POINTER, __FILE__, __LINE__ );
01307 # endif
01308 return result;
01309 }
01310
01311 GLuint glGetEnum( GLenum which ){
01312 GLint result[32];
01313 glGetIntegerv(which, result);
01314 return (GLuint)result[0];
01315 }
01316
01317 GLfloat glGetFloat( GLenum which ){
01318 GLfloat result[32];
01319 glGetFloatv(which, result);
01320 return result[0];
01321 }
01322
01323 GLboolean glGetBoolean( GLenum which ){
01324 GLboolean result[32];
01325 glGetBooleanv(which, result);
01326 return result[0];
01327 }
01328
01329 #if GLdouble
01330 GLdouble glGetDouble(GLenum which) {
01331 GLdouble result[32];
01332 glGetDoublev(which, result);
01333 return result[0];
01334 }
01335 #endif
01336
01337 void getGLVersion( int *major, int *minor ){
01338 const char *verstr = (const char *)glGetString( GL_VERSION );
01339 if( ( verstr == NULL ) || ( sscanf( verstr,"%d.%d", major, minor ) != 2 ) ){
01340 *major = *minor = 0;
01341 }
01342 }
01343
01344 void getGLSLVersion( int *major, int *minor ){
01345 # ifndef RT_GLES1
01346 int gl_major, gl_minor;
01347 getGLVersion( &gl_major, &gl_minor );
01348
01349 *major = *minor = 0;
01350 if( gl_major == 1 ){
01351
01352 const char *extstr = ( const char * )glGetString( GL_EXTENSIONS );
01353 if( ( extstr != NULL ) && ( strstr( extstr, "GL_ARB_shading_language_100" ) != NULL ) ){
01354 *major = 1;
01355 *minor = 0;
01356 }
01357 }
01358 else if( gl_major >= 2 ){
01359
01360 const char *verstr = ( const char * )glGetString( GL_SHADING_LANGUAGE_VERSION );
01361
01362 if( ( verstr == NULL ) || ( sscanf( verstr, "%d.%d", major, minor ) != 2 ) ){
01363 *major = *minor = 0;
01364 }
01365 }
01366 # endif
01367 }
01368 #endif
01369
01370 #ifndef RT_AS3
01371
01373 istream & operator >> ( istream & s, PropertyContainerPtr v ){
01374 return s;
01375 }
01376 #endif
01377
01378 istream & operator >> ( istream & s, NAABB & v ){
01379 s >> v.getLow();
01380 s >> v.getHigh();
01381 return s;
01382 }
01383
01384 istream & operator >> ( istream & s, AABB & v ){
01385 s >> v.getSize();
01386 return s;
01387 }
01388
01389
01390 #ifndef RT_AS3
01391 ostream & operator << ( ostream & s, const PropertyContainerPtr vc ){
01393 return s;
01394 }
01395 #endif
01396
01397 ostream & operator << ( ostream & s, const NAABB & vc ){
01398 NAABB & v = (NAABB &)vc;
01399 char txt[256];
01400 sprintf( txt, "%g %g %g %g %g %g", v.getLow()[0], v.getLow()[1], v.getLow()[2], v.getHigh()[0], v.getHigh()[1], v.getHigh()[2] );
01401 s << txt;
01402 return s;
01403 }
01404
01405 ostream & operator << ( ostream & s, const AABB & vc ){
01406 AABB & v = (AABB &)vc;
01407 char txt[256];
01408 sprintf( txt, "%g %g %g", v.getSize()[0], v.getSize()[1], v.getSize()[2] );
01409 s << txt;
01410 return s;
01411 }
01412
01413 const char * basename( const char * fullPath ){
01414 const char * base = strrchr( fullPath, (int)'/' );
01415 if( base ){
01416 return( base + 1 );
01417 }
01418 else if( ( base = strrchr(fullPath,(int)'\\') ) ){
01419 return( base + 1 );
01420 }
01421 else{
01422 return( fullPath );
01423 }
01424 }
01425
01426 bool basename( string fullName, string & path, string & basename ){
01427 size_t last = fullName.find_last_of( '/' );
01428 if( last == string::npos ){
01429 last = fullName.find_last_of( '\\' );
01430 }
01431 if( last != string::npos ){
01432 path = fullName.substr( 0, last );
01433 basename = fullName.substr( last + 1 );
01434 return( true );
01435 }
01436 else{
01437 return( false );
01438 }
01439 }
01440
01441 Vec3 closestPoint( int type, Vec3 & size, Mat4 & trans, Vec3 & p ){
01442 Vec3 q, c;
01443
01444 q = ( trans.inverse() * Vec4( p ) ).xyz();
01445 q = q / size;
01446 Vec3 s = q.sgn();
01447 Vec3 qab = q.abs();
01448 Vec2 _xy;
01449 float l;
01450
01451 switch( type ){
01452 case 0:
01453
01454 qab = normalize( qab );
01455 break;
01456 case 1:
01457 _xy = Vec2( qab[0], qab[1] );
01458 l = length( _xy );
01459 if( l > 1.0 ){
01460 _xy = normalize( _xy );
01461 }
01462 qab[0] = _xy[0];
01463 qab[1] = _xy[1];
01464 qab[2] = clamp( qab[2], 0.0f, 1.0f );
01465 break;
01466 case 2:
01467
01468 qab = qab.clamp( 0.0f, 1.0f );
01469
01470 break;
01471 }
01472 return( ( trans * Vec4( size * s * qab, 0.0 ) ).xyz() );
01473 }
01474
01475 Vec2 spherePointToCubeUV( Vec3 & sphere, int *plane ){
01476 Vec3 p = normalize( sphere ) * 10.0f;
01477 Vec3 x;
01478 int a, b, c;
01479
01480 a = 0, b = 1, c = 2;
01481 if( fabs( p[a] ) > 1.0 ){
01482 x = p / fabs( p[a] );
01483 if( fabs( x[b] ) <= 1.0 && fabs( x[c] ) <= 1.0 ){
01484 *plane = ( p[a] < 0.0 ? 0 : 1 );
01485 return( Vec2( 0.5 + 0.5 * x[b], 0.5 + 0.5 * x[c] ) );
01486 }
01487 }
01488 a = 1, b = 0, c = 2;
01489 if( fabs( p[a] ) > 1.0 ){
01490 x = p / fabs( p[a] );
01491 if( fabs( x[b] ) <= 1.0 && fabs( x[c] ) <= 1.0 ){
01492 *plane = ( p[a] < 0.0 ? 2 : 3 );
01493 return( Vec2( 0.5 + 0.5 * x[b], 0.5 + 0.5 * x[c] ) );
01494 }
01495 }
01496 a = 2, b = 0, c = 1;
01497 if( fabs( p[a] ) > 1.0 ){
01498 x = p / fabs( p[a] );
01499 if( fabs( x[b] ) <= 1.0 && fabs( x[c] ) <= 1.0 ){
01500 *plane = ( p[a] < 0.0 ? 4 : 5 );
01501 return( Vec2( 0.5 + 0.5 * x[b], 0.5 + 0.5 * x[c] ) );
01502 }
01503 }
01504 return( Vec2( 1, 1 ) );
01505 }
01506
01507 #ifdef RT_IOS
01508 bool getDefaultInt( const char * key, int * value ){
01509
01510 CFStringRef str = CFStringCreateWithCString( kCFAllocatorDefault, key, CFStringGetSystemEncoding() );
01511
01512 CFNumberRef number = (CFNumberRef)CFPreferencesCopyAppValue( str, kCFPreferencesCurrentApplication );
01513 if( number ){
01514
01515 if( ! CFNumberGetValue( number, kCFNumberIntType, value ) ){
01516 return( false );
01517 }
01518 CFRelease( number );
01519
01520 return( true );
01521 }
01522 else{
01523
01524 number = CFNumberCreate( NULL, kCFNumberIntType, value );
01525
01526
01527 CFPreferencesSetAppValue( str, number, kCFPreferencesCurrentApplication );
01528
01529
01530 CFRelease( number );
01531
01532
01533 CFPreferencesAppSynchronize( kCFPreferencesCurrentApplication );
01534
01535 return( false );
01536 }
01537 }
01538
01539 bool getDefaultUnsignedInt( const char * key, unsigned int * value ){
01540
01541 CFStringRef str = CFStringCreateWithCString( kCFAllocatorDefault, key, CFStringGetSystemEncoding() );
01542
01543 CFNumberRef number = (CFNumberRef)CFPreferencesCopyAppValue( str, kCFPreferencesCurrentApplication );
01544 if( number ){
01545
01546 if( ! CFNumberGetValue( number, kCFNumberIntType, value ) ){
01547 return( false );
01548 }
01549 CFRelease( number );
01550
01551 return( true );
01552 }
01553 else{
01554
01555 number = CFNumberCreate( NULL, kCFNumberIntType, value );
01556
01557
01558 CFPreferencesSetAppValue( str, number, kCFPreferencesCurrentApplication );
01559
01560
01561 CFRelease( number );
01562
01563
01564 CFPreferencesAppSynchronize( kCFPreferencesCurrentApplication );
01565
01566 return( false );
01567 }
01568 }
01569
01570 bool getDefaultFloat( const char * key, float * value ){
01571
01572 CFStringRef str = CFStringCreateWithCString( kCFAllocatorDefault, key, CFStringGetSystemEncoding() );
01573
01574 CFNumberRef number = (CFNumberRef)CFPreferencesCopyAppValue( str, kCFPreferencesCurrentApplication );
01575 if( number ){
01576
01577 if( ! CFNumberGetValue( number, kCFNumberFloatType, value ) ){
01579 return( false );
01580
01581 }
01582 CFRelease( number );
01583
01584 return( true );
01585 }
01586 else{
01587
01588 number = CFNumberCreate( NULL, kCFNumberFloatType, value );
01589
01590
01591 CFPreferencesSetAppValue( str, number, kCFPreferencesCurrentApplication );
01592
01593
01594 CFRelease( number );
01595
01596
01597 CFPreferencesAppSynchronize( kCFPreferencesCurrentApplication );
01598
01599 return( false );
01600 }
01601 }
01602
01603 bool getDefaultString( const char * key, string & value ){
01604
01605 CFStringRef str = CFStringCreateWithCString( kCFAllocatorDefault, key, CFStringGetSystemEncoding() );
01606
01607 CFStringRef s = (CFStringRef)CFPreferencesCopyAppValue( str, kCFPreferencesCurrentApplication );
01608 if( s ){
01609 char buf[255];
01610 CFStringGetCString( s, buf, 255, CFStringGetSystemEncoding() );
01611 value = buf;
01612
01613 return( true );
01614 }
01615 else{
01616
01617 CFPreferencesSetAppValue( str, s, kCFPreferencesCurrentApplication );
01618
01619
01620 CFPreferencesAppSynchronize( kCFPreferencesCurrentApplication );
01621
01622 return( false );
01623 }
01624 }
01625
01626 void setDefaultInt( const char * key, int value ){
01627
01628 CFStringRef str = CFStringCreateWithCString( kCFAllocatorDefault, key, CFStringGetSystemEncoding() );
01629
01630
01631 CFNumberRef number = CFNumberCreate( NULL, kCFNumberIntType, & value );
01632
01633
01634 CFPreferencesSetAppValue( str, number, kCFPreferencesCurrentApplication );
01635
01636
01637 CFRelease( number );
01638
01639
01640 CFPreferencesAppSynchronize( kCFPreferencesCurrentApplication );
01641 }
01642
01643 void setDefaultUnsignedInt( const char * key, unsigned int value ){
01644
01645 CFStringRef str = CFStringCreateWithCString( kCFAllocatorDefault, key, CFStringGetSystemEncoding() );
01646
01647
01648 CFNumberRef number = CFNumberCreate( NULL, kCFNumberIntType, & value );
01649
01650
01651 CFPreferencesSetAppValue( str, number, kCFPreferencesCurrentApplication );
01652
01653
01654 CFRelease( number );
01655
01656
01657 CFPreferencesAppSynchronize( kCFPreferencesCurrentApplication );
01658 }
01659
01660 void setDefaultFloat( const char * key, float value ){
01661
01662 CFStringRef str = CFStringCreateWithCString( kCFAllocatorDefault, key, CFStringGetSystemEncoding() );
01663
01664
01665 CFNumberRef number = CFNumberCreate( NULL, kCFNumberFloatType, & value );
01666
01667
01668 CFPreferencesSetAppValue( str, number, kCFPreferencesCurrentApplication );
01669
01670
01671 CFRelease( number );
01672
01673
01674 CFPreferencesAppSynchronize( kCFPreferencesCurrentApplication );
01675
01676 }
01677
01678 void setDefaultString( const char * key, string & value ){
01679
01680 CFStringRef keystr = CFStringCreateWithCString( kCFAllocatorDefault, key, CFStringGetSystemEncoding() );
01681 CFStringRef valstr = CFStringCreateWithCString( kCFAllocatorDefault, value.c_str(), CFStringGetSystemEncoding() );
01682
01683 CFPreferencesSetAppValue( keystr, valstr, kCFPreferencesCurrentApplication );
01684
01685 CFPreferencesAppSynchronize( kCFPreferencesCurrentApplication );
01686 }
01687
01688 #endif
01689
01690
01691 };
01692
01693