OpenGL kamera quaternionnal

OpenGL kamera quaternionnal
2011-04-14T17:29:05+02:00
2011-04-15T18:52:24+02:00
2022-11-21T13:20:44+01:00
Istu7
Sziasztok

Már régóta küzdök egy OpenGL kamera megírásával, azonban nem azt a működést kapom, amit szeretnék.
A kiindulási alap, hogy áttanulmányoztam az ide vágó NeHe tutoriált, s a hasonló Google eredményeket, s ezek alapján indultam el.
Terveim szerint a kamera orientációját csak egy quaternionnal tárolnám. (ellentétben a NeHe két quaternionos megvalósításával). Ezen felül még tárolom a kamera targetét és pozicioját, egy-egy vektorban.

Első kérdésem, hogy jól látom-e, egy quaternion-nal tudom tárolni a kamera térbeli orientációját?

Első nehézségem ott akadt, mikor implementáltam a kamera SetPosition () fuggvenyet. Ezt ugy kepzeltem el, hogy ugy fog a kamera erre reagálni, hogy a poziciója elhelyeződik az új helyre, s az orientációja pedig úgy változik, hogy továbbra is a target legyen a nézet középpontjában. A kód igy néz ki:

void Camera::set_position (const glm::vec3& position) { if (m_position == position) return; glm::vec3 old_view (glm::normalize (m_target - m_position)); glm::vec3 new_view (glm::normalize (m_target - position)); float dot (glm::dot (new_view, old_view)); if (!math::equal (dot, 1.0f)) { // set new position and orientation glm::vec3 axis (glm::normalize (glm::cross (new_view, old_view))); float angle (glm::acos (dot)); m_orientation.from_rotation(axis, angle); glm::mat4 view; m_orientation.to_matrix (view); glm::mat4 translate_to_target (glm::translate (glm::mat4 (1.0f), -m_target)); glm::mat4 translate_from_target (glm::translate (glm::mat4 (1.0f), m_target)); glm::mat4 view_rot_around_target (translate_to_target * view * translate_from_target * view); glm::mat4 translate_to_pos (glm::translate (glm::mat4 (1.0f), -position)); m_view_matrix = view_rot_around_target * translate_to_pos; } else { // set new position, do not touch orientation glm::mat4 translate_to_pos (glm::translate (glm::mat4 (1.0f), -position)); m_view_matrix[3][0] = translate_to_pos[3][0]; m_view_matrix[3][1] = translate_to_pos[3][1]; m_view_matrix[3][2] = translate_to_pos[3][2]; } m_position = position; }

kezdeti ertekek ertekek:
m_position = [0.0, 0.0, 1.0]
m_target = [0.0, 0.0, 0.0]

Ha ezt a fuggvenyt meghivom az [1.0, 1.0, 1.0] vektorral, azt varnam, hogy a 0, 0, 0-ban levo 3 x,y,z egysegvektort latom a megadott pontbol.

De nem, mert helyette eltorzulva latom a 3 tengelyt.. a kamera nem abban a pozicioban van amire szamitottam.

Igy hasznalom ezt a fuggvenyt:

void Camera::load_transform (void) { glMultMatrixf (glm::value_ptr (m_view_matrix)); } ... init resz ... m_camera.set_position (glm::vec3 (1.0f, 1.0f, 1.0f)); ... draw resz ... glLoadIdentity (); [b]m_camera.load_transform ();[/b] m_grid_system.draw ();


Müködhet egyáltalán az elképzelésem? Ha nem, mi a baj vele? Ha igen, mi a hiba a kódban?

Előre is köszönöm a segitséget!
Üdv,
Istu
Mutasd a teljes hozzászólást!
Csatolt állomány
Itt is vagyok.
Az irányítás:
W - előre
S - hátra
Mouse mozgás a forgolódás
Induláskor camera módban vagyunk...
0 - Camera mód kiválasztása
1 - Első objektum kiválaszása

A Kamera gimballock mentes(remélem jól mondtam), a repülő teljesen szabad mozgású.
Tetszés szerint lehet alakítani hogy a repülő is csak a föld síkjában mozoghasson.

Szabad kérdezni...
Mutasd a teljes hozzászólást!
Csatolt állomány

  • Azt szeretném megkérdezni miért mindenki egzotikus megoldásokat akar használni kamerakezelésre(meg mozgásokra)??
    Az OpenGL mátrixokat használ és mindenre elegendő, miért törik az emberek a fejüket sinusokkal, cosinusokkal, meg quaternionokkal???
    Akkor csinálod szögekkel meg quaternionokkal ha épp kihívásra vágysz és meg akarod csinálni nemhagyományos módon is.
    Az OpenGL-be benne van a glLoadMatrix() glMultMatrix() függvények ami által mág csak meg sem kell írjunk egy darab mátrixműveletet sem.
    Egyébként ezzel a témával az OpenGL Redbook is foglalkozik.
    Mutasd a teljes hozzászólást!
  • Az, hogy mátrixokkal való szorzásnál mikor fog kamera mozgásra vonatkozni és mikor fog objektum mozgásra vontakozni a művelet csak attól függ hogy milyen sorrendbe végezzük a mátrixszorzásokat. Ezt leegyszerűsíted úgy, hogy létrehozol egy kamera mátrixot(4x4=16 elemű tömb) és ez tárolja a kamera poziciót. Deklarálsz egy másik 16 elemű float tömböt ez lessz az objektum poziciós mátrixxa. Ha kamera mozgás történik a kamera mátrixot glRotate, glTranslate-olgatod, ha pedig objektum mozgás történik akkor az objektum mátrixot glLoadMatrix()-olod es glRotate, gtTranslate-olod, csak a LÉNYEG hogy a végén a végső megjelenítési mátrix a kamera mátrix és az objektum mátrix szorzata. És kész vagyunk!
    És ha nem leszek munkába jön a hétvége, összedobok egy példaprogramot, ahol a kamera csak a "föld" szintje mentén mozoghat, az objektum viszont teljesen szabadon.
    Na jó belátom, a téma nem olyan egyszerű.
    Mutasd a teljes hozzászólást!
  • Szeva Locutos.

    Kössz a választ! Az ok amiert Quaternional probalkozom, hogy volt mar egy matrixos megvalositásom a problémára, de a jó öreg GimbalLock miatt használhatatlan volt.

    Ebben az esetben is lesz egy 4x4es mátrixom azt glMultMatrixf-elem minden egyes rajzolási lépésnél. A Quaternion-t a tetszőleges tengely menti elforgatáshoz használom, de a számolás végén, mint ahogy a példakód is mutatja, m_orientation.to_matrix (view) atkonvertálom mátrixá.
    Ez a view mátrix ugye az origó körül forgat. Ezért kezdem el tologatni a koordináta rendszert a target-be, majd vissza, hogy a forgatás ezen pont körül történjen..

    De ha mondasz nekem olyan, tisztán mátrix alapú megoldást, ami nem esik a GimbalLock csapdájába, örömmel veszem..

    Szivesen elküldöm a forráskódot is, ami használja ezt a megvalósitást, ha ugy jobban átlátod a problémát..

    Köszönöm, Istu
    Mutasd a teljes hozzászólást!
  • Hogy teszed bele a referencia tengelyt a kameramátrixba?

    Tipp Istu-nak:Konvertlás előtt normáld le a quaternion-t

    "De ha mondasz nekem olyan, tisztán mátrix alapú megoldást, ami nem esik a GimbalLock csapdájába, örömmel veszem.."
    hát ezaz!
    Mutasd a teljes hozzászólást!
  • Hali ChainsaW_GS

    Kiprobaltam amit mondasz, de nem segit. Aztan kiderult, hogy a a Quaternion mar amugy is egyseg hosszu volt..

    En valahol a targetbe es a targetbol valo ide-oda tologatasnal sejtem a problemat. De hiba probaltam, mondjuk a forgatas utan, a mar elforgatott koordinata rendszerben visszatolni az origot az eredeti helyere, nem lett jo az eredmeny.. :(

    Mondjuk, ebben a kodban is amit posztoltam, a
    glm::mat4 translate_from_target (glm::translate (glm::mat4 (1.0f), m_target));

    sorban a target, meg lokal koordinata rendszerben van. Ez ugy a a forgatas utan mar nem ugyan az a pont, mint a forgatas elott volt.. De hiaba szorozgattam a view matrixal, vagy annak az inverzevel, nem vezetett jo eredmenyre.. S ez a probalgatom.. programozas nem vezet sokra..

    Szeretnem megerteni mi a baj ezzel..

    Most vettem eszre, az else agban van egy nagy hiba, a translate_to_pos valtozot nem hasznalom semmire, de ez nem lenyeges a problema szempontjabol, mert a hibas eset nem ezen az agon fut.. ez az ag akkor fut le, mikor az uj pozicio a regi pozicio es a target altal meghatarozott egyenesre esik..
    Mutasd a teljes hozzászólást!
  • Nem referncia tengelyt kell tenni a mátrixba hanem lementjük a referencia tengely értékeket egy-egy float változóba és mindig visszaRotate-olgatunk úgy hogy ne legyen gimbal lock problémánk(szerintem így már sejtitek). Annakidején én is kicsit megizzadtam a problémán de megcsináltam. Fejből ne kérjétek vágjam fel, de míg utazom a vonaton a laptopon összeütök egy példakódot, és mire netre érek felteszem
    Mutasd a teljes hozzászólást!
  • Kivancsian varom! Jo utat
    Mutasd a teljes hozzászólást!
  • Itt is vagyok.
    Az irányítás:
    W - előre
    S - hátra
    Mouse mozgás a forgolódás
    Induláskor camera módban vagyunk...
    0 - Camera mód kiválasztása
    1 - Első objektum kiválaszása

    A Kamera gimballock mentes(remélem jól mondtam), a repülő teljesen szabad mozgású.
    Tetszés szerint lehet alakítani hogy a repülő is csak a föld síkjában mozoghasson.

    Szabad kérdezni...
    Mutasd a teljes hozzászólást!
    Csatolt állomány
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd