прикладное шанаство .. или исправляем rotate.Y->max в матрице
на разных форумах писал о своей ошибке
но нигде неотвечали ... падаваны млин ...
учите алгебру ... и на учитесь понимать людей ! :)
а теперь собсно
когда я переводил матрицу трансформации из PhysX -> Irrlicht
то получалось что когда угл поворота по Y был ~90 или ~270
то он переходил в = max .. тоесть в бесконечность
ету багу я знал давно
но ее исправление появилось только сегодня
суть исправления злого бага состоит в том чтобы насильно выдрать углы поворота из матрицы
и в процессе етого выдирания если cos(Y) -> min
то добавить доп проверку :
если tan(Y) < 0
то Y = 270.0f
если tan(Y) >= 0
то Y = 90.0f
чтобы дойти до етого пришлось помучатся :''((
но все получилось - и работает :-)
собсно вот весь код
Код:
void CCarPhysX::UpdateIrrCarBody()
{
//get transformation matrix 3x4 from PhysX car actor
NxMat34 pose = GetNxVehicle()->getActor()->getGlobalPose();
//------- Global Car Actor Transformation Matrix
irr::core::matrix4 irrMat;
pose.M.getColumnMajorStride4(&irrMat.M[0]);
pose.t.get(&irrMat.M[12]);
irrMat.M[3] = irrMat.M[7] = irrMat.M[11] = 0.0f;
irrMat.M[15] = 1.0f;
//--------------------------
//------- Local Position Matrix
irr::core::matrix4 irrMat2;
irrMat2.setRotationDegrees(irr::core::vector3df(0,-90.0f,0));
irrMat2.setTranslation(irr::core::vector3df(0,-1.3f,0));
irrMat*=irrMat2;
//--------------------------
//------ Corect angles
const irr::core::matrix4 &mat = irrMat;
irr::f64 Y = -asin(mat(2,0));
irr::f64 C = cos(Y);
irr::f64 C2 = tan(Y);
Y *= irr::core::GRAD_PI;
irr::f64 rotx, roty, X, Z;
if (fabs(C)>0.0005f)
{
rotx = mat(2,2) / C;
roty = mat(2,1) / C;
X = atan2( roty, rotx ) * irr::core::GRAD_PI;
rotx = mat(0,0) / C;
roty = mat(1,0) / C;
Z = atan2( roty, rotx ) * irr::core::GRAD_PI;
}
else
{
//------ (Y->max) Angle Corection Mehanizm
if (C2 < 0)
Y = 270.0f;
else
Y = 90.0f;
//-----------------
X = 0.0f;
rotx = mat(1,1);
roty = -mat(0,1);
Z = atan2( roty, rotx ) * (irr::f32)irr::core::GRAD_PI;
}
//corect angles to 2 PI circle system
if (X < 0.0) X += 360.0;
if (Y < 0.0) Y += 360.0;
if (Z < 0.0) Z += 360.0;
//set corect angles
irrMat.setRotationDegrees (irr::core::vector3df((irr::f32)X,(irr::f32)Y,(irr::f32)Z));
//set car node position/rotation
car_node->setPosition(irrMat.getTranslation());
car_node->setRotation(irrMat.getRotationDegrees());
//update car node transformation matrix
car_node->updateAbsolutePosition();
}
ps. ненавижу матричные операции ...
но куда без них ! :(
сними удобнее, сними геморнее
|