Styl OpenGL "Magic" 

Agata Firlejczyk

Środowisko Framsticks pozwala zobrazować świat wirtualny w sposób trójwymiarowy. Obecnie jest już zdefiniowanych kilka stylów takiej wizualizacji. Przed rozpoczęciem jakichkolwiek prac nad nowym stylem warto zapoznać się ze skryptami dla wspomnianych wcześniej styli (jaka funkcja za co odpowiada, jakie rozszerzenia modeli są obsługiwane). Warto przeczytać również jak stworzyłem Spooksticks oraz dokumentację nt. tworzenia stylów skryptowych i znaczenia nazw funkcji. Ważne jest, aby modele zostaly utworzone w odpowiedniej skali: rozmiar świata może mieć różną wielkość, jednak domyślnie jest ona ustawiona na 20px, a długość elementu joint – na 1px. Podczas tworzenia poszczególnych modeli elementów świata i stworzeń warto mieć na uwadzę te wielkości. Do projektowania nowych modeli korzystałam głównie z programu AC3D, który posiada prosty i intuicyjny interfejs.

Tworzenie nowego stylu

Jak wspomniałam, można zamodelować wiele różnych elementów wirtualnego świata. Jednym z nich są creatures. Dla każdego stworzenia można zdefiniować następujące części: joint, neuro, part. Można również zmieniać właściwości środowiska – granice, rozmiar świata, czy też jego typ (flat, blocks, height field).

Jeśli zapoznaliśmy się chociaż częściowo z dostępnymi stylami, możemy zauważyć, że większa część kodu powtarza się we wszystkich skryptach – występuje oczywiście pewna różnica przy wyświetlaniu określonych elementów. Przybliżę teraz parę istotnych funkcji służących do modyfikacji wyświetlanego stylu:

  •  default_part_build

    Funkcja odpowiedzialna za styl wyświetlania elementów part. Jest to element odpowiedzialny za łączenie elementów joint. W moim stylu nie zdefiniowałam modelu dla tego elementu. Oczywiście styl można w prosty sposób zmodyfikować – stworzyć własny model, a następnie zmienić kod zawarty w tej funkcji na:
    loadAndAddAsTransformNode(”nazwaModeluDlaPart”). W ten sposób wczytamy model o podanej przez nas nazwie.

  •  default_joint_build

    Funkcja odpowiedzialna za wyświetlanie elementu joint. W kodzie tej funkcji wywoływana jest funkcja loadAndAddAsTransformNode(”joint.3ds”), gdzie joint.3ds jest nazwą modelu 3D, stworzoną dla tego elementu. Jego wygląd możemy zobaczyć na rysunku 1.


    Rysunek 1: Joint

  •  default_neuro_build

    Funkcja odpowiedzialna za wyświetlanie neuronów. Jak wiemy, istnieją różne klasy neuronów. Stworzyłam osobne modele dla niektórych z nich: G, S, T, bend, @. Przy wyświetlaniu pozostałych typów neuronów korzystam z tego samego modelu o nazwie neuro.3ds. Jaki model zostanie wyświetlony zależy od klasy neuronu – właściwość n.class. Tak jak poprzednio, wystarczy tylko w odpowiednim miejscu zmienić nazwy modeli na własne, i już neurony mogą być wyświetlane w inny sposób. Na kolejnych rysunkach: 2(a), 2(b), 2(c), 2(d), 2(e), 2(f) możemy zobaczyć wygląd poszczególnych neuronów.

    (a) Neuro G
    (b) Neuro S
    (c) Neuro T
    (d) Neuro twist
    (e) Neuro
    (f) Neuro bend
    Rysunek 2: Neurony

  •  food_part_build

    Funkcja odpowiedzialna za wczytanie modelu dla elementu food. W moim przypadku jest to kula – rysunek 3.


    Rysunek 3: Food

  •  manipulator_part_build

    W tej funkcji wczytywany jest model manipulatora służący do przemieszczania elementów. Tutaj wykorzystałam już stworzony wcześniej model we Framsticku – zmieniłam jedynie teksturę modelu – rysunek 4.


    Rysunek 4: Manipulator

  •  world_build

    W tej funkcji została zdefiniowana tekstura świata, w moim przypadku niebo z gwiazdkami: 5(a). Możemy również w tej funkcji wczytać model podłoża – element, po którym poruszają się stworzenia. W moim przypadku jest to kapelusz – rys. 5(b).

    (a) Tekstura otaczającego świata
    (b) Kapelusz
    Rysunek 5: Elementy świata

    W sposobie wyświetlania pozostałych typów świata (block oraz field) zostały odpowiednio zmienione tylko wczytywane tekstury. Wystarczy odnaleźć funkcje buildBlockWorld() oraz buildSmoothWorld i zmienić nazwę tekstury w części Material.texture(”nazwaPlikuTekstury”).

  • Granice

    Za wyświetlanie różnych typów granic odpowiada funkcja buildWorldBoundary(). Typ granicy możemy odczytać z pola World.wrldbnd, które może mieć jedną z trzech wartości: 0, 1 lub 2. Zdefiniowane są zatem trzy typy granic: 0 – flat (brak granicy), 1 – fence: rysunek 6(a) oraz 2 – teleport: rysunek 6(b). Modele dla granic zawierają jedynie pojedyńczy element z jakiego jest zbudowana granica – stworzenie całego ogrodzenia jest zdefiniowane w skrypcie. Model jest odpowiednio kilka razy powielany oraz obracany.

    (a) Fence
    (b) Teleport
    Rysunek 6: Elementy granic

W czasie tworzenia nowego stylu można skupić się na konstrukcji modeli trójwymiarowych, gdyż duża część kodu odpowiedzialna za prawidłowe wyświetlanie stylu jest już zawarta w istniejących skryptach.

Styl “Magic”

Stworzony przeze mnie styl posiada nazwę Magic. Elementy joint mają imitować różdżki. Wszystkie stworzenie poruszają się po kapeluszu magika, a wokół otaczają je magiczne gwiazdki. Na poniższych rysunkach przedstawiono jak wygląda świat po złożeniu ze sobą wszystkich pokazanych wcześniej elementów.