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ą? |
|
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. |
|
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ę? |
|
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ć. |
|
kampar Temat założony przez niniejszego użytkownika |
» 2011-11-26 14:56:59 niestety dalej występuje gimbal lock
#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; }
|
|
waxx |
» 2011-11-26 20:50:40 |
|
« 1 » |