poniedziałek, 30 marca 2009

Napisy przestrzenne (WPF 3D), a ich wektory położenia (przykłady w języku C#)

Chciałbym zwrócić uwagę na jeszcze jedną sprawę. Istotne są też wektory które wyznaczają płaszczyznę na której umieszczany jest napis (wektory vectorUp i vectorOver w przedstawionym wcześniej przykładzie).Jeżeli napis umieszczany jest na pewnym obiekcie należącym do sceny, wtedy wyznaczenie odpowiednich wektorów jest proste (ew. może się okazać konieczność ich normalizacji). Trudniejsze jest natomiast dobranie odpowiednich wektorów, gdy napisy mają służyć do opisu sceny i mają się pojawiać na powierzchni wyznaczanej przez płaszczyznę która jest prostopadła do kierunku patrzenia. W tym przypadku należy wybrać takie wektory, które będą wzajemnie do siebie prostopadłe oraz prostopadłe do kierunku patrzenia. Do wyznaczenia takich wektorów należy użyć własności iloczynu skalarnego, którego wartość wynosi 0 jeżeli wektory są prostopadłe.

Funkcja wyznaczająca takie wektory może mieć postać:

void UpdateViewToLookDirection(Vector3D LookDirection)

{

Vector3D look = LookDirection;

look.Normalize();

TextVectorOver = new Vector3D(-look.Y, look.X, 0);

TextVectorUp = new Vector3D(-look.Z * look.X, -look.Z * look.Y, look.Y * look.Y + look.X * look.X);

TextVectorOver.Normalize();

TextVectorUp.Normalize();

}

(przedstawione tutaj powyżej rozwiązanie nie jest może optymalne, ale na pewno poprawia czytelność napisów, nie będąc również skomplikowane w implementacji - jeśli ktoś ma lepszy pomysł chętnie poznam)

Funkcję tą należy wywołać każdorazowo przy zmianie kierunku patrzenia. Kierunek patrzenia można odczytać z używanego Viewport'u 3D:

PerspectiveCamera camera = (PerspectiveCamera)mainViewport.Camera;

Vector3D newlookdirection = Panel3DMath.Transform3DVector(camera.Transform,camera.LookDirection);

W przykładowym kodzie wyżej pokazany jest jeszcze sposób transformowania wektora patrzenia, w oparciu o transformatę wykorzystaną aktualnie do obracania kamery. Funkcja Transform3DVector powinna mieć natomiast postać:

public static Vector3D Transform3DVector(Transform3D transform, Vector3D vector)

{

Point3D input = new Point3D(vector.X, vector.Y, vector.Z);

Point3D output;

if (transform.TryTransform(input, out output))

{

return new Vector3D(output.X, output.Y, output.Z);

}

return vector;

}

(To tylko jedna z części artykułu, przeczytaj pozostałe: 1, 2, 3, 4, 5, 6, 7)

2 komentarze:

Posty powiązane / Related posts