00001
00002
00003
00004
00005
00006
00007
00008 #include "Camera.h"
00009 #include "Error.h"
00010 #include "Property.h"
00011 #include "StateSet.h"
00012 #include "Program.h"
00013
00014 namespace RenderTools {
00015
00016 using namespace Matrix;
00017
00018 CameraPtr Camera::s_current = CameraPtr();
00019
00020 CameraPtr Camera::getCurrent( void ){
00021 return( s_current );
00022 }
00023
00024 Camera::Camera( void ):
00025 TransformNode(),
00026 m_type( PERSPECTIVE ),
00027 m_aspect( 1.0f ),
00028 m_mode( NONE ),
00029 m_modePushed( NONE ),
00030 m_flip( false ),
00031 m_flop( false ){
00032
00033 }
00034
00035 PropertyPtr Camera::create( const XMLNodePtr & xml ){
00036 CameraPtr p( new Camera() );
00037 p->setName( xml );
00038 p->createProperties();
00039 p->setProperties( xml, false );
00040 return( dynamic_pointer_cast< AbstractProperty, Camera >( p ) );
00041 }
00042
00043 void Camera::createProperties( void ){
00044 createProperty( this, "type", CamTypeStruct( & m_type ), getCamTypeEnums() );
00045 createProperty( this, "screenSize", & m_screen );
00046 createProperty( this, "eye", & m_eye );
00047 createProperty( this, "focus", & m_center );
00048 createProperty( this, "zoom", & m_zoom );
00049 createProperty( this, "nearClip", & m_nearc );
00050 createProperty( this, "farClip", & m_farc );
00051 createProperty( this, "fieldOfView", & m_fovy );
00052 createProperty( this, "roll", & m_roll );
00053 createProperty( this, "viewport", & m_vp );
00054 createProperty( this, "horizontalFlip", BooleanStruct( & m_flip ) );
00055 createProperty( this, "verticalFlip", BooleanStruct( & m_flop ) );
00056 createProperty( this, "ortho", & m_ortho );
00057 }
00058
00059 const string Camera::getTypeName( bool ofComponent ) const {
00060 return( "Camera" );
00061 }
00062
00067 Camera::~Camera( void ){
00068 CameraPtr thisPtr = getNullDeletingSharedPtr< Camera >();
00069 if( s_current == thisPtr ){
00070 s_current = CameraPtr();
00071 }
00072 }
00073
00074 Camera & Camera::operator = ( const Camera & c ){
00075 m_eye = c.m_eye;
00076 m_center = c.m_center;
00077 m_zoom = c.m_zoom;
00078 m_nearc = c.m_nearc;
00079 m_farc = c.m_farc;
00080 m_fovy = c.m_fovy;
00081 m_roll = c.m_roll;
00082 return( * this );
00083 }
00084
00085 Camera & Camera::operator += ( const Camera & cc ){
00086 Camera & c = ( Camera & )cc;
00087 m_eye += c.m_eye;
00088 m_center += c.m_center;
00089 m_zoom += c.m_zoom;
00090 m_nearc += c.m_nearc;
00091 m_farc += c.m_farc;
00092 m_fovy += c.m_fovy;
00093 m_roll += c.m_roll;
00094 return( * this );
00095 }
00096
00101 Camera & Camera::operator *= ( const float f ){
00102 m_eye *= f;
00103 m_center *= f;
00104 m_zoom *= f;
00105 m_nearc *= f;
00106 m_farc *= f;
00107 m_fovy *= f;
00108 m_roll *= f;
00109 return( * this );
00110 }
00111
00117 void Camera::frame( const NAABB & b, float scale, bool send ){
00118
00119 Vec3 sub,los;
00120
00121
00122 Vec3 c = b.getCenter();
00123
00124
00125 float s = length( ( b.getHigh() - b.getLow() ) *= 0.5 );
00126
00127 s *= m_zoom;
00128
00129
00130 los = m_eye - m_center;
00131 los = normalize( los );
00132
00133 m_center = c;
00134 m_eye = c;
00135
00136
00137 float t = tan( ( m_fovy / 180.0 ) );
00138 float d = 0.0;
00139
00140
00141
00142 if( t != 0.0 ){
00143 d = ( s / t );
00144 }
00145
00146 if( d > 1000.0f )d = 1000.0f;
00147
00148
00149 m_eye += los * float( fabs( d ) );
00150 if( send ){
00152 }
00153 }
00154
00161 void Camera::setDistance( float dist, bool send ){
00162 Vec3 sub;
00163 sub = m_eye - m_center;
00164 sub = normalize( sub );
00165 m_eye = m_center;
00166 m_eye += dist * sub;
00167 if( send ){
00169 }
00170 }
00171
00178 float Camera::getDistance( void ) const{
00179 Vec3 sub;
00180 sub = m_eye - m_center;
00181 return( length( sub ) );
00182 }
00183
00195 void Camera::move( const Vec3 & v, bool send ){
00196 float w,h;
00197 if( m_type == ORTHO ){
00198 if( m_mode & DRAG ){
00199 Vec2 v2 = Vec2( v[0] / m_screen[0], v[1] / m_screen[1] );
00200 w = getOrthoWidthZoomed();
00201 h = getOrthoHeightZoomed();
00202 m_ortho[0] += v2[0] * w;
00203 m_ortho[1] += v2[0] * w;
00204 m_ortho[2] += v2[1] * h;
00205 m_ortho[3] += v2[1] * h;
00206 bind();
00207 }
00208 if( m_mode & ( ZOOM | TRACK | DOLLY ) ){
00209 Vec2 v2 = Vec2( v[0] / m_screen[0], v[1] / m_screen[1] + 1.0 );
00210 m_zoom *= fabs( v2[1] );
00211 bind();
00212 }
00213 if( m_mode & ORBIT ){
00214 Vec3 sub;
00215 float tmp,d;
00216
00217 Vec3 v2 = Vec3( v[0] < -50.0 ? -50.0 : v[0] > 50.0 ? 50.0 : v[0],
00218 v[1] < -50.0 ? -50.0 : v[1] > 50.0 ? 50.0 : v[1],
00219 v[2] < -50.0 ? -50.0 : v[2] > 50.0 ? 50.0 : v[2] );
00220
00221 sub = m_eye - m_center;
00222 d = length( sub );
00223
00224 if( d < 100.0 ){
00225 v2 *= ( d / 100.0 );
00226 }
00227
00228 sub = normalize( sub );
00229
00230 tmp = 1.0 - fabs( sub[2] );
00231
00232 if( tmp <= 0.1 && v[1] * sub[2] > 0.0f ){
00233 tmp *= 10.0;
00234 v2 *= tmp;
00235 }
00236 m_eye = m_eye;
00237 m_eye += v2[0] * m_local.getCol(1).xyz();
00238 m_eye += v2[1] * m_local.getCol(2).xyz();
00239
00240 sub = m_eye - m_center;
00241 sub = normalize( sub );
00242
00243 m_eye = sub * d;
00244 m_eye += m_center;
00245
00246 bind();
00247 }
00248 }
00249 else{
00250 Vec3 sub;
00251 float tmp,d;
00252 if( m_mode & ORBIT ){
00253
00254 Vec3 v2 = Vec3( v[0] < -50.0 ? -50.0 : v[0] > 50.0 ? 50.0 : v[0],
00255 v[1] < -50.0 ? -50.0 : v[1] > 50.0 ? 50.0 : v[1],
00256 v[2] < -50.0 ? -50.0 : v[2] > 50.0 ? 50.0 : v[2] );
00257
00258 sub = m_eye - m_center;
00259 d = length( sub );
00260
00261 if( d < 100.0 ){
00262 v2 *= ( d / 100.0 );
00263 }
00264
00265 sub = normalize( sub );
00266 tmp = 1.0 - fabs( sub[2] );
00267
00268 if( tmp <= 0.1 && v[1] * sub[2] > 0.0f ){
00269 tmp *= 10.0;
00270 v2 *= tmp;
00271 }
00272
00273 m_eye += Vec3( v2[0] * m_local.getCol(1).xyz() );
00274 m_eye += Vec3( v2[1] * m_local.getCol(2).xyz() );
00275 sub = m_eye - m_center;
00276 sub = normalize( sub );
00277
00278 m_eye = sub * d;
00279 m_eye += m_center;
00280 }
00281 if( m_mode & DRAG ){
00282 sub = m_eye - m_center;
00283 d = length( sub );
00284 Vec3 v2( v );
00285 if( d < 100.0 ){
00286 v2 *= ( d / 100.0f );
00287 }
00288 m_center += v2[0] * m_local.getCol(1).xyz();
00289 m_center += v2[1] * m_local.getCol(2).xyz();
00290 m_eye += v2[0] * m_local.getCol(1).xyz();
00291 m_eye += v2[1] * m_local.getCol(2).xyz();
00292 }
00293 if( m_mode & DOLLY ){
00294 m_center += v[1] * m_local.getCol(0).xyz();
00295 m_eye += v[1] * m_local.getCol(0).xyz();
00296 }
00297 if( m_mode & TRACK ){
00298 m_eye += v[1] * m_local.getCol(0).xyz();
00299 }
00300 if( m_mode & ROLL ){
00301 Vec2 v2 = Vec2( v[0] / m_screen[0], v[1] / m_screen[1] + 1.0 );
00302 m_roll *= fabs( v2[1] );
00303 }
00304 if( m_mode & ZOOM ){
00305 Vec2 v2 = Vec2( v[0] / m_screen[0], v[1] / m_screen[1] + 1.0 );
00306 m_fovy *= fabs( v2[1] );
00307 }
00308 }
00309 if( send ){
00311 }
00312 }
00313
00314 void Camera::reshape( int w, int h, bool send ){
00315 initViewport( Vec2( (float)w, (float)h ), send );
00316 }
00317
00318 void Camera::onBind( int unit ){
00319
00320 s_current = dynamic_pointer_cast< Camera, AbstractProperty >( getSharedPtr< AbstractProperty >() );
00321
00322 Error::assertNoErrors( __FILE__, __LINE__ );
00323
00324 Vec3 x( m_center - m_eye );
00325 x = normalize( x );
00326 Vec3 y( -x[1], x[0], 0.0 );
00327 if( length( y ) < 0.001f ){
00328 y[0] = -1.0;
00329 y[1] = 0.0;
00330 y[2] = 0.0;
00331 }
00332
00333 Vec3 z = cross( x, y );
00334 z = normalize( z );
00335 z = Vec3::fromAxisAngle( z, x, float( ( m_roll / 180.0f ) * M_PI ) );
00336
00337 m_local.setCol( 0, Vec4( normalize( x ), 0.0f ) );
00338 m_local.setCol( 1, Vec4( normalize( y ), 0.0f ) );
00339 m_local.setCol( 2, Vec4( normalize( z ), 0.0f ) );
00340
00341 Error::assertNoErrors( __FILE__, __LINE__ );
00342
00343 if( m_flip || m_flop ){
00344 Mat4 identity;
00345 if( m_flip ){
00346 identity[0] = -1.0f;
00347 }
00348 if( m_flop ){
00349 identity[5] = -1.0f;
00350 }
00351 set( PROJECTION, *identity );
00352 }
00353
00354 Error::assertNoErrors( __FILE__, __LINE__ );
00355
00357 glViewport( (GLint)m_vp[0], (GLint)m_vp[1], (GLint)m_vp[2], (GLint)m_vp[3]);
00358
00359 set( PROJECTION, Mat4::fromIdentity() );
00360 set( MODELVIEW, Mat4::fromIdentity() );
00361
00362 Error::assertNoErrors( __FILE__, __LINE__ );
00363
00364 if( m_type == ORTHO ){
00365
00366 GLfloat l, r, b, t, x, y;
00367 float f = 0.5 * m_zoom;
00368
00369 x = m_ortho[0] + getOrthoWidth() * 0.5;
00370 y = m_ortho[2] + getOrthoHeight() * 0.5;
00371
00372 l = x - getOrthoWidth() * f;
00373 r = x + getOrthoWidth() * f;
00374 b = y - getOrthoHeight() * f;
00375 t = y + getOrthoHeight() * f;
00376
00377 set( PROJECTION, Mat4::fromOrtho( l, r, b, t, m_nearc, m_farc ) );
00378 }
00379 else{
00380 set( PROJECTION, Mat4::fromPerspective( m_fovy * m_zoom, m_aspect, m_nearc, m_farc ) );
00381
00382 }
00383
00384 Mat4 m = get( MODELVIEW );
00385 m.lookAt( m_eye, m_center, z );
00386 set( MODELVIEW, m );
00387
00388 Error::assertNoErrors( __FILE__, __LINE__ );
00389
00390 Vec3 n = m_local.getCol(0).xyz();
00391 Vec3 v = m_eye + ( m_nearc + 0.1f ) * n;
00392
00393 m_nearPlane = Vec4( n[0], n[1], n[2], 0.0f );
00394 m_nearPlane[3] = dot( v, n );
00395
00396 Error::assertNoErrors( __FILE__, __LINE__ );
00397 }
00398
00403 void Camera::drawGrid( int size, int stp ){
00404
00405 #ifndef RT_GLES
00406 glMatrixMode( GL_PROJECTION );
00407 glLoadMatrixf( * get( PROJECTION ) );
00408 glMatrixMode( GL_MODELVIEW );
00409 glLoadMatrixf( * get( MODELVIEW ) );
00410
00411 glDisable( GL_TEXTURE_2D );
00412 #ifdef GL_ALPHA_TEST
00413 glDisable( GL_ALPHA_TEST );
00414 #endif
00415 #ifdef GL_BLEND
00416 glEnable( GL_BLEND );
00417 #endif
00418 glDepthMask( GL_FALSE );
00419 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
00420
00421 #ifdef GL_LINES
00422 glBegin( GL_LINES );
00423 #endif
00424
00425
00426 glColor3f( 1.0, 0.0, 0.0 );
00427 glVertex3i( 0, 0, 0 );
00428 glVertex3i( stp, 0, 0 );
00429 glColor3f( 0.0, 1.0, 0.0 );
00430 glVertex3i( 0, 0, 0 );
00431 glVertex3i( 0, stp, 0 );
00432 glColor3f( 0.0, 0.0, 1.0 );
00433 glVertex3i( 0, 0, 0 );
00434 glVertex3i( 0, 0, stp );
00435
00436 glColor4f( 0.0, 0.0, 0.0, 0.2 );
00437
00438 for( int i = -size; i <= size; i += stp ){
00439 glVertex2i( i, -size );
00440 glVertex2i( i, size );
00441 }
00442 for( int i = -size; i <= size; i += stp ){
00443 glVertex2i( -size, i );
00444 glVertex2i( size, i );
00445 }
00446 glEnd();
00447 #endif // OpenGL|ES
00448 }
00449
00450 void Camera::onPropertyEvent( const PropertyEvent & e ){
00451
00452 }
00457 void Camera::onUnbind( int unit ){
00458 set( PROJECTION, Mat4::fromIdentity() );
00459 set( MODELVIEW, Mat4::fromIdentity() );
00460 }
00461
00462 void Camera::onInitialize( void ){
00463
00464 }
00465
00466 void Camera::setMode( CamMode mode, bool send ){
00467 m_mode = mode;
00468 if( send ){
00470 }
00471 }
00472
00473 const int Camera::getMode( void ) const {
00474 return( m_mode );
00475 }
00476
00477 void Camera::setType( CamType type, bool send ){
00478 m_type = type;
00479 if( send ){
00481 }
00482 }
00483
00484 const Camera::CamType Camera::getType( void ) const {
00485 return( m_type );
00486 }
00487
00488 void Camera::setFOV( float s, bool send ){
00489 m_fovy = s;
00490 if( send ){
00492 }
00493 }
00494
00495 const float Camera::getFOV( void ) const {
00496 return( m_fovy );
00497 }
00498
00499 void Camera::setNear( float s, bool send ){
00500 m_nearc = s;
00501 if( send ){
00503 }
00504 }
00505
00506 const float Camera::getNear( void ) const {
00507 return( m_nearc );
00508 }
00509
00510 void Camera::setFar( float s, bool send ){
00511 m_farc = s;
00512 if( send ){
00514 }
00515 }
00516
00517 const float Camera::getFar( void ) const {
00518 return( m_farc );
00519 }
00520
00521 void Camera::setEye( const Vec3 & v, bool send ){
00522 m_eye = v;
00523 if( send ){
00525 }
00526 }
00527
00528 const Vec3 & Camera::getEye( void ) const {
00529 return( m_eye );
00530 }
00531
00532 void Camera::setCenter( const Vec3 & v, bool send ){
00533 m_center = v;
00534 if( send ){
00536 }
00537 }
00538
00539 const Vec3 & Camera::getCenter( void ) const {
00540 return( m_center );
00541 }
00542
00543 void Camera::setRoll( float deg, bool send ){
00544 m_roll = deg;
00545 if( send ){
00547 }
00548 }
00549
00550 const float Camera::getRoll( void ) const {
00551 return( m_roll );
00552 }
00553
00554 void Camera::setFlip( bool state, bool send ){
00555 m_flip = state;
00556 if( send ){
00558 }
00559 }
00560
00561 const bool Camera::getFlip( void ) const {
00562 return( m_flip );
00563 }
00564
00565 void Camera::setFlop( bool state, bool send ){
00566 m_flop = state;
00567 if( send ){
00569 }
00570 }
00571
00572 const bool Camera::getFlop( void ) const {
00573 return( m_flop );
00574 }
00575
00576 const Vec4 & Camera::getViewport( void ) const{
00577 return( m_vp );
00578 }
00579
00580 void Camera::setViewport( const Vec4 & vp, bool send ){
00581 m_vp = vp;
00582 glViewport( (GLint)m_vp[0], (GLint)m_vp[1], (GLint)m_vp[2], (GLint)m_vp[3] );
00583 m_aspect = (float)m_vp[2] / (float)m_vp[3];
00584 if( send ){
00586 }
00587 }
00588
00589 void Camera::setScreen( const Vec2 & screen, bool send ){
00590 m_screen = screen;
00591 m_aspect = screen[0] / screen[1];
00592 if( send ){
00594 }
00595 }
00596
00597 const Vec2 & Camera::getScreen( void ) const {
00598 return( m_screen );
00599 }
00600
00601 void Camera::pushMode( void ){
00602 m_modePushed = m_mode;
00603 }
00604
00605 void Camera::popMode( void ){
00606 m_mode = m_modePushed;
00607 }
00608
00616 bool Camera::clipNear( Vec3 & l1, Vec3 & l2 ){
00617
00618 float d1 = dot( m_nearPlane.xyz(), l1 ) - m_nearPlane[3];
00619 float d2 = dot( m_nearPlane.xyz(), l2 ) - m_nearPlane[3];
00620
00621 if( d1 <= 0.0f && d2 <= 0.0f )return( false );
00622
00623 if( d1 * d2 <= 0.0f ){
00624 Vec3 x1 = l1;
00625 Vec3 x2 = l2;
00626 float fd1 = fabs(d1);
00627 float fd2 = fabs(d2);
00628 if( fd1 + fd2 != 0.0f ){
00629 float s = fd1 / ( fd1 + fd2 );
00630 x2 = l2 * s;
00631 x2 += l1 * float( 1.0 - s );
00632 if( d1 <= 0.0f ){
00633 x1 = l2;
00634 }
00635 else{
00636 x1 = l1;
00637 }
00638 }
00639 l1 = x1;
00640 l2 = x2;
00641 }
00642 return( true );
00643 }
00652 Rectangle Camera::project( const NAABB & naabb ){
00653
00654 Rectangle rect;
00655
00656 #ifndef RT_GLES
00657 int i = 0;
00658 Vec3 corner[8];
00659 Vec3 center = naabb.getCenter();
00660 for( i = 0; i < 8; i++ ){
00661 corner[i] = naabb.getCorner( i );
00662 }
00663
00664 i = 0;
00665
00666 Vec3 segments[12][2];
00667 segments[i][0] = corner[ 0 ];
00668 segments[i][1] = corner[ 1 ]; i++;
00669 segments[i][0] = corner[ 1 ];
00670 segments[i][1] = corner[ 2 ]; i++;
00671 segments[i][0] = corner[ 2 ];
00672 segments[i][1] = corner[ 3 ]; i++;
00673 segments[i][0] = corner[ 3 ];
00674 segments[i][1] = corner[ 0 ]; i++;
00675 segments[i][0] = corner[ 4 ];
00676 segments[i][1] = corner[ 5 ]; i++;
00677 segments[i][0] = corner[ 5 ];
00678 segments[i][1] = corner[ 6 ]; i++;
00679 segments[i][0] = corner[ 6 ];
00680 segments[i][1] = corner[ 7 ]; i++;
00681 segments[i][0] = corner[ 7 ];
00682 segments[i][1] = corner[ 4 ]; i++;
00683 segments[i][0] = corner[ 0 ];
00684 segments[i][1] = corner[ 4 ]; i++;
00685 segments[i][0] = corner[ 1 ];
00686 segments[i][1] = corner[ 5 ]; i++;
00687 segments[i][0] = corner[ 2 ];
00688 segments[i][1] = corner[ 6 ]; i++;
00689 segments[i][0] = corner[ 3 ];
00690 segments[i][1] = corner[ 7 ];
00691
00692 GLint vp[4];
00693 glGetIntegerv( GL_VIEWPORT, vp );
00694
00695 GLdouble pm[16];
00696 GLdouble mm[16];
00697
00698 glGetDoublev( GL_MODELVIEW_MATRIX, mm );
00699 glGetDoublev( GL_PROJECTION_MATRIX, pm );
00700
00701 # if gluProject
00702 GLdouble _wx = 0.0;
00703 GLdouble _wy = 0.0;
00704 GLdouble _wz = 0.0;
00705
00706
00707 for( i = 0; i < 12; i++ ){
00708 if( clipNear( segments[i][0], segments[i][1] ) ){
00709 for( j = 0; j < 2; j++ ){
00710
00711 gluProject( segments[i][j][0], segments[i][j][1], segments[i][j][2], mm, pm, vp, &_wx, &_wy, &_wz );
00712 if( _wx < rect[0] )rect[0] = _wx;
00713 if( _wx > rect[1] )rect[1] = _wx;
00714 if( _wy < rect[2] )rect[2] = _wy;
00715 if( _wy > rect[3] )rect[3] = _wy;
00716 }
00717 }
00718 }
00719 # endif
00720 #elif WIN32
00721 # pragma message( "warning: Camera::project() not implemented under OpenGL|ES" )
00722 #endif
00723
00724 return( rect );
00725 }
00726
00737 Rectangle Camera::project( const AABB & _aabb, const Mat4 & mat ){
00738 Rectangle rect;
00739 #ifndef RT_GLES
00740 int i = 0;
00741 Vec4 corner[8];
00742 Vec3 center( (float)mat[12], (float)mat[13], (float)mat[14] );
00743
00744 for( i = 0; i < 8; i++ ){
00745 corner[i] = mat * Vec4( _aabb.getCorner( i ) );
00746 }
00747 i = 0;
00748
00749 Vec4 segments[12][2];
00750 segments[i][0] = corner[ 0 ];
00751 segments[i][1] = corner[ 1 ]; i++;
00752 segments[i][0] = corner[ 1 ];
00753 segments[i][1] = corner[ 2 ]; i++;
00754 segments[i][0] = corner[ 2 ];
00755 segments[i][1] = corner[ 3 ]; i++;
00756 segments[i][0] = corner[ 3 ];
00757 segments[i][1] = corner[ 0 ]; i++;
00758 segments[i][0] = corner[ 4 ];
00759 segments[i][1] = corner[ 5 ]; i++;
00760 segments[i][0] = corner[ 5 ];
00761 segments[i][1] = corner[ 6 ]; i++;
00762 segments[i][0] = corner[ 6 ];
00763 segments[i][1] = corner[ 7 ]; i++;
00764 segments[i][0] = corner[ 7 ];
00765 segments[i][1] = corner[ 4 ]; i++;
00766 segments[i][0] = corner[ 0 ];
00767 segments[i][1] = corner[ 4 ]; i++;
00768 segments[i][0] = corner[ 1 ];
00769 segments[i][1] = corner[ 5 ]; i++;
00770 segments[i][0] = corner[ 2 ];
00771 segments[i][1] = corner[ 6 ]; i++;
00772 segments[i][0] = corner[ 3 ];
00773 segments[i][1] = corner[ 7 ];
00774
00775
00776 GLint vp[4];
00777 glGetIntegerv( GL_VIEWPORT, vp );
00778
00779 GLdouble pm[16];
00780 GLdouble mm[16];
00781
00782 glGetDoublev( GL_MODELVIEW_MATRIX, mm );
00783 glGetDoublev( GL_PROJECTION_MATRIX, pm );
00784
00785 # if gluProject
00786 GLdouble _wx, _wy, _wz;
00787
00788 for( i = 0; i < 12; i++ ){
00789 if( clipNear( segments[i][0].xyz(), segments[i][1].xyz() ) ){
00790 for( int j = 0; j < 2; j++ ){
00791
00792 gluProject( segments[i][j][0], segments[i][j][1], segments[i][j][2], mm, pm, vp, &_wx, &_wy, &_wz );
00793 if( _wx < rect[0] )rect[0] = _wx;
00794 if( _wx > rect[1] )rect[1] = _wx;
00795 if( _wy < rect[2] )rect[2] = _wy;
00796 if( _wy > rect[3] )rect[3] = _wy;
00797 }
00798 }
00799 }
00800 # endif
00801 #elif WIN32
00802 # pragma message( "warning: Camera::project() not implemented under OpenGL|ES 2.0" )
00803 #endif
00804
00805 return( rect );
00806 }
00807
00816 Rectangle Camera::project( const Vec3 & p, float r ){
00817 Vec3 rv = Vec3( r, r, r );
00818 NAABB naabb( p - rv, p + rv );
00819 return( project( naabb ) );
00820 }
00821
00822 void Camera::setOrthoWidth( float x, float y, float w, bool send ){
00823 m_ortho[0] = x;
00824 m_ortho[1] = x + w;
00825 m_ortho[2] = y;
00826 m_ortho[3] = w / m_aspect;
00827 if( send ){
00829 }
00830 }
00831
00832 void Camera::setOrthoHeight( float x, float y, float h, bool send ){
00833 m_ortho[0] = x;
00834 m_ortho[1] = h * m_aspect;
00835 m_ortho[2] = y;
00836 m_ortho[3] = y + h;
00837 if( send ){
00839 }
00840 }
00841
00842 void Camera::setOrtho( const Vec4 & ortho, bool send ){
00843 m_ortho = ortho;
00844 if( send ){
00846 }
00847 }
00848
00849 const Vec4 & Camera::getOrtho( void ) const{
00850 return( m_ortho );
00851 }
00852
00853 Vec4 & Camera::getOrtho( void ){
00854 return( m_ortho );
00855 }
00856
00857 Vec4 Camera::getOrthoZoomed( void ) const{
00858 float x,y;
00859 float f = 0.5f * m_zoom;
00860
00861 x = m_ortho[0] + getOrthoWidth() * 0.5f;
00862 y = m_ortho[2] + getOrthoHeight() * 0.5f;
00863
00864 Vec4 r;
00865 r[0] = x - getOrthoWidth() * f;
00866 r[1] = x + getOrthoWidth() * f;
00867 r[2] = y - getOrthoHeight() * f;
00868 r[3] = y + getOrthoHeight() * f;
00869
00870 return( r );
00871 }
00872
00873 float Camera::getOrthoWidth( void ) const {
00874 return( m_ortho[1] - m_ortho[0] );
00875 }
00876
00877 float Camera::getOrthoHeight( void ) const {
00878 return( m_ortho[3] - m_ortho[2] );
00879 }
00880
00881 float Camera::getOrthoWidthZoomed( void ) const {
00882 return(( m_ortho[1] - m_ortho[0] ) * m_zoom );
00883 }
00884
00885 float Camera::getOrthoHeightZoomed( void ) const {
00886 return( ( m_ortho[3] - m_ortho[2] ) * m_zoom );
00887 }
00888
00889
00890 void Camera::rectZoom( const Vec2 & p1, const Vec2 & p2, bool send ){
00891 GLint vp[4];
00892 glGetIntegerv( GL_VIEWPORT, vp );
00893 m_vp[0] = vp[0];
00894 m_vp[1] = vp[1];
00895 m_vp[2] = vp[2];
00896 m_vp[3] = vp[3];
00897
00898 float l1, r1, b1, t1, w1, h1;
00899 float l2, r2, b2, t2, w2, h2;
00900
00901 l1 = ( p1[0] < p2[0] ) ? p1[0] : p2[0];
00902 r1 = ( p1[0] > p2[0] ) ? p1[0] : p2[0];
00903 b1 = ( p1[1] < p2[1] ) ? p1[1] : p2[1];
00904 t1 = ( p1[1] > p2[1] ) ? p1[1] : p2[1];
00905
00906 w1 = r1 - l1 + 1;
00907 h1 = t1 - b1 + 1;
00908
00909 if( m_type == PERSPECTIVE ){
00910 }
00911 else{
00912 if( w1 > h1 ){
00913 l2 = l1;
00914 r2 = r1;
00915
00916 m_aspect = (float)m_vp[2] / (float)m_vp[3];
00917 h2 = m_aspect * w1;
00918 b2 = ( b1 + 0.5 * h1 ) - 0.5 * h2;
00919 t2 = ( b1 + 0.5 * h1 ) + 0.5 * h2;
00920 }
00921 else{
00922 t2 = t1;
00923 b2 = b1;
00924
00925 m_aspect = (float)m_vp[2] / (float)m_vp[3];
00926 w2 = m_aspect * h1;
00927 l2 = ( l1 + 0.5 * w1 ) - 0.5 * w2;
00928 r2 = ( l1 + 0.5 * w1 ) + 0.5 * w2;
00929 }
00930 m_ortho[0] = l2;
00931 m_ortho[1] = r2;
00932 m_ortho[2] = b2;
00933 m_ortho[3] = t2;
00934 }
00935 if( send ){
00937 }
00938 }
00939
00940 Vec3 Camera::screen2Global( const Vec3 & screen ){
00941 #ifndef RT_GLES
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955 GLdouble pm[16], ret[3], screend[3] = { screen[0], screen[1], screen[2] };
00956 GLdouble mm[16];
00957 GLint vp[4] = { (GLint)m_vp[0], (GLint)m_vp[1], (GLint)m_vp[2], (GLint)m_vp[3] };
00958
00959 glGetDoublev( GL_MODELVIEW_MATRIX, mm );
00960 glGetDoublev( GL_PROJECTION_MATRIX, pm );
00961
00962 gluUnProject( screend[0], screend[1], screend[2], mm, pm, vp, &ret[0], &ret[1], &ret[2] );
00963 return( Vec3( ret[0], ret[1], ret[2] ) );
00964 #elif WIN32
00965 # pragma message( "warning: Sampler::render() not implemented under OpenGL|ES" )
00966 #endif
00967 return( Vec3() );
00968 }
00969
00970 void Camera::getProjectionPyramid( Vec3& p1, Vec3& p2, Vec3& p3, Vec3& p4, Vec3& apex, Vec3& m1, Vec3& m2 ){
00971
00972
00973 float l = ( m1[0] < m2[0] ) ? m1[0] : m2[0];
00974 float r = ( m1[0] > m2[0] ) ? m1[0] : m2[0];
00975 float b = ( m1[1] < m2[1] ) ? m1[1] : m2[1];
00976 float t = ( m1[1] > m2[1] ) ? m1[1] : m2[1];
00977
00978 m1 = Vec3( l, b, 1.0f );
00979 m2 = Vec3( r, t, 1.0f );
00980
00981 Vec3 c1( m2[0], m1[1], 1.0f );
00982 Vec3 c2( m1[0], m2[1], 1.0f );
00983
00984 p1 = screen2Global( m1 );
00985 p2 = screen2Global( c1 );
00986 p3 = screen2Global( m2 );
00987 p4 = screen2Global( c2 );
00988
00989 apex = m_eye;
00990 }
00991
00992 void Camera::initViewport( const Vec2 & vp, bool send ){
00993 setScreen( vp, false );
00994 setViewport( Vec4( 0.0f, 0.0f, vp ), send );
00995 }
00996
00997
00998 };