8

Zaczynam na Molehill i mam wiele problemów z uchwyceniem Matrix3D. Mój pierwszy problem polega na zarządzaniu Matrix3D, który opisuje orientację jednego modelu.Jak połączyć rotacje X, Y i Z w lokalnej przestrzeni modelu (nie globalnej)?

Do tego celu używam Matrix3D.appendRotation(). Ale w zależności od kolejności, do której dołączam, otrzymuję inny wynik (oczywiście, ponieważ obracam się jeden po drugim w przestrzeni globalnej). Wiem, że jest to częsty problem, do którego doszłam z 3d modelowaniem oprogramowania. Ale tym razem muszę to programować. Tutaj potrzebuję pomocy.

Po pierwsze, w przypadku jakichkolwiek niejasności, tu jest problem na zdjęciach:

Krok 1: I renderowania modelu.

Start position

Etap 2a: obrócić ją na osi x. Wygląda poprawnie!

X-axis rotation

Etap 2b: obrócić ją na osi. Wygląda poprawnie!

Z-axis rotation

Więc ... jeśli obracają się na osi X i Z w modelu Chcę to:

desired XZ rotation

Ale sadface, otrzymuję to:

enter image description here

Mogę Zobacz problem. Załączam rotacje pojedynczo w przestrzeni globalnej. Muszę obracać się w lokalnej przestrzeni obiektu. Nie mam pojęcia, jak to zrobić lub czego powinienem szukać (terminologia itp.). Kod jest prosty (i źle):

modelLocalMatrix.identity(); 
modelLocalMatrix.appendRotation(modelZRot, Vector3D.Z_AXIS); 
modelLocalMatrix.appendRotation(modelXRot, Vector3D.X_AXIS); 
//eventually y-axis rotation as well... 
renderMatrix.append(modelLocalMatrix); 

ja domyślam się, że zamiast używać stałych osi Vector3D, chcę użyć trochę znormalizowany wektor a niektóre ... uh, rzecz ... zamiast modelZRot , modelXRot i ostatecznie modelYRot. Czy ktoś może mi powiedzieć, jakie jest najlepsze rozwiązanie do zastosowania powyższego rodzaju rotacji?

AKTUALIZACJA: Po spędzeniu dnia na "książkach" (aka KhanAcademy na YouTube) i rozpoczęciu tej prezentacji: The Mathematics of the 3d Rotation Matrix Natknąłem się na rodzaj metody "spojrzenia", która jest bardzo zbliżona do mojego pożądanego rozwiązania. Niestety, tylko 50% to rozumiem. Wciąż mam nadzieję, że ktoś może rzucić trochę światła na ten temat!

var angleOfRotation:Number = Math.PI/2; //90 degrees... 
var axisOfRotation:Vector3D = new Vector3D(0, 1, 0); //some point to look at... 
//normalize the vector! 
axisOfRotation.normalize(); 
var x:Number = axisOfRotation.x; 
var y:Number = axisOfRotation.y; 
var z:Number = axisOfRotation.z; 
var c:Number = Math.cos(angleOfRotation); 
var s:Number = Math.sin(angleOfRotation); 
var t:Number = 1 - c; 

//Graphics Gems (Glassner, Academic Press, 1990). 
modelLocalMatrix = new Matrix3D(new <Number>[ 
    t * (x * x) + c, t * x * y - s * z, t * x * z + s * y, 0, 
    t * x * y + s * z, t * (y * y) + c, t * y * z - s * x, 0, 
    t * x * z - s * y, t * y * z + s * x, t * (z * z) + c, 0, 
    0,   0,   0,   1 
]); 

Chodzi o to, wydaje się raczej niezgrabne. Zwłaszcza, że ​​kąt obrotu dla Vector3D powinien być czwartą (w) wartością. Co ważniejsze, Matrix3D wydaje się już mieć metodę lookAt(). Nie rozumiem jeszcze ... proszę, niech ktoś mnie uratuje od wielu godzin prób i błędów!

Odpowiedz

2

Ok, w zasadzie zorientowałem się, jak to zrobić. Jest DUŻO prostsze niż ja to robiłem. Pomógł również przejrzeć interfejs API Matrix3D (ma on niesamowite funkcje!).

pierwsze, kod źródłowy kiedyś obrócić mój model na swoich lokalnych osiach:

var raw:Vector.<Number> = modelLocalMatrix.rawData; 
var right:Vector3D = new Vector3D(raw[0], raw[1], raw[2]); 
var up:Vector3D = new Vector3D(raw[4], raw[5], raw[6]); 
var out:Vector3D = new Vector3D(raw[8], raw[9], raw[10]); 

modelLocalMatrix.appendRotation(modelXRot, right); 
modelLocalMatrix.appendRotation(modelYRot, up); 
modelLocalMatrix.appendRotation(modelZRot, out); 

„UP”, „prawo” i „out” znormalizowane wektory są omawiane w link w moim egzemplarzu stanowisko. Zasadniczo są to nachylenie, odchylenie i osi rolki modelu. Wystarczy powiedzieć, że podczas inicjalizacji obiektu, wektory te sĘ ... identyczne z Vector3D.X_AXIS, Y_AXIS i Z_AXIS. Wyodrębniłem je za pomocą właściwości Matrix3D.rawData, chociaż może istnieć lepszy sposób.

Teraz możesz obracać się wzdłuż dowolnej z tych osi, ale w momencie, gdy to zrobisz, orientacja pozostałych dwóch osi natychmiast się zmieni. To ma sens. Twój model się obrócił, a jego "prawo", "góra" i "przód" są teraz inne! Jeśli zaczniesz od obracania na "prawej" osi modelu (pamiętaj, że zaczyna się to tak samo jak globalna X_AXIS), a następnie chcesz przetasować model na jego oś "na zewnątrz", musisz pobrać ją z lokalnego modelu matryca. Oczywiście nie jest już taki sam jak globalny Z_AXIS. Zauważ, że nie nazywam Matrix3D.identity(). Gdybym to zrobił, wtedy osie mojego modelu zostałyby zresetowane! Jest to w porządku dla mojej pętli renderowania, chociaż musiałem zmienić nieco mój kod (i sposób myślenia), ponieważ odtworzyłem wszystkie matryce przed zastosowaniem transformacji i rotacji. Zauważ, że modelXRot, modelYRot i modelZRot zapisują wartość obrotu w stopniach.

Mam nadzieję, że to pomoże komuś. Nie mogę uwierzyć, że nie można było znaleźć tak powszechnego problemu z tak prostym rozwiązaniem. W każdym razie wydaje się, że robi to, co chcę.

Powiązane problemy