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

ObjectManager.cpp

Go to the documentation of this file.
00001 
00002 /*
00003     TSGL - Teddy Space Game Library
00004     Copyright (C) 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: ObjectManager.cpp,v 1.1 2002/01/08 20:47:05 tksuoran Exp $
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 //  Mesh *cobra_mesh = new Box( "cobra", 30,10,20);
00081 //  Mesh *viper_mesh = new Box( "viper", 10,10,40);
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 );  //  Needed in scene so it will be ticked to be kept at player_ship location
00105 //  scene->addInstance( wingman_1     );
00106 //  scene->addInstance( wingman_2     );
00107 
00108     setActiveCamera( camera );
00110 
00111     //  This torus is currently used as Mesh for the spectator camera
00112 //  Torus *torus = new Torus( "Torus", 5.0, 2.0, 14, 14 );
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 //  addFFE();
00133 //  addROAM();
00134 //  addRigidBodies();
00135 
00136     //  Add reference point
00137 /*
00138     LineMesh *line_mesh = new LineMesh( "Lines" );
00139     Vertex *origo = new Vertex( 0, 0, 0 );
00140     Vertex *x_end = new Vertex(40, 0, 0 );
00141     Vertex *y_end = new Vertex( 0,40, 0 );
00142     Vertex *z_end = new Vertex( 0, 0,40 );
00143     line_mesh->insert( new Line(origo,x_end) );
00144     line_mesh->insert( new Line(origo,y_end) );
00145     line_mesh->insert( new Line(origo,z_end) );
00146     line_mesh->setClipRadius( sqrt(40*40*3) );
00147     ModelInstance *mi_lines = new ModelInstance( "Lines", line_mesh );
00148     Material      *mat      = new Material( Material::RED );
00149     mat     ->setLighting( RENDER_LIGHTING_COLOR );
00150     mi_lines->setMaterial( mat );
00151     mi_lines->setPosition( 10, 10, 10 );
00152     scene   ->addInstance( mi_lines );*/
00153 
00154 #if 0
00155     PostElement *pe;
00156         
00157 /*  pe = new PostElement( "star.png", 20 );
00158     pe->insert( new Vector4( 0, 0, 0, 1 ) );
00159     pe->insert( new Vector4(40, 0, 0, 1 ) );
00160     pe->insert( new Vector4( 0,40, 0, 1 ) );
00161     pe->insert( new Vector4( 0, 0,40, 1 ) );
00162     pe->setPosition( 10, 10, 10 );
00163     scene->addPostElement( pe );      */
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 //  ply_light = light;
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 //          light->tick_translation = DoubleVector( 2.0, 0.0, 0.0 );
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 //          light->tick_translation = DoubleVector( 0.0, -20.0, 0.0 );
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 //          light->tick_translation = DoubleVector( -2.0, -1.0, 10.0 );
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 //      if( animate ){
00252 //          light->tick_translation = DoubleVector( 40.0, 20.0, 1.0 );
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 //  this->player_ship   = c;
00328 }
00329 
00330 
00332 void ObjectManager::instanceTranslateXZ( const int x_delta, const int y_delta ){
00333     if( instance==NULL ){
00334         return;
00335     }
00336 
00337 //  instance->translate( Vector( -x_delta, 0.0, -y_delta ) );
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 //  instance->translate( Vector( -x_delta, -y_delta, 0.0 ) );
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 //              *console << "Disabling outline from old selection"; console->newLine();
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 //                  *console << "Disabling outline from old selection"; console->newLine();
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 //          *console << "Enabling outline for new selection"; console->newLine();
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 //              *console << "Enabling outline for new selection"; console->newLine();
00426                 m->setMode( RENDER_MODE_FILL_OUTLINE );
00427             }
00428             m_it++;
00429         }
00430 #endif
00431 
00432         player_ship->setTarget( instance );
00433 //      player_camera->setShip( instance );
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         //  Test collision with player
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         //  Test collision with player
00470         if( mi != source ){
00471             if( mi->rayCollision(origin,direction) == true ){
00472                 //mi->damage();
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 };  //  namespace SpaceGame
00488 };  //  namespace Teddy
00489