piątek, 1 października 2010

[WPF 3D] Obracamy, przesuwamy, skalujemy? Kamerę (i nie tylko). [PL]

W poprzedniej części zacząłem pisać o przekształceniach i transformatach, w tym wpisie pokazane zostaną przykłady jak można wykorzystać transformaty do poruszania kamerą.
Okazuje się, że przekształcanie (w tym obracanie, przesuwanie) wszystkich elementów w scenie może być niewygodne i nieopłacalne (np. ze względów wydajnościowych), dlatego czasem lepiej będzie wykonać przekształcenie dla samej kamery.
Niniejszy wpis poza prezentacją różnych i niezależnych od konkretnego wykorzystania treści stanowi również opis pewnych zagadnień związanych z projektem Mesh Diagram 3D.Informacje dotyczące projektu oznaczone są etykietą MeshDiagram3D.
Użytkownik powinien mieć możliwość przesuwania, obracania i skalowania obiektów w scenie lub kamery, do osiągnięcia tego można wykorzystać następujące transformacje:
  • TranslateTransform3D – służy do przesuwania obiektu w przestrzeni trójwymiarowej, do jej utworzenia wykorzystujemy wektor w przestrzeni 3D lub podajemy wartości trzech przesunięć (offsetów) dla każdej osi układu współrzędnych.
  • RotateTransform3D – służy do wykonywania obrotu obiektem w scenie 3D. Przy jej tworzeniu przekujemy obiekt opisujący obrót (Rotation3D) oraz ew. środek obrotu. Przy konfigurowaniu obrotu najwygodniej posłużyć się klasą AxisAngleRotation3D, dla której obiektów można ustawić Vector3D, który wskazuje oś, dookoła której chcemy obracać oraz wartość kąta obrotu w stopniach.
  • ScaleTransform3D – służy do skalowania obiektu w scenie, utworzenia wykorzystujemy wektor w przestrzeni 3D opisujący skalowanie lub podajemy wartości trzech skal dla każdej osi układu współrzędnych.
Do interakcji z użytkownikiem można wykorzystać suwaki (Slider), które konfigurować będą wybrane transformacje. W celu osiągnięcia wspomnianej wcześniej funkcjonalności należy jeszcze wykorzystać złożenie transformacji (zapewniane poprzez wykorzystania Transform3DGroup).
Ostatecznie funkcja generująca odpowiednią transformację może wyglądać następująco:
private static Transform3DGroup PrepareTransform3D( double Offset_X, double Offset_Y, double Offset_Z, double Scale_X, double Scale_Y, double Scale_Z, double Rot_X, double Rot_Y, double Rot_Z )
{
  TranslateTransform3D MyTranslateTransform3D = new TranslateTransform3D( Offset_X, Offset_Y, Offset_Z ); //center point
  AxisAngleRotation3D AxisAngleRotator_rot_x = new AxisAngleRotation3D( new Vector3D( 1, 0, 0 ), Rot_X ); // setup rotation angle
  AxisAngleRotation3D AxisAngleRotator_rot_y = new AxisAngleRotation3D( new Vector3D( 0, 1, 0 ), Rot_Y ); // setup rotation angle
  AxisAngleRotation3D AxisAngleRotator_rot_z = new AxisAngleRotation3D( new Vector3D( 0, 0, 1 ), Rot_Z ); // setup rotation angle
  ScaleTransform3D ScaleTransform3D_zoom = new ScaleTransform3D( Scale_X, Scale_Y, Scale_Z );

  Transform3DGroup Transform3DGroup_transform = new Transform3DGroup();
  Transform3DGroup_transform.Children.Add( ScaleTransform3D_zoom );
  // the order of the following three is significant
  Transform3DGroup_transform.Children.Add( new RotateTransform3D( AxisAngleRotator_rot_y ) );
  Transform3DGroup_transform.Children.Add( new RotateTransform3D( AxisAngleRotator_rot_x ) );
  Transform3DGroup_transform.Children.Add( new RotateTransform3D( AxisAngleRotator_rot_z ) );

  Transform3DGroup_transform.Children.Add( MyTranslateTransform3D );
  return Transform3DGroup_transform;
}
Tak przygotowaną transformację przypisujemy do kamery:
Transform3DGroup MyTransform=PrepareTransform3D(0,0,0,0,0,0,0,0,0);
mainViewport.Camera.Transform = MyTransform;
W ten sposób kamerę (jak i inne obiekty) możemy dowolnie przekształcać (transformować).
Promuj

2 komentarze:

  1. Fajna funkcja, ogólnie kurs spoko :) Jednak dopiero się uczę, a chciałem napisać na podstawie tego funkcję, którą powoduje płynny ruch kamery po okręgu jak w 3ds maxie. Jednak musze przyznać, że mnie to przerosło. Pytanie do autora, jak to zrobić? :P

    OdpowiedzUsuń
    Odpowiedzi
    1. Nie zajmowałem się tym już dłuższy czas, ale wydaje mi się że wystarczyło by umieścić kamerę w pewnym punkcie, a później tylko ustawiać RotateTransform3D z kątem zmienianym w jakiejś pętli.

      Usuń

Posty powiązane / Related posts