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 "config.h"
00026 #include "Teddy/Graphics/View.h"
00027 #include "Teddy/Imports/LWMesh.h"
00028 #include "Teddy/Materials/Material.h"
00029 #include "Teddy/Materials/Light.h"
00030 #include "Teddy/Maths/Vector.h"
00031 #include "Teddy/Maths/Vector4.h"
00032 #include "Teddy/Models/Line.h"
00033 #include "Teddy/Models/Vertex.h"
00034 #include "Teddy/Models/Grid.h"
00035 #include "Teddy/Models/Torus.h"
00036 #include "Teddy/Models/Tube.h"
00037 #include "Teddy/PhysicalComponents/ConsoleStream.h"
00038 #include "Teddy/PhysicalComponents/Projection.h"
00039 #include "Teddy/Scenes/Camera.h"
00040 #include "Teddy/Scenes/PostElement.h"
00041 #include "Teddy/Scenes/Scene.h"
00042 #include "Teddy/SpaceGame/CollisionGroup.h"
00043 #include "Teddy/SpaceGame/ComputerShip.h"
00044 #include "Teddy/SpaceGame/ObjectManager.h"
00045 #include "Teddy/SpaceGame/PlayerShip.h"
00046 #include "Teddy/SpaceGame/ShipCamera.h"
00047 #include "Teddy/SpaceGame/ShipType.h"
00048 #include "Teddy/SpaceGame/Root.h"
00049 #include "Teddy/SysSupport/Messages.h"
00050 #include <cstdio>
00051 using namespace Teddy::Graphics;
00052 using namespace Teddy::Imports;
00053 using namespace Teddy::Materials;
00054 using namespace Teddy::PhysicalComponents;
00055 using namespace Teddy::Scenes;
00056 
00057 
00058 namespace Teddy     {
00059 namespace SpaceGame {
00060 
00061 
00062 #define PITCH_CONST  (float)(   1.0f * M_2_PI/1000000.0f )  //  RADS PER TICK
00063 #define ROLL_CONST   (float)(   1.0f * M_2_PI/1000000.0f )  //  RADS PER TICK
00064 #define MAX_PITCH    (float)( 250.0f * M_2_PI/1000000.0f )  //  RADS PER TICK
00065 #define MAX_ROLL     (float)( 250.0f * M_2_PI/1000000.0f )  //  RADS PER TICK
00066 #define ACCEL_CONST  (float)(   0.0020f)                    //  m/s PER TICK
00067 #define MAX_SPEED    (float)(   6.5000f)                    //  m/s PER TICK
00068 
00069 
00071 ObjectManager::ObjectManager( Root *root ){
00072     this->root = root;
00073     instance   = NULL;
00074 }
00075 
00076 
00078 void ObjectManager::addObjects(){
00079     solar_bodies_cg = new CollisionGroup( "solar bodies" );
00080 
00081 
00082     Mesh     *cobra_mesh      = new LWMesh  ( "lwo/cobra_with_texture.lwo", 0 );
00083     Mesh     *viper_mesh      = new LWMesh  ( "lwo/VIPER.lwo",              0 );
00084     ShipType *cobra_ship_type = new ShipType( cobra_mesh, ACCEL_CONST, MAX_SPEED, PITCH_CONST, ROLL_CONST, MAX_PITCH, MAX_ROLL );
00085     ShipType *viper_ship_type = new ShipType( viper_mesh, ACCEL_CONST, MAX_SPEED, PITCH_CONST, ROLL_CONST, MAX_PITCH, MAX_ROLL );
00086     scene           = new Scene       ( "Test scene" );
00087     camera          = new Camera      ( "Spectator Camera", scene );
00088     camera2         = new Camera      ( "Other View",       scene );
00089     player_ship     = new PlayerShip  ( cobra_ship_type, root );
00090     Ship *wingman_1 = new ComputerShip( "Wingman 1", viper_ship_type, root );
00091     Ship *wingman_2 = new ComputerShip( "Wingman 2", viper_ship_type, root );
00092     active_camera   = camera;
00093 
00094     player_ship->setPosition( 0, 400.0, 0 );
00095     wingman_1->setTarget( player_ship, Vector(-400,0,-300) );
00096     wingman_2->setTarget( player_ship, Vector( 400,0,-300) );
00097     wingman_1->setTargetPosition();
00098     wingman_2->setTargetPosition();
00099 
00100     player_camera = new ShipCamera( player_ship, scene, NULL );
00101     player_camera->disableOptions( MI_VISIBLE );
00102 
00103     scene->addInstance( player_ship   );
00104     scene->addInstance( player_camera );  
00105 
00106 
00107 
00108     setActiveCamera( camera );
00110 
00111     
00112 
00113 
00114     camera ->translate     ( 0, 400,  800 );
00115     camera ->pitch         ( -35 );
00116     camera2->translate     ( 0, 10, -100 );
00117     camera2->disableOptions( MI_VISIBLE );
00118     camera2->heading       ( 180.0f );
00119     scene  ->addInstance   ( camera );
00120     camera ->setMesh       ( NULL );
00121     camera2->setMesh       ( NULL );
00122     scene  ->addInstance   ( camera2 );
00123 
00124     camera ->setMaterial( &Material::YELLOW );
00125     camera2->setMaterial( &Material::MAGENTA );
00126 
00127     addLights( 4, false );
00128     addGrid( 50, 50, 100, 100 );
00129 
00130     addPrimitives();
00131     loadLWO();
00132 
00133 
00134 
00135 
00136     
00137 
00138 
00139 
00140 
00141 
00142 
00143 
00144 
00145 
00146 
00147 
00148 
00149 
00150 
00151 
00152 
00153 
00154 #if 0
00155     PostElement *pe;
00156         
00157 
00158 
00159 
00160 
00161 
00162 
00163 
00164 
00165     char name[100];
00166     int  i;
00167     for( i=1; i<2; i++ ){
00168         float x = 3000 * sin( i*M_PI/7 );
00169         float z = 3000 * cos( i*M_PI/7 );
00170         sprintf( name, "alphasprites/Star%d.png", i );
00171         pe = new PostElement( name, 500, i*117, 315*(i%6+2) );
00172         pe->insert( new Vector4( 0, 0, 0, 1 ) );
00173         pe->setPosition( x, 1000, z );
00174         scene->addPostElement( pe );
00175     }
00176 #endif
00177 }
00178 
00179 
00184 void ObjectManager::addLights( int num, const bool animate ){
00185 #   define LX 20000
00186 #   define LY 50000
00187 #   define LZ 20000
00188     Light *light;
00189 
00190     light = new Light( "Player Light" );
00191     light->setAmbient ( Color(0.6f,0.6f,0.6f) );
00192     light->setDiffuse ( Color(0.6f,0.6f,0.6f) );
00193     light->setSpecular( Color(0.6f,0.6f,0.6f) );
00194     light->setPosition( 0, 0, 0 );
00195     light->setSpotCutOff( 25.0f );
00196     light->setSpotExponent( 32.0f );
00197     light->enable();
00198     scene->addLight( light );
00199 
00200     
00201     if( num>1 ){
00202         light = new Light( "Light 1" );
00203         light->setAmbient ( Color(0.4f,0.4f,0.4f) );
00204         light->setDiffuse ( Color(0.4f,0.4f,0.4f) );
00205         light->setSpecular( Color(0.4f,0.4f,0.4f) );
00206         light->setPosition( LX, LY, 0 );
00207         light->enable();
00208         scene->addLight( light );
00209         if( animate ){
00210 
00211             light->orbit( 8000, 15000, 0 );
00212         }
00213     }
00214 
00215     if( num>2 ){
00216         light = new Light( "Light 2" );
00217         light->setAmbient ( Color(0.4f,0.4f,0.4f) );
00218         light->setDiffuse ( Color(0.4f,0.4f,0.4f) );
00219         light->setSpecular( Color(0.4f,0.4f,0.4f) );
00220         light->setPosition(  0, LY, LZ );
00221         light->enable();
00222         scene->addLight( light );
00223         if( animate ){
00224 
00225             light->orbit( 6000, 30000, 1 );
00226         }
00227     }
00228 
00229     if( num>3 ){
00230         light = new Light( "Light 3" );
00231         light->setAmbient ( Color(0.4f,0.4f,0.4f) );
00232         light->setDiffuse ( Color(0.4f,0.4f,0.4f) );
00233         light->setSpecular( Color(0.4f,0.4f,0.4f) );
00234         light->setPosition( 0, -LY, 0 );
00235         light->enable();
00236         scene->addLight( light );
00237         if( animate ){
00238 
00239             light->orbit( 7000, 50000, 2 );
00240         }
00241     }
00242 
00243     if( num>4 ){
00244         light = new Light( "Light 4" );
00245         light->setAmbient ( Color::GRAY_50 );
00246         light->setDiffuse ( Color::GRAY_50 );
00247         light->setSpecular( Color::GRAY_50 );
00248         light->setPosition( -LX, LY, LZ );
00249         light->enable();
00250         scene->addLight( light );
00251 
00252 
00253             light->orbit( 15000, 700, 3 );
00254 
00255     }
00256 
00257     if( num>5 ){
00258         light = new Light( "Light 5" );
00259         light->setAmbient ( Color(0,0,0.2f) );
00260         light->setDiffuse ( Color(0,0,0.2f) );
00261         light->setSpecular( Color(0,0,0.2f) );
00262         light->setPosition( LX, LY, 0 );
00263         light->enable();
00264         scene->addLight( light );
00265         light->orbit( 50000, 71, 5 );
00266     }
00267     if( num>6 ){
00268         light = new Light( "Light 6" );
00269         light->setAmbient ( Color::BLACK );
00270         light->setDiffuse ( Color::LIGHT_BLUE );
00271         light->setSpecular( Color::LIGHT_BLUE );
00272         light->setPosition( -LX, -LY, 0 );
00273         light->enable();
00274         scene->addLight( light );
00275         light->orbit( 25000, 300, 4 );
00276     }
00277 }
00278 
00279 
00281 void ObjectManager::addGrid( int xcount, int zcount, int xspace, int zspace ){
00282     Material      *m;
00283     ModelInstance *mi;
00284 
00285 #   if 0 // !defined( USE_TINY_GL )
00286     Grid *grid = new Grid( xcount, zcount, xspace, zspace );
00287 
00288     mi = new ModelInstance( "Grid", grid );
00289     mi->setPosition( 0.0, 1000.0f, 0.0 );
00290     mi->setMaterial( m = new Material( Material::DARK_BLUE, RENDER_LIGHTING_COLOR ) );
00291     m->setDiffuse( Color(0.334f,0.33f,0.44f) );
00292     scene->addInstance( mi );
00293 
00294     mi = new ModelInstance( "Grid", grid );
00295     mi->setPosition( 0, -1000, 0 );
00296     mi->setMaterial( m = new Material( Material::DARK_BLUE, RENDER_LIGHTING_COLOR ) );
00297     m->setDiffuse( Color(0.33f,0.33f,0.44f) );
00298     scene->addInstance( mi );
00299 #else
00300     Grid *grid = new Grid( xcount/2, zcount/2, xspace*2, zspace*2 );
00301 #endif
00302 
00303     mi = new ModelInstance( "Grid", grid );
00304     mi->setPosition( 0, 0.0f, 0 );
00305     mi->setMaterial( m = new Material( Material::DARK_RED, RENDER_LIGHTING_COLOR ) );
00306     m->setDiffuse( Color(0.5f,0.40f,0.65f) );
00307     scene->addInstance( mi );
00308 
00309 }
00310 
00311 
00313 PlayerShip *ObjectManager::getPlayerShip(){
00314     return this->player_ship;
00315 }
00316 
00317 
00319 ShipCamera *ObjectManager::getShipCamera(){
00320     return this->player_camera;
00321 }
00322 
00323 
00325 void ObjectManager::setActiveCamera( Camera *c ){
00326     this->active_camera = c;
00327 
00328 }
00329 
00330 
00332 void ObjectManager::instanceTranslateXZ( const int x_delta, const int y_delta ){
00333     if( instance==NULL ){
00334         return;
00335     }
00336 
00337 
00338     DoubleVector pos = instance->getPosition();
00339     pos += DoubleVector( x_delta*0.1, 0.0, y_delta*0.1 );
00340     instance->setPosition( pos );
00341 }
00342 
00343 
00345 void ObjectManager::instanceTranslateYZ( const int x_delta, const int y_delta ){
00346     if( instance==NULL ){
00347         return;
00348     }
00349 
00350 
00351     DoubleVector pos = instance->getPosition();
00352     pos += DoubleVector( x_delta*0.1, y_delta*0.1, 0.0 );
00353     instance->setPosition( pos );
00354 }
00355 
00356 
00358 void ObjectManager::instanceRotate( const int x_delta, const int y_delta ){
00359     if( instance==NULL ){
00360         return;
00361     }
00362     instance->heading( x_delta*4.0f );
00363     instance->pitch  ( y_delta*4.0f );
00364 }
00365 
00366 
00368 void ObjectManager::instanceScale( const int x_delta, const int y_delta ){
00369     if( instance==NULL ){
00370         return;
00371     }
00372         
00373     double dist = 0.3*y_delta;
00374     if( dist<0 ){
00375         dist = 1/sqrt(1-(dist/10));
00376     }else{
00377         dist = sqrt(1+(dist/10));
00378     }
00379         
00380     instance->roll (  rads( x_delta*0.3)  );
00381     instance->pitch(  rads( y_delta*0.3)  );
00382 }
00383 
00384 
00386 void ObjectManager::selectInstance( const int x, const int y ){
00387     static char    sel_line[80];
00388     ModelInstance *pick;
00389     list<Mesh*>::iterator m_it;
00390         
00391     pick = root->getUserInterface()->getActiveProjection()->pickInstance( x, y );
00392 
00393     if( pick!=NULL ){
00394 #if 0
00395         Material      *m;
00396         if( instance !=NULL ){
00397             m = instance->getMaterial();
00398             if( m != NULL ){
00399 
00400                 m->setMode( RENDER_MODE_FILL );
00401             }
00402             m_it = instance->getMesh()->submeshes.begin();
00403             while( m_it != instance->getMesh()->submeshes.end() ){
00404                 Material *m = (*m_it)->getMaterial();
00405                 if( m != NULL ){
00406 
00407                     m->setMode( RENDER_MODE_FILL );
00408                 }
00409                 m_it++;
00410             } 
00411         }
00412 #endif
00413         instance = pick;
00414 
00415 #if 0
00416         m = instance->getMaterial();
00417         if( m != NULL ){
00418 
00419             m->setMode( RENDER_MODE_FILL_OUTLINE );
00420         }
00421         m_it = instance->getMesh()->submeshes.begin();
00422         while( m_it != instance->getMesh()->submeshes.end() ){
00423             Material *m = (*m_it)->getMaterial();                                                                             
00424             if( m != NULL ){
00425 
00426                 m->setMode( RENDER_MODE_FILL_OUTLINE );
00427             }
00428             m_it++;
00429         }
00430 #endif
00431 
00432         player_ship->setTarget( instance );
00433 
00434     }
00435 }
00436 
00437 
00439 void ObjectManager::updateObjects(){
00440     list<ModelInstance*>::iterator i_it = scene->getInstances().begin();
00441     while( i_it != scene->getInstances().end() ){
00442         ModelInstance *mi = *i_it;
00443         Simulated     *s  = dynamic_cast<Simulated*>( mi );
00444 
00445         
00446         if( mi != player_ship ){
00447             if( player_ship->testCollision(mi) == true ){
00448                 player_ship->collide();
00449                 root->getAudioManager()->playHitEm();
00450             }
00451         }
00452 
00453         if( s != NULL ){
00454             s->tick();
00455         }
00456         i_it++;
00457     }
00458 }
00459 
00460 
00461 void ObjectManager::rayCollision( ModelInstance *source ){
00462     Vector origin    = source->getPosition();
00463     Vector direction = source->getViewAxis();
00464 
00465     list<ModelInstance*>::iterator i_it = scene->getInstances().begin();
00466     while( i_it != scene->getInstances().end() ){
00467         ModelInstance *mi = *i_it;
00468 
00469         
00470         if( mi != source ){
00471             if( mi->rayCollision(origin,direction) == true ){
00472                 
00473                 root->getAudioManager()->playHitEm();
00474             }
00475         }
00476 
00477         i_it++;
00478     }
00479 }
00480 
00481 
00482 Camera *ObjectManager::getCamera(){
00483     return camera;
00484 }
00485 
00486 
00487 };  
00488 };  
00489