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

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

GTPD - Jungle Rumble - GLOBAL_player_freezeQ WIP

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