source: GTP/trunk/App/Games/Jungle_Rumble/src/Player.cpp @ 1407

Revision 1407, 33.8 KB checked in by giegl, 18 years ago (diff)

GTPD - Jungle Rumble - Player wins final :-)

Line 
1#include "dxstdafx.h"
2#include ".\player.h"
3#include "Terrain.h"
4#include "GameManager.h"
5#include "GameScene.h"
6#include "ParticleGroup.h"
7#include "ParticleEmitter.h"
8#include "SimpleBullet.h"
9#include "Sprite.h"
10#include <exception>
11
12#define FL 0
13#define FR 1
14#define RL 2
15#define RR 3
16
17#define M_PI 3.1415
18
19//static NxDistanceJoint* distanceJoint = NULL;
20
21Player::Player(void) : Node() {
22
23        counter= 0;
24        this->activeWeapon = NULL;
25        this->playerPlayerCol = false;
26        this->gotHit = false;
27        this->health = 100;
28        this->iHealth = this->health;
29        this->pe=NULL;
30        for(int i=0;i<10;i++) {
31                this->weaponList[i] = NULL;
32                this->munition[i] = 0;
33        }
34        this->springCounter = 0;
35        this->upperSpringActor = NULL;
36        this->upperJoint = NULL;
37        this->rauchEmitter = NULL;
38        this->team = 0;
39        this->setAvatareFileName("./media/models/wurm.x");
40        this->fireHitCount = 0;
41        this->sleepCounter = 0;
42}
43
44Player::~Player(void)
45{
46}
47
48void Player::initPlayer(float _x, float _y, float _z) {
49        //Setup Engine
50        this->sleepCounter = 0;
51        this->engineForce = 0;
52        this->maxEngineForce = 6000;
53        this->deltaEngineForce = 4000;
54        this->Cdrag = 0.1257f*15.0f;
55        this->Crr = 0.0001f*20.0f;
56        this->Cdaempfung = 0.0012f;
57        this->Croll     = 0.2f;
58        this->Clateral = 0.6f;
59        this->Cschale = 10;
60        this->Crotschale = 5;
61        this->CimpactRot = 0.00003f;
62        this->CrotBeschleunigung = 0.001f;
63        this->vMax = 300;
64        this->desiredFlyingDownForce = 350;
65        this->fireHitCount = 0;
66        this->iceHitCount = 0;
67
68        this->currentRotSchale = 0;
69
70        maxBreakForce = 5000;
71        breakForce = 0;
72        deltaBreakForce = 2000;
73
74        //Steering setup
75        this->maxSteering = 20*D3DX_PI/180;
76        this->steering = 0;
77        this->steeringFactor = 10;
78
79        this->vHeading = 0;
80
81        //Physik
82        this->vLength = 0;
83        heading.x = 0; heading.y = 0; heading.z = 1;
84        direction.x = 0; direction.y = 0; direction.z = 1;
85        cFront  = 1.2f;
86        cRear   = 1.2f;
87        cSide   = 1.2f;
88        cHeight = 0.6f;
89        rfDistance = cFront+cRear;
90        this->cR_D = this->cRear/this->rfDistance;
91        this->cF_D = this->cFront/this->rfDistance;
92        this->cH_D = this->cHeight/this->rfDistance;
93
94        vehicleMass = 10;
95        tMoment = vehicleMass;
96        wheelMass = 5;
97        wheelRadius = 0.5;
98        springL = 1.0f;
99        springK = 1000;
100
101        //Ageia Physic
102        this->s.x = _x; this->s.y = _y; this->s.z = _z;
103    this->setPosition(s.x, s.y, s.z);
104        NxSphereShapeDesc sphereDesc;
105        sphereDesc.localPose.t = NxVec3(0, 1, 0);
106        sphereDesc.radius = 2;
107       
108        this->pActorDesc.density = 0;
109        this->pBodyDesc.mass = this->vehicleMass;
110        this->pActorDesc.shapes.pushBack(&sphereDesc);
111
112        this->triggerSphereDesc.radius = 2.1f;
113        this->triggerSphereDesc.shapeFlags = NX_TRIGGER_ON_ENTER | NX_TRIGGER_ON_LEAVE | NX_SF_DISABLE_RAYCASTING;
114        this->pActorDesc.shapes.pushBack(&this->triggerSphereDesc);
115
116        this->setBehaveAs(Node::RIGIDBODY);
117        this->setColDetGroup(UserContactReport::COLGROUP_PLAYER);
118        this->pActor->setAngularDamping(1);
119
120        NxShape* const* shapes = this->pActor->getShapes();
121        int nbShapes = this->pActor->getNbShapes();
122
123        for(int i=0;i<nbShapes;i++) {
124                if(shapes[i]->isSphere() && ((NxSphereShape*)shapes[i])->getRadius()==1) {
125                        this->sphere = (NxSphereShape*)shapes[i];
126                }
127        }
128
129        //Physic spring
130        this->springDistance = 20;
131        this->upperDelta = 0;
132        this->springBias = 1.2f;
133        this->upperSpringActor = this->createDistanceJoint(Vector(_x, _y+this->springDistance-this->upperDelta, _z), false);
134       
135        //Setup Geometry
136        this->schale = (Object3d *) this->myScene->createNode(this->myScene->NODE_OBJECT3D, *this, true);
137        this->schale->loadMeshFromFile("./media/models/nussschale.x");
138
139        this->wurm = (Object3d *) this->myScene->createNode(this->myScene->NODE_OBJECT3D, *this->schale, true);
140        this->wurm->loadMeshFromFile(this->avatar);
141               
142        for(int i=0;i<4;i++) {
143                this->wheel[i] = (Object3d *) this->myScene->createNode(this->myScene->NODE_OBJECT3D, true);
144                this->wheel[i]->loadMeshFromFile("./media/models/wheel15.x");
145        }
146        this->wheel[FL]->setPosition(cSide+_x, 0+_y, cFront+_z);
147        this->wheel[FR]->setPosition(-cSide+_x, 0+_y, cFront+_z);
148
149        this->wheel[RL]->setPosition(cSide+_x, 0+_y, -cRear+_z);
150        this->wheel[RR]->setPosition(-cSide+_x, 0+_y, -cRear+_z);
151
152        this->schale->setPosition(0, springL, 0);
153        schaleAlpha = 0;
154        schaleHoehe = 0;
155               
156        this->wheelAngle = 0;
157        this->w.setXYZ(0, 0, 0);
158        this->p = 0;
159       
160        ixSchale = 0;
161        iySchale = 0;
162        izSchale = 0;
163        iaSchale = 0;
164        ibSchale = 0;
165        igSchale = 0;
166        daSchale = 0;
167        dbSchale = 0;
168        dgSchale = 0;
169        this->resetValues();
170
171        //Create motor sound
172        this->motor = (SoundNode *) this->myScene->createNode(this->myScene->NODE_SOUND, *this->schale, false);
173        if(!this->motor->loadFile("./media/sound/fan_blade_idle_loop1.wav", true)) {
174                this->myScene->manager->printToConsole("Loading motor sound failed!");
175        } else {
176                this->motor->play();
177                this->motor->setVolume(0);
178        }
179
180        //Create nooooo Sounds
181        hitSounds[0] = "./media/sound/screams/no1.mp3";
182        hitSounds[1] = "./media/sound/screams/no2.mp3";
183        hitSounds[2] = "./media/sound/screams/no3.mp3";
184        for(int i=0;i<3;i++) {
185                this->noSounds[i] = (SoundNode *) this->myScene->createNode(this->myScene->NODE_SOUND, *this->schale, false);
186                if(!this->noSounds[i]->loadFile(this->hitSounds[i], false)) {
187                        this->myScene->manager->printToConsole("Loading scream sound failed!");
188                } else {
189                        //this->noSounds[i]->play();
190                        this->noSounds[i]->setKillSoundNodeAfterPlayed(false);
191                        this->noSounds[i]->setVolume(255);
192                }
193        }
194        srand((UINT)time(NULL));
195
196
197        this->gotHit = false;
198
199        ParticleGroup* pg = (ParticleGroup*) this->myScene->createNode(Scene::NODE_PARTICLEGROUP, false);
200        this->rauchEmitter = (ParticleEmitter*) this->myScene->createNode(Scene::NODE_PARTICLEEMITTER, *this->schale);
201        pg->addParticleEmitter(this->myScene->getSmartPointer(this->rauchEmitter));
202        pg->useGravity(false);
203        this->rauchEmitter->setDimensions(1,1,1);
204        this->rauchEmitter->setEMBirthRate(20);
205        this->rauchEmitter->setEMEmissionDuration(2);
206        this->rauchEmitter->setEMParticleLifeTime(2);
207        this->rauchEmitter->setEMParticleVelocity(0);
208        this->rauchEmitter->setPosition(0, 0, 0);
209        this->rauchEmitter->setRotation(-D3DX_PI/2, 0, 0);
210        this->rauchEmitter->setDeleteMeAfterEmission(false);
211        this->rauchEmitter->setColDetGroup(UserContactReport::COLGROUP_NOCOL);
212        this->rauchEmitter->setStandBy(true);
213       
214        Sprite *rauch;
215        rauch = (Sprite*) this->myScene->createNode(Scene::NODE_SPRITE);
216        rauch->setDimension(3, 3);
217        rauch->setTexture("./media/textures/explosion.png");
218        rauch->setFPS(64);
219        rauch->setTimeToLive(1);
220        rauch->setRowColumnCount(8, 8);
221        rauch->setFrameCount(64);
222        rauch->setLoopAnimation(true);
223        rauch->setLookAtCamera(true);
224        rauch->setAlpha(0.5f);
225        rauch->setPosition(this->getAbsolutePosition());
226        rauch->generatePhysicMesh();
227        rauch->setBehaveAs(Node::RIGIDBODY);
228        rauch->setColDetGroup(UserContactReport::COLGROUP_NOCOL);
229        this->rauchEmitter->addRefNode(*rauch);
230
231        ParticleGroup* winPg = (ParticleGroup*) this->myScene->createNode(Scene::NODE_PARTICLEGROUP, false);
232        this->winPe = (ParticleEmitter*) this->myScene->createNode(Scene::NODE_PARTICLEEMITTER, *this->schale);
233        winPg->addParticleEmitter(this->myScene->getSmartPointer(this->winPe));
234        winPg->useGravity(true);
235        this->winPe->setDimensions(1,1,1);
236        this->winPe->setEMBirthRate(10);
237        //this->winPe->setEMEmissionDuration(5);
238        this->winPe->setEMEmissionDuration(10); // MG
239        this->winPe->setEMParticleLifeTime(5);
240        this->winPe->setEMParticleVelocity(15);
241        this->winPe->setPosition(0, 10, 0);
242        this->winPe->setRotation(D3DX_PI/2, 0, 0);
243        this->winPe->setEMRotationalDegree(500, 500, 500);
244        this->winPe->setEMHorizontalDegree(1.5f);
245        this->winPe->setEMVerticalDegree(1.5f);
246        this->winPe->setDeleteMeAfterEmission(false);
247        this->winPe->setColDetGroup(UserContactReport::COLGROUP_OTHER);
248        this->winPe->setStandBy(true);
249       
250        Object3d *cube;
251        cube = (Object3d*) this->myScene->createNode(Scene::NODE_OBJECT3D);
252        cube->loadMeshFromFile("./media/models/gtpcube.x");
253        cube->generatePhysicMesh(Object3d::COL_CONVEX);
254        cube->setBehaveAs(Node::RIGIDBODY);
255        cube->setColDetGroup(UserContactReport::COLGROUP_OBSTACLE);
256        cube->setSoftKill(true, 1);
257
258        this->winPe->addRefNode(*cube);
259
260        /*Sprite *rauch;
261        rauch = (Sprite*) this->myScene->createNode(Scene::NODE_SPRITE);
262        rauch->setDimension(3, 3);
263        rauch->setTexture("./media/textures/explosion.png");
264        rauch->setFPS(64);
265        rauch->setTimeToLive(1);
266        rauch->setRowColumnCount(8, 8);
267        rauch->setFrameCount(64);
268        rauch->setLoopAnimation(true);
269        rauch->setLookAtCamera(true);
270        rauch->setAlpha(0.5f);
271        rauch->setPosition(this->getAbsolutePosition());
272        rauch->generatePhysicMesh();
273        rauch->setBehaveAs(Node::RIGIDBODY);
274        rauch->setColDetGroup(UserContactReport::COLGROUP_NOCOL);
275        this->rauchEmitter->addRefNode(*rauch);*/
276}
277
278void Player::setPlayerHit(Vector position, Bullet &bullet) {
279        //Joints deaktivieren
280        if(this->upperJoint) {
281                this->myScene->pScene->releaseJoint(*this->upperJoint);
282                this->upperJoint = NULL;
283        }
284
285        //ZufallsSound abspielen
286        int sndId = (int)((((float) rand()/RAND_MAX)+0.5)*5);
287        if(sndId<3) {
288                this->noSounds[sndId]->play();
289        }
290
291        //TraceRays auf best. länge reduzieren
292        //Impuls an player anlegen
293        this->gotHit = true;
294        this->engineForce*=0.5;
295        Vector forceDir;
296        forceDir = bullet.getDirection();
297        forceDir.y = 1;
298        forceDir.normalize();
299        forceDir = forceDir*bullet.getImpactForce()*120;
300        this->pActor->setAngularDamping(0);
301        this->pActor->addForceAtPos(forceDir.getNxVector(), bullet.getAbsolutePosition().getNxVector(), NX_IMPULSE);
302        this->lastYPos = -10000;
303        this->realFlyingDownForce = 0;
304
305        //Emit some Stones...
306        ParticleGroup* stoneGroup = (ParticleGroup*) this->myScene->createNode(Scene::NODE_PARTICLEGROUP, false);
307        ParticleEmitter* stoneEmitter = (ParticleEmitter*) this->myScene->createNode(Scene::NODE_PARTICLEEMITTER);
308        stoneGroup->addParticleEmitter(this->myScene->getSmartPointer(stoneEmitter));
309        stoneEmitter->setEMParticleVelocity(20);
310        stoneEmitter->setDimensions(1, 1, 1);
311        stoneEmitter->setPosition(this->getAbsolutePosition()-Vector(0, 2, 0));
312        stoneEmitter->setEMEmissionDuration(0.3f);
313        stoneEmitter->setEMHorizontalDegree(1);
314        stoneEmitter->setEMVerticalDegree(1);
315        stoneEmitter->setEMRotationalDegree(8, 8, 8);
316        stoneEmitter->setEMBirthRate(10);
317        stoneEmitter->setEMParticleLifeTime(5.0f);
318        stoneEmitter->setRotation(-D3DX_PI/2, 0, 0);
319        stoneEmitter->setDeleteMeAfterEmission(true);
320        stoneEmitter->setColDetGroup(UserContactReport::COLGROUP_OTHER);
321
322        Object3d* stone = (Object3d*) this->myScene->createNode(Scene::NODE_OBJECT3D);
323        stone->loadMeshFromFile("./media/models/Stein_3.x");
324        stone->generatePhysicMesh(Object3d::COL_CONVEX);
325        stone->setColDetGroup(UserContactReport::COLGROUP_OTHER);
326        stone->setSoftKill(true, 2);
327        stoneEmitter->addRefNode(*stone);
328        stoneEmitter->addRefNode(*stone);
329        stoneEmitter->addRefNode(*stone);
330
331        //Attach Sprites to Emitter
332        ParticleGroup* spriteGroup = (ParticleGroup*) this->myScene->createNode(Scene::NODE_PARTICLEGROUP, true);
333        ParticleEmitter* spriteEmitter = (ParticleEmitter*) this->myScene->createNode(Scene::NODE_PARTICLEEMITTER);
334        spriteGroup->addParticleEmitter(this->myScene->getSmartPointer(spriteEmitter));
335        spriteEmitter->setEMParticleVelocity(0);
336        spriteEmitter->setDimensions(1, 1, 1);
337        spriteEmitter->setPosition(this->getAbsolutePosition());
338        spriteEmitter->setEMEmissionDuration(3);
339        spriteEmitter->setEMHorizontalDegree(0.1f);
340        spriteEmitter->setEMVerticalDegree(0.1f);
341        spriteEmitter->setEMRotationalDegree(8, 8, 8);
342        spriteEmitter->setEMBirthRate(10);
343        spriteEmitter->setEMParticleLifeTime(5.0f);
344        spriteEmitter->setRotation(-D3DX_PI/2, 0, 0);
345        spriteEmitter->setDeleteMeAfterEmission(true);
346        spriteEmitter->setColDetGroup(UserContactReport::COLGROUP_NOCOL);
347        spriteEmitter->setStandBy(false);
348
349        Sprite *rauch;
350        rauch = (Sprite*) this->myScene->createNode(Scene::NODE_SPRITE, false);
351        rauch->setDimension(3, 3);
352        rauch->setTexture("./media/textures/explosion.png");
353        rauch->setFPS(64);
354        rauch->setTimeToLive(2);
355        rauch->setRowColumnCount(8, 8);
356        rauch->setFrameCount(64);
357        rauch->setLoopAnimation(true);
358        rauch->setLookAtCamera(true);
359        rauch->setAlpha(0.5f);
360        rauch->setPosition(this->getAbsolutePosition());
361        rauch->generatePhysicMesh();
362        rauch->setBehaveAs(Node::RIGIDBODY);
363        rauch->setColDetGroup(UserContactReport::COLGROUP_NOCOL);
364        spriteEmitter->addRefNode(*rauch);
365        spriteEmitter->addRefNode(*rauch);
366
367        stone->addChild(this->myScene->getSmartPointer(spriteEmitter));
368}
369
370void Player::setPlayerOnGround()
371{
372        Vector L[4];
373        L[FL].x = cSide; L[FL].y = -this->springL; L[FL].z = cFront;
374        L[FR].x = -cSide; L[FR].y = -this->springL; L[FR].z = cFront;
375        L[RL].x = cSide; L[RL].y = -this->springL; L[RL].z = -cRear;
376        L[RR].x = -cSide; L[RR].y = -this->springL; L[RR].z = -cRear;
377
378        Vector playerPos = this->getAbsolutePosition();
379        for(int i=0;i<4;i++) {
380                this->wheel[i]->setPosition(playerPos+L[i]);
381        }
382        this->lastYPos = -10000;
383        playerPos = this->getTerrainHeight(playerPos);
384        this->upperSpringActor = this->createDistanceJoint(Vector(playerPos.x, playerPos.y+this->springDistance-this->upperDelta, playerPos.z), false);
385        this->gotHit = false;
386        this->realFlyingDownForce = 0;
387        this->pActor->setLinearMomentum(NxVec3(0, 0, 0));
388        this->pActor->setLinearVelocity(NxVec3(0, 0, 0));
389        this->pActor->setAngularMomentum(NxVec3(0, 0, 0));
390        this->pActor->setAngularVelocity(NxVec3(0, 0, 0));
391}
392
393
394void Player::update(float dt) {
395
396        if(this->sleepCounter++<10) {
397                if(this->sleepCounter==2) {
398                        this->motor->setVolume(1);
399                }
400                return;
401        }
402        exception e;
403        try {
404                this->iHealth+= (this->health-this->iHealth)*dt;
405                if(dt==0) {
406                        this->setBehaveAs(Node::KINEMATIC);
407                        return;
408                } else {
409                        this->setBehaveAs(Node::RIGIDBODY);
410                }
411
412                dt = min(dt, 0.04f);
413                if(this->gotHit) {
414                        this->updateFlyingPlayer(dt);
415                } else {
416                        this->updateDrivingPlayer(dt);
417                }
418
419                this->activeWeapon->setPosition(Vector(this->pActor->getGlobalPosition()));
420
421                //Calculate Frequency
422                float frequency = this->vLength/60*90000 + 10000;
423                FSOUND_SetFrequency(this->motor->getChannel(), (int)frequency);
424
425                //Hack to get objects moving
426                this->resetValues();
427
428                Node::update(dt);
429
430                this->checkPosition();
431
432                if(this->fireHitCount>0) {
433                        this->fireHitCount-=dt;
434                }
435        } catch(exception e) {
436                this->myScene->manager->printToConsole("Exception in player occured!");
437        }
438}
439
440void Player::updateFlyingPlayer(float dt)
441{
442        Vector L[4];
443        L[FL].x = cSide; L[FL].y = -this->springL; L[FL].z = cFront;
444        L[FR].x = -cSide; L[FR].y = -this->springL; L[FR].z = cFront;
445        L[RL].x = cSide; L[RL].y = -this->springL; L[RL].z = -cRear;
446        L[RR].x = -cSide; L[RR].y = -this->springL; L[RR].z = -cRear;
447
448        D3DXMATRIXA16 wheelMat;
449        D3DXMATRIXA16 currentWorldMat;
450        Vector wheelPos;
451        Vector playerPos = this->getAbsolutePosition();
452        bool fallingDown = false;
453        if(playerPos.y < this->lastYPos-1) {
454                fallingDown = true;
455        } else {
456                this->lastYPos = playerPos.y;
457        }
458
459        bool onGround = false;
460        for(int i=0;i<4;i++) {
461                D3DXMatrixTranslation(&wheelMat, L[i].x, L[i].y, L[i].z);
462                D3DXMatrixMultiply(&wheelMat, &wheelMat, &this->myWorldMatrix);
463                this->wheel[i]->setWorldMatrix(wheelMat);
464                if(fallingDown) {
465                        wheelPos = this->wheel[i]->getAbsolutePosition();
466                        wheelPos = this->getTerrainHeight(wheelPos, true);
467                        if(wheelPos.y!=-10000) {
468                                onGround = true;
469                        }
470                }
471        }
472        wheelPos = this->getTerrainHeight(playerPos);
473        if(playerPos.y-1.5<wheelPos.y) {
474                onGround = true;
475        }
476        if(onGround) {
477                this->setPlayerOnGround();
478        } else {
479                this->realFlyingDownForce += (this->desiredFlyingDownForce - this->realFlyingDownForce)*min(1.0f, 12*dt);
480                this->pActor->addForce(NxVec3(0, -this->realFlyingDownForce, 0));
481        }
482}
483
484
485void Player::updateDrivingPlayer(float dt) {
486        //Calculate Heading
487        heading.x = 0; heading.y = 0; heading.z=1;
488        this->getAbsoluteDirectionVector(this->heading, this->heading);
489        this->heading.y = 0;
490        this->heading.normalize();
491
492        //Wichtige Daten aus dem PhysicActor auslesen   
493        this->myPosition = Vector(this->pActor->getGlobalPosition());
494
495        this->w = Vector(this->pActor->getAngularVelocity());
496       
497        Vector vlinear = Vector(this->pActor->getLinearVelocity());
498        //char temp[100];
499        float vl;
500        vl = vlinear.length();
501        if(abs(vl)>100) {
502                //this->myScene->manager->printToConsole("vl >100!!!!!!!!");
503                vlinear.normalize();
504                vlinear = vlinear*100;
505                this->pActor->setLinearVelocity(vlinear.getNxVector());
506                //this->w.normalize();
507                //this->w = this->w*5;
508               
509        }
510        //sprintf(temp, "v length = %f",vl);
511        //this->myScene->manager->printToConsole(temp);
512
513        //Durchschnittshöhe berechnen
514        avgy=0;
515        for(int i=0;i<4;i++) {
516                avgy += wheel[i]->myPosition.y;
517        }
518        avgy/=4;
519
520        //SpringActor in position bringen
521        float tempBias = 0.2f*sin(10*this->springCounter);
522        Vector saPos = this->getAbsolutePosition();
523        saPos.y = avgy+this->springDistance+this->springBias+tempBias;
524        this->upperSpringActor->moveGlobalPosition(saPos.getNxVector());
525        Vector mp = this->getAbsolutePosition();
526        if(saPos.y<mp.y) {
527                this->pActor->setGlobalPosition(NxVec3(mp.x, 2*saPos.y - mp.y, mp.z));
528                this->pActor->setLinearVelocity(NxVec3(0, 0, 0));
529        }
530        this->springCounter+=dt;
531
532        //"schräglage" des Terrains berrechnen
533        yf = (wheel[FL]->myPosition.y+wheel[FR]->myPosition.y)/2;
534        yr = (wheel[RL]->myPosition.y+wheel[RR]->myPosition.y)/2;
535        yleft = (wheel[FL]->myPosition.y+wheel[RL]->myPosition.y)/2;
536        yright = (wheel[FR]->myPosition.y+wheel[RR]->myPosition.y)/2;   
537       
538        dyFrontRear = yf - yr;
539        dyLeftRight = yleft - yright;
540        terrainAngle.x = (float) -atan2(dyFrontRear, cRear+cFront);
541        terrainAngle.z = (float) atan2(dyLeftRight, 2*cSide);
542
543        //Alpha & Gamma Rotationsmatrizen berechnen
544        D3DXMATRIX mAlpha; D3DXMatrixRotationX(&mAlpha, (FLOAT)(daSchale*M_PI/180));
545        D3DXMATRIX mGamma; D3DXMatrixRotationZ(&mGamma, (FLOAT)(dgSchale*M_PI/180));
546
547
548        //Graffel mit Beta Rotation
549        D3DXMATRIX mGYaw;
550        D3DXMATRIX mYaw;
551        D3DXMatrixIdentity(&mYaw);
552        this->pActor->getGlobalOrientation().getColumnMajorStride4(((NxF32 *) &mYaw.m[0][0]));
553        mGYaw = mYaw;
554
555        D3DXMATRIX nmAlpha; D3DXMatrixRotationX(&nmAlpha, -daSchale);
556        D3DXMATRIX nmGamma; D3DXMatrixRotationZ(&nmGamma, -dgSchale);
557
558        //Calculate engineForce
559        if(baccelerate) {
560                this->engineForce += dt*this->deltaEngineForce;
561                if(this->engineForce > this->maxEngineForce) this->engineForce = this->maxEngineForce;         
562        } else {
563                if(this->engineForce>0) {
564                        this->engineForce -= dt*this->deltaEngineForce;
565                } else {
566                        this->engineForce = 0;
567                }
568        }
569       
570        //Break force
571        if(bstop) {
572                this->breakForce += dt*this->deltaBreakForce;
573                if(this->breakForce > this->maxBreakForce) this->breakForce = this->maxBreakForce;
574        } else {
575                if(this->breakForce>0) {
576                        this->breakForce -= dt*this->deltaBreakForce;
577                        this->engineForce = min(this->breakForce, this->engineForce);
578                } else {
579                        this->breakForce = 0;
580                }
581        }
582
583        //Calculate Steering Angle
584        float desiredSteering = 0;
585        float vsize = this->vLength;
586        if(btoLeft) {
587                desiredSteering = -this->maxSteering;
588        } else if(btoRight) {
589                desiredSteering = this->maxSteering;
590        }
591
592        this->steering += dt*(desiredSteering - this->steering)*this->steeringFactor;
593        if(desiredSteering==0) {
594                this->steering += dt*(desiredSteering - this->steering)*this->steeringFactor;
595        }
596
597        //berechne gravitationsvektor
598        this->gravity.setNxVector(this->myScene->pDefaultGravity);
599
600        float tempAngle;
601        direction = this->v;
602        direction.normalize();
603        heading.normalize();
604        float cosBeta;
605        cosBeta = direction.dotProd(heading);
606
607        if(this->vLength>=0.8f) {
608                alphaFront = (float) (atan2((v.x+w.y*cFront),this->vLength) - steering*((cosBeta>0) ? 1 : -1));
609                alphaRear = (float) (atan2((v.x-w.y*cRear),this->vLength));
610        } else {
611                alphaFront = 0;
612                alphaRear = 0;
613                w.setXYZ(0, 0, 0);
614        }
615        alphaFront*=180/D3DX_PI;
616        alphaRear*=180/D3DX_PI;
617       
618        Vector fa[4]; //Feder Halterungspunkt am Reifen
619        Vector L[4];  //Temporärer Speicher für Haltepunkt
620        fa[FL].x = cSide; fa[FL].y = 0; fa[FL].z = cFront;
621        fa[FR].x = -cSide; fa[FR].y = 0; fa[FR].z = cFront;
622        fa[RL].x = cSide; fa[RL].y = 0; fa[RL].z = -cRear;
623        fa[RR].x = -cSide; fa[RR].y = 0; fa[RR].z = -cRear;
624        L[FL].x = cSide; L[FL].y = 0; L[FL].z = cFront;
625        L[FR].x = -cSide; L[FR].y = 0; L[FR].z = cFront;
626        L[RL].x = cSide; L[RL].y = 0; L[RL].z = -cRear;
627        L[RR].x = -cSide; L[RR].y = 0; L[RR].z = -cRear;
628       
629
630        int mult1=1;
631        int mult2=1;
632        float mult3 = 1;
633
634       
635        Vector vVectorForce[4];
636        Vector eDreh[4];
637   
638        Vector gravMass = gravity*vehicleMass/4;
639        Vector gravAcc = eAcc*this->cH_D*this->vehicleMass;
640
641        Vector normGravity;
642        normGravity = gravity;
643        normGravity.normalize();
644
645        this->schale->setPosition(0,0,0);
646        float downForceSum =0;
647        for(int i=0;i<4;i++) {  //Rotiere Vectoren um absolute Position der FederAngel zu berechnen
648                this->getAbsoluteVector(fa[i], fa[i]);
649                terrainHeight[i] = this->getTerrainHeight(fa[i]);
650                terrainHeight[i].y+=this->wheelRadius;
651                wheel[i]->setPosition(terrainHeight[i]);
652
653                //HALBE Kraft die auf die Feder ausgeübt wird.
654                vDownForce[i] = 0.5f*springK*(springL-(this->myPosition.y - wheel[i]->myPosition.y));
655                vDownForce[i]-=vDownForce[i]*Cdaempfung*40;
656
657                //Wheel DownForce to ground
658        wDownForce[i] +=vDownForce[i];
659                wDownForce[i] +=gravity.y*wheelMass;
660
661                mult1 = (i<2) ? 1 : -1;                                         //Front Rear
662                mult2 = (i==0 || i==2) ? -1 : 1;                        //Left Right
663                mult3 = (i<2) ? this->cR_D : this->cF_D;        //Factors for front rear
664
665                //Kraftvectoren erzeugen wegen dem drehmoment
666                vVectorForce[i] = normGravity*vDownForce[i];
667
668                //Drehmoment berechen
669                eDreh[i] = (vVectorForce[i]/tMoment).crossProd(L[i]);
670
671                //downForceSum += wDownForce[i];
672                tempAngle = (i<2) ? alphaFront : alphaRear;
673                Flateral[i] = this->calcLateralForce(tempAngle)*1000;
674        }
675
676        //Radius berechnen
677        float drehM=0;
678        Vector vYaw;
679        Vector latForce;
680
681        int multRollForward = (cosBeta>0) ? 1 : -1;
682        Fcornering = vHeading*steering*1.2f;
683
684        if(abs(this->vHeading)>=1) {
685                p = p + (0.12f*(70-min(abs(this->vHeading), 30.0f))*dt)*steering;
686        }
687        this->setRotation(0, p, 0);
688        vYaw.x = 0; vYaw.y = 1; vYaw.z = 0;
689        latForce = heading.crossProd(vYaw);
690        latForce.normalize();
691        latForce = latForce*Fcornering;
692       
693        int mult = (cosBeta>=0) ? 1: -1;
694        heading.normalize();
695        Vector vecDown(0, -1, 0);
696        this->schale->getAbsoluteDirectionVector(vecDown, vecDown);
697        float rollFactor = 0;
698        if(vecDown.x!=0 || vecDown.z!=0) {
699                vecDown.y = 0;
700                vecDown.normalize();
701                rollFactor = heading.dotProd(vecDown);
702        }
703        longForce = (heading*(this->engineForce -rollFactor*this->vehicleMass*Croll*50)) - v*v.length()*Cdrag - v*Crr - (heading*this->breakForce);
704        eAcc = longForce/this->vehicleMass;
705
706        //Beschleunigungen ausrechnen
707        Vector f;
708        //Longitudinal force
709        f = f+longForce;
710        //Lateral force
711        f = f-latForce;
712       
713        if(this->iceHitCount>0) {
714                f = f - f*(this->iceHitCount/100.0f);
715                this->iceHitCount-=10*dt;
716                this->pActor->setLinearDamping(max(0.0f,10*this->iceHitCount/100.0f));
717        } else {
718                this->iceHitCount = 0;
719                this->pActor->setLinearDamping(0);
720        }
721        NxVec3 tempF = f.getNxVector();
722        this->pActor->addForce(tempF);
723        this->s = this->myPosition;
724        this->v = Vector(this->pActor->getLinearVelocity());
725        this->vLength = this->v.length();
726        Vector tempV = this->v;
727        if(this->vLength>1) {
728                tempV.normalize();
729                this->vHeading = this->vLength*(this->heading.dotProd(tempV));
730        } else {
731                this->vHeading = 0;
732        }
733        tempV = v; tempV.y = 0;
734       
735        this->wheelAngle+=((tempV.length()*dt)/(this->wheelRadius))*multRollForward;
736       
737        //Winkelzeugs ausrechnen
738        Vector wDreh;
739        Vector wPos;
740        Vector wOther;
741        for(unsigned int i=0;i<this->torqueVector.size();i++) {
742                wOther = wOther + this->torqueVector.at(i);
743        }
744        e = (eDreh[FL] + eDreh[FR] + eDreh[RL] + eDreh[RR] + wDreh + wOther)*dt/tMoment;
745
746        //Neigung der Schale für Beschleunigung usw berechen
747        Vector a = f;
748        float aLength = a.length();
749        aLength/=10;
750        float aHeadingFactor=0;
751        a.normalize();
752        if(aLength!=0) {
753                aHeadingFactor = heading.dotProd(a);
754        }
755        this->currentRotSchale += (aHeadingFactor*aLength*this->CrotBeschleunigung*10-this->currentRotSchale)*min(1.0f,dt*2);
756        daSchale = terrainAngle.x - aHeadingFactor*aLength*this->CrotBeschleunigung*10 +e.x + this->currentRotSchale;
757        dbSchale = -e.y;
758        dgSchale = terrainAngle.z;
759
760        iaSchale+= (daSchale - iaSchale)*dt*Crotschale;
761        ibSchale+= (dbSchale - ibSchale)*dt*Crotschale;
762        igSchale+= (dgSchale - igSchale)*dt*Crotschale;
763
764        this->schale->setRotation((iaSchale+schaleAlpha), ibSchale, igSchale);
765        Vector quatVec(0, this->myRotation.y, 0);
766        this->pActor->setGlobalOrientationQuat(NxQuat(quatVec.getNxQuatRotation()));
767        //Angulare Dämpfung
768        NxVec3 pActorVel = this->pActor->getAngularVelocity();
769        float aVelFactor = 10;
770        pActorVel.x-=dt*aVelFactor*pActorVel.x;
771        pActorVel.y-=dt*aVelFactor*pActorVel.y;
772        pActorVel.z-=dt*aVelFactor*pActorVel.z;
773        this->pActor->setAngularVelocity(pActorVel);
774
775        float wa;
776        wa = (float)(-this->wheelAngle*180/M_PI);
777
778        //Schräglage berechnen
779        float wg = ((this->wheel[FL]->myPosition.y+this->wheel[RL]->myPosition.y)/2-
780                                (this->wheel[FR]->myPosition.y+this->wheel[RR]->myPosition.y)/2)/2;
781        wg = (float)(atan2(wg, 2*this->cSide)*180/M_PI);
782        wa*=(float)(-M_PI/180);
783        wg = wg*cos(wa);
784        this->wheel[FL]->setRotation(wa, this->myRotation.y+this->steering, (float)(wg*M_PI/180));
785        this->wheel[FR]->setRotation(wa, this->myRotation.y+this->steering, (float)(wg*M_PI/180));
786        this->wheel[RL]->setRotation(wa, this->myRotation.y+0, (float)(wg*M_PI/180));
787        this->wheel[RR]->setRotation(wa, this->myRotation.y+0, (float)(wg*M_PI/180));
788
789
790        Vector schalePos;
791        schalePos = schale->myPosition;
792        schalePos.y-=avgy;
793        schalePos.y/=2;
794        Vector tempVec;
795        schalePos.applyD3DXVector(D3DXVec4Transform(&tempVec, &schalePos, &mAlpha));
796        schalePos.applyD3DXVector(D3DXVec4Transform(&tempVec, &schalePos, &mGamma));
797        schalePos.y+=avgy;
798
799        ixSchale+= (schalePos.x - ixSchale)*dt*Cschale;
800        iySchale+= (schalePos.y+schaleHoehe - iySchale)*dt*Cschale;
801        izSchale+= (schalePos.z - izSchale)*dt*Cschale;
802
803        avgy=0;
804        for(int i=0;i<4;i++) {
805                avgy += wheel[i]->myPosition.y;
806        }
807        avgy/=4;
808        iySchale = max(iySchale, avgy+0.4f);
809
810        NxVec3 tempPos = this->pActor->getGlobalPosition();
811        tempPos.y = max(tempPos.y, avgy+0.4f);
812        this->pActor->setGlobalPosition(tempPos);
813}
814
815float Player::calcLateralForce(float _angle) {
816        float f=0;
817        float k=0.02f;
818        if(abs(_angle)<3) {
819                f = 1.2f/3*_angle;
820        } else if(_angle>=3) {
821                f = -k*_angle + 1.2f + k*3;
822        } else {
823                f = -k*_angle - 1.2f - k*3;
824        }
825       
826        return f;
827}
828
829void Player::resetValues() {
830        baccelerate = false;
831        bstop = false;
832        btoLeft = false;
833        btoRight = false;
834        bfire = false;
835
836        for(int i=0;i<4;i++) {
837                wDownForce[i] = 0;
838                vDownForce[i] = 0;
839        }
840        this->torqueVector.clear();
841        this->fOther.x = 0; this->fOther.y = 0; this->fOther.z = 0;
842}
843
844void Player::accelerate() {baccelerate = true;}
845void Player::stop() {bstop = true;}
846void Player::toLeft() {btoLeft = true; btoRight = false;}
847void Player::toRight() {btoRight = true; btoLeft = false;}
848void Player::setMouse(int x, int y) { mouseX = x; mouseY = y;}
849
850void Player::addWeapon(Weapon &weapon) {
851        weapon.setPlayer(*this);
852        weapon.setVisible(false);
853        weapon.setStandBy(true);
854        int wtype = weapon.getWeaponType();
855        if(this->weaponList[wtype]==NULL) {
856                this->weaponList[wtype] = &weapon;
857                this->weaponList[wtype]->addMunition((int)this->munition[wtype]);
858                this->munition[wtype] = 0;
859        }
860}
861
862void Player::addMunition(int type, int count) {
863        if(this->weaponList[type]==NULL) {
864                this->munition[type]+=count;
865        } else {
866                this->weaponList[type]->addMunition(count);
867        }
868}
869
870void Player::setActiveWeapon(int wId) {
871        if(this->activeWeapon!=NULL) {
872                this->activeWeapon->setVisible(false);
873                this->activeWeapon->setStandBy(true);
874        }
875        wId = min(wId, 9);
876        while(this->weaponList[wId] == NULL) {
877                wId--;
878                assert(wId>=0);
879        }
880        this->activeWeapon = this->weaponList[wId];
881        this->activeWeapon->setStandBy(false);
882        this->activeWeapon->setVisible(true);
883}
884
885Weapon* Player::getActiveWeapon() {
886        return this->activeWeapon;
887}
888
889void Player::addHealth(float dHealth)
890{
891        this->health+=dHealth;
892        this->health = min(this->health, 100.0f);
893}
894
895void Player::setHealth(float _health) {
896        this->health = _health;
897        this->health = min(this->health, 100.0f);
898}
899
900float Player::getRealHealth() {
901        return this->health;
902}
903
904float Player::getHealth() {
905        return this->iHealth;
906}
907
908int Player::getAmo() {
909        return this->activeWeapon->getAmo();
910}
911
912void Player::applyForce(Vector point, Vector force) {
913        point.y = iySchale;
914        this->fOther = this->fOther + force;
915        this->torqueVector.push_back((point.crossProd(force))/80);
916}
917
918Node* Player::clone() {
919        return NULL;
920}
921
922void Player::checkPosition() {
923        float ch = (((GameScene *) this->myScene)->getWidth()/2);
924        Vector chDir;
925        Vector absPos = this->getAbsolutePosition();
926        Vector center(ch, absPos.y, ch);
927        chDir = center - absPos;
928        float absPosY = absPos.y;
929        float chDirLength = chDir.length();
930        ch*=0.8f;
931        if(chDirLength>ch) {
932                chDir.normalize();
933                chDir = chDir * (chDirLength-ch)*(chDirLength-ch)*10;
934                this->pActor->addForce(chDir.getNxVector());
935        }
936        if(this->myPosition.y < ((GameScene *) this->myScene)->getTerrain()->getHeight(this->myPosition.x, this->myPosition.z)) {
937                this->myPosition.y = ((GameScene *) this->myScene)->getTerrain()->getHeight(this->myPosition.x, this->myPosition.z);
938        }
939}
940
941NxActor* Player::createDistanceJoint(Vector pos, bool lowerJoint, bool reuse)
942{
943        NxActor *springActor = NULL;
944        if(!reuse) {
945                NxSphereShapeDesc springSphere;
946                springSphere.shapeFlags = NX_SF_DISABLE_RAYCASTING;
947                springSphere.radius = 1;
948                NxActorDesc springActorDesc;
949                NxBodyDesc springBodyDesc;
950                springBodyDesc.mass = 0;
951                springActorDesc.globalPose.t = pos.getNxVector();
952                springActorDesc.density = 10;
953                springActorDesc.body = &springBodyDesc;
954                springActorDesc.shapes.pushBack(&springSphere);
955
956                springActor = this->myScene->pScene->createActor(springActorDesc);
957                springActor->raiseBodyFlag(NX_BF_KINEMATIC);
958                springActor->setGroup(UserContactReport::COLGROUP_NOCOL);
959                springActor->getShapes()[0]->setGroup(UserContactReport::COLGROUP_NOCOL);
960        }
961
962        //DistanceJoint zwischen springActor und hauptActor
963        NxDistanceJointDesc distDesc;
964        distDesc.actor[0] = this->pActor;
965        if(!reuse) {
966                distDesc.actor[1] = springActor;
967        } else {
968                distDesc.actor[1] = this->upperSpringActor;/*(lowerJoint) ? this->lowerSpringActor : this->upperSpringActor;*/
969        }
970       
971        distDesc.localAnchor[0]=NxVec3(0.0f,0.0f,0.0f);
972        distDesc.localAnchor[1]=NxVec3(0.0f,0.0f,0.0f);
973
974        if(lowerJoint) {
975                distDesc.minDistance= (NxReal)(this->springDistance-2.4);//0.015;
976                distDesc.maxDistance= (NxReal)(this->springDistance-1.8);
977        } else {
978                distDesc.minDistance= (NxReal)(this->springDistance-0.6-this->upperDelta);//0.015;
979                distDesc.maxDistance= (NxReal)(this->springDistance-0.4-this->upperDelta);
980        }
981               
982        NxSpringDesc springDesc;
983        springDesc.spring = 400;
984        if(!lowerJoint) {
985                springDesc.spring*=3;
986        } else {
987        }
988        springDesc.damper = (NxReal)0.1;
989        distDesc.spring = springDesc;
990
991        distDesc.flags = (NX_DJF_MIN_DISTANCE_ENABLED | NX_DJF_MAX_DISTANCE_ENABLED);  // combination of the bits defined by ::NxDistanceJointFlag
992        distDesc.flags |= NX_DJF_SPRING_ENABLED;
993
994        if(!distDesc.isValid()) {
995                this->myScene->manager->printToConsole("distDescriptor not valid!");
996        }
997        distDesc.jointFlags = NX_JF_VISUALIZATION | NX_JF_COLLISION_ENABLED;
998        NxDistanceJoint* distanceJoint = (NxDistanceJoint*) this->myScene->pScene->createJoint(distDesc);
999        this->upperJoint = distanceJoint;
1000        return springActor;
1001}
1002
1003void Player::killMe()
1004{
1005        if(this->upperJoint) {
1006                this->myScene->pScene->releaseJoint(*this->upperJoint);
1007                this->upperJoint = NULL;
1008        }
1009        if(this->upperSpringActor) {
1010                this->myScene->pScene->releaseActor(*this->upperSpringActor);
1011                this->upperSpringActor = NULL;
1012        }
1013        for(int i=0;i<4;i++) {
1014                this->wheel[i]->killMe();
1015        }
1016        Node::killMe();
1017}
1018
1019void Player::setSoftKill(bool _softKill, float _duration)
1020{
1021        this->setTimeToLive(_duration);
1022        Node::setSoftKill(_softKill, _duration);
1023        for(int i=0;i<4;i++) {
1024                this->wheel[i]->setTimeToLive(_duration);
1025                this->wheel[i]->setSoftKill(_softKill, _duration);
1026        }
1027        this->schale->setTimeToLive(_duration);
1028        this->schale->setSoftKill(_softKill, _duration);
1029        this->wurm->setTimeToLive(_duration);
1030        this->wurm->setSoftKill(_softKill, _duration);
1031        for(int i=0;i<10;i++) {
1032                if(this->weaponList[i]) {
1033                        this->weaponList[i]->setTimeToLive(_duration);
1034                        this->weaponList[i]->setSoftKill(_softKill, _duration);
1035                }
1036        }
1037}
1038
1039void Player::setTeam(int _team)
1040{
1041        this->team = _team;
1042}
1043
1044int Player::getTeam()
1045{
1046        return this->team;
1047}
1048
1049void Player::setAvatareFileName(std::string _avatar)
1050{
1051        this->avatar = _avatar;
1052}
1053
1054void Player::hitByFire()
1055{
1056        this->fireHitCount++;
1057        if(this->iceHitCount>0)
1058                this->iceHitCount-=0.5f;
1059}
1060
1061bool Player::isToasted()
1062{
1063        if(this->fireHitCount>200) {
1064                this->fireHitCount = 0;
1065                return true;
1066        }
1067        return false;
1068}
1069
1070void Player::hitByIce()
1071{
1072        this->iceHitCount+=1;
1073        this->iceHitCount = min(100.0f, this->iceHitCount);
1074}
1075
1076Vector Player::getTerrainHeight(Vector v, bool flying) {
1077        NxVec3 direction(0, -1, 0);
1078        NxRay ray(v.getNxVector(), direction);
1079        NxRaycastHit hit;
1080        Vector hv = v;
1081
1082        // Get the closest shape
1083        NxU32 mask = 0;
1084        mask |= UserContactReport::COLGROUP_PLAYER;
1085        mask |= UserContactReport::COLGROUP_NOCOL;
1086        NxReal maxDist = (!flying) ? NX_MAX_F32 : 1.0f;
1087        NxShape* closestShape = this->myScene->pScene->raycastClosestShape(ray, NX_ALL_SHAPES, hit, mask, maxDist);//0xffffff);
1088        if (closestShape)
1089        {
1090                hv.y = hit.worldImpact.y;
1091        } else {
1092                hv.y = 0;
1093                if(flying) {
1094                        hv.y = -10000;
1095                        return hv;
1096                }
1097        }
1098        float h = ((GameScene*) this->myScene)->getTerrain()->getHeight(v.x, v.z);
1099        hv.y = (hv.y>=h) ? hv.y : h;
1100        return hv;
1101}
1102
1103void Player::initWin()
1104{
1105        //emitter starten
1106        this->winPe->restartEmitting();
1107}
1108
1109void Player::initLose()
1110{
1111        //player hit
1112        //this->setPlayerHit(this->myPosition,
1113        SimpleBullet* bullet = (SimpleBullet*) ((GameScene*) this->myScene)->createNode(GameScene::NODE_SIMPLEBULLET);
1114        bullet->setBulletType(0);
1115        bullet->setImpactForce(5);
1116        bullet->setWeaponDirection(Vector(0, 1, 0));
1117        this->setPlayerHit(this->myPosition, *bullet);
1118}
Note: See TracBrowser for help on using the repository browser.