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

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

GTPD - Jungle Rumble - integrate into GTP SVN structure

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