Итак, сейчас я пытаюсь работать над системой вертолета для игры. Проблема, которая у меня возникла, я хочу изменить гравитацию для вертолета, и только когда я использую / использую его, но сейчас все объекты, использующие PhysX, теряют гравитацию.
Вот функция, которую я использую. g_pPhysicsWorld->PhysXScene->setGravity(HeliGravity);
это то, что может быть причиной проблемы.
void obj_Vehicle::HelicopterPhysx() // controls of helicopter
{
if (isHelicopter == true)
{
const float fTimePassed = r3dGetFrameTime();
PxTransform pose = vd->vehicle->getRigidDynamicActor()->getGlobalPose();
r3dVector angles;
r3dPoint3D position(0,0,0);
PxVec3 HeliGravity(0,0,0);
if (HasDriver() && HSpeed > 70)
{
if (Keyboard->IsPressed(kbsRight)) // Rotate Left
{
if (!(Keyboard->IsPressed(kbsW) || Keyboard->IsPressed(kbsS)))
HelyX+=0.5f;
}
else if (Keyboard->IsPressed(kbsLeft)) // rotate Right
{
if (!(Keyboard->IsPressed(kbsW) || Keyboard->IsPressed(kbsS)))
HelyX-=0.5f;
}
if (Keyboard->IsPressed(kbsW) && distanceFromGround>=5) // move front
{
HeliGravity = PxVec3(0,-1.0,0);
if (HelyY<15.0f)
HelyY+=0.5f;
//HelyUp=-0.1f;
if (HelyFB>1 && FB>=0)
FB=HelyFB-=0.25f;
}
else {
if (FB >0 && HelyFB<20)
FB=HelyFB+=0.05f;
if (HelyY>0)
{
HelyY-=0.5f;
if (HelyY<0) HelyY = 0;
}
}
if (Keyboard->IsPressed(kbsS) && distanceFromGround>=5) // Move back
{
if (HelyY>-15.0f)
HelyY-=0.5f;
if (HelyFB>5 && FB<=0)
FB=abs(HelyFB-=0.5f)*-1;
}
else {
if (FB <0 && HelyFB<20)
FB=abs(HelyFB+=0.05f)*-1;
if (HelyY<0)
{
HelyY+=0.5f;
}
}
if (Keyboard->IsPressed(kbsD) && distanceFromGround>=10) // move Right
{
if (HelyZ>-30.0)
HelyZ-=0.5f;
if ((Keyboard->IsPressed(kbsW) || Keyboard->IsPressed(kbsS)))
{
HelyX+=0.5f;
}
else {
if (HelyLR>5 && LR>=0)
LR=HelyLR-=0.5f;
}
}
else {
if (LR >0 && HelyLR<20)
LR=HelyLR+=0.1f;
if (HelyZ<0)
{
HelyZ+=0.5f;
}
}
if (Keyboard->IsPressed(kbsA) && distanceFromGround>=10) // move Left
{
if (HelyZ<30.0)
HelyZ+=0.5f;
if ((Keyboard->IsPressed(kbsW) || Keyboard->IsPressed(kbsS)))
{
HelyX-=0.5f;
}
else {
if (HelyLR>5 && LR<=0)
LR=abs(HelyLR-=0.5f)*-1;
}
}
else {
if (LR <0 && HelyLR<20)
LR=abs(HelyLR+=0.1f)*-1;
if (HelyZ>0)
{
HelyZ-=0.5f;
if (HelyZ<0) HelyZ = 0;
}
}
if (Keyboard->IsPressed(kbsQ) && HSpeed > 70) // move up
{
//r3dOutToLog("###### distanceFromGround %f\n",distanceFromGround);
//if (distanceFromGround<100)
//HelyUp=0.1f;
HeliGravity = PxVec3(0,2,0); //m70b1jr gravity
}
else if (Keyboard->IsPressed(kbsZ)) // Move down
{
HeliGravity = PxVec3(0,-1,0);
//HelyUp=-0.1f;
}
}
else {
if (distanceFromGround>0)
{
if (HSpeed < 50 || !CheckFuel())
{
//r3dOutToLog("######## HSpeed: %f\n",HSpeed);
//Gravity = PxVec3(0,-9.81f,0);
if (HelyUp>0)
HelyUp=-0.1f;
}
}
}
pose.p.y+=HelyUp;
if (HelyFB>=20)
FB=0;
if (HelyLR>=20)
LR=0;
//r3dOutToLog("######## HelyFB: %f FB: %f\n",HelyFB,FB);
position = r3dPoint3D(pose.p.x,pose.p.y,pose.p.z) + (GetvForw() / FB) + (GetvRight() / LR);
if (HelyUp<0)
{
HelyUp+=0.001f;
}
else if (HelyUp>0)
{
HelyUp-=0.001f;
if (HelyUp<0) HelyUp = 0;
}
//g_pPhysicsWorld->PhysXScene->setGravity(HeliGravity); // m70 test
D3DXMATRIX RotateMatrix,RotateMatrix2,toOrigin,fromOrigin,boneTransform;
D3DXMatrixTranslation(&toOrigin, -GetPosition().x, -GetPosition().y, -GetPosition().z);
D3DXMatrixTranslation(&fromOrigin, pose.p.x, pose.p.y, pose.p.z);
D3DXMatrixRotationYawPitchRoll(&RotateMatrix,R3D_DEG2RAD(HelyX),R3D_DEG2RAD(HelyY),R3D_DEG2RAD(HelyZ));
D3DXMatrixMultiply(&boneTransform, &fromOrigin, &RotateMatrix);
D3DXMatrixMultiply(&boneTransform, &boneTransform, &toOrigin);
PxMat33 orientation(PxVec3(boneTransform._11, boneTransform._12, boneTransform._13),
PxVec3(boneTransform._21, boneTransform._22, boneTransform._23),
PxVec3(boneTransform._31, boneTransform._32, boneTransform._33));
pose.q = PxQuat(orientation);
/*D3DMATRIX m = GetRotationMatrix();*/
pose.p.x=position.x;//HelyFB;
pose.p.z=position.z;//HelyLR;
/*HelyLR=position.z;
HelyFB=position.x;*/
vd->vehicle->getRigidDynamicActor()->setGlobalPose(pose);
SetPosition(r3dPoint3D(position.x,pose.p.y,position.z)); //Another test
r3dPoint3D vel = GetVelocity();
vel.x *= pose.p.x;
vel.y *= pose.p.y;
vel.z *= pose.p.y;
if(vel.Length() < 0.001f) vel = r3dPoint3D(0, 0, 0);
SetVelocity(vel);
}
}
setGravity()
используется для установки глобальной гравитации сцены, которая влияет на всех ее актеров.
Если вы хотите «личную» гравитацию для актера, вы должны отключить глобальную гравитацию для этого актера:
PxActor::setActorFlag(PxActorFlag::eDISABLE_GRAVITY, false);
А затем добавьте свою собственную силу к актеру:
void PxRigidBody::addForce(const PxVec3& force, PxForceMode::Enum mode, bool autowake);
Обратите внимание, что addForce()
должен вызываться на каждом кадре обновления.
Других решений пока нет …