forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   C++ (http://forum.boolean.name/forumdisplay.php?f=22)
-   -   прикладное шанаство .. или исправляем rotate.Y->max в матрице (http://forum.boolean.name/showthread.php?t=1974)

jimon 22.11.2006 22:44

прикладное шанаство .. или исправляем 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. ненавижу матричные операции ...
но куда без них ! :(
сними удобнее, сними геморнее


Часовой пояс GMT +4, время: 07:38.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot