Serwer WWW z elementami grafiki 3D – praktyczne wykorzystanie pakietów Node.js oraz Three.js w systemach wbudowanych (część 2)

Node.js – rozbudowa interfejsu o proste elementy grafiki 3D (Three.js)

Na obecnym etapie realizacji projektu przygotowane zostały już wszystkie elementy składowe. W poprzedniej części artykułu omówiono back-end w postaci serwera WWW ze skryptu main.js, którego zadaniem był odczyt danych z procesu potomnego gyro-i2c oraz przesłanie danych za pomocą socket.io do warstwy front-end – interfejsu graficznego w postaci strony index.html. W ostatnim podrozdziale artykułu rozbudujemy interfejs graficzny aplikacji o prostą grafikę 3D w postaci sześciennej kostki, odwzorowującej ruch podłączonego modułu żyroskopu.
Do realizacji operacji graficznych wykorzystamy bibliotekę Three.js, która to natomiast korzysta z API WebGL – oficjalnego rozszerzenia możliwości języka JavaScript o interfejs grafiki 3D. Bezpośrednie wykorzystanie interfejsu WebGL jest dość uciążliwe, choćby ze względu na dużą liczbę operacji niskiego poziomu, jakie spoczywają na programiście – definicja wierzchołków, buforów, macierzy transformacji, operacje związane z wyświetlaniem sceny, obsługa shaderów, oświetlenia, modeli, kamer i wiele innych. W bibliotece Three.js scena budowana jest z obiektów (sama scena jest również obiektem w którym umieszczamy inne obiekty). Do podstawowych obiektów możemy zaliczyć: figury geometryczne (biblioteka posiada zdefiniowane kilka gotowych do użycia obiektów takich jak sfera czy sześcian), materiały przypisywane do figur geometrycznym (określające m.in. ich kolor i fizykę odbijania światła), źródła światła oraz obserwatora sceny (czyli „kamerę”, która obserwuje scenę w określonym położeniu).

Ponieważ kod odpowiedzialny za animację 3D jest wykonywany przez przeglądarkę po stronie komputera użytkownika, należy upewnić się, że wybrana przez nas przeglądarka internetowa wspiera API WebGL v1.

Rozbudowę aplikacji rozpoczynamy od pobrania kodu biblioteki Three.js (plik three.min.js) do katalogu w którym umieszczono skrypt main.js oraz stronę index.html (pełny kod źródłowy skryptu main.js oraz strony index.html został przedstawiony na listingu 6 i listingu 9 w pierwszej części artykułu):

Edycję pliku index.html rozpoczynamy od zdefiniowania w sekcji head „płótna” canvas (o wymiarach 500x500px oraz identyfikatorze mycanvas), w którym będzie renderowana docelowa animacja:

Następnie w sekcji head dołączamy bibliotekę Three.js:

W dalszej części skryptu definiujemy zmienne w których będziemy przechowywać wyniki pomiarów w osi x, y, z oraz informacje o tworzonej scenie i dołączonych do niej obiektach:

Następnie implementujemy funkcję init(), której zadaniem jest zbudowanie sceny z określonych obiektów – listing 5.

Listing 5. Budowanie sceny z wykorzystaniem biblioteki Three.js

W pierwszej linii kodu funkcji init() tworzymy scenę, do której będziemy dołączali kolejno definiowane obiekty (kamerę, figurę geometryczną oraz materiał dla tej figury):

W następnym kroku tworzymy obiekt kamery określając kąt jej widzenia (70 stopni), proporcje kadru, zakresy widzenia: bliski i daleki, a także jej umiejscowienie:

Korzystając ze zdefiniowanych w bibliotece Three.js kształtów, tworzymy obiekt reprezentujący sześcian (BoxGeometry):

oraz obiekt stanowiący „materiał” z jakiego wykony jest nasz sześcian (decyduje on m.in. o kolorze obiektu i sposobie rozpraszania światła) – wykorzystamy tutaj predefiniowany materiał MeshNormalMaterial:

Z połączenia figury z materiałem możemy utworzyć obiekt klasy Mesh, który dodajemy do tworzonej sceny:

W ostatnich liniach funkcji init(), określamy rozmiar i identyfikator powierzchni (mycanvas) na której będzie renderowana animacja:

Na listingu 6 przedstawiono kod funkcji animate(), której zadaniem jest wykonanie obrotu obiektu, zgodnie z kątem obrotu zapisanym w zmiennych x, y, z:

Listing 6. Kod funkcji wykonującej obrót obiektu

Pełna zawartość pliku index.html została przedstawiona na listingu 7.

Listing 7. Pełny kod źródłowy strony index.html po dodaniu elementów grafiki 3D

Niewielkiej modyfikacji wymaga również sam kod serwera main.js. Dotychczas serwer na żądnie klienta udostępniał wyłącznie plik index.html. W aktualnie formie, przy ładowaniu strony głównej, klient zażąda również pliku three.min.js – serwer powinien to żądanie obsłużyć i dostarczyć klientowi wymaganą bibliotekę – listing 8.

Po skopiowaniu do katalogu /tmp skompilowanej wersji kodu gyro-i2c z listingu 4, oraz ponownym skryptu main.js:

uruchomiony na komputerze jednopłytkowym serwer WWW prezentuje dane pomiarowe w postaci animowanej kostki 3D, jak przedstawiono to na Rysunku 4.

Rys. 4. Prezentacja danych odczytanych z żyroskopu w postaci animacji 3D

Łukasz Skalski

contact@lukasz-skalski.com

O autorze