00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "Teddy/SpaceGame/Root.h"
00026 #include "Teddy/SpaceGame/SimulatedInstance.h"
00027 #include "Teddy/SpaceGame/Ship.h"
00028 #include "Teddy/SpaceGame/ShipType.h"
00029 using namespace Teddy::Models;
00030
00031
00032 namespace Teddy {
00033 namespace SpaceGame {
00034
00035
00036 void Ship::collide(){
00037 tick_translation = getViewAxis() * speed * -2;;
00038 translate( tick_translation );
00039 speed *= -0.5;
00040 }
00041
00042
00048 Ship::Ship( char *name, ShipType *ship_type, Root *root )
00049 :
00050 SimulatedInstance( name, ship_type->getMesh() )
00051 {
00052 this->ship_type = ship_type;
00053 this->root = root;
00054
00055 target = NULL;
00056 target_offset = Vector(0,0,0);
00057 pitch = 0;
00058 roll = 0;
00059 speed = 0;
00060 accel = 0;
00061 control_pitch_up = false;
00062 control_pitch_down = false;
00063 control_roll_left = false;
00064 control_roll_right = false;
00065 control_more_speed = false;
00066 control_less_speed = false;
00067 control_stop = false;
00068 control_fire_weapon = false;
00069 active_pitch = false;
00070 active_roll = false;
00071 pitch_delta = 0;
00072 roll_delta = 0;
00073 }
00074
00076 void Ship::tick(){
00077 applyControls( 10.0f );
00078 SimulatedInstance::tick();
00079 }
00080
00081
00082
00083
00084 void Ship::stopSpeed(){
00085 if( speed > 0 ){
00086 controlMoreSpeed( false );
00087 controlLessSpeed( true );
00088 }else if( speed < 0 ){
00089 controlMoreSpeed( true );
00090 controlLessSpeed( false );
00091 }
00092 }
00093
00094
00095 void Ship::stopPitch(){
00096 if( pitch > 0 ){
00097 controlPitchDown( true );
00098 controlPitchUp ( false );
00099 }else if( pitch < 0 ){
00100 controlPitchDown( false );
00101 controlPitchUp ( true );
00102 }
00103 }
00104
00105
00106 void Ship::stopRoll(){
00107 if( roll > 0 ){
00108 controlRollLeft ( true );
00109 controlRollRight( false );
00110 }else if( roll < 0 ){
00111 controlRollLeft ( false );
00112 controlRollRight( true );
00113 }
00114 }
00115
00116
00117
00118
00119
00120 float Ship::getTargetDistance() const {
00121 if( target != NULL ){
00122 Vector tpos = target->getPosition();
00123 Vector cpos = this->getPosition();
00124 Vector delta = tpos - cpos;
00125
00126 float target_distance = delta.magnitude();
00127 target_distance -= target->getClipRadius() * 2;
00128
00129 return target_distance;
00130 }else{
00131 return 0;
00132 }
00133 }
00134
00135 float Ship::getBrakeDistance() const {
00136 return (speed * speed) / (2 * ship_type->getAcceleration() * 10);
00137 }
00138
00139
00140
00141
00142
00155 void Ship::trackTarget(){
00156 if( target == NULL ){
00157 return;
00158 }
00159
00160 Vector tpos = target->getPosition();
00161 Vector cpos = this->getPosition();
00162 Vector tview = target->getViewAxis ();
00163 Vector tup = target->getUpAxis ();
00164 Vector tright = target->getRightAxis();
00165 Vector cview = getViewAxis ();
00166 Vector cup = getUpAxis ();
00167 Vector cright = getRightAxis();
00168 Vector offset = tright * target_offset.v[0] +
00169 tup * target_offset.v[1] +
00170 tview * target_offset.v[2];
00171 Vector delta = tpos + offset - cpos;
00172 float target_speed;
00173
00174 SimulatedInstance *sim_target = dynamic_cast<SimulatedInstance*>( target );
00175 if( sim_target != NULL ){
00176 target_speed = (float)(sim_target->tick_translation.magnitude());
00177 }else{
00178 target_speed = 0;
00179 }
00180
00181 float target_distance = getTargetDistance();
00182 float brake_distance = (speed * speed) / (20 * ship_type->getAcceleration() );
00183 float b_pitch_distance = 10 * (pitch * pitch) / (2 * ship_type->getPitchConst () );
00184 float b_roll_distance = 10 * (roll * roll ) / (2 * ship_type->getRollConst () );
00185
00186 delta .normalize();
00187 float v = cview | delta;
00188 float u = cup | delta;
00189 float r = cright | delta;
00190 float v_epsilon = 0.01f;
00191 float u_epsilon = 0.01f;
00192 float r_epsilon = 0.02f;
00193 pitch_distance = (float)acos( u );
00194 roll_distance = (float)acos( r );
00195
00196
00197 if( target_distance < 1 ){
00198 stopSpeed();
00199 stopPitch();
00200 stopRoll ();
00201 return;
00202 }
00203
00204 bool speed_control = false;
00205 if(
00206 ( brake_distance < target_distance )
00207
00208 &&
00209
00210 (
00211
00212 (
00213 (target_distance < 100 ) &&
00214 (fabs(speed) < fabs(target_speed) )
00215 )
00216
00217 ||
00218
00219 (
00220 target_distance >= 100
00221 )
00222 )
00223 ){
00224 speed_control = true;
00225 }
00226
00227
00228 if( v > 0.5 ){
00229
00230
00231 if( speed_control == true ){
00232 controlMoreSpeed( true );
00233 controlLessSpeed( false );
00234 }else{
00235 stopSpeed();
00236 }
00237 }
00238
00239
00240 if( v < 0.5 ){
00241
00242
00243 if( speed_control == true ){
00244 controlMoreSpeed( false );
00245 controlLessSpeed( true );
00246 }else{
00247 stopSpeed();
00248 }
00249 }
00250
00251
00252 if( fabs(0.5-v) < v_epsilon ){
00253 stopPitch();
00254 stopRoll();
00255 return;
00256 }
00257
00258
00259 if( u >= 0 ){
00260
00261
00262 if( (b_pitch_distance < pitch_distance) &&
00263 (fabs(u) > fabs(r) ) &&
00264 (u > u_epsilon ) )
00265 {
00266 controlPitchUp ( true );
00267 controlPitchDown( false );
00268 }else{
00269 stopPitch();
00270 }
00271
00272
00273 if( r > r_epsilon ){
00274
00275 if( b_roll_distance < roll_distance ){
00276 controlRollRight( true );
00277 controlRollLeft ( false );
00278 }else{
00279 stopRoll();
00280 }
00281 }
00282
00283
00284 if( r < -r_epsilon ){
00285
00286 if( b_roll_distance < roll_distance ){
00287 controlRollRight( false );
00288 controlRollLeft ( true );
00289 }else{
00290 stopRoll();
00291 }
00292 }
00293 }
00294
00295
00296 if( u < 0 ){
00297
00298
00299 if( (b_pitch_distance < pitch_distance) &&
00300 (fabs(u) > fabs(r) ) &&
00301 (u < -u_epsilon ) )
00302 {
00303 controlPitchUp ( false );
00304 controlPitchDown( true );
00305 }else{
00306 stopPitch();
00307 }
00308
00309
00310 if( r > r_epsilon ){
00311
00312 if( b_roll_distance < roll_distance ){
00313 controlRollRight( false );
00314 controlRollLeft ( true );
00315 }else{
00316 stopRoll();
00317 }
00318 }
00319
00320
00321 if( r < -r_epsilon ){
00322
00323 if( b_roll_distance < roll_distance ){
00324 controlRollRight( true );
00325 controlRollLeft ( false );
00326 }else{
00327 stopRoll();
00328 }
00329 }
00330 }
00331 }
00332
00333
00334
00335
00336
00337 ShipType *Ship::getShipType(){
00338 return this->ship_type;
00339 }
00340
00341 void Ship::setTarget( ModelInstance *mi, Vector offset ){
00342 this->target = mi;
00343 this->target_offset = offset;
00344 }
00345
00346
00348 void Ship::setTargetPosition(){
00349 Vector tpos = target->getPosition();
00350
00351 Vector tview = target->getViewAxis ();
00352 Vector tup = target->getUpAxis ();
00353 Vector tright = target->getRightAxis();
00354
00355
00356
00357 Vector offset = tright * target_offset.v[0] +
00358 tup * target_offset.v[1] +
00359 tview * target_offset.v[2];
00360
00361 setPosition( tpos + offset );
00362 }
00363
00364 ModelInstance *Ship::getTarget(){
00365 return target;
00366 }
00367
00368 float Ship::getPitch() const {
00369 return pitch;
00370 }
00371
00372 float Ship::getRoll() const {
00373 return roll;
00374 }
00375
00376 float Ship::getSpeed() const {
00377 return speed;
00378 }
00379
00380
00381 };
00382 };
00383