Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 10229 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
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004-2006 orx
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
12   main-programmer: Marc Schaerrer, Nicolas Schlumberger
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"
24#include "space_ships/space_ship.h"
25#include "effects/trail.h"
26
27#include "debug.h"
28
29#include "class_id_DEPRECATED.h"
30
31#include "math/vector.h"
32
33ObjectListDefinitionID(SwarmProjectile, CL_SWARM_PROJECTILE);
34CREATE_FAST_FACTORY_STATIC(SwarmProjectile);
35
36/**
37 *  standard constructor
38*/
39SwarmProjectile::SwarmProjectile () : Projectile()
40{
41
42/*  this->loadModel("models/projectiles/orx-rocket.obj", 0.5);*/
43  this->loadModel("models/projectiles/swarm_projectile.obj"); // no double rescale (see draw())
44  this->loadExplosionSound("sound/explosions/explosion_4.wav");
45
46
47  this->setMinEnergy(1);
48  this->setHealthMax(10);
49  this->lifeSpan = 4.0;
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);
55
56  this->turningSpeed = 10;
57
58  this->physDamage = 200;
59  this->elecDamage = 0;
60
61  this->trail = new Trail(2.5,4,.2, this);
62  //this->trail->setParent( this);
63  this->trail->setTexture( "maps/laser.png");
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  }
79  // delete this->emitter;
80  delete this->trail;
81}
82
83SpriteParticles* SwarmProjectile::explosionParticles = NULL;
84
85
86
87void SwarmProjectile::activate()
88{
89  this->toList(OM_ENVIRON);
90  if (unlikely(SwarmProjectile::explosionParticles == NULL))
91  {
92    SwarmProjectile::explosionParticles = new SpriteParticles(200);
93    SwarmProjectile::explosionParticles->setName("SwarmProjectileExplosionParticles");
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
105  this->emitter->setEmissionRate(50.0);
106  this->emitter->setEmissionVelocity(0.0);
107  this->emitter->setInheritSpeed(0);
108
109  this->setHealth(10.0* (float)rand()/(float)RAND_MAX);
110
111  this->maxVelocity = 300;
112
113  this->rotationSpeed = 360;
114  this->angle = 0;
115
116  this->curDir = this->lastDir = this->velocity;
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;
136  //dynamic_cast<SpaceShip*>(entity)->damage(this->getPhysDamage(),this->getElecDamage());
137  this->destroy(this);
138}
139
140
141void SwarmProjectile::setTarget(PNode* target)
142{
143    this->target = target;
144}
145
146
147
148/**
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{
157  if (unlikely(curDirection.len() == 0))
158    return curDirection;
159  //printf("recalculating direction\n");
160  float tmp = angleRad ( curDirection, estTargetDir);
161  if ( unlikely(tmp == 0) ) { return curDirection * maxVelocity / curDirection.len(); }
162//   printf("turning angle: %f\ntemp: %f\n", angle, tmp);
163
164  if( fabsf(angle) >  fabsf(tmp) ) 
165    angle = tmp;
166  else
167    angle *= tmp/fabsf(tmp);
168
169  Vector d = curDirection.cross(estTargetDir).cross(curDirection);
170  d.normalize();
171  if( unlikely( fabsf(angle) == 90)) { return d; } //avoid complication
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/**
183 *  signal tick, time dependent things will be handled here
184 * @param time since last tick
185*/
186void SwarmProjectile::tick (float time)
187{
188  if(unlikely(this->target == NULL)) /** Check whether the target still exists*/
189    this->deactivate();
190
191/*
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);
217  this->shiftCoor(v);*/
218
219
220/** old  guiding functuion*/
221
222  float projectileVelocity = this->getVelocity().len();
223  if (target != NULL){
224    Vector estTargetDir = (this->target->getAbsCoor() - this->getAbsCoor()).getNormalized();
225    this->velocity = this->newDirection(this->velocity, estTargetDir, this->turningSpeed * time );
226  }
227  else
228    if (likely(projectileVelocity != 0 || projectileVelocity != this->maxVelocity) )
229      this->velocity *= (this->maxVelocity / projectileVelocity); // set speed to max
230
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
234  this->shiftCoor(this->velocity * time);
235
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
266  if(this->tickLifeCycle(time))
267    this->deactivate();
268
269  this->trail->tick(time);
270
271  this->angle += this->rotationSpeed * time;
272  while (this->angle > 360)
273    this->angle -= 360;
274
275  this->lastDir = this->curDir;
276  this->curDir = this->velocity;
277  if( (this->getAbsCoor() - this->target->getAbsCoor()).len() < 3)   // FIXME  Temp fake workaround for collision :)
278  {
279    dynamic_cast<WorldEntity*>(target)->destroy( this);
280    this->destroy( this);
281  }
282}
283
284/**
285 *  the function gets called, when the projectile is destroyed
286 */
287void SwarmProjectile::destroy (WorldEntity* killer)
288{
289
290//   printf("THIS SHOULD WORK!\n");
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);
299  this->deactivate();
300
301}
302
303
304void SwarmProjectile::draw () const
305{
306  glMatrixMode(GL_MODELVIEW);
307  glPushMatrix();
308
309  Vector tmpDir = this->curDir; // *.7 + this->lastDir * .3;
310  tmpDir.slerpTo(this->lastDir, .4);
311
312  float matrix[4][4];
313  glTranslatef (this->getAbsCoor ().x, this->getAbsCoor ().y, this->getAbsCoor ().z);
314  Vector tmpRot = this->getAbsCoor().cross(tmpDir);
315  glRotatef (angleRad ( this->getAbsCoor(), tmpDir), tmpRot.x, tmpRot.y, tmpRot.z );
316  glRotatef(this->angle, 1.0f, 0.0f, 0.0f); //spinning missile
317  this->getAbsDir().matrix (matrix);
318  glMultMatrixf((float*)matrix);
319  //glScalef(2.0, 2.0, 2.0);  // no double rescale
320  this->getModel()->draw();
321  glTranslatef(-.9,0,0);
322  this->trail->draw();
323  glPopMatrix();
324}
Note: See TracBrowser for help on using the repository browser.