#include "dxstdafx.h" #include ".\player.h" #include "Terrain.h" #include "GameManager.h" #include "GameScene.h" #include "ParticleGroup.h" #include "ParticleEmitter.h" #include "SimpleBullet.h" #include "Sprite.h" #include #define FL 0 #define FR 1 #define RL 2 #define RR 3 #define M_PI 3.1415 //static NxDistanceJoint* distanceJoint = NULL; Player::Player(void) : Node() { counter= 0; this->activeWeapon = NULL; this->playerPlayerCol = false; this->gotHit = false; this->health = 100; this->iHealth = this->health; this->pe=NULL; for(int i=0;i<10;i++) { this->weaponList[i] = NULL; this->munition[i] = 0; } this->springCounter = 0; this->upperSpringActor = NULL; this->upperJoint = NULL; this->rauchEmitter = NULL; this->team = 0; this->setAvatareFileName("./media/models/wurm.x"); this->fireHitCount = 0; this->sleepCounter = 0; } Player::~Player(void) { } void Player::initPlayer(float _x, float _y, float _z) { //Setup Engine this->sleepCounter = 0; this->engineForce = 0; this->maxEngineForce = 6000; this->deltaEngineForce = 4000; this->Cdrag = 0.1257f*15.0f; this->Crr = 0.0001f*20.0f; this->Cdaempfung = 0.0012f; this->Croll = 0.2f; this->Clateral = 0.6f; this->Cschale = 10; this->Crotschale = 5; this->CimpactRot = 0.00003f; this->CrotBeschleunigung = 0.001f; this->vMax = 300; this->desiredFlyingDownForce = 350; this->fireHitCount = 0; this->iceHitCount = 0; this->currentRotSchale = 0; maxBreakForce = 5000; breakForce = 0; deltaBreakForce = 2000; //Steering setup this->maxSteering = 20*D3DX_PI/180; this->steering = 0; this->steeringFactor = 10; this->vHeading = 0; //Physik this->vLength = 0; heading.x = 0; heading.y = 0; heading.z = 1; direction.x = 0; direction.y = 0; direction.z = 1; cFront = 1.2f; cRear = 1.2f; cSide = 1.2f; cHeight = 0.6f; rfDistance = cFront+cRear; this->cR_D = this->cRear/this->rfDistance; this->cF_D = this->cFront/this->rfDistance; this->cH_D = this->cHeight/this->rfDistance; vehicleMass = 10; tMoment = vehicleMass; wheelMass = 5; wheelRadius = 0.5; springL = 1.0f; springK = 1000; //Ageia Physic this->s.x = _x; this->s.y = _y; this->s.z = _z; this->setPosition(s.x, s.y, s.z); NxSphereShapeDesc sphereDesc; sphereDesc.localPose.t = NxVec3(0, 1, 0); sphereDesc.radius = 2; this->pActorDesc.density = 0; this->pBodyDesc.mass = this->vehicleMass; this->pActorDesc.shapes.pushBack(&sphereDesc); this->triggerSphereDesc.radius = 2.1f; this->triggerSphereDesc.shapeFlags = NX_TRIGGER_ON_ENTER | NX_TRIGGER_ON_LEAVE | NX_SF_DISABLE_RAYCASTING; this->pActorDesc.shapes.pushBack(&this->triggerSphereDesc); this->setBehaveAs(Node::RIGIDBODY); this->setColDetGroup(UserContactReport::COLGROUP_PLAYER); this->pActor->setAngularDamping(1); NxShape* const* shapes = this->pActor->getShapes(); int nbShapes = this->pActor->getNbShapes(); for(int i=0;iisSphere() && ((NxSphereShape*)shapes[i])->getRadius()==1) { this->sphere = (NxSphereShape*)shapes[i]; } } //Physic spring this->springDistance = 20; this->upperDelta = 0; this->springBias = 1.2f; this->upperSpringActor = this->createDistanceJoint(Vector(_x, _y+this->springDistance-this->upperDelta, _z), false); //Setup Geometry this->schale = (Object3d *) this->myScene->createNode(this->myScene->NODE_OBJECT3D, *this, true); this->schale->loadMeshFromFile("./media/models/nussschale.x"); this->wurm = (Object3d *) this->myScene->createNode(this->myScene->NODE_OBJECT3D, *this->schale, true); this->wurm->loadMeshFromFile(this->avatar); for(int i=0;i<4;i++) { this->wheel[i] = (Object3d *) this->myScene->createNode(this->myScene->NODE_OBJECT3D, true); this->wheel[i]->loadMeshFromFile("./media/models/wheel15.x"); } this->wheel[FL]->setPosition(cSide+_x, 0+_y, cFront+_z); this->wheel[FR]->setPosition(-cSide+_x, 0+_y, cFront+_z); this->wheel[RL]->setPosition(cSide+_x, 0+_y, -cRear+_z); this->wheel[RR]->setPosition(-cSide+_x, 0+_y, -cRear+_z); this->schale->setPosition(0, springL, 0); schaleAlpha = 0; schaleHoehe = 0; this->wheelAngle = 0; this->w.setXYZ(0, 0, 0); this->p = 0; ixSchale = 0; iySchale = 0; izSchale = 0; iaSchale = 0; ibSchale = 0; igSchale = 0; daSchale = 0; dbSchale = 0; dgSchale = 0; this->resetValues(); //Create motor sound this->motor = (SoundNode *) this->myScene->createNode(this->myScene->NODE_SOUND, *this->schale, false); if(!this->motor->loadFile("./media/sound/fan_blade_idle_loop1.wav", true)) { this->myScene->manager->printToConsole("Loading motor sound failed!"); } else { this->motor->play(); this->motor->setVolume(0); } //Create nooooo Sounds hitSounds[0] = "./media/sound/screams/no1.mp3"; hitSounds[1] = "./media/sound/screams/no2.mp3"; hitSounds[2] = "./media/sound/screams/no3.mp3"; for(int i=0;i<3;i++) { this->noSounds[i] = (SoundNode *) this->myScene->createNode(this->myScene->NODE_SOUND, *this->schale, false); if(!this->noSounds[i]->loadFile(this->hitSounds[i], false)) { this->myScene->manager->printToConsole("Loading scream sound failed!"); } else { //this->noSounds[i]->play(); this->noSounds[i]->setKillSoundNodeAfterPlayed(false); this->noSounds[i]->setVolume(255); } } srand((UINT)time(NULL)); this->gotHit = false; ParticleGroup* pg = (ParticleGroup*) this->myScene->createNode(Scene::NODE_PARTICLEGROUP, false); this->rauchEmitter = (ParticleEmitter*) this->myScene->createNode(Scene::NODE_PARTICLEEMITTER, *this->schale); pg->addParticleEmitter(this->myScene->getSmartPointer(this->rauchEmitter)); pg->useGravity(false); this->rauchEmitter->setDimensions(1,1,1); this->rauchEmitter->setEMBirthRate(20); this->rauchEmitter->setEMEmissionDuration(2); this->rauchEmitter->setEMParticleLifeTime(2); this->rauchEmitter->setEMParticleVelocity(0); this->rauchEmitter->setPosition(0, 0, 0); this->rauchEmitter->setRotation(-D3DX_PI/2, 0, 0); this->rauchEmitter->setDeleteMeAfterEmission(false); this->rauchEmitter->setColDetGroup(UserContactReport::COLGROUP_NOCOL); this->rauchEmitter->setStandBy(true); Sprite *rauch; rauch = (Sprite*) this->myScene->createNode(Scene::NODE_SPRITE); rauch->setDimension(3, 3); rauch->setTexture("./media/textures/explosion.png"); rauch->setFPS(64); rauch->setTimeToLive(1); rauch->setRowColumnCount(8, 8); rauch->setFrameCount(64); rauch->setLoopAnimation(true); rauch->setLookAtCamera(true); rauch->setAlpha(0.5f); rauch->setPosition(this->getAbsolutePosition()); rauch->generatePhysicMesh(); rauch->setBehaveAs(Node::RIGIDBODY); rauch->setColDetGroup(UserContactReport::COLGROUP_NOCOL); this->rauchEmitter->addRefNode(*rauch); ParticleGroup* winPg = (ParticleGroup*) this->myScene->createNode(Scene::NODE_PARTICLEGROUP, false); this->winPe = (ParticleEmitter*) this->myScene->createNode(Scene::NODE_PARTICLEEMITTER, *this->schale); winPg->addParticleEmitter(this->myScene->getSmartPointer(this->winPe)); winPg->useGravity(true); this->winPe->setDimensions(1,1,1); this->winPe->setEMBirthRate(10); this->winPe->setEMEmissionDuration(5); this->winPe->setEMParticleLifeTime(5); this->winPe->setEMParticleVelocity(15); this->winPe->setPosition(0, 10, 0); this->winPe->setRotation(D3DX_PI/2, 0, 0); this->winPe->setEMRotationalDegree(500, 500, 500); this->winPe->setEMHorizontalDegree(1.5f); this->winPe->setEMVerticalDegree(1.5f); this->winPe->setDeleteMeAfterEmission(false); this->winPe->setColDetGroup(UserContactReport::COLGROUP_OTHER); this->winPe->setStandBy(true); Object3d *cube; cube = (Object3d*) this->myScene->createNode(Scene::NODE_OBJECT3D); cube->loadMeshFromFile("./media/models/gtpcube.x"); cube->generatePhysicMesh(Object3d::COL_CONVEX); cube->setBehaveAs(Node::RIGIDBODY); cube->setColDetGroup(UserContactReport::COLGROUP_OBSTACLE); cube->setSoftKill(true, 1); this->winPe->addRefNode(*cube); /*Sprite *rauch; rauch = (Sprite*) this->myScene->createNode(Scene::NODE_SPRITE); rauch->setDimension(3, 3); rauch->setTexture("./media/textures/explosion.png"); rauch->setFPS(64); rauch->setTimeToLive(1); rauch->setRowColumnCount(8, 8); rauch->setFrameCount(64); rauch->setLoopAnimation(true); rauch->setLookAtCamera(true); rauch->setAlpha(0.5f); rauch->setPosition(this->getAbsolutePosition()); rauch->generatePhysicMesh(); rauch->setBehaveAs(Node::RIGIDBODY); rauch->setColDetGroup(UserContactReport::COLGROUP_NOCOL); this->rauchEmitter->addRefNode(*rauch);*/ } void Player::setPlayerHit(Vector position, Bullet &bullet) { //Joints deaktivieren if(this->upperJoint) { this->myScene->pScene->releaseJoint(*this->upperJoint); this->upperJoint = NULL; } //ZufallsSound abspielen int sndId = (int)((((float) rand()/RAND_MAX)+0.5)*5); if(sndId<3) { this->noSounds[sndId]->play(); } //TraceRays auf best. länge reduzieren //Impuls an player anlegen this->gotHit = true; this->engineForce*=0.5; Vector forceDir; forceDir = bullet.getDirection(); forceDir.y = 1; forceDir.normalize(); forceDir = forceDir*bullet.getImpactForce()*120; this->pActor->setAngularDamping(0); this->pActor->addForceAtPos(forceDir.getNxVector(), bullet.getAbsolutePosition().getNxVector(), NX_IMPULSE); this->lastYPos = -10000; this->realFlyingDownForce = 0; //Emit some Stones... ParticleGroup* stoneGroup = (ParticleGroup*) this->myScene->createNode(Scene::NODE_PARTICLEGROUP, false); ParticleEmitter* stoneEmitter = (ParticleEmitter*) this->myScene->createNode(Scene::NODE_PARTICLEEMITTER); stoneGroup->addParticleEmitter(this->myScene->getSmartPointer(stoneEmitter)); stoneEmitter->setEMParticleVelocity(20); stoneEmitter->setDimensions(1, 1, 1); stoneEmitter->setPosition(this->getAbsolutePosition()-Vector(0, 2, 0)); stoneEmitter->setEMEmissionDuration(0.3f); stoneEmitter->setEMHorizontalDegree(1); stoneEmitter->setEMVerticalDegree(1); stoneEmitter->setEMRotationalDegree(8, 8, 8); stoneEmitter->setEMBirthRate(10); stoneEmitter->setEMParticleLifeTime(5.0f); stoneEmitter->setRotation(-D3DX_PI/2, 0, 0); stoneEmitter->setDeleteMeAfterEmission(true); stoneEmitter->setColDetGroup(UserContactReport::COLGROUP_OTHER); Object3d* stone = (Object3d*) this->myScene->createNode(Scene::NODE_OBJECT3D); stone->loadMeshFromFile("./media/models/Stein_3.x"); stone->generatePhysicMesh(Object3d::COL_CONVEX); stone->setColDetGroup(UserContactReport::COLGROUP_OTHER); stone->setSoftKill(true, 2); stoneEmitter->addRefNode(*stone); stoneEmitter->addRefNode(*stone); stoneEmitter->addRefNode(*stone); //Attach Sprites to Emitter ParticleGroup* spriteGroup = (ParticleGroup*) this->myScene->createNode(Scene::NODE_PARTICLEGROUP, true); ParticleEmitter* spriteEmitter = (ParticleEmitter*) this->myScene->createNode(Scene::NODE_PARTICLEEMITTER); spriteGroup->addParticleEmitter(this->myScene->getSmartPointer(spriteEmitter)); spriteEmitter->setEMParticleVelocity(0); spriteEmitter->setDimensions(1, 1, 1); spriteEmitter->setPosition(this->getAbsolutePosition()); spriteEmitter->setEMEmissionDuration(3); spriteEmitter->setEMHorizontalDegree(0.1f); spriteEmitter->setEMVerticalDegree(0.1f); spriteEmitter->setEMRotationalDegree(8, 8, 8); spriteEmitter->setEMBirthRate(10); spriteEmitter->setEMParticleLifeTime(5.0f); spriteEmitter->setRotation(-D3DX_PI/2, 0, 0); spriteEmitter->setDeleteMeAfterEmission(true); spriteEmitter->setColDetGroup(UserContactReport::COLGROUP_NOCOL); spriteEmitter->setStandBy(false); Sprite *rauch; rauch = (Sprite*) this->myScene->createNode(Scene::NODE_SPRITE, false); rauch->setDimension(3, 3); rauch->setTexture("./media/textures/explosion.png"); rauch->setFPS(64); rauch->setTimeToLive(2); rauch->setRowColumnCount(8, 8); rauch->setFrameCount(64); rauch->setLoopAnimation(true); rauch->setLookAtCamera(true); rauch->setAlpha(0.5f); rauch->setPosition(this->getAbsolutePosition()); rauch->generatePhysicMesh(); rauch->setBehaveAs(Node::RIGIDBODY); rauch->setColDetGroup(UserContactReport::COLGROUP_NOCOL); spriteEmitter->addRefNode(*rauch); spriteEmitter->addRefNode(*rauch); stone->addChild(this->myScene->getSmartPointer(spriteEmitter)); } void Player::setPlayerOnGround() { Vector L[4]; L[FL].x = cSide; L[FL].y = -this->springL; L[FL].z = cFront; L[FR].x = -cSide; L[FR].y = -this->springL; L[FR].z = cFront; L[RL].x = cSide; L[RL].y = -this->springL; L[RL].z = -cRear; L[RR].x = -cSide; L[RR].y = -this->springL; L[RR].z = -cRear; Vector playerPos = this->getAbsolutePosition(); for(int i=0;i<4;i++) { this->wheel[i]->setPosition(playerPos+L[i]); } this->lastYPos = -10000; playerPos = this->getTerrainHeight(playerPos); this->upperSpringActor = this->createDistanceJoint(Vector(playerPos.x, playerPos.y+this->springDistance-this->upperDelta, playerPos.z), false); this->gotHit = false; this->realFlyingDownForce = 0; this->pActor->setLinearMomentum(NxVec3(0, 0, 0)); this->pActor->setLinearVelocity(NxVec3(0, 0, 0)); this->pActor->setAngularMomentum(NxVec3(0, 0, 0)); this->pActor->setAngularVelocity(NxVec3(0, 0, 0)); } void Player::update(float dt) { if(this->sleepCounter++<10) { if(this->sleepCounter==2) { this->motor->setVolume(1); } return; } exception e; try { this->iHealth+= (this->health-this->iHealth)*dt; if(dt==0) { this->setBehaveAs(Node::KINEMATIC); return; } else { this->setBehaveAs(Node::RIGIDBODY); } dt = min(dt, 0.04f); if(this->gotHit) { this->updateFlyingPlayer(dt); } else { this->updateDrivingPlayer(dt); } this->activeWeapon->setPosition(Vector(this->pActor->getGlobalPosition())); //Calculate Frequency float frequency = this->vLength/60*90000 + 10000; FSOUND_SetFrequency(this->motor->getChannel(), (int)frequency); //Hack to get objects moving this->resetValues(); Node::update(dt); this->checkPosition(); if(this->fireHitCount>0) { this->fireHitCount-=dt; } } catch(exception e) { this->myScene->manager->printToConsole("Exception in player occured!"); } } void Player::updateFlyingPlayer(float dt) { Vector L[4]; L[FL].x = cSide; L[FL].y = -this->springL; L[FL].z = cFront; L[FR].x = -cSide; L[FR].y = -this->springL; L[FR].z = cFront; L[RL].x = cSide; L[RL].y = -this->springL; L[RL].z = -cRear; L[RR].x = -cSide; L[RR].y = -this->springL; L[RR].z = -cRear; D3DXMATRIXA16 wheelMat; D3DXMATRIXA16 currentWorldMat; Vector wheelPos; Vector playerPos = this->getAbsolutePosition(); bool fallingDown = false; if(playerPos.y < this->lastYPos-1) { fallingDown = true; } else { this->lastYPos = playerPos.y; } bool onGround = false; for(int i=0;i<4;i++) { D3DXMatrixTranslation(&wheelMat, L[i].x, L[i].y, L[i].z); D3DXMatrixMultiply(&wheelMat, &wheelMat, &this->myWorldMatrix); this->wheel[i]->setWorldMatrix(wheelMat); if(fallingDown) { wheelPos = this->wheel[i]->getAbsolutePosition(); wheelPos = this->getTerrainHeight(wheelPos, true); if(wheelPos.y!=-10000) { onGround = true; } } } wheelPos = this->getTerrainHeight(playerPos); if(playerPos.y-1.5setPlayerOnGround(); } else { this->realFlyingDownForce += (this->desiredFlyingDownForce - this->realFlyingDownForce)*min(1.0f, 12*dt); this->pActor->addForce(NxVec3(0, -this->realFlyingDownForce, 0)); } } void Player::updateDrivingPlayer(float dt) { //Calculate Heading heading.x = 0; heading.y = 0; heading.z=1; this->getAbsoluteDirectionVector(this->heading, this->heading); this->heading.y = 0; this->heading.normalize(); //Wichtige Daten aus dem PhysicActor auslesen this->myPosition = Vector(this->pActor->getGlobalPosition()); this->w = Vector(this->pActor->getAngularVelocity()); Vector vlinear = Vector(this->pActor->getLinearVelocity()); //char temp[100]; float vl; vl = vlinear.length(); if(abs(vl)>100) { //this->myScene->manager->printToConsole("vl >100!!!!!!!!"); vlinear.normalize(); vlinear = vlinear*100; this->pActor->setLinearVelocity(vlinear.getNxVector()); //this->w.normalize(); //this->w = this->w*5; } //sprintf(temp, "v length = %f",vl); //this->myScene->manager->printToConsole(temp); //Durchschnittshöhe berechnen avgy=0; for(int i=0;i<4;i++) { avgy += wheel[i]->myPosition.y; } avgy/=4; //SpringActor in position bringen float tempBias = 0.2f*sin(10*this->springCounter); Vector saPos = this->getAbsolutePosition(); saPos.y = avgy+this->springDistance+this->springBias+tempBias; this->upperSpringActor->moveGlobalPosition(saPos.getNxVector()); Vector mp = this->getAbsolutePosition(); if(saPos.ypActor->setGlobalPosition(NxVec3(mp.x, 2*saPos.y - mp.y, mp.z)); this->pActor->setLinearVelocity(NxVec3(0, 0, 0)); } this->springCounter+=dt; //"schräglage" des Terrains berrechnen yf = (wheel[FL]->myPosition.y+wheel[FR]->myPosition.y)/2; yr = (wheel[RL]->myPosition.y+wheel[RR]->myPosition.y)/2; yleft = (wheel[FL]->myPosition.y+wheel[RL]->myPosition.y)/2; yright = (wheel[FR]->myPosition.y+wheel[RR]->myPosition.y)/2; dyFrontRear = yf - yr; dyLeftRight = yleft - yright; terrainAngle.x = (float) -atan2(dyFrontRear, cRear+cFront); terrainAngle.z = (float) atan2(dyLeftRight, 2*cSide); //Alpha & Gamma Rotationsmatrizen berechnen D3DXMATRIX mAlpha; D3DXMatrixRotationX(&mAlpha, (FLOAT)(daSchale*M_PI/180)); D3DXMATRIX mGamma; D3DXMatrixRotationZ(&mGamma, (FLOAT)(dgSchale*M_PI/180)); //Graffel mit Beta Rotation D3DXMATRIX mGYaw; D3DXMATRIX mYaw; D3DXMatrixIdentity(&mYaw); this->pActor->getGlobalOrientation().getColumnMajorStride4(((NxF32 *) &mYaw.m[0][0])); mGYaw = mYaw; D3DXMATRIX nmAlpha; D3DXMatrixRotationX(&nmAlpha, -daSchale); D3DXMATRIX nmGamma; D3DXMatrixRotationZ(&nmGamma, -dgSchale); //Calculate engineForce if(baccelerate) { this->engineForce += dt*this->deltaEngineForce; if(this->engineForce > this->maxEngineForce) this->engineForce = this->maxEngineForce; } else { if(this->engineForce>0) { this->engineForce -= dt*this->deltaEngineForce; } else { this->engineForce = 0; } } //Break force if(bstop) { this->breakForce += dt*this->deltaBreakForce; if(this->breakForce > this->maxBreakForce) this->breakForce = this->maxBreakForce; } else { if(this->breakForce>0) { this->breakForce -= dt*this->deltaBreakForce; this->engineForce = min(this->breakForce, this->engineForce); } else { this->breakForce = 0; } } //Calculate Steering Angle float desiredSteering = 0; float vsize = this->vLength; if(btoLeft) { desiredSteering = -this->maxSteering; } else if(btoRight) { desiredSteering = this->maxSteering; } this->steering += dt*(desiredSteering - this->steering)*this->steeringFactor; if(desiredSteering==0) { this->steering += dt*(desiredSteering - this->steering)*this->steeringFactor; } //berechne gravitationsvektor this->gravity.setNxVector(this->myScene->pDefaultGravity); float tempAngle; direction = this->v; direction.normalize(); heading.normalize(); float cosBeta; cosBeta = direction.dotProd(heading); if(this->vLength>=0.8f) { alphaFront = (float) (atan2((v.x+w.y*cFront),this->vLength) - steering*((cosBeta>0) ? 1 : -1)); alphaRear = (float) (atan2((v.x-w.y*cRear),this->vLength)); } else { alphaFront = 0; alphaRear = 0; w.setXYZ(0, 0, 0); } alphaFront*=180/D3DX_PI; alphaRear*=180/D3DX_PI; Vector fa[4]; //Feder Halterungspunkt am Reifen Vector L[4]; //Temporärer Speicher für Haltepunkt fa[FL].x = cSide; fa[FL].y = 0; fa[FL].z = cFront; fa[FR].x = -cSide; fa[FR].y = 0; fa[FR].z = cFront; fa[RL].x = cSide; fa[RL].y = 0; fa[RL].z = -cRear; fa[RR].x = -cSide; fa[RR].y = 0; fa[RR].z = -cRear; L[FL].x = cSide; L[FL].y = 0; L[FL].z = cFront; L[FR].x = -cSide; L[FR].y = 0; L[FR].z = cFront; L[RL].x = cSide; L[RL].y = 0; L[RL].z = -cRear; L[RR].x = -cSide; L[RR].y = 0; L[RR].z = -cRear; int mult1=1; int mult2=1; float mult3 = 1; Vector vVectorForce[4]; Vector eDreh[4]; Vector gravMass = gravity*vehicleMass/4; Vector gravAcc = eAcc*this->cH_D*this->vehicleMass; Vector normGravity; normGravity = gravity; normGravity.normalize(); this->schale->setPosition(0,0,0); float downForceSum =0; for(int i=0;i<4;i++) { //Rotiere Vectoren um absolute Position der FederAngel zu berechnen this->getAbsoluteVector(fa[i], fa[i]); terrainHeight[i] = this->getTerrainHeight(fa[i]); terrainHeight[i].y+=this->wheelRadius; wheel[i]->setPosition(terrainHeight[i]); //HALBE Kraft die auf die Feder ausgeübt wird. vDownForce[i] = 0.5f*springK*(springL-(this->myPosition.y - wheel[i]->myPosition.y)); vDownForce[i]-=vDownForce[i]*Cdaempfung*40; //Wheel DownForce to ground wDownForce[i] +=vDownForce[i]; wDownForce[i] +=gravity.y*wheelMass; mult1 = (i<2) ? 1 : -1; //Front Rear mult2 = (i==0 || i==2) ? -1 : 1; //Left Right mult3 = (i<2) ? this->cR_D : this->cF_D; //Factors for front rear //Kraftvectoren erzeugen wegen dem drehmoment vVectorForce[i] = normGravity*vDownForce[i]; //Drehmoment berechen eDreh[i] = (vVectorForce[i]/tMoment).crossProd(L[i]); //downForceSum += wDownForce[i]; tempAngle = (i<2) ? alphaFront : alphaRear; Flateral[i] = this->calcLateralForce(tempAngle)*1000; } //Radius berechnen float drehM=0; Vector vYaw; Vector latForce; int multRollForward = (cosBeta>0) ? 1 : -1; Fcornering = vHeading*steering*1.2f; if(abs(this->vHeading)>=1) { p = p + (0.12f*(70-min(abs(this->vHeading), 30.0f))*dt)*steering; } this->setRotation(0, p, 0); vYaw.x = 0; vYaw.y = 1; vYaw.z = 0; latForce = heading.crossProd(vYaw); latForce.normalize(); latForce = latForce*Fcornering; int mult = (cosBeta>=0) ? 1: -1; heading.normalize(); Vector vecDown(0, -1, 0); this->schale->getAbsoluteDirectionVector(vecDown, vecDown); float rollFactor = 0; if(vecDown.x!=0 || vecDown.z!=0) { vecDown.y = 0; vecDown.normalize(); rollFactor = heading.dotProd(vecDown); } longForce = (heading*(this->engineForce -rollFactor*this->vehicleMass*Croll*50)) - v*v.length()*Cdrag - v*Crr - (heading*this->breakForce); eAcc = longForce/this->vehicleMass; //Beschleunigungen ausrechnen Vector f; //Longitudinal force f = f+longForce; //Lateral force f = f-latForce; if(this->iceHitCount>0) { f = f - f*(this->iceHitCount/100.0f); this->iceHitCount-=10*dt; this->pActor->setLinearDamping(max(0.0f,10*this->iceHitCount/100.0f)); } else { this->iceHitCount = 0; this->pActor->setLinearDamping(0); } NxVec3 tempF = f.getNxVector(); this->pActor->addForce(tempF); this->s = this->myPosition; this->v = Vector(this->pActor->getLinearVelocity()); this->vLength = this->v.length(); Vector tempV = this->v; if(this->vLength>1) { tempV.normalize(); this->vHeading = this->vLength*(this->heading.dotProd(tempV)); } else { this->vHeading = 0; } tempV = v; tempV.y = 0; this->wheelAngle+=((tempV.length()*dt)/(this->wheelRadius))*multRollForward; //Winkelzeugs ausrechnen Vector wDreh; Vector wPos; Vector wOther; for(unsigned int i=0;itorqueVector.size();i++) { wOther = wOther + this->torqueVector.at(i); } e = (eDreh[FL] + eDreh[FR] + eDreh[RL] + eDreh[RR] + wDreh + wOther)*dt/tMoment; //Neigung der Schale für Beschleunigung usw berechen Vector a = f; float aLength = a.length(); aLength/=10; float aHeadingFactor=0; a.normalize(); if(aLength!=0) { aHeadingFactor = heading.dotProd(a); } this->currentRotSchale += (aHeadingFactor*aLength*this->CrotBeschleunigung*10-this->currentRotSchale)*min(1.0f,dt*2); daSchale = terrainAngle.x - aHeadingFactor*aLength*this->CrotBeschleunigung*10 +e.x + this->currentRotSchale; dbSchale = -e.y; dgSchale = terrainAngle.z; iaSchale+= (daSchale - iaSchale)*dt*Crotschale; ibSchale+= (dbSchale - ibSchale)*dt*Crotschale; igSchale+= (dgSchale - igSchale)*dt*Crotschale; this->schale->setRotation((iaSchale+schaleAlpha), ibSchale, igSchale); Vector quatVec(0, this->myRotation.y, 0); this->pActor->setGlobalOrientationQuat(NxQuat(quatVec.getNxQuatRotation())); //Angulare Dämpfung NxVec3 pActorVel = this->pActor->getAngularVelocity(); float aVelFactor = 10; pActorVel.x-=dt*aVelFactor*pActorVel.x; pActorVel.y-=dt*aVelFactor*pActorVel.y; pActorVel.z-=dt*aVelFactor*pActorVel.z; this->pActor->setAngularVelocity(pActorVel); float wa; wa = (float)(-this->wheelAngle*180/M_PI); //Schräglage berechnen float wg = ((this->wheel[FL]->myPosition.y+this->wheel[RL]->myPosition.y)/2- (this->wheel[FR]->myPosition.y+this->wheel[RR]->myPosition.y)/2)/2; wg = (float)(atan2(wg, 2*this->cSide)*180/M_PI); wa*=(float)(-M_PI/180); wg = wg*cos(wa); this->wheel[FL]->setRotation(wa, this->myRotation.y+this->steering, (float)(wg*M_PI/180)); this->wheel[FR]->setRotation(wa, this->myRotation.y+this->steering, (float)(wg*M_PI/180)); this->wheel[RL]->setRotation(wa, this->myRotation.y+0, (float)(wg*M_PI/180)); this->wheel[RR]->setRotation(wa, this->myRotation.y+0, (float)(wg*M_PI/180)); Vector schalePos; schalePos = schale->myPosition; schalePos.y-=avgy; schalePos.y/=2; Vector tempVec; schalePos.applyD3DXVector(D3DXVec4Transform(&tempVec, &schalePos, &mAlpha)); schalePos.applyD3DXVector(D3DXVec4Transform(&tempVec, &schalePos, &mGamma)); schalePos.y+=avgy; ixSchale+= (schalePos.x - ixSchale)*dt*Cschale; iySchale+= (schalePos.y+schaleHoehe - iySchale)*dt*Cschale; izSchale+= (schalePos.z - izSchale)*dt*Cschale; avgy=0; for(int i=0;i<4;i++) { avgy += wheel[i]->myPosition.y; } avgy/=4; iySchale = max(iySchale, avgy+0.4f); NxVec3 tempPos = this->pActor->getGlobalPosition(); tempPos.y = max(tempPos.y, avgy+0.4f); this->pActor->setGlobalPosition(tempPos); } float Player::calcLateralForce(float _angle) { float f=0; float k=0.02f; if(abs(_angle)<3) { f = 1.2f/3*_angle; } else if(_angle>=3) { f = -k*_angle + 1.2f + k*3; } else { f = -k*_angle - 1.2f - k*3; } return f; } void Player::resetValues() { baccelerate = false; bstop = false; btoLeft = false; btoRight = false; bfire = false; for(int i=0;i<4;i++) { wDownForce[i] = 0; vDownForce[i] = 0; } this->torqueVector.clear(); this->fOther.x = 0; this->fOther.y = 0; this->fOther.z = 0; } void Player::accelerate() {baccelerate = true;} void Player::stop() {bstop = true;} void Player::toLeft() {btoLeft = true; btoRight = false;} void Player::toRight() {btoRight = true; btoLeft = false;} void Player::setMouse(int x, int y) { mouseX = x; mouseY = y;} void Player::addWeapon(Weapon &weapon) { weapon.setPlayer(*this); weapon.setVisible(false); weapon.setStandBy(true); int wtype = weapon.getWeaponType(); if(this->weaponList[wtype]==NULL) { this->weaponList[wtype] = &weapon; this->weaponList[wtype]->addMunition((int)this->munition[wtype]); this->munition[wtype] = 0; } } void Player::addMunition(int type, int count) { if(this->weaponList[type]==NULL) { this->munition[type]+=count; } else { this->weaponList[type]->addMunition(count); } } void Player::setActiveWeapon(int wId) { if(this->activeWeapon!=NULL) { this->activeWeapon->setVisible(false); this->activeWeapon->setStandBy(true); } wId = min(wId, 9); while(this->weaponList[wId] == NULL) { wId--; assert(wId>=0); } this->activeWeapon = this->weaponList[wId]; this->activeWeapon->setStandBy(false); this->activeWeapon->setVisible(true); } Weapon* Player::getActiveWeapon() { return this->activeWeapon; } void Player::addHealth(float dHealth) { this->health+=dHealth; this->health = min(this->health, 100.0f); } void Player::setHealth(float _health) { this->health = _health; this->health = min(this->health, 100.0f); } float Player::getRealHealth() { return this->health; } float Player::getHealth() { return this->iHealth; } int Player::getAmo() { return this->activeWeapon->getAmo(); } void Player::applyForce(Vector point, Vector force) { point.y = iySchale; this->fOther = this->fOther + force; this->torqueVector.push_back((point.crossProd(force))/80); } Node* Player::clone() { return NULL; } void Player::checkPosition() { float ch = (((GameScene *) this->myScene)->getWidth()/2); Vector chDir; Vector absPos = this->getAbsolutePosition(); Vector center(ch, absPos.y, ch); chDir = center - absPos; float absPosY = absPos.y; float chDirLength = chDir.length(); ch*=0.8f; if(chDirLength>ch) { chDir.normalize(); chDir = chDir * (chDirLength-ch)*(chDirLength-ch)*10; this->pActor->addForce(chDir.getNxVector()); } if(this->myPosition.y < ((GameScene *) this->myScene)->getTerrain()->getHeight(this->myPosition.x, this->myPosition.z)) { this->myPosition.y = ((GameScene *) this->myScene)->getTerrain()->getHeight(this->myPosition.x, this->myPosition.z); } } NxActor* Player::createDistanceJoint(Vector pos, bool lowerJoint, bool reuse) { NxActor *springActor = NULL; if(!reuse) { NxSphereShapeDesc springSphere; springSphere.shapeFlags = NX_SF_DISABLE_RAYCASTING; springSphere.radius = 1; NxActorDesc springActorDesc; NxBodyDesc springBodyDesc; springBodyDesc.mass = 0; springActorDesc.globalPose.t = pos.getNxVector(); springActorDesc.density = 10; springActorDesc.body = &springBodyDesc; springActorDesc.shapes.pushBack(&springSphere); springActor = this->myScene->pScene->createActor(springActorDesc); springActor->raiseBodyFlag(NX_BF_KINEMATIC); springActor->setGroup(UserContactReport::COLGROUP_NOCOL); springActor->getShapes()[0]->setGroup(UserContactReport::COLGROUP_NOCOL); } //DistanceJoint zwischen springActor und hauptActor NxDistanceJointDesc distDesc; distDesc.actor[0] = this->pActor; if(!reuse) { distDesc.actor[1] = springActor; } else { distDesc.actor[1] = this->upperSpringActor;/*(lowerJoint) ? this->lowerSpringActor : this->upperSpringActor;*/ } distDesc.localAnchor[0]=NxVec3(0.0f,0.0f,0.0f); distDesc.localAnchor[1]=NxVec3(0.0f,0.0f,0.0f); if(lowerJoint) { distDesc.minDistance= (NxReal)(this->springDistance-2.4);//0.015; distDesc.maxDistance= (NxReal)(this->springDistance-1.8); } else { distDesc.minDistance= (NxReal)(this->springDistance-0.6-this->upperDelta);//0.015; distDesc.maxDistance= (NxReal)(this->springDistance-0.4-this->upperDelta); } NxSpringDesc springDesc; springDesc.spring = 400; if(!lowerJoint) { springDesc.spring*=3; } else { } springDesc.damper = (NxReal)0.1; distDesc.spring = springDesc; distDesc.flags = (NX_DJF_MIN_DISTANCE_ENABLED | NX_DJF_MAX_DISTANCE_ENABLED); // combination of the bits defined by ::NxDistanceJointFlag distDesc.flags |= NX_DJF_SPRING_ENABLED; if(!distDesc.isValid()) { this->myScene->manager->printToConsole("distDescriptor not valid!"); } distDesc.jointFlags = NX_JF_VISUALIZATION | NX_JF_COLLISION_ENABLED; NxDistanceJoint* distanceJoint = (NxDistanceJoint*) this->myScene->pScene->createJoint(distDesc); this->upperJoint = distanceJoint; return springActor; } void Player::killMe() { if(this->upperJoint) { this->myScene->pScene->releaseJoint(*this->upperJoint); this->upperJoint = NULL; } if(this->upperSpringActor) { this->myScene->pScene->releaseActor(*this->upperSpringActor); this->upperSpringActor = NULL; } for(int i=0;i<4;i++) { this->wheel[i]->killMe(); } Node::killMe(); } void Player::setSoftKill(bool _softKill, float _duration) { this->setTimeToLive(_duration); Node::setSoftKill(_softKill, _duration); for(int i=0;i<4;i++) { this->wheel[i]->setTimeToLive(_duration); this->wheel[i]->setSoftKill(_softKill, _duration); } this->schale->setTimeToLive(_duration); this->schale->setSoftKill(_softKill, _duration); this->wurm->setTimeToLive(_duration); this->wurm->setSoftKill(_softKill, _duration); for(int i=0;i<10;i++) { if(this->weaponList[i]) { this->weaponList[i]->setTimeToLive(_duration); this->weaponList[i]->setSoftKill(_softKill, _duration); } } } void Player::setTeam(int _team) { this->team = _team; } int Player::getTeam() { return this->team; } void Player::setAvatareFileName(std::string _avatar) { this->avatar = _avatar; } void Player::hitByFire() { this->fireHitCount++; if(this->iceHitCount>0) this->iceHitCount-=0.5f; } bool Player::isToasted() { if(this->fireHitCount>200) { this->fireHitCount = 0; return true; } return false; } void Player::hitByIce() { this->iceHitCount+=1; this->iceHitCount = min(100.0f, this->iceHitCount); } Vector Player::getTerrainHeight(Vector v, bool flying) { NxVec3 direction(0, -1, 0); NxRay ray(v.getNxVector(), direction); NxRaycastHit hit; Vector hv = v; // Get the closest shape NxU32 mask = 0; mask |= UserContactReport::COLGROUP_PLAYER; mask |= UserContactReport::COLGROUP_NOCOL; mask != mask; NxReal maxDist = (!flying) ? NX_MAX_F32 : 1.0f; NxShape* closestShape = this->myScene->pScene->raycastClosestShape(ray, NX_ALL_SHAPES, hit, mask, maxDist);//0xffffff); if (closestShape) { hv.y = hit.worldImpact.y; } else { hv.y = 0; if(flying) { hv.y = -10000; return hv; } } float h = ((GameScene*) this->myScene)->getTerrain()->getHeight(v.x, v.z); hv.y = (hv.y>=h) ? hv.y : h; return hv; } void Player::initWin() { //emitter starten this->winPe->restartEmitting(); } void Player::initLose() { //player hit //this->setPlayerHit(this->myPosition, SimpleBullet* bullet = (SimpleBullet*) ((GameScene*) this->myScene)->createNode(GameScene::NODE_SIMPLEBULLET); bullet->setBulletType(0); bullet->setImpactForce(5); bullet->setWeaponDirection(Vector(0, 1, 0)); this->setPlayerHit(this->myPosition, *bullet); }