Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[Irrlicht] Współrzędne przy rotacji

Ostatnio zmodyfikowano 2011-11-26 20:50
Autor Wiadomość
kampar
Temat założony przez niniejszego użytkownika
[Irrlicht] Współrzędne przy rotacji
» 2011-11-23 19:19:00
Witam , mam taki problem, że gdy obracam obiekt (getRotation()) o 90 stopni względem osi współrzędnej pionowej (drugą sprawą jest to, że nie wiem dlaczego u mnie jest to Y) to obiekt sprawia wrażenie jakby dwie osie poziome (X i Z) się na siebie nałożyły, tylko mają przeciwne zwroty. Efekt jest taki, że gdy obracam obiekt w osi X albo Z to obraca się w tej samej płaszczyźnie. Z kolei gdy zmieniam położenie obiektu, albo jest on obrócony o 0 lub 180 stopni(Y) to wszystko jest ok. Macie jakieś pomysły co może być przyczyną?
P-44601
waxx
» 2011-11-23 19:37:37
Dochodzi do zjawiska zwanego gimbal lockiem
http://en.wikipedia.org/wiki/Gimbal_lock

Dzieje się tak właśnie przy tego typu kątach używając macierzy Eulera. Spróbuj poobracać kwaternionami.
P-44602
kampar
Temat założony przez niniejszego użytkownika
» 2011-11-23 20:41:29
Macierzy, ani kwaternionów jeszcze niestety się nie uczyłem. Z tego co zrozumiałem to używając macierzy Eulera obracamy obiekt razem ze współrzędną, a korzystając z kwaternionów obracamy sam obiekt. Dobrze myślę?
P-44605
waxx
» 2011-11-23 21:22:01
Na warsztacie był o tym jakiś artykuł kiedyś. Poszukaj. Tu raczej chodzi o to, że kątami Eulera wykonujemy rotacje w pewnej kolejności (Yaw, Pitch, Roll), przez co własnie dwie osie mogą się nałożyć, jak jedną zmienie, gdy druga stoi. Poza tym kwaterniony można interpolować, więc tymbardziej warto się nimi zainteresować.
P-44610
kampar
Temat założony przez niniejszego użytkownika
» 2011-11-26 14:56:59
niestety dalej występuje gimbal lock

C/C++
#include <irrlicht.h>
#include <iostream>

using namespace irr;

using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;



class Klawisze
    : public IEventReceiver
{
public:
    virtual bool OnEvent( const SEvent & event )
    {
       
        if( event.EventType == irr::EET_KEY_INPUT_EVENT )
             KeyIsDown[ event.KeyInput.Key ] = event.KeyInput.PressedDown;
       
        return false;
    }
   
    virtual bool IsKeyDown( EKEY_CODE keyCode ) const
    {
        return KeyIsDown[ keyCode ];
    }
    Klawisze()
    {
        for( u32 i = 0; i < KEY_KEY_CODES_COUNT; ++i )
             KeyIsDown[ i ] = false;
       
    }
   
private:
   
    bool KeyIsDown[ KEY_KEY_CODES_COUNT ];
};


int main( int argc, char ** argv )
{
   
    Klawisze aktywne;
    IrrlichtDevice * device = createDevice( EDT_OPENGL, dimension2d < u32 >( 640, 480 ), 32, false, false, false, & aktywne );
   
    IVideoDriver * driver = device->getVideoDriver();
    irr::scene::ISceneManager * smgr = device->getSceneManager();
    IGUIEnvironment * guienv = device->getGUIEnvironment();
   
    smgr->addCameraSceneNode( 0, vector3df( 0, 30, - 40 ), vector3df( 0, 0, 0 ) );
    irr::scene::ISceneNode * pCube = smgr->addCubeSceneNode( 30.0f );
   
    irr::f32 degAngle = 0;
    irr::f32 radAngle = 0;
    irr::f32 angle = 0;
    irr::f32 wangle = 0;
   
   
    while( device->run() )
    {
       
       
        if( aktywne.IsKeyDown( KEY_KEY_A ) )
        {
            if( degAngle >= 90.0 && degAngle <= 91.0 )
            {
                degAngle += 180.0f;
            }
            else degAngle += 0.04f;
           
            printf( "%.2f: \n", degAngle );
        }
       
        if( aktywne.IsKeyDown( KEY_KEY_D ) )
        {
            if( degAngle >= 269.0 && degAngle <= 270.0 )
            {
                degAngle -= 180.0f;
            }
            else degAngle -= 0.04f;
           
            printf( "%.2f: \n", degAngle );
        }
       
       
        if( degAngle >= 360 ) degAngle -= 360;
        else if( degAngle < 0 ) degAngle += 360;
       
        if( aktywne.IsKeyDown( KEY_KEY_W ) )
        {
            angle += 0.04f;
        }
        if( aktywne.IsKeyDown( KEY_KEY_S ) )
        {
            angle -= 0.04f;
        }
       
        if( aktywne.IsKeyDown( KEY_KEY_Q ) )
        {
            wangle += 0.04f;
        }
        if( aktywne.IsKeyDown( KEY_KEY_E ) )
        {
            wangle -= 0.04f;
        }
       
       
        irr::core::quaternion q;
        radAngle = degAngle * PI / 180;
       
       
        q = q.set( wangle * PI / 180, radAngle, angle * PI / 180 );
        irr::core::vector3df rot;
        q.toEuler( rot );
       
       
       
        pCube->setRotation( rot * 360 / PI );
       
       
        driver->beginScene( true, true, SColor( 0, 200, 200, 200 ) );
       
        smgr->drawAll();
        guienv->drawAll();
       
        driver->endScene();
    }
   
    device->drop();
   
    return 0;
}
P-44741
waxx
» 2011-11-26 20:50:40
Ale ty nie masz z kwaterniona znów przejść na Eulera, a wyciągnąć macierz rotacji i ręcznie obrócić.

Poczytaj trochę o takiej matmie, bo w 3D bez tego ani rusz
http://www.flipcode.com/documents/matrfaq.html
P-44781
« 1 »
  Strona 1 z 1