Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/playability/src/world_entities/projectiles/swarm_projectile.cc @ 10196

Last change on this file since 10196 was 10196, checked in by nicolasc, 17 years ago

just another upload
GUI seems to work, but there are still some unexplainable segfaults

File size: 9.2 KB
RevLine 
[10004]1/*
2   orxonox - the future of 3D-vertical-scrollers
3
[10104]4   Copyright (C) 2004-2006 orx
[10004]5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific
[10104]12   main-programmer: Marc Schaerrer, Nicolas Schlumberger
[10004]13   co-programmer:
14
15*/
16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
17
18#include "swarm_projectile.h"
19
20#include "state.h"
21
22#include "particles/dot_emitter.h"
23#include "particles/sprite_particles.h"
[10064]24#include "space_ships/space_ship.h"
[10081]25#include "effects/trail.h"
[10004]26
27#include "debug.h"
28
29#include "class_id_DEPRECATED.h"
30
[10079]31#include "math/vector.h"
32
[10004]33ObjectListDefinitionID(SwarmProjectile, CL_SWARM_PROJECTILE);
34CREATE_FAST_FACTORY_STATIC(SwarmProjectile);
35
36/**
37 *  standard constructor
38*/
39SwarmProjectile::SwarmProjectile () : Projectile()
40{
41
[10035]42/*  this->loadModel("models/projectiles/orx-rocket.obj", 0.5);*/
[10037]43  this->loadModel("models/projectiles/swarm_projectile.obj"); // no double rescale (see draw())
[10004]44  this->loadExplosionSound("sound/explosions/explosion_4.wav");
45
46
47  this->setMinEnergy(1);
48  this->setHealthMax(10);
[10064]49  this->lifeSpan = 4.0;
[10004]50  this->agility = 3.5;
51
52  this->emitter = new DotEmitter(100, 5, M_2_PI);
53  this->emitter->setParent(this);
54  this->emitter->setSpread(M_PI, M_PI);
[10037]55
[10132]56  this->turningSpeed = 10;
[10080]57
58  this->physDamage = 200;
[10104]59  this->elecDamage = 0;
[10081]60
[10095]61  this->trail = new Trail(2.5,4,.2, this);
62  //this->trail->setParent( this);
[10081]63  this->trail->setTexture( "maps/laser.png");
[10004]64}
65
66
67/**
68 *  standard deconstructor
69*/
70SwarmProjectile::~SwarmProjectile ()
71{
72
73  if (SwarmProjectile::explosionParticles != NULL && SwarmProjectile::objectList().size() <= 1)
74  {
75    if (ParticleSystem::objectList().exists(SwarmProjectile::explosionParticles))
76      delete SwarmProjectile::explosionParticles;
77    SwarmProjectile::explosionParticles = NULL;
78  }
[10081]79  // delete this->emitter;
80  delete this->trail;
[10004]81}
82
83SpriteParticles* SwarmProjectile::explosionParticles = NULL;
84
85
86
87void SwarmProjectile::activate()
88{
[10168]89  this->toList(OM_ENVIRON);
[10004]90  if (unlikely(SwarmProjectile::explosionParticles == NULL))
91  {
92    SwarmProjectile::explosionParticles = new SpriteParticles(200);
[10073]93    SwarmProjectile::explosionParticles->setName("SwarmProjectileExplosionParticles");
[10004]94    SwarmProjectile::explosionParticles->setMaterialTexture("maps/radial-trans-noise.png");
95    SwarmProjectile::explosionParticles->setLifeSpan(.5, .3);
96    SwarmProjectile::explosionParticles->setRadius(0.0, 10);
97    SwarmProjectile::explosionParticles->setRadius(.5, 15.0);
98    SwarmProjectile::explosionParticles->setRadius(1.0, 10.0);
99    SwarmProjectile::explosionParticles->setColor(0.0, 0,1,0,1);
100    SwarmProjectile::explosionParticles->setColor(0.5, .8,.8,0,.8);
101    SwarmProjectile::explosionParticles->setColor(0.8, .8,.8,.3,.8);
102    SwarmProjectile::explosionParticles->setColor(1.0, 1,1,1,.0);
103  }
104
[10078]105  this->emitter->setEmissionRate(50.0);
[10004]106  this->emitter->setEmissionVelocity(0.0);
[10078]107  this->emitter->setInheritSpeed(0);
[10004]108
109  this->setHealth(10.0* (float)rand()/(float)RAND_MAX);
[10079]110
111  this->maxVelocity = 300;
112
[10086]113  this->rotationSpeed = 360;
[10079]114  this->angle = 0;
[10087]115
116  this->curDir = this->lastDir = this->velocity;
[10004]117}
118
119
120void SwarmProjectile::deactivate()
121{
122  this->emitter->setSystem(NULL);
123  this->lifeCycle = 0.0;
124
125  this->toList(OM_DEAD);
126  this->removeNode();
127  SwarmProjectile::fastFactory->kill(this);
128}
129
130
131void SwarmProjectile::collidesWith(WorldEntity* entity, const Vector& location)
132{
133  if (this->hitEntity != entity)
134    this->destroy( entity );
135  this->hitEntity = entity;
[10117]136  //dynamic_cast<SpaceShip*>(entity)->damage(this->getPhysDamage(),this->getElecDamage());
[10109]137  this->destroy(this);
[10004]138}
139
[10035]140
[10080]141void SwarmProjectile::setTarget(PNode* target)
142{
143    this->target = target;
144}
[10035]145
[10080]146
147
[10004]148/**
[10035]149 *  this function gets called by tick to calculate the new flight direction
150 *  @param curDirection direction vector
151 *  @param estTargetDir target vector, pointing to where the target will be on hit
152 *  @param angle = tick * turningSpeed
153 *  @return (new) direction vector
154*/
155Vector SwarmProjectile::newDirection(Vector curDirection, Vector estTargetDir, float angle)
156{
[10038]157  if (unlikely(curDirection.len() == 0))
158    return curDirection;
[10080]159  //printf("recalculating direction\n");
160  float tmp = angleRad ( curDirection, estTargetDir);
[10035]161  if ( unlikely(tmp == 0) ) { return curDirection * maxVelocity / curDirection.len(); }
[10080]162//   printf("turning angle: %f\ntemp: %f\n", angle, tmp);
[10035]163
[10132]164  if( fabsf(angle) >  fabsf(tmp) ) 
165    angle = tmp;
166  else
167    angle *= tmp/fabsf(tmp);
[10035]168
169  Vector d = curDirection.cross(estTargetDir).cross(curDirection);
170  d.normalize();
[10132]171  if( unlikely( fabsf(angle) == 90)) { return d; } //avoid complication
[10035]172
173  Vector newDir = curDirection + d *  curDirection.len() * tan (angle);
174  newDir.normalize();
175  newDir *= curDirection.len();
176  return newDir;
177}
178
179
180
181
182/**
[10004]183 *  signal tick, time dependent things will be handled here
184 * @param time since last tick
185*/
186void SwarmProjectile::tick (float time)
187{
[10196]188  if(unlikely(this->target == NULL)) /** Check whether the target still exists*/
189    this->deactivate();
190
[10035]191/*
[10004]192  Vector targetFarFarAway = this->getAbsCoor() + Vector(100000, 0, 0);
193
194  {
195    speed = velocity.len();
196    diffVector = ((targetFarFarAway - this->getAbsCoor()).getNormalized());
197
198    if(velocity.dot(diffVector) != 0)
199    {
200      correctionVector = (( ( diffVector *  (speed * speed/( velocity.dot(diffVector ) ) )) - velocity).getNormalized()) * agility;
201
202      if( (diffVector *  (speed * speed/( velocity.dot(diffVector ) ) ) -velocity).len() < agility )
203        velocity = ((diffVector *  (speed * speed/( velocity.dot(diffVector ) ) )).getNormalized())*agility;
204      else if(velocity.dot(diffVector) > 0)
205        velocity += correctionVector;
206      else if (velocity.dot(diffVector) < 0)
207        velocity -= correctionVector;
208    }
209    else
210      velocity += diffVector * agility;
211
212    this->setAbsDir(Quaternion(velocity, Vector(0,1,0)) * Quaternion ( -M_PI_2, Vector(0,1,0)));
213  }
214
215  velocity *= maxVelocity/velocity.len();
216  Vector v = this->velocity * (time);
[10035]217  this->shiftCoor(v);*/
[10004]218
[10153]219
220/** old  guiding functuion*/
221
[10080]222  float projectileVelocity = this->getVelocity().len();
[10087]223  if (target != NULL){
[10132]224    Vector estTargetDir = (this->target->getAbsCoor() - this->getAbsCoor()).getNormalized();
[10080]225    this->velocity = this->newDirection(this->velocity, estTargetDir, this->turningSpeed * time );
[10087]226  }
227  else
[10104]228    if (likely(projectileVelocity != 0 || projectileVelocity != this->maxVelocity) )
[10087]229      this->velocity *= (this->maxVelocity / projectileVelocity); // set speed to max
[10035]230
[10080]231//   printf("position: %f, %f, %f\n", this->getAbsCoor().x, this->getAbsCoor().y, this->getAbsCoor().z);
232//   printf("target position: %f, %f, %f\n", this->target->getAbsCoor().x, this->target->getAbsCoor().y, this->target->getAbsCoor().z);
233
[10153]234  this->shiftCoor(this->velocity * time);
[10080]235
[10153]236
237/*
238  Vector pjV = this->getVelocity();
239  Vector tV = this->target->getVelocity();
240  Vector pT = this->target->getAbsCoor() - this->getAbsCoor(); // vector projectile target
241
242  Vector a = tV.getNormalized() * pT.dot(tV.getNormalized());
243
244  float A = 2 * pT.len() * pT.len();
245  float B = 2 * a.len() * tV.len();
246  float D = 2 * sqrt(B * B - 4 * pT.len() * pT.len() *(tV.len() * tV.len() - pjV.len() * pjV.len()));
247  float tti;
248
249  if (A != 0){
250    if ( B < D ) tti = ( B + D ) / A;
251    else tti = ( B + D ) / A;
252  }
253  else tti = 0;
254
255
256  Vector estTargetDir;
257  if (tti == 0)
258    estTargetDir = pT.getNormalized() * pjV.len();
259  else
260    estTargetDir = pT / tti + pjV;
261
262  this->velocity = this->newDirection(this->velocity, estTargetDir, this->turningSpeed * time );
263
264  this->shiftCoor(this->velocity * (this->maxVelocity * time));*/
265
[10004]266  if(this->tickLifeCycle(time))
267    this->deactivate();
[10037]268
[10087]269  this->trail->tick(time);
[10081]270
[10087]271  this->angle += this->rotationSpeed * time;
[10188]272  while (this->angle > 360)
273    this->angle -= 360;
[10087]274
275  this->lastDir = this->curDir;
276  this->curDir = this->velocity;
[10109]277  if( (this->getAbsCoor() - this->target->getAbsCoor()).len() < 3)   // FIXME  Temp fake workaround for collision :)
[10095]278  {
279    dynamic_cast<WorldEntity*>(target)->destroy( this);
280    this->destroy( this);
[10168]281  }
[10004]282}
283
284/**
285 *  the function gets called, when the projectile is destroyed
286 */
287void SwarmProjectile::destroy (WorldEntity* killer)
288{
289
[10109]290//   printf("THIS SHOULD WORK!\n");
[10004]291
292  Projectile::destroy( killer );
293  PRINTF(5)("DESTROY SwarmProjectile\n");
294  this->lifeCycle = .95; //!< @todo calculate this usefully.
295  this->emitter->setSystem(SwarmProjectile::explosionParticles);
296
297  this->emitter->setEmissionRate(1000.0);
298  this->emitter->setEmissionVelocity(50.0);
[10073]299  this->deactivate();
[10004]300
301}
302
303
304void SwarmProjectile::draw () const
305{
306  glMatrixMode(GL_MODELVIEW);
307  glPushMatrix();
308
[10132]309  Vector tmpDir = this->curDir; // *.7 + this->lastDir * .3;
310  tmpDir.slerpTo(this->lastDir, .4);
[10087]311
[10004]312  float matrix[4][4];
313  glTranslatef (this->getAbsCoor ().x, this->getAbsCoor ().y, this->getAbsCoor ().z);
[10087]314  Vector tmpRot = this->getAbsCoor().cross(tmpDir);
[10188]315  glRotatef (angleRad ( this->getAbsCoor(), tmpDir), tmpRot.x, tmpRot.y, tmpRot.z );
[10037]316  glRotatef(this->angle, 1.0f, 0.0f, 0.0f); //spinning missile
[10004]317  this->getAbsDir().matrix (matrix);
318  glMultMatrixf((float*)matrix);
[10037]319  //glScalef(2.0, 2.0, 2.0);  // no double rescale
[10004]320  this->getModel()->draw();
[10081]321  glTranslatef(-.9,0,0);
322  this->trail->draw();
[10004]323  glPopMatrix();
324}
Note: See TracBrowser for help on using the repository browser.