VRML/X3D jako język zapisu geometrii konstrukcji i nie tylko
Transkrypt
VRML/X3D jako język zapisu geometrii konstrukcji i nie tylko
Grafika komputerowa VRLM – Virtual Reality Modelling Language Dr inż. Hojny Marcin pawilon B5/p.406 tel. (+48)12 617 46 37 e-mail: [email protected] Wydział Inżynierii Metali i Informatyki Przemysłowej 1 VRML/X3D jako język zapisu geometrii konstrukcji i nie tylko... http://www.web3d.org/ 2 Wirtualna instalacja przemysłowa 3 1 Wirtualna instalacja przemysłowa 4 Wirtualna instalacja przemysłowa 5 Wirtualna instalacja przemysłowa 6 2 Wirtualna instalacja przemysłowa 7 Co na początek? Przeglądarka WWW z zainstalowaną „wtyczką” do interpretacji języka VRML, np. CORTONA VRML CLIENT firmy Parallel Graphics. Dowolny edytor tekstu np. Notatnik. Każdy plik VRML-a/X3D zaczynamy od lini #VRML V2.0 utf8 / #X3D V3.0 utf8 która jest obowiązkowa i zapisujemy z rozszerzeniem *.wrl/*.x3dv; Rozszerzenie pliku Typ *.x3dv model/x3d+vrml *.x3d model/x3d+xml *.wrl model/vrml PRZYKŁAD 8 1/2 Co na początek? Przykładowy szkielet strony WWW z implementacją pliku VRML-a <HTML> <BODY> <CENTER><EMBED SRC=„nazwa.wrl"></CENTER> </BODY> </HTML> 9 2/2 3 VRML - wstęp Elementy składowe świata VRML: Węzły Węzły grupujące – traktujemy pojedynczy obiekt Węzły samodzielne je jako Węzły grupujące definiowane są w polu węzła grupującego o nazwie children. Niektóre z węzłów grupujących mają możliwość kontroli nad tym, które z jego „dzieci" ma być aktualnie ukazane na scenie. Węzły samodzielne nie mogą mieć „dzieci". Zawierają one informacje na temat kształtów obiektów, świateł, zdefiniowanych na stałe punktów patrzenia na wykreowany świat (viewpoints), dźwięków, skryptów, czujników, interpolatorów i innych węzłów, które przekazują informacje do przeglądarki. 10 1/4 VRML - wstęp Węzeł składa się: Nazwy typu węzła, np.: Cube, Cone, itd… Parametrów, które odróżniają od siebie węzły tego samego typu, np.: każda kula opisana przez węzeł Sphere może mieć inny promień, kąt padania światła, kolor, lokalizację. Parametry te nazywamy polami. W węźle może być kilka pól lub może ich nie być wcale. Każdy węzeł definiuje typ, nazwę i wartości domyślne każdego z pól. Wartość domyślna danego pola jest uaktywniana wtedy, gdy dane pole w ogóle nie jest w danym węźle wyspecyfikowane. 11 2/4 VRML - wstęp W węzłach można zdefiniować zdarzenia, o których informacja może być przez węzeł wysyłana lub przyjmowana. Zdarzenia są przyjmowane przez węzeł za pomocą przedrostka set_, np.: set_color. Natomiast wysyłanie informacji o zdarzeniach realizujemy za pomocą końcówki _changed, np.: color_changed. Zdarzenia, które węzeł może przyjąć mają etykietę eventIn, natomiast zdarzenia, które mogą zostać przez węzeł wysłane, mają etykietę eventOut. Aby ułatwić wyspecyfikowanie zdarzeń przyjmowanych i wysyłanych w węźle, wprowadzone zostało polecenie exposedField, które łączy oba pola set_ eventIn i _changed eventOut. exposedField zdarzenie pełni taką samą funkcję co: eventIn set_zdarzenie eventOut zdarzenie_changed 12 3/4 4 VRML - wstęp Możemy wyspecyfikować dwa sposoby zapisu właściwości węzłów: Interfejs użytkownika który zawiera definicję pól, zdarzeń, nazw, typów i wartości domyślnych danego węzła. Składnia węzła w pliku źródłowym, zawiera on nazwę węzła i pola wraz z ich wartościami, które będziemy chcieli na danej scenie zdefiniować. Składnia węzła w pliku zawiera się w definicji interfejsu użytkownika. 13 4/4 Tworzenie prostych obiektów i grupowanie Proste obiekty definiujemy wykorzystując węzeł o nazwie Shape. Interfejs użytkownika tego węzła wygląda następująco: Shape { exposedField SFNode appearance NULL exposedField SFNode geometry NULL } Węzeł Shape ma dwa pola appearance i geometry. Pole appearance jest typu SFNode co oznacza, że może ono zawierać definicję jednego węzła. W tym przypadku będzie to węzeł Appearance. Pole geometry może zawierać jeden węzeł z grupy Geometry np.: Box, Cone, Sphare,Text, PointSet. 14 1/3 Tworzenie prostych obiektów i grupowanie #VRML V2.0 utf8 Shape { appearance Appearance { material Material { } } geometry Text { string [ "Systemy pracy", "wspolbieznej" ] fontStyle FontStyle { spacing 2.0 } } } PRZYKŁAD 15 2/3 5 Tworzenie prostych obiektów i grupowanie #VRML V2.0 utf8 Shape { appearance NULL geometry Box { size 3 3 3 } } PRZYKŁAD 16 3/3 Przemieszczanie obiektów – węzeł Transform Interfejs węzła Transform (węzeł grupujący): Transform { eventIn MFNode addChildren eventIn MFNode removeChildren exposedField SFVec3f center 000 exposedField MFNode children [] exposedField SFRotation rotation 0010 exposedField SFVec3f scale 111 exposedField SFRotation scaleOrientation 0 0 1 0 exposedField SFVec3f translation 000 field SFVec3f bboxCenter 000 field SFVec3f bboxSize -1 -1 -1 } 17 1/4 Przemieszczanie obiektów – węzeł Transform Obiekty, które mają ulec przekształceniom umieszczane są w polu children węzła grupującego. Każde zastosowanie węzła nowego układu współrzędnych. Transform powoduje utworzenie Pole center określa położenie środka układu współrzędnych w stosunku do lokalnego układu współrzędnych, czyli punktu (0,0,0). Pole to jest typu SFVec3f . Typ SFVec3f opisuje pojedynczy wektor trójwymiarowy, a typ MFVec3f może zawierać dowolnie wiele definicji takich wektorów. Wektory trójwymiarowe przedstawiane są za pomocą trzech liczb zmiennoprzecinkowych np.: [ 0 0 2, 0.7 0.2 1, 2 2 2.6 ] opisuje wektory [0,0,2], [0.7,0.2,1], [2,2,2.6]. 18 2/4 6 Przemieszczanie obiektów – węzeł Transform W polu rotation możemy zdefiniować obrót obiektu w układzie współrzędnym. Jest to pole typu SFRotation. SFRotation zawiera definicję jednego dowolnego obrotu, a typ MFRotation dowolną liczbę. Wartości pól lub zdarzeń typów SF/MFRotation zapisujemy jako cztery liczby zmiennoprzecinkowe oddzielone spacjami. Pierwsze trzy liczby wskazują, wokół której osi następuje obrót, czwarta z nich kąt w radianach o jaki chcemy obrócić obiekt. Np.: obrót wokół osi Y o kąt 180 stopni: przykładRotation 0.0 1.0 0.0 3.141592265 Pole scale o typie SFVec3f określa skalowanie utworzonego przez nas układu współrzędnych. Pole scaleOrientation odpowiada za obrót układu współrzędnych przed skalowaniem w celu określenia kierunku skalowania. 19 3/4 Przemieszczanie obiektów – węzeł Transform Pole translation definiuje przesunięcie danego obiektu względem środka układu współrzędnych utworzonego przez zastosowanie węzła Transform. #VRML V2.0 utf8 Transform { rotation 1 0 0 0.5 translation 0 0 -6 children [ Shape { appearance NULL geometry Box { size 5 5 5 } } ] } PRZYKŁAD 20 4/4 Kolorowanie i teksturowanie obiektów – węzeł Appearance Charakterystykę wizualną obiektów definiuje się przy użyciu węzła Appearance. Appearance { exposedField SFNode material NULL exposedField SFNode texture NULL exposedField SFNode textureTransform NULL } 21 1/12 7 Kolorowanie i teksturowanie obiektów – węzeł Appearance Pole material może zawierać definicję węzła Material. Material { exposedField SFFloat ambientIntensity 0.2 exposedField SFColor diffuseColor 0.8 0.8 0.8 exposedField SFColor emissiveColor 000 exposedField SFFloat shininess 0.2 exposedField SFColor specularColor 000 exposedField SFFloat transparency 0 } Pola węzła Material określają kolor obiektu przez nadanie odpowiednich wartości refleksom świetlnym, które powstają w wyniku odbicia się od danego obiektu. 22 2/12 Kolorowanie i teksturowanie obiektów – węzeł Appearance Pole ambientIntensity typu SFFloat określa intensywność światła na tej części obiektu, który nie jest bezpośrednio oświetlony, a jej kolor zależy od wartości w polu diffuseColor. Pole diffuseColor typu SFColor określa kolor obiektu w miejscach gdzie światło pada na niego bezpośrednio. Typ SFColor definiuje kolor w standardzie RGB w którym kolor jest zapisywany jako trzy liczby zmiennoprzecinkowe reprezentujące składowe koloru czerwonego, zielonego i niebieskiego. Wartość każdego z tych kolorów zawiera się w przedziale od 0.0 do 1.0. Typ MFColor może zawierać dowolną liczbę zdefiniowanych kolorów w standardzie RGB, np.: [ 1 0 0, 0 1 1, 1 1 0 ] 23 3/12 Kolorowanie i teksturowanie obiektów – węzeł Appearance Pole emissiveColor definiuje kolor jaki emituje dany obiekt (np.: w nocy). Pola specularColor i shininess odpowiadają za kolor i siłę światła odbitego od danego obiektu. transparency definiuje stopień Pole przezroczystości obiektu. Wartości w tym polu mogą zawierać się między 0.0 czyli nie przeźroczysty, a 1.0 - przeźroczysty. 4/12 24 8 Kolorowanie i teksturowanie obiektów – węzeł Appearance Pole texture węzła Appearance może definicję jednego z następujących węzłów. zawierać ImageTexture { exposedField MFString url [] field SFBool repeatS TRUE field SFBool repeatT TRUE } Aby nałożyć teksturę na obiekt w polu url wpisujemy ścieżkę dostępu do pliku graficznego (dopuszczalne formaty: GIF, JPEG, PNG, CGM). 25 5/12 Kolorowanie i teksturowanie obiektów – węzeł Appearance MovieTexture { exposedField SFBool loop FALSE exposedField SFFloat speed 1.0 exposedField SFTime startTime 0 exposedField SFTime stopTime 0 exposedField MFString url [] field SFBool repeatS TRUE field SFBool repeatT TRUE eventOut SFTime duration_changed eventOut SFBool isActive } Wpisanie w pole url ścieżki dostępu do pliku filmowego formatu MPEG, oraz określenie innych pól tego węzła dotyczących m.in. czasu startu i zatrzymania filmu, spowoduje nałożenie na obiekt tego filmu jako tekstury. 26 6/12 Kolorowanie i teksturowanie obiektów – węzeł Appearance PixelTexture { exposedField SFImage image 000 field SFBool repeatS TRUE field SFBool repeatT TRUE } Węzeł ten zawiera pole image typu SFImage gdzie definiujemy wygląd pikseli, które pokryją powierzchnię naszego obiektu. 7/12 27 9 Kolorowanie i teksturowanie obiektów – węzeł Appearance Pole lub zdarzenie o typie SFImage definiuje pojedynczy, nieskompresowany dwuwymiarowy obraz. Pola i zdarzenia typu SFImage zawierają trzy liczby całkowite odpowiadające kolejno szerokości, wysokości i składowym (liczba bajtów przypadających na jeden piksel) obrazu. Następnie występuje wysokość*szerokość liczb szesnastkowych reprezentujące poszczególne piksele. Wszystkie wymienione elementy definicji obrazu przedzielone są spacjami, np.: 1 2 1 0xFF 0x00 Powyższy przykład definiuje obraz o szerokości jednego piksela, wysokości dwóch pikseli oraz składowej o wartości 1 (1 bajt na piksel; co oznacza, że jest to obraz monochromatyczny), gdzie dolny piksel jest biały, a górny jest czarny. 28 8/12 Kolorowanie i teksturowanie obiektów – węzeł Appearance Pole textureTransform węzła Appearance może zawierać definicję węzła TextureTransform. TextureTransform { exposedField SFVec2f center 00 exposedField SFFloat rotation 0 exposedField SFVec2f scale 11 exposedField SFVec2f translation 0 0 } Węzeł TextureTransform definiuje dwuwymiarowe przekształcenie tekstury na obiekcie. 29 9/12 Kolorowanie i teksturowanie obiektów – węzeł Appearance Pole center określa środek dwuwymiarowego układu współrzędnych, względem którego będą odbywać się operacje obrotu, skalowania i przemieszczania tekstury. Operacje te definiujemy odpowiednio w polach rotation, scale i translation. Operujemy na dwuwymiarowym układzie współrzędnych, stąd zmiana typu pól centrowania, skalowania i przemieszczania na SFVec2f. Pola i zdarzenia typu SFVec2f definiują dwuwymiarowy wektor, a pola i zdarzenia typu MFVec2f mogą zawierać dowolną liczbę takich wektorów. Typy SFVec2f i MFVec2f zapisywane są jako para liczb zmiennoprzecinkowych oddzielonych spacjami, np.: przykład [ 3.5, 4.0 ] opisuje wektor [3.5, 4.0]. 10/12 30 10 Kolorowanie i teksturowanie obiektów – węzeł Appearance #VRML V2.0 utf8 Transform { rotation 1 0 0 0.5 translation 0 0 -5 children [ Shape { appearance Appearance { material Material { emissiveColor 1 0 0 transparency 0.3 specularColor 1 0 0 } } geometry Box { size 4 4 4 } } ] } PRZYKŁAD 31 11/12 Kolorowanie i teksturowanie obiektów – węzeł Appearance #VRML V2.0 utf8 Transform { rotation 1 0 0 0.5 translation 0 0 -5 children [ Shape { appearance Appearance { texture ImageTexture { url „AGH.gif" } textureTransform TextureTransform { translation 0.5 0.5 } } geometry Box { size 4 4 4 } } ] } PRZYKŁAD 12/12 32 Oświetlanie obiektów – węzeły DirectionalLight, PointLight, SpotLight Obiekty umieszczone na scenie trójwymiarowej są oświetlane przez sumę świateł zdefiniowanych w pliku VRML. Węzły definiujące światła zawierają m.in. informacje na temat kierunku i zakresu padającego światła. Zakres światła, które ostatecznie oświetli scenę, jest zależny od rozproszenia i odbić od innych obiektów. Wyróżniamy trzy węzły, które definiują światło padające na scenie: DirectionalLight, PointLight, SpotLight. 33 1/9 11 Oświetlanie obiektów – węzeły DirectionalLight, PointLight, SpotLight DirectionalLight oświetla jedynie obiekty umieszczone w węźle grupującym. Określamy kierunek, w którym będzie padać światło, ale lokalizacja źródła jest uzależniona od lokalizacji węzła grupującego, np: Transform. PointLight - oświetla wszystkie obiekty zdefiniowane na scenie. Określamy lokalizację źródła światła, ale nie określimy już kierunku, ponieważ światło tego typu roznosi się we wszystkich kierunkach. SpotLight - efekt działania tego węzła przypomina działanie latarki. Z małego punktu światło rozchodzi się coraz bardziej się rozszerzając. Określamy pozycję źródła światła, kierunek padania promieni, szerokość snopu światła. 34 2/9 Oświetlanie obiektów – węzeły DirectionalLight, PointLight, SpotLight Węzeł DirectionalLight DirectionalLight { exposedField SFFloat ambientIntensity 0 exposedField SFColor color 111 exposedField SFVec3f direction 0 0 -1 exposedField SFFloat intensity 1 exposedField SFBool on TRUE } 35 3/9 Oświetlanie obiektów – węzeły DirectionalLight, PointLight, SpotLight Pole ambientIntensity typu SFFloat definiuje intensywność światła, które nie pada bezpośrednio na żadną powierzchnię (intensywność cienia). Pole intensity definiuje siłę emitowanego światła. Intensywność światła przybiera wartości od 0.0 (światło nie świeci) do 1.0 (pełna siła oświetlenia). Pole color typu SFColor określa kolor emitowanego światła. Pole direction określa kierunek padania światła. Pole on typu SFBool – sterowanie włączeniem i wyłączeniem światła zdefiniowanego w tym węźle. 36 4/9 12 Oświetlanie obiektów – węzeły DirectionalLight, PointLight, SpotLight Węzeł PointLight PointLight { exposedField exposedField exposedField exposedField exposedField exposedField exposedField } SFFloat ambientIntensity 0 SFVec3f attenuation 100 SFColor color 111 SFFloat intensity 1 SFVec3f location 000 SFBool on TRUE SFFloat radius 100 Węzeł PointLight występuje w dowolnym miejscu pliku VRML. W polu location, które określa miejsce położenia źródła światła, tworzy swój własny układ współrzędnych. Światło zdefiniowane w tym węźle oświetla wszystkie obiekty na scenie snopem światła, którego szerokość określana jest w polu radius. 37 5/9 Oświetlanie obiektów – węzeły DirectionalLight, PointLight, SpotLight Pole attenuation typu SFVec3f odpowiada za słabnięcie snopu światła w zależności od oddalania się od jego źródła. Pozostałe pola tego węzła są analogiczna do pól w węźle DirectionalLight. 38 6/9 Oświetlanie obiektów – węzeły DirectionalLight, PointLight, SpotLight Węzeł SpotLight SpotLight { exposedField SFFloat ambientIntensity 0 exposedField SFVec3f attenuation 100 exposedField SFFloat beamWidth 1.570796 exposedField SFColor color 111 exposedField SFFloat cutOffAngle 0.785398 exposedField SFVec3f direction 0 0 -1 exposedField SFFloat intensity 1 exposedField SFVec3f location 000 exposedField SFBool on TRUE exposedField SFFloat radius 100 } 39 7/9 13 Oświetlanie obiektów – węzeły DirectionalLight, PointLight, SpotLight Węzeł SpotLight definiuje źródło światła padającego z określonego punktu, w określonym kierunku. Węzeł SpotLight definiuje snop światła na podstawie danych o promieniu (radius), szerokości snopu światła (beamWidth) oraz kącie, po przekroczeniu którego snop światła zanika (cutOffAngle). beamWidth źródło światła radius cutOffAngle 40 8/9 Oświetlanie obiektów – węzeły DirectionalLight, PointLight, SpotLight Źródło światła w punkcie (10,0 ,0). Snop światła w kolorze czerwonym, skierowany w kierunku ujemnej części osi X (oświetlenie prawej strony obiektu. Światło włączone PRZYKŁAD Światło wyłączone PRZYKŁAD 41 9/9 Punkty patrzenia na świat - węzeł Viewpoint Węzeł Viewpoint umożliwia zdefiniowanie stałych punktów, do których możemy się udać korzystając z opcji Viewpoint interfejsu przeglądarki. Viewpoint { eventIn SFBool set_bind exposedField SFFloat fieldOfView 0.785398 exposedField SFBool jump TRUE exposedField SFRotation orientation 0 0 1 0 exposedField SFVec3f position 0 0 10 field SFString description "" eventOut SFTime bindTime eventOut SFBool isBound } 42 1/3 14 Punkty patrzenia na świat - węzeł Viewpoint Pole position typu SFVec3f określa miejsce z którego będziemy patrzeć. Pole orientation typu SFRRotation określa kierunek w którym będziemy patrzeć. Pole description służy do definicja nazwy definiowanego miejsca. Pole jump typu SFBool jeśli ma wartość FALSE informuje przeglądarkę, że przeskakując z jednego punktu do drugiego, musi ona uważać, czy obserwator nie dotknie jakiegoś czujnika, który zmieni wygląd sceny. Pole fieldOfView typu SFFLoat definiuje kąt szerokości patrzenia z danego miejsca. Wartości w tym polu podajemy w radianach (0 – 3.14). 43 2/3 Punkty patrzenia na świat - węzeł Viewpoint Transform { rotation 1 0 0 0.5 translation 0 0 -5 #VRML V2.0 utf8 Viewpoint { fieldOfView 0.8 jump TRUE orientation 0 0 0 0 position 0 0 10 description "Start" } Viewpoint { fieldOfView 0.8 jump TRUE orientation 0 1 0 1.6 position 20 0 -5 description "SpotLight" } children [ Shape { appearance Appearance { material Material { emissiveColor 0 1 0 transparency 0 specularColor 0 0.25 0.5 } } geometry Box { size 4 4 4 } } ] SpotLight { ambientIntensity 0 attenuation 100 beamWidth 1.570796 color 100 cutOffAngle 0.785398 direction -1 0 0 intensity 1 location 10 0 0 on TRUE radius 100 } } PRZYKŁAD 44 3/3 Wyświetlanie wcześniej zdefiniowanych już obiektów - komendy DEF i USE Komendy DEF używany do jednorazowego definiowania obiektów, natomiast użycie komendy USE daje nam możliwość wielokrotnego wykorzystania już wcześniej zdefiniowanych obiektów. 45 1/2 15 Wyświetlanie wcześniej zdefiniowanych już obiektów - komendy DEF i USE #VRML V2.0 utf8 Transform { rotation 1 0 0 0.5 translation 0 2 -10 children [ DEF Szescian Shape { appearance Appearance { material Material { emissiveColor 1 1 0 transparency 0 specularColor 0 1 0 } } geometry Box { size 4 4 4 } } ] } Transform { rotation 0 1 0 0.5 translation 10 0 -10 children [ USE Szescian ] } Transform { rotation 0 0 1 0.5 translation -10 4 -10 children [ USE Szescian ] } Transform { rotation 0 0 1 0.5 translation -10 10 -10 children [ USE Szescian ] } PRZYKŁAD 46 2/2 Czas animacji - węzeł TimeSensor Węzeł TimeSensor należy do grupy węzłów czujnikowych odpowiedzialnych za interakcję między użytkownikiem a światem wirtualnym, zajmując się kontrolowaniem czasu w jakim te wszystkie operacje mają się odbywać. Interfejs węzeła TimeSensor jest następujący: TimeSensor { exposedField SFTime cycleInterval 1 exposedField SFBool enabled TRUE exposedField SFBool loop FALSE exposedField SFTime startTime 0 exposedField SFTime stopTime 0 eventOut SFTime cycleTime eventOut SFFloat fraction_changed eventOut SFBool isActive eventOut SFTime time } 47 1/3 Czas animacji - węzeł TimeSensor Pole cycleInterval typu SFTime definiuje szybkości animacji. Pole enabled typu SFBool odpowiada za to czy węzeł TimeSensor jest aktywny czy też nie. Pole loop typu SFBool odpowiada za to czy pętla animacji ma następować jedna po drugiej (wartość TRUE), czy też ma zostać wykonana tylko jedna (wartość FALSE). Kiedy węzeł TimeSesor w polu loop ma wartość TRUE i wartość pola startTime jest większa bądź równa wartości w polu stopTime wtedy węzeł będzie wykonywał swoje zadanie w nieskończoność lub do momentu gdy wartość w polu stopTime będzie większa od wartości w polu startTime. 48 2/3 16 Czas animacji - węzeł TimeSensor Węzeł TimeSensor jest nieaktywny do momentu kiedy wartość pola startTime nie zostanie odczytana. Kiedy czas rzeczywisty równy jest wartości pola startTime zdarzenie isActive zostaje wygenerowane, przybiera wartość TRUE i węzeł się uaktywnia. Wartości domyślne dla każdego pola węzła TimeSensor zostały tak ustawione, że jeśli nie podamy żadnych nowych wartości to po załadowaniu węzeł będzie nieaktywny i żadne ze zdarzeń nie zostanie wysłane. Węzeł TimeSensor możemy uaktywnić od razu po załadowaniu wpisując w pole loop wartość TRUE. 49 3/3 Trasa animacji – węzły z grupy Interpolator Węzły z grupy Interpolator definiują trasę jaką dany obiekt będzie przebywał podczas animacji. Węzły z grupy Interpolator definiują funkcję liniową f(t) w przedziale od plus do minus nieskończoności. Funkcja definiowana jest przez n wartości t, które nazywamy kluczami (key) i n odpowiadających im wartości f(t), które są nazywane wartościami kluczy (keyValue). Ciąg kluczy musi być monotoniczny, niemalejący i nie może być ograniczony do żadnego przedziału. Węzeł interpolacji oblicza wartość funkcji f(t) dla każdej wartości t, którą przyjmie zdarzenie eventIn set_fraction. 50 1/7 Trasa animacji – węzły z grupy Interpolator OrientationInterpolator { eventIn SFFloat set_fraction exposedField MFFloat key [] exposedField MFRotation keyValue [] eventOut SFRotation value_changed } Węzeł OrientationInterpolator interpoluje między wartościami typu MFRotation określającymi dane dotyczące obrotu obiektu. Obrót obiektu definiowany jest w polu key określając liczbę „momentów kluczowych animacji" czyli takich punktów, w których dany obiekt ma być obrócony o wartość określoną w polu keyValue. Węzeł korzystając z pól key i keyValue oblicza funkcję interpolacyjną obrotu obiektu. Liczba wartości w polu key i keyValue musi być identyczna. Zdarzenia set_fraction i value_changed używane są do sterowania węzłem OrientationInterpolator. 51 2/7 17 Trasa animacji – węzły z grupy Interpolator PositionInterpolator { eventIn SFFloat set_fraction exposedField MFFloat key [] exposedField MFVec3f keyValue [] eventOut SFVec3f value_changed } Węzeł PositionInterpolator interpoluje między punktami zdefiniowanymi w przestrzeni trójwymiarowej. Liczba wartości w polu key i keyValue musi być identyczna. Zasady działania pól key, keyValue są analogiczne jak w węźle OrientationInterpolator. 52 3/7 Trasa animacji – węzły z grupy Interpolator ScalarInterpolator { eventIn SFFloat set_fraction [] exposedField MFFloat key exposedField MFFloat keyValue [] eventOut SFFloat value_changed } Węzeł ScalarInterpolator interpoluje między wartościami typu SFFloat. Liczba wartości w polu key i keyValue musi być identyczna. Zasady działania pól key, keyValue są analogiczne jak w węźle OrientationInterpolator. 53 4/7 Trasa animacji – węzły z grupy Interpolator CoordinateInterpolator { [ 0.0, 0.5, 1.0] [ 0 0 0, 10 10 30, 10 20 10, 40 50 50, 30 50 60, 40 50 60 ] } CoordinateInterpolator { key eventIn SFFloat set_fraction keyValue exposedField MFFloat key [] exposedField MFVec3f keyValue [] eventOut MFVec3f value_changed } key = 3, keyValue = 6 6/3=2 Węzeł CoordinateInterpolator interpoluje między wektorami typu MFVec3f. Każdej wartości w polu key musi odpowiadać x definicji wektorów w polu keyValue. x musi być taką liczbą, której wynik dzielenia z ilością wartości w polu key da liczbę całkowitą. 54 5/7 18 Trasa animacji – węzły z grupy Interpolator ColorInterpolator { eventIn SFFloat set_fraction exposedField MFFloat key [] exposedField MFColor keyValue [] eventOut SFColor value_changed } Węzeł ColorInterpolator interpoluje między wartościami typu MFColor. Ilość definicji kolorów w polu keyValue powinna odpowiadać ilości wartości w polu key. Wszystkie węzły interpolacji uruchamiamy wraz z przyjęciem zdarzenia set_fraction. 55 6/7 Trasa animacji – węzły z grupy Interpolator NormalInterpolator { eventIn SFFloat set_fraction exposedField MFFloat key [] exposedField MFVec3f keyValue [] eventOut MFVec3f value_changed } Węzeł NormalInterpolator interpoluje między prostopadłymi do określonej powierzchni wektorami typu MFVec3f. Każdej wartości w polu key musi odpowiadać x definicji wektorów w polu keyValue. x musi być taką liczbą, której wynik dzielenia z ilością wartości w polu key da liczbę całkowitą. Można używać tego węzła do tworzenia ruchomych efektów cieniowania. 56 7/7 Powiązanie zdarzeń – polecenie ROUTE Połączenie między węzłem generującym zdarzenie a węzłem przyjmującym zdarzenie nazywane jest trasą (route). Węzeł, który wysyła zdarzenia danego typu może być połączone trasą z węzłem przyjmującym zdarzenia tego samego typu. Trasy nie są węzłami tylko konstrukcją służącą do połączenia węzłów, między którymi przebiega zdarzenie. Komenda ROUTE może zostać zdeklarowana w dowolnym miejscu pliku *.wrl. Wymagana jest zgodność typów pól. Trasy ustala się tylko od eventOut do eventIn. Jeżeli oba pola lub zdarzenia są rodzaju exposedField kolejność pola/zdrzenia, od którego zaczynamy nie jest istotna. 57 1/3 19 Powiązanie zdarzeń – polecenie ROUTE ROUTE [nazwa_węzła].[zdarzenie_changed] TO [nazwa_węzła].[set_zdarzenie] 58 2/3 Powiązanie zdarzeń – polecenie ROUTE DEF Button TouchSensor { enabled TRUE } DEF Light DirectionalLight { on FALSE } ROUTE Button.enabled TO Light.on ROUTE Button.enabled_changed TO Light.on ROUTE Button.enabled TO Light.set_on ROUTE Button.enabled_changed TO Light.set_on 59 3/3 Pierwsza animacja Etap 1- definicja obiektów #VRML V2.0 utf8 DEF First Transform { translation 0 0 0 children [ Shape { appearance Appearance { material Material { diffuseColor 0 0 1 } } geometry Sphere {} 1/4 } ] DEF Second Transform { translation 5 0 0 children [ Shape { appearance Appearance { material Material { diffuseColor 1 10 } } geometry Sphere {} } ] } 60 20 Pierwsza animacja Etap 1- definicja obiektów PRZYKŁAD 61 2/4 Pierwsza animacja Etap 2- definicja węzłów: TimeSensor, PositionInterpolator oraz trasy ROUTE DEF Time TimeSensor { loop TRUE cycleInterval 10 } DEF Inter PositionInterpolator { key [ 0, 0.25, 0.5, 0.75, 1 ] keyValue [ 5 0 0, 0 5 0, -5 0 0, 0 -5 0, 5 0 0 ] } 62 3/4 Pierwsza animacja Etap 2- definicja węzłów: TimeSensor, PositionInterpolator oraz trasy ROUTE 1. Węzeł TimeSensor jest domyślnie aktywowany. 2. Aktywacja węzła PositionInterpolator poprzez zdarzenia set_fraction. przyjęcia ROUTE Time.fraction_changed TO Inter.set_fraction 3. Przypisanie przesunięcie. Łączymy zdarzenie value_changed węzła PositionInterpolator ze zdarzeniem set_translation węzła Transform, w którym zdefiniowany jest nasz obiekt. ROUTE Inter.value_changed TO Second.set_translation PRZYKŁAD 63 4/4 21 Czujniki dotykowe – węzeł Anchor Wykorzystując węzeł Anchor możemy stworzyć link między światem VRML a innym miejscem w sieci. Może on także odsyłać do miejsc zdefiniowanych w tym samym świecie za pomocą węzła Viewpoint. Interfejs węzła Anchor jest następujący : 1/5 Anchor { eventIn MFNode addChildren eventIn MFNode removeChildren exposedField MFNode children [] exposedField SFString description "" exposedField MFString parameter [] exposedField MFString url [] field SFVec3f bboxCenter 000 field SFVec3f bboxSize -1 -1 -1 } 64 Czujniki dotykowe – węzeł Anchor Przykład 1 – dowolny plik który obsługuje nasza przeglądarka #VRML V2.0 utf8 Anchor { url "index.html" children [ Shape { geometry Box {} } ] } PRZYKŁAD 65 2/5 Czujniki dotykowe – węzeł Anchor Przykład 2 – link do innego miejsca Viewpoint tego samego świata #VRML V2.0 utf8 Anchor { url "#Viewpoint 2" children [ Shape { geometry Box {} } ] } Powyższa konstrukcja przeniesie użytkownika obecnego świata do miejsca o nazwie „Viewpoint 2" zdefiniowanego w węźle Viewpoint. 66 3/5 22 Czujniki dotykowe – węzeł Anchor Przykład 3 – link do innego miejsca Viewpoint w innym świecie #VRML V2.0 utf8 Anchor { url „inny_swiat#Viewpoint 3" children [ Shape { geometry Box {} } ] } Powyższa konstrukcja przeniesie użytkownika obecnego świata do świata o nazwie inny_swiat i miejsca o nazwie „Viewpoint 3" zdefiniowanego w węźle Viewpoint. 67 4/5 Czujniki dotykowe – węzeł Anchor Przykład 4 – java script #VRML V2.0 utf8 Anchor { url "javascript: alert('Systemy pracy wspolbieznej')" children [ Shape { geometry DEF Kula1 Sphere {} } ] } PRZYKŁAD 68 5/5 Czujniki dotykowe – węzeł TouchSensor Interfejs węzła TouchSensor: TouchSensor { exposedField SFBool enabled TRUE eventOut SFVec3f hitNormal_changed eventOut SFVec3f hitPoint_changed eventOut SFVec2f hitTexCoord_changed eventOut SFBool isActive eventOut SFBool isOver eventOut SFTime touchTime } 69 1/4 23 Czujniki dotykowe – węzeł TouchSensor W przypadku gdy pole enabled będzie miało wartość TRUE oraz „klikniemy” na aktywny obiekt lub najedziemy na niego kursorem myszy wysyłane zostają pozostałe zdarzenia: Podczas przesunięcia kursora z miejsca nie aktywnego w aktywne zdarzenie isOver wysyła wartość TRUE. W sytuacji odwrotnej zdarzenie isOver wysyła wartość FALSE. 70 2/4 Czujniki dotykowe – węzeł TouchSensor W przypadku gdy zdarzenie isOver wyśle wartość TRUE zostaną wysyłane również zdarzenia hitPoint_changed, hitNormal_changed i hitTexCoord_changed. Wartość wysyłana wraz ze zdarzeniem hitPoint_changed zawiera definicję punktu (x, y, z) na powierzchni obiektu objętego działaniem węzła TouchSensor. Zdarzenie hitNormal_changed wysyła informację o wektorze prostopadłym do aktywnej powierzchni stykający się z powierzchnią w punkcie wyznaczonym przez zdarzenie hitPoint_changed. Zdarzenie hitTexCoord_changed zawiera informację o współrzędnych tekstury nałożonej na obiekt aktywny od punktu wyznaczonego przez zdarzenie hitPoint_changed. 71 3/4 Czujniki dotykowe – węzeł TouchSensor W przypadku gdy zdarzenie isOver ma wartość TRUE „kliknięcie” klawiszem myszy spowoduje wysłanie zdarzenia isActive o wartości TRUE. Jeżeli przytrzymamy klawisz myszki zdarzenie isActive spowoduje, że na czas przytrzymania klawisza myszka zostanie wyłączona z innych zadań aż do czasu gdy klawisz zostanie puszczony. Zdarzenie touchTime jest wysyłane w momencie gdy trzy poniższe warunki zostaną spełnione: kursor myszki był skierowany na obiekt aktywny a klawisz myszki wciśnięty w momencie gdy zdarzenie isActive było TRUE, kursor myszki w danej chwili jest skierowany na aktywny obiekt, czyli wartość zdarzenie isOver ma wartość TRUE, klawisz myszki zostanie puszczony - zdarzenie isActive przyjmuje wartość FALSE. 72 4/4 24 Czujniki obrotu i przesunięcia Do grupy czujników obrotu i przesunięcia zaliczamy następujące węzły: i. PlaneSensor, ii. CylinderSensor, iii.SphereSensor. Działanie powyższych czujników polega na tym, że w momencie przytrzymania klawisza myszy na aktywnym obiekcie, można go przesuwać lub obracać -w zależności od rodzaju użytego węzła czujnikowego. 73 1/9 Czujniki obrotu i przesunięcia Wspólne pola dla węzłów PlaneSensor, CylinderSensor i SphereSensor. Powyższe węzły posiadają kilka wspólnych pól: i. Pole offset i autoOffset. Pola te odpowiadają za zapamiętanie stanu ostatniego przesunięcia lub obrotu obiektu. W momencie gdy autoOffset ma ustawioną wartość TRUE to miejsce, w którym obiekt został zostawiony podczas ostatniego korzystania z węzła czujnikowego zostaje zapamiętane i przy ponownym użyciu tego węzła, ruch rozpoczyna się właśnie od tego miejsca. ii. Pole maxPosition i minPosition wyznaczają granice wychylenia obiektu. W momencie gdy pole autoOffset ma ustawioną wartość FALSE można zdefiniować własny punkt, z którego zacznie się przesuwanie obiektu przy uaktywnieniu tych węzłów czujnikowych. Punkt ten definiuje się w polu offset. wysłane w chwili iii. Zdarzenie trackPoint_changed, które zostaje uaktywnienia węzła. Zdarzenie to „śledzi" pozycję kursora, w związku z czym jeżeli połączymy zdarzenie trackPoint_changed ze zdarzeniem set_translation węzła Transform, w którym znajduje się definicja obiektu, to obiekt będzie się przesuwał w ślad za kursorem myszki. 74 2/9 Czujniki obrotu i przesunięcia #VRML V2.0 utf8 DEF Obiekt Transform { children [ Shape { appearance Appearance { material Material { diffuseColor 0 0 1 } } geometry Sphere {} } ] } DEF Czujnik SphereSensor {} ROUTE Czujnik.rotation_changed TO Obiekt.set_rotation ROUTE Czujnik.trackPoint_changed TO PRZYKŁAD Obiekt.set_translation 75 3/9 25 Czujniki obrotu i przesunięcia PlaneSensor { exposedField SFBool autoOffset TRUE exposedField SFBool enabled TRUE exposedField SFVec2f maxPosition -1 -1 exposedField SFVec2f minPosition 00 exposedField SFVec3f offset 000 eventOut SFBool isActive eventOut SFVec3f trackPoint_changed eventOut SFVec3f translation_changed } Węzeł PlaneSenor umożliwia przesuwanie obiektów względem osi X i Y oraz umożliwia ograniczenie przesunięcia obiektu. W polach maxPosition i minPosition określa się granice, w których obiekt może być przemieszczany. Pierwsza wartość w tych polach dotyczy osi X a druga osi Y. Pozostawienie wartości domyślnych spowoduje, że można przemieszczać aktywny obiekt bez ograniczeń. 76 4/9 Czujniki obrotu i przesunięcia 5/9 #VRML V2.0 utf8 DEF Obiekt Transform { children [ Shape { appearance Appearance { material Material { diffuseColor 0 0 1 } } geometry Box {size 3 3 0.1} } ] } DEF Czujnik PlaneSensor { autoOffset FALSE offset 0 0 0 minPosition -1 -1 maxPosition 2 2 } PRZYKŁAD ROUTE Czujnik.translation_changed TO 77 Obiekt.set_translation Czujniki obrotu i przesunięcia CylinderSensor { exposedField SFBool autoOffset TRUE exposedField SFFloat diskAngle 0.262 exposedField SFBool enabled TRUE exposedField SFFloat maxAngle -1 exposedField SFFloat minAngle 0 exposedField SFFloat offset 0 eventOut SFBool isActive eventOut SFRotation rotation_changed eventOut SFVec3f trackPoint_changed } Działanie węzeła CylinderSensor jest podobnie do działania węzeła PlaneSensor. Różnica polega na tym, że aktywny obiekt nie jest przesuwany a obracany tylko względem osi Y. 78 6/9 26 Czujniki obrotu i przesunięcia #VRML V2.0 utf8 DEF Obiekt Transform { children [ Shape { appearance Appearance { material Material { diffuseColor 0 0 1 } } geometry Box {size 3 3 0.1} } ] } DEF Czujnik CylinderSensor { autoOffset TRUE minAngle -1 PRZYKŁAD maxAngle 1 } ROUTE Czujnik.rotation_changed TO Obiekt.set_rotation 79 7/9 Czujniki obrotu i przesunięcia SphereSensor { exposedField SFBool autoOffset TRUE exposedField SFBool enabled TRUE exposedField SFRotation offset 0100 eventOut SFBool isActive eventOut SFRotation rotation_changed eventOut SFVec3f trackPoint_changed } Węzeł SphereSensor działa analogicznie jak CylinderSensor. Wykorzystanie węzła SphereSensor umożliwia obrót danego obiektu we wszystkich kierunkach. 80 8/9 Czujniki obrotu i przesunięcia #VRML V2.0 utf8 DEF Obiekt Transform { children [ Shape { appearance Appearance { material Material { diffuseColor 0 0 1 } } geometry Cone { height 4 } } ] } DEF Czujnik SphereSensor { enabled TRUE PRZYKŁAD autoOffset TRUE } ROUTE Czujnik.rotation_changed TO Obiekt.set_rotation 81 9/9 27 Czujniki środowiskowe Czujniki środowiskowe są uruchamiane przez użytkownika nieświadomie, tzn. do ich uaktywnienia nie potrzebne jest świadomie działanie użytkownika. Do grupy czujników środowiskowych zaliczamy węzły: i. Collision, ii.ProximitySensor, iii.VisibilitySensor. 82 1/8 Czujniki środowiskowe Collision { eventIn MFNode addChildren eventIn MFNode removeChildren [] exposedField MFNode children exposedField SFBool collide TRUE field SFVec3f bboxCenter 000 field SFVec3f bboxSize -1 -1 -1 field SFNode proxy NULL eventOut SFTime collideTime } 83 2/8 Czujniki środowiskowe Collision jest węzłem grupującym określającym właściwości kolizji dla obiektów zdefiniowanych w polu children. Pole collide odpowiada za włączenie lub wyłączenie wykrywania kolizji z obiektami zdefiniowanymi w węźle Collision. Pole proxy definiuje obiekt który jest niewidoczny, o który się zatrzymamy chcąc dotrzeć do danego obiektu. Jeżeli w polu children nie znajdzie się definicja żadnego obiektu, pole collide będzie miało wartość TRUE, a w polu proxy zostanie zdefiniowany obiekt to nic nie zostanie wyświetlone na ekranie, ale w ten właśnie sposób można zdefiniować kolizje z niewidzialnym obiektem. Przy zderzeniu z obiektami utworzonymi w polu proxy węzeł również wysyła odpowiednie zdarzenia. Podczas kolizji, węzeł Collision wysyła zdarzenie collideTime, które można powiązać z innymi zdarzeniami wywołując jakiś efekt, który ma kolizji towarzyszyć. Jednak aby zdarzenie collideTime mogło zostać wysłane pole collide musi mieć wartość TRUE. PRZYKŁAD 84 3/8 28 Czujniki środowiskowe ProximitySensor { exposedField SFVec3f center 000 exposedField SFVec3f size 000 exposedField SFBool enabled TRUE eventOut SFBool isActive eventOut SFVec3f position_changed eventOut SFRotation orientation_changed eventOut SFTime enterTime eventOut SFTime exitTime } 85 4/8 Czujniki środowiskowe Wykorzystując węzeł ProximitySensor można zdefiniować obszar aktywny na wkroczenie użytkownika. W momencie wkroczenia użytkownika w aktywny obszar węzeł wysyła grupę zdarzeń. Aktywny obszar jest określony niewidocznym sześcianem, którego środek określany jest w polu center, a rozmiar w polu size. Kiedy użytkownik wkracza w zdefiniowaną przestrzeń wysyłane jest zdarzenie isActive o wartości TRUE oraz zdarzenie enterTime, natomiast kiedy użytkownik opuszcza daną przestrzeń, wysyłane jest zdarzenie isActive o wartości FALSE oraz zdarzenie exitTime. Zdarzenia position_changed i orientation_changed "śledzą" ruch uczestnika świata i wysyłają zdarzenia, które mogą być odczytywane przez inne węzły. Jeżeli węzeł ProximitySensor ponownie przywołamy w innym miejscu używając np.: mechanizmu DEF/USE to wtedy aktywna staje się przestrzeń, którą stanowi suma "przestrzeni" ją wyznaczających. 86 5/8 Czujniki środowiskowe #VRML V2.0 utf8 Transform { translation 0 0 0 children [ Collision { collide FALSE children [ DEF Prox ProximitySensor {size 2 2 2} Shape { appearance Appearance { material Material { transparency 0.6 } } geometry Box {} } ] } ] } DEF Obiekt Transform { translation -10 0 -20 children [ Shape { appearance Appearance { material Material { diffuseColor 0 1 0 } } geometry Sphere {} } ] } DEF Czas TimeSensor {cycleInterval 5} DEF Ruch PositionInterpolator { key [ 0, 0.25, 0.5, 0.75 , 1 ] keyValue [ -5 0 -20, 0 5 -20, 5 0 -20, 0 -5 -20, -5 0 -20] } ROUTE Prox.enterTime TO Czas.set_startTime ROUTE Czas.fraction_changed TO Ruch.set_fraction ROUTE Ruch.value_changed TO Obiekt.set_translation ROUTE Prox.isActive TO Czas.set_loop PRZYKŁAD 87 6/8 29 Czujniki środowiskowe VisibilitySensor { exposedField SFVec3f center 0 0 0 exposedField SFBool enabled TRUE exposedField SFVec3f size 000 eventOut SFTime enterTime eventOut SFTime exitTime eventOut SFBool isActive } Węzeł VisibilitySensor "uwrażliwia" zdefiniwany obszar na spojrzenie użytkownika. Budowa węzeła VisibilitySensor jest analogiczna do budowy węzeła ProximitySensor. W obu węzłach identycznie działają zdarzenia oraz pola center, size i enabled. 88 7/8 Czujniki środowiskowe #VRML V2.0 utf8 Transform { translation 5 0 0 children [ DEF Obiekt Shape { appearance Appearance { material DEF Kolor Material { diffuseColor 0 1 1 } } geometry Cylinder { } } ] } Transform { translation -5 0 0 children [ USE Obiekt ] } DEF Obszar VisibilitySensor { center 0 0 0 size 5 5 5 } DEF Czas TimeSensor {} DEF Czas2 TimeSensor {} DEF Animacja ColorInterpolator { key [0, 1] keyValue [1 0 1, 0 1 0] } DEF Animacja2 ColorInterpolator { key [0, 1] keyValue [0 1 0, 1 01] } ROUTE Obszar.enterTime TO Czas.set_startTime ROUTE Czas.fraction_changed TO Animacja.set_fraction ROUTE Animacja.value_changed TO Kolor.set_diffuseColor ROUTE Obszar.exitTime TO Czas2.set_startTime ROUTE Czas2.fraction_changed TO Animacja2.set_fraction ROUTE Animacja2.value_changed TO Kolor.set_diffuseColor PRZYKŁAD 89 8/8 Rzeźba terenu – węzeł ElevationGrid ElevationGrid { eventIn MFFloat set_height exposedField SFNode color NULL exposedField SFNode normal NULL exposedField SFNode texCoord NULL field MFFloat height [] field SFBool ccw TRUE field SFBool colorPerVertex TRUE field SFFloat creaseAngle 0 field SFBool normalPerVertex TRUE field SFBool solid TRUE field SFInt32 xDimension 0 field SFFloat xSpacing 1.0 field SFInt32 zDimension 0 field SFFloat zSpacing 1.0 } 90 1/5 30 Rzeźba terenu – węzeł ElevationGrid Pierwszym krokiem jest budowa dwuwymiarowej siatki rozciągniętej pomiędzy osią X i Z a następnie ustalenie wysokości punktów w których siatka się przecina. Siatkę tworzy się za pomocą pól xDimension i zDimension gdzie definiuje się w nich ilość linii przecinających się. W polach xSpacing i zSpacing ustala się odległość między tymi liniami (rozrzedzenie lub zagęszczenie siatki). Kolejnym krokiem jest definicja pola height, gdzie każdemu punktowi przecięcia linii siatki podporządkowuje się wysokość wierzchołków. Pierwsza wartość w tym polu odnosi się do punktu (0, 0) w układzie (X, Z), następne wartości odnoszą się do kolejnych punktów znajdujących się na osi X (wartość określona w polu xDimension). Kiedy wszystkie wartości na osi X dla Z=0 zostaną opisane wtedy kolejnym punktem, który należy opisać w polu height będzie pierwszy punkt znajdujący się na dodatniej stronie osi Z dla X=0. Kolejno opisuje się pozostałe punkty od X=0 do X=n, aż do chwili opisania wszystkich punktów przecięcia siatki. Ilość wartości w polu height jest równa działaniu xDimension * zDimension. 91 2/5 Rzeźba terenu – węzeł ElevationGrid W polu ccw określa się porządek współrzędnych wierzchołków użytych w celu utworzenia bryły. Jeżeli w polu tym znajdzie się wartość TRUE to oznacza, że wierzchołki tworzące jedną ścianę bryły definiowane są w kierunku przeciwnym do ruchu wskazówek zegara. Jeżeli w polu tym znajadzie się wartość FALSE to oznacza, że wierzchołki będą definiowane zgodnie z ruchem wskazówek zegara. W polu solid wartość FALSE oznacza, że każdy z wielokątów wchodzących w skład definiowanej bryły będzie renderowany niezależnie od tego, czy użytkownik ma ku niemu zwrócony wzrok czy też nie. Pole color pozwala przypisać inny kolor każdemu wierzchołkowi bądź każdemu wielokątowi zdefiniowanemu w węźle ElevationGrid. W polu color można zdefiniować węzeł Color, jednak wartości które mogą się w nim znaleźć, zależne są od pola colorPerVertex. Pole colorPerVertex określa czy kolory zdefiniowane w polu color będą przypisane do każdego wierzchołka (TRUE) czy do każdego czworoboku (FALSE). 92 3/5 Rzeźba terenu – węzeł ElevationGrid Pole normal przypisuje każdemu wierzchołkowi bądź czworobokowi wektory normalne. W polu normal można zdefiniować węzeł Normal, jeżeli nie zostanie to zrobione przeglądarka automatycznie wygeneruje wektory normalne korzystając z wartości pola creaseAngle. Jeśli kąt między dwoma płaszczyznami będzie mniejszy od kąta zawartego w polu creaseAngle to krawędzie tych dwóch płaszczyzn powinny być delikatnie wycieniowane. Podobnie jak w przypadku kolorów, cieniowanie można przypisać albo do wierzchołków albo do wielokątów (pole normalPerVertex). W polu texCoord można zdefiniować węzeł TextureCoordinate odpowiadający za nałożenie tekstury na obiekty o budowie wierzchołkowej. 93 4/5 31 Rzeźba terenu – węzeł ElevationGrid geometry ElevationGrid { xDimension 5 zDimension 5 xSpacing 2 zSpacing 4 height [ 0, 0.7, 0, 1, 0, 0, 0.4, 0.1, 0.2, 0, 0, 0.3, 0.2, 0, 0, 0.2, 0.1, 0.3, 0.2, 0, 0.1, 0, 0.5, 0.1, 0.1 #VRML V2.0 utf8 DirectionalLight {direction 0 -0.5 0.5} Shape { appearance Appearance { material Material { diffuseColor 0 1 0} } ] } } PRZYKŁAD 94 5/5 Horyzont, panorama i mgła – węzły Background i Fog Wykorzystując węzeł Background można dokładnie określić kolor "nieba" oraz "ziemi” wirtualnego świata. Background { eventIn SFBool set_bind exposedField MFFloat groundAngle [] exposedField MFColor groundColor [] exposedField MFString backUrl [] exposedField MFString bottomUrl [] exposedField MFString frontUrl [] exposedField MFString leftUrl [] exposedField MFString rightUrl [] exposedField MFString topUrl [] exposedField MFFloat skyAngle [] exposedField MFColor skyColor 000 eventOut SFBool isBound } 95 1/6 Horyzont, panorama i mgła – węzły Background i Fog Kolor "nieba" i "ziemi" określa się korzystając z pól groundAngle, groundColor oraz skyAngle i skyColor. W polu skyAngle wyznacza się kąt tworzący koncentryczny pas wokół zenitu, a w polu skyColor określa się barwę, jaka ma się w tym pasie znaleźć (barwę określamy w standardzie RGB). Takich pasów możemy utworzyć bardzo wiele, ale zawsze w polu skyColor musi znajdować się jedna definicja koloru więcej, niż jest zdefiniowanych kątów. Dzieje się tak dlatego, iż pierwsza wartość w polu skyColor przyjmowana jest za kolor dla zenitu. Wygląd „ziemi" tworzy się w sposób analogiczny, tylko że kąty w polu groundAngle liczone są od nadiru. 96 2/6 32 Horyzont, panorama i mgła – węzły Background i Fog #VRML V2.0 utf8 Background { skyColor [ 1 1 1, 0 0.25 0.5, 0.5 0.25 0.5 ] skyAngle [ 0.1, 1.57] groundColor [ 000 000 0.5 0.25 0.5 ] groundAngle [ 1.5, 1.57] } PRZYKŁAD 97 3/6 Horyzont, panorama i mgła – węzły Background i Fog Za pomocą węzła Background można utworzyć również panoramę otaczającą nasz świat. W skład takiej panoramy wchodzą pliki graficzne (JPG, PNG, GIF), które jako teksturę nakładamy na wielki sześcian otaczający cały nasz świat (sześcian ten jest domyślnie tworzony przez węzeł Background). Stąd w składni węzła Background pola: backUrl, bottomUrl, frontUrl, leftUrl, rightUrl, topUrl. W każdym z tych pól umieszcza się ścieżkę dostępu do plików graficznych, które mają tworzyć naszą panoramę. 98 4/6 Horyzont, panorama i mgła – węzły Background i Fog Fog { exposedField SFColor color 111 exposedField SFString fogType "LINEAR" exposedField SFFloat visibilityRange 0 eventIn SFBool set_bind eventOut SFBool isBound } Pole color określa kolor mgły. Wartość LINEAR w polu fogType powoduje, że mgła rozpościera się liniowo we wszystkich kierunkach, natomiast gdy zostanie umieszczona tam wartość EXPONENTIAL uzyskamy efekt bardziej naturalny, zbliżony do rzeczywistości. W polu visibilityRange określa się najmniejszą odległość między użytkownikiem a obiektem, przy której obiekt zostaje zupełnie przez mgłę przesłonięty. 99 5/6 33 Horyzont, panorama i mgła – węzły Background i Fog 6/6 #VRML V2.0 utf8 Background { skyColor [ 0.0 0.2 0.7, 0.0 0.5 1.0, 1.0 1.0 1.0 ] skyAngle [ 1.309, 1.571 ] } Fog { color 1 1 1 visibilityRange 10 fogType "LINEAR" } Shape { appearance Appearance { material Material { diffuseColor 1 1 0 } } PRZYKŁAD geometry Box {} 100 } Dzwięk i film – węzły Sound, MovieTexture i AudioClip Sound { exposedField SFVec3f direction 001 exposedField SFFloat intensity 1 exposedField SFVec3f location 000 exposedField SFFloat maxBack 10 exposedField SFFloat maxFront 10 exposedField SFFloat minBack 1 exposedField SFFloat minFront 1 exposedField SFFloat priority 0 exposedField SFNode source NULL field SFBool spatialize TRUE } 101 1/9 Dzwięk i film – węzły Sound, MovieTexture i AudioClip W polu direction określa się kierunek rozchodzenia się dźwięku. Pole intensity odpowiada za głośność z jaką dany dźwięk będzie odtwarzany (0 - cisza, 1 - pełna głośność). Pole location definiuje miejsce, z którego dany dźwięk będzie się rozchodził. Pole spatialize odpowiada za funkcję przestrzenności odgrywanego dźwięku. Jeżeli wartością tej funkcji będzie FALSE to dane dotyczące kierunku, w którym fale dźwiękowe mają się rozchodzić zostaną zignorowane. Pole priority stanowi podpowiedź dla przeglądarki dotyczącą dźwięku, który ma odtwarzać w momencie gdy na scenie zdefiniowanych jest więcej niż jedno źródeł dźwięku. Pole priority podobnie jak pole intensity może przybierać wartości od 0 do 1, gdzie wartość 0 pomniejsza słyszalność danego dźwięku, a wartość 1 nadaje mu pierwszeństwo. 102 2/9 34 Dzwięk i film – węzły Sound, MovieTexture i AudioClip Właściwości każdego dźwięku są takie, że jego fale rozchodzą się elipsoidalnie, w związku z czym dźwięk słychać również stojąc niedaleko od źródła dźwięku z tyłu. Zagadnienie to tłumaczy występowanie pól minBack, maxBack i minFront, maxFront. Wartość minBack określa odległość od źródła dźwięku "z tyłu", na której słyszalna jest pełna jego moc, a pole maxBack określa odległość również "z tyłu" źródła ale taką, na której dźwięk zupełnie zanika. Analogicznie wygląda sytuacja z polami minFront i maxFront - odnosi się ona jedynie do odległości od źródła dźwięku zgodnej z kierunkiem transmisji. Im większy będzie odstęp między wartościami min a max, tym dźwięk będzie narastał łagodniej podczas zbliżania się do jego źródła. 103 3/9 Dzwięk i film – węzły Sound, MovieTexture i AudioClip W polu source umieszcza się węzeł AudioClip lub MovieTexture, w którym znajdzie się: ścieżka dostępu do pliku dźwiękowego oraz właściwości dotyczące trwania dźwięku w czasie. Podobnie jak węzeł TimeSensor, węzły AudioClip i MovieTexture są "węzłami zależnymi od czasu" czyli posiadają pola charakterystyczne dla tego typu węzłów i działają w podobny sposób. 104 4/9 Dzwięk i film – węzły Sound, MovieTexture i AudioClip AudioClip { exposedField SFString description "" exposedField SFBool loop FALSE exposedField SFFloat pitch 1.0 exposedField SFTime startTime 0 exposedField SFTime stopTime 0 exposedField MFString url [] eventOut SFTime duration_changed eventOut SFBool isActive } 105 5/9 35 Dzwięk i film – węzły Sound, MovieTexture i AudioClip Pola loop, startTime i stopTime – patrz węzeł TimeSensor. W polu description umieszcza się opis dźwięku (tylko niektóre przeglądarki obsługuje tą funkcję. W polu pitch określa się czy dźwięk ma być odtwarzany z normalną prędkością 1 czy też ma być odtwarzany szybciej 1> lub wolniej 1<. 106 6/9 Dzwięk i film – węzły Sound, MovieTexture i AudioClip Shape { #VRML V2.0 utf8 appearance Appearance { DEF Obrot Transform { material Material { children [ emissiveCo Transform { lor 1 0 0 } rotation 1 0 0 0 } translation 5 2 0 geometry Sphere { radius DEF Czas TimeSensor { loop TRUE children [ cycleInterval 5 } DEF Click TouchSensor 2 } } {} DEF Interpolator OrientationInterpolator { Sound { Sound { key [ 0, .5, 1] source AudioClip { source DEF Efekt keyValue [0 1 0 0, 0 1 0 3.14, 0 1 0 6.28] loop TRUE AudioClip { } url "x.mid" } url #Połączenie zdarzeń odpowiedzialnych za priority 0.5 "efekt.wav" efekt dźwiękowy direction 0 0 1 loop ROUTE Click.touchTime TO Efekt.startTime minFront 12 FALSE } #Połączenie zdarzeń wywołujących animację minBack 12 priority 0.5 ROUTE Czas.fraction_changed TO maxBack 30 minFront 12 Interpolator.set_fraction maxFront 30 minBack 12 ROUTE Interpolator.value_changed TO spatialize TRUE } maxBack 30 Obrot.set_rotation maxFront 30 ROUTE Click.touchTime TO ] spatialize TRUE } Czas.set_startTime } ] } PRZYKŁAD 107 7/9 Dzwięk i film – węzły Sound, MovieTexture i AudioClip MovieTexture { exposedField SFBool loop FALSE exposedField SFFloat speed 1.0 exposedField SFTime startTime 0 exposedField SFTime stopTime 0 exposedField MFString url [] field SFBool repeatS TRUE field SFBool repeatT TRUE eventOut SFTime duration_changed eventOut SFBool isActive } 108 8/9 36 Dzwięk i film – węzły Sound, MovieTexture i AudioClip Jak wszystkie inne węzły odpowiadające za nałożenie tekstury, węzeł MovieTexture umieszcza się w polu texture węzła Appearance i tak samo jak inne tekstury może ona podlegać operacji przesuwania, skalowania, obracania, rozciągania. Pole speed działa na tej samej zasadzie co pole pitch węzła AudioClip - odpowiada za prędkość z jaką plik filmowy umieszczony w polu url będzie odtwarzany. PRZYKŁAD 109 9/9 Animowanie kamery – węzeł Viewpoint DEF Ruchomy Transform { translation 5 0 0 children [ Viewpoint { position 0 0 5 description „Follow me"} Shape { appearance Appearance { material Material { diffuseColor 1 0 0 } } geometry Sphere { } } ] } PRZYKŁAD 110 1/1 Węzły wiążące Do węzłów wiążących należą: Background, Fog, NavigationInfo i Viewpoint. W kodzie źródłowym można zdefiniować dowolną ilość każdego z tych węzłów, jednak jednorazowo tylko jeden węzeł z danej grupy może być aktywny. W tym przypadku grupą nazywamy np. wszystkie węzły Background zdefiniowane w kodzie źródłowym, drugą grupą są wszystkie węzły Viewpoint itd. Każda grupa węzłów tego samego rodzaju posiada w pamięci przeglądarki własny tzw. stos wiążący. Węzeł aktywny znajduje się na górze takiego stosu. W pamięci przeglądarki istnieją w związku z tym cztery stosy wiążące, każdy z nich obsługuje jedną grupę węzłów wiążących, np. wszystkie węzły Fog. 1/13 111 37 Węzły wiążące Dzięki węzłom wiążącym można dowolnie zmieniać np. warunki atmosferyczne jakie panują w naszym świecie w zależności np. od czasu jaki upływa podczas wizyty. Możemy również spowodować, że użytkownikowi wchodzącemu do ciemnego pokoju zapala się światło headlight (NavigationInfo). Najprostszym przykładem może być przełączanie między kolejnymi węzłami Viewpoint. Wysyłane jest wtedy zdarzenia set_bind odpowiedzialne za uaktywnienie o wartości TRUE do kolejnych węzłów Viewpoint. 112 2/13 Węzły wiążące NavigationInfo { eventIn SFBool set_bind exposedField MFFloat avatarSize [0.25, 1.6, 0.75] exposedField SFBool headlight TRUE exposedField SFFloat speed 1.0 exposedField MFString type ["WALK", "ANY"] exposedField SFFloat visibilityLimit 0.0 eventOut SFBool isBound } Węzeł ten odpowiada za fizyczne cechy uczestnika świata wirtualnego (awatara), jak i również za sposób prezentacji obiektów znajdujących się w tym świecie. 113 3/13 Węzły wiążące Pole avatarSize określa możliwości fizyczne uczestnika świata. Pierwsza wartość w tym polu odnosi się do odległości między użytkownikiem a obiektem, przy której następuje zderzenie. Druga wartość określa wysokość najniższego elementu świata, pod którym użytkownik może przejść (czyli wysokość). Trzecia wartość natomiast określa wysokości najwyższego elementu świata, przez który użytkownik może przejść. 4/13 114 38 Węzły wiążące Pole headlight odpowiada za włączenie lub wyłączenie źródła światła, które jest umiejscowione tuż przy głowie uczestnika świata i oświetla wszystko co się przed nim znajduje. W polu speed definiuje się prędkość, z jaką uczestnik świata będzie się poruszał. W polu tym nie może znajdować się wartość ujemna. Jeżeli w polu type ustalimy wartość EXAMINE, działanie pola speed nie będzie przynosiło żadnego rezultatu. 115 5/13 Węzły wiążące Pole type narzuca sposób eksplorowania stworzonego świata. Wartości umieszczane w tym polu odnoszą się do przeglądarki VRML, zmieniają jej interfejs, włączając lub wyłączając różne jej opcje. W polu type mogą występować następujące wartości: ANY, WALK, EXAMINE, FLY, NONE. Wartość ANY daje uczestnikowi świata do dyspozycji wszystkie opcje interfejsu przeglądarki. Jeżeli w polu type oprócz wartości ANY znajdą się również inne, WALK, EXAMINE czy FLY, oznaczać do będzie, że uczestnik będzie mógł korzystać ze wszystkich opcji interfejsu przeglądarki, ale inne będą ustawienia tego interfejsu tuż po załadowaniu świata. Na przykład wartość ["EXAMINE", "ANY"] w polu type spowoduje, że po załadowaniu świata będziemy od razu w trybie examine. Jeżeli wybierzemy wartość WALK, zostanie wyłączona możliwość wejścia w tryb obracania obiektów i wyłączenia grawitacji. Wartość EXAMINE w polu type spowoduje, że będziemy mogli daną sceną jedynie obracać bez możliwości chodzenia. Gdy w polu type umieści się wartość FLY, zostanie wyłączona możliwość obracania obiektami oraz możliwość włączenia grawitacji. Wartość NONE w polu type spowoduje, że interfejs przeglądarki zostanie w ogóle wyłączony. Użytkownik zostanie pozbawiony możliwości ruchu w świecie VRML. 116 6/13 Węzły wiążące W polu visibilityLimit można określić jak duża część świata VRML będzie ukazywana jego uczestnikowi. Wartość domyślna (0.0) ukazuje całą scenę, natomiast wartość (10) - metrów, a (100) – metrów. Pole to może być użyte przy budowaniu dużych przestrzeni w celu optymalizacji - im mniejszy fragment świata będzie widoczny tym szybciej będzie on wyświetlany. 7/13 117 39 Węzły wiążące DEF Wieczor Fog { #VRML V2.0 utf8 color 1 1 1 DEF DzienNav NavigationInfo {} visibilityRange 0 } DEF NocNav NavigationInfo {headlightShape { FALSE} appearance Appearance { material DEF Dzien Background { Material { skyColor [ diffuseColor 0 0.0 0.2 0.7, 10}} 0.0 0.5 1.0, geometry Box {} 1.0 1.0 1.0 ] } skyAngle [ 1.3, 1.57 ] DEF DzienView Viewpoint { } description "Dzien" DEF Rano Fog { position 0 0 10 } color 1 1 1 DEF NocView Viewpoint { visibilityRange 20 } description "Noc" DEF Noc Background { position 0 0 -10 skyColor [ orientation 0 1 0 3.14 } 111, DEF DzienProx ProximitySensor 0 0 0, {center 0 0 10 0 0.25 0.5, size 20 20 20 } 000] DEF NocProx ProximitySensor { center skyAngle [ 0.5, 1, 2 ] 0 0 -10 } size 20 20 20 } ROUTE DzienProx.isActive TO DzienView.set_bind ROUTE DzienProx.isActive TO Dzien.set_bind ROUTE DzienProx.isActive TO Rano.set_bind ROUTE DzienProx.isActive TO DzienNav.set_bind ROUTE NocProx.isActive TO NocView.set_bind ROUTE NocProx.isActive TO Noc.set_bind ROUTE NocProx.isActive TO Wieczor.set_bind ROUTE NocProx.isActive TO NocNav.set_bind PRZYKŁAD 118 8/13 Węzły wiążące Węzły wiążące posiadają unikalne zdarzenia, które mogą zostać uaktywnione w dowolnym momencie, ale tylko po jednym zdarzeniu z każdego typu. Każdy z tych węzłów zawiera zdarzenie eventIn set_bind oraz zdarzenie eventOut isBound. Zdarzenie eventIn set_bind używane jest do przesuwania danego węzła po zakresie pamięci oferowanym przez przeglądarkę. Wartość TRUE dla zdarzenia eventIn set_bind przesuwa węzeł na górę stosu, a wartość FALSE w ogóle usuwa węzeł ze stosu. Zdarzenie isBound zostaje wysłane, gdy dany węzeł przesunie się na górę stosu, zostanie z niego usunięty lub zrzucony i zastąpiony przez inny węzeł. Węzeł, który znajduje się na górze stosu jest węzłem aktywnym dla reprezentowanego typu i używany jest przez przeglądarkę do określenia stanu sceny. Jeśli stos jest pusty, to do ustawienia stanu sceny użyta jest wartość domyślna. Rezultat tej operacji pozostaje niezdefiniowany, jeżeli więcej niż jeden spośród węzłów wiążących (przywołanych za pomocą mechanizmu DEF/USE) zostaje dowiązany do stosu. 119 9/13 Węzły wiążące Zachowania stosu wiążącego 1. Podczas czytania pliku: a. Pierwszy znaleziony węzeł wiążący jest umieszczany na górze stosu: a.1. Węzły wiążące, które znajdują się w plikach dołączonych za pomocą węzła Inline, nie mogą zostać jako pierwsze umieszczone na górze stosu; a.2.węzeł, który znajduje się wewnątrz prototypu, może zostać umieszczony na górze stosu jako pierwszy; b. Pierwszy napotkany węzeł więżący wysyła zdarzenie isBound o wartości TRUE. 10/13 120 40 Węzły wiążące Zachowania stosu wiążącego 2. Kiedy zdarzenie set_bind węzła wiążącego przyjmie wartość TRUE: a. jeśli węzeł wiążący nie jest na górze stosu wiążącego: a.1.węzeł, który aktualnie znajduje się na górze stosu, wysyła zdarzenie isBound o wartości FALSE; a.2. nowy węzeł zostaje umieszczony na górze stosu (w danym momencie na górze stosu może przebywać jedynie jeden węzeł); a.3. nowy węzeł wysyła zdarzenie isBound o wartości TRUE; b. jeśli węzeł już jest na górze stosu to zdarzenie nie wywołuje żadnego efektu. 121 11/13 Węzły wiążące Zachowania stosu wiążącego 3. Kiedy zdarzenie set_bind węzła wiążącego przyjmie wartość FALSE: a. węzeł zostaje usunięty ze stosu wiążącego; b. jeśli węzeł wiążący jest na górze stosu: a.1. wysyła zdarzenie isBound o wartości FALSE; a.2. następny węzeł znajdujący się na stosie wiążącym wchodzi na górę i wysyła zdarzenie isBound o wartości TRUE. 122 12/13 Węzły wiążące Zachowania stosu wiążącego 4. Jeśli zdarzenie set_bind o wartości FALSE zostanie przyjęte przez węzeł, który nie należy aktualnie do stosu wiążącego, zdarzenie zostaje zignorowane i zdarzenie isBound nie jest wysłane. 5. Kiedy węzeł zastąpi inny węzeł na górze stosu, wtedy jeden węzeł wysyła zdarzenie o wartości TRUE, a drugi jednocześnie o wartości FALSE. Oba węzły w tym momencie mają identyczne etykiety czasowe. 6. Jeśli węzeł wiążący zostaje wykasowany, wtedy zachowuje się on jakby wysłał zdarzenie set_bind o wartości FALSE. 13/13 123 41 Tworzenie złożonych obiektów Obiekty złożone tworzymy wykorzystując następujące węzły: IndexedFaceSet, IndexedLineSet, PointSet i Extrusion. Tworzenie obiektów za pomocą powyższych węzłów polega na metodzie wyznaczania punktów w przestrzeni trójwymiarowej a następnie łączenia ich. Każdy z tych trzech węzłów w inny sposób traktuje określone punkty. Węzeł IndexedfaceSet używa ich do utworzenia dwuwymiarowych wielokątów - trzy połączone ze sobą punkty tworzą wielokąt. Z pojedynczych wielokątów dwuwymiarowych tworzone są potem obiekty trójwymiarowe. Węzeł IndexedLineSet tworzy linie między minimum dwoma punktami a węzeł PointSet tworzy pojedyncze, świecące w przestrzeni punkty. Węzeł Extrusion tworzy obiekty trójwymiarowe z dwuwymiarowego planu obiektu. 124 1/21 Tworzenie złożonych obiektów IndexedFaceSet { eventIn MFInt32 set_colorIndex eventIn MFInt32 set_coordIndex eventIn MFInt32 set_normalIndex eventIn MFInt32 set_texCoordIndex NULL exposedField SFNode color exposedField SFNode coord NULL exposedField SFNode normal NULL exposedField SFNode texCoord NULL field SFBool ccw TRUE field MFInt32 colorIndex [] field SFBool colorPerVertex TRUE field SFBool convex TRUE field MFInt32 coordIndex [] field SFFloat creaseAngle 0 field MFInt32 normalIndex [] field SFBool normalPerVertex TRUE field SFBool solid TRUE field MFInt32 texCoordIndex [] } 2/21 125 Tworzenie złożonych obiektów W węźle IndexedfaceSet tworzy się trójwymiarowy obiekt poprzez osobne zdefiniowanie każdej jego ściany. Ściany te składają się z wielokątów, których wierzchołki wyznacza się w polu coord węzeła Coordinate. Zdefiniowane punkty łączy się według ustalonych zasad w polu coordIndex węzła IndexedfaceSet. Wartość -1 w polu coordIndex wskazuje na to, że kończy się definicja pierwszego wielokąta i zaczyna następnego. Jeśli liczba zdefiniowanych punktów w węźle Coordinate wynosi N, to liczba wartości w coordIndex powinna być N-1. Wynika to z indeksowania od 0 do N. Każda zdefiniowana ściana obiektu powinna zawierać przynajmniej trzy nie pokrywające się wierzchołki, które definiują płaski wielokąt. 3/21 126 42 Tworzenie złożonych obiektów #VRML V2.0 utf8 Transform { translation 0 0 0 rotation 0 1 0 -3.14 children [ Shape { appearance NULL geometry IndexedFaceSet { coord Coordinate { point [ -1 -1 0, #punkt [0] -1 1 0, #punkt [1] 1 1 0, #punkt [2] 1 -1 0 ] #punkt [3] } coordIndex [0, 1, 2, 3, -1] } } ] 4/21 PRZYKŁAD } 127 Tworzenie złożonych obiektów Pole ccw określa porządek współrzędnych wierzchołków użytych w celu utworzenia bryły. Jeżeli w polu tym znajdzie się wartość TRUE, oznacza to, że wierzchołki tworzące jedną ścianę bryły definiowane są w kierunku przeciwnym do ruchu wskazówek zegara. Jeżeli pole to przyjmie wartość FALSE, będzie to oznaczać, że wierzchołki będą definiowane zgodnie z ruchem wskazówek zegara. W polu solid wartość FALSE oznacza, że każdy z wielokątów wchodzących w skład definiowanej bryły będzie wyświetlany niezależnie od tego, czy użytkownik ma ku niemu zwrócony wzrok czy nie. Wartość TRUE powoduje, że niewidoczne wielokąty nie są wyświetlane, dzięki czemu wyświetlanie świata jest płynniejsze. Pole convex wskazuje na to, czy wszystkie ściany kształtu są wypukłe. 128 5/21 Tworzenie złożonych obiektów W polach color, normal, texCoord można zdefiniować odpowiednio węzły Color, Normal i TextureCoordinate. Użycie tych węzłów wiąże się również z zastosowaniem pozostałych pól węzła IndexedFaceSet: colorIndex, colorPerVertex, normalIndex, normalPerVertex, texCoordIndex. Zależności między tymi wszystkimi elementami opisują dosyć złożone zasady: 6/21 129 43 Tworzenie złożonych obiektów W polu color umieszcza się definicję węzła Color. Jeżeli pole color pozostanie niezdefiniowane, całemu obiektowi zostanie przypisany kolor bądź tekstura zdefiniowana w węźle Appearance. Jeżeli zostanie określony węzeł Color, to należy zdecydować czy kolory, które w nim są zdefiniowane, będą przypisane do każdego wierzchołka czy do każdej ściany. 130 7/21 Tworzenie złożonych obiektów 1. W przypadku gdy pole colorPerVertex będzie miało wartość TRUE to kolory będą przypisane do wierzchołków: a. W polu colorIndex przyporządkowuje się kolory do każdego wierzchołka w ten sam sposób jak przy indeksowaniu wielokątów w polu coordIndex. Pole coordIndex musi zawierać tyle samo wartości, co pole coordIndex, a definicja każdego koloru musi się kończyć wartością -1. Jeśli w węźle Color jest zdefiniowanych N kolorów, to w polu colorIndex powinno się znaleźć N-1 indeksów. b. Jeśli pole colorIndex zostanie puste, wtedy przeglądarka do nałożenia kolorów użyje wartości znajdujących się w polu coordIndex. 131 8/21 Tworzenie złożonych obiektów 2. W przypadku gdy pole colorPerVertex będzie miało wartość FALSE, to kolory przypisane będą do ścian obiektu: a. W polu colorIndex przyporządkowuje kolory do każdej ściany obiektu. Liczba wartości w tym polu musi być przynajmniej równa liczbie zdefiniowanych ścian. Jeśli w węźle Color jest zdefiniowanych N kolorów, to w polu colorIndex powinno się znaleźć N-1 indeksów. b. Jeżeli pole colorIndex zostawimy puste, to na ściany obiektu zostaną nałożone kolory w takiej kolejności, w jakiej występują w węźle Color. W węźle Color musi się znajdować przynajmniej tyle definicji kolorów, ile obiekt ma ścian. 9/21 132 44 Tworzenie złożonych obiektów Jeżeli w polu normal zdefiniowany będzie węzeł Normal, to wektory normalne względem wierzchołków lub ścian obiektu określa w sposób opisany poniżej: Pole colorPerVertex odpowiada polu normalPerVertex, a pole colorIndex odpowiada polu normalIndex. Jeżeli pole normal zostanie niezdefiniowane, to przeglądarka automatycznie obliczy wektory normalne na podstawie pola creaseAngle. 133 10/21 Tworzenie złożonych obiektów Jeśli nie określi się węzła TextureCoordinate w polu texCoord, to tekstura na zdefiniowany obiekt zostanie nałożona domyślnie. Natomiast jeżeli zdefiniuje się węzeł TextureCoordinate, tekstura na obiekt stworzony w węźle IndexedFaceSet zostanie nałożona w sposób opisany poniżej: 1. Wartości w polu texCoordIndex wskazują, które współrzędne tekstury (określone w węźle TextureCoordinate), do jakich wierzchołków mają zostać przypisane. Przyporządkowanie to opiera się na tych samych zasadach co w polu coordIndex. Liczba wartości w polu texCoordIndex musi być przynajmniej równa liczbie wartości w polu coordIndex. 2. Jeśli pole texCoordIndex zostanie nie zdefiniowane, do nałożenia tekstury zostaną wybrane wartości z pola coordIndex. 134 11/21 Tworzenie złożonych obiektów IndexedLineSet { eventIn MFInt32 set_colorIndex eventIn MFInt32 set_coordIndex NULL exposedField SFNode color exposedField SFNode coord NULL field MFInt32 colorIndex [] field SFBool colorPerVertex TRUE field MFInt32 coordIndex [] } 12/21 135 45 Tworzenie złożonych obiektów Węzeł IndexedLineSet tworzy linie w przestrzeni trójwymiarowej przebiegające między zdefiniowanymi wierzchołkami. Wierzchołki te definiuje się w polu coord, w którym umieszcza się definicję węzła Coordinate. Kolejność łączenia wierzchołków ustanawia się tworząc indeks w polu coordIndex, gdzie definiowane jednej linii kończy się wartością1. Linie zdefiniowane w tym polu nie uczestniczą w kolizji, nie można na nie również nałożyć tekstury ani ich oświetlić. Ich szerokość zależy od tego, jak przeglądarka interpretuje węzeł IndexedLineSet. Można natomiast nadać im dowolny kolor. 136 13/21 Tworzenie złożonych obiektów Jeżeli w polu color zdefiniuje się węzeł Color, to kolory zdefiniowane w tym węźle można zastosować następująco: 1. Jeżeli pole colorPerVertex ma wartość FALSE: a. W polu colorIndex musi się znaleźć przynajmniej tyle indeksów, ile jest zdefiniowanych linii. Jeśli w węźle Color jest zdefiniowanych N kolorów, to w polu colorIndex powinno się znaleźć N-1 indeksów. b. Jeśli w polu colorIndex nie wprowadzi się żadnych wartości, to kolory zostaną nałożone na linie w takiej kolejności, w jakiej znajdują się w węźle Color. W związku z tym w węźle Color musi znajdować się przynajmniej tyle definicji kolorów, ile w węźle IndexedLineSet jest zdefiniowanych linii. 137 14/21 Tworzenie złożonych obiektów 2. Jeżeli pole colorPerVertex ma wartość TRUE: a. Korzystając z pola colorIndex przypisuje się każdemu wierzchołkowi inny kolor. Pole colorIndex powinno zawierać przynajmniej tyle indeksów, ile znajduje się w polu coordIndex. Jeśli w węźle Color jest zdefiniowanych N kolorów, to w polu colorIndex powinno się znaleźć N-1 indeksów. Na końcu każdego indeksu w polu colorIndex musi się znaleźć wartość - 1 w tych samych miejscach co w polu coordIndex. b. Jeśli pole colorIndex pozostanie puste, to do nałożenia kolorów na linie zostaną wykorzystane wartości z pola coordIndex. Jeśli w polu color nie zdefiniuje się węzła Color, to na wszystkie linie zostanie nałożona barwa określona w polu emissiveColor węzła Material. 15/21 138 46 Tworzenie złożonych obiektów #VRML V2.0 utf8 Transform { translation 0 0 0 rotation 0 1 0 -3.14 children [ Shape { appearance NULL geometry DEF Trojkat IndexedLineSet { coord Coordinate { point [ 1 0 0, -1 0 0, 010] } coordIndex [0, 1, 2, 0, -1] } } Transform { rotation 0 1 0 -1.57 children [ Shape { geometry USE Trojkat } ] } Transform { rotation 0 1 0 -0.8 children [ Shape { geometry USE Trojkat } ] } Transform { rotation 0 1 0 0.8 children [ Shape { geometry USE Trojkat } ] } ] } PRZYKŁAD 139 16/21 Tworzenie złożonych obiektów PointSet { exposedField SFNode color exposedField SFNode coord } NULL NULL 140 17/21 Tworzenie złożonych obiektów Węzeł PointSet definiuje punkty w przestrzeni trójwymiarowej. Każdemu z punktów można nadać inny kolor. W polu coord można zdefiniować węzeł Coordinate, w którym wprowadza się współrzędne punktów. W polu color natomiast umieszcza się węzeł Color, w którym każdemu z punktów określonych w polu coord przypisuje się określony kolor. Jeżeli pole color będzie miało wartość NULL, a w węźle Shape, w którym definiuje się węzeł PointSet, znajdzie się definicja węzła Material to dla wszystkich zdefiniowanych punktów powinien zostać przyjęty kolor określony w polu emissiveColor. 18/21 141 47 Tworzenie złożonych obiektów Extrusion { eventIn MFVec2f set_crossSection eventIn MFRotation set_orientation eventIn MFVec2f set_scale eventIn MFVec3f set_spine field SFBool beginCap TRUE field SFBool ccw TRUE field SFBool convex TRUE field SFFloat creaseAngle 0 field MFVec2f crossSection [ 1 1, 1 -1, -1 -1, -1 1, 1 1 ] field SFBool endCap TRUE field MFRotation orientation 0010 field MFVec2f scale 11 field SFBool solid TRUE field MFVec3f spine [ 0 0 0, 0 1 0 ] } 142 19/21 Tworzenie złożonych obiektów Dzięki węzłowi Extrusion można utworzyć trójwymiarowy obiekt o dowolnym kształcie. Na początku w polu crossSection tworzy się dwuwymiarowy przekrój bryły. Następnie w polu spine definiuje się trójwymiarowe wektory nadając przekrojowi trzeci wymiar. Każdemu punktowi opisanemu w polu spine można przypisać operację skalowania (pole scale) lub obrotu (pole orientation). Liczba wartości w tych polach musi być identyczna z liczbą wartości w polu spine. Aby w polu scale uzyskać efekt zmiejszenia, wartości muszą zawierać się między 0 a 1. Wartości powyżej 1 będą powodowały zwiększanie obiektu. Obiekt utworzony przez węzeł Extrusion składa się z trzech części: płaszczyzn stanowiących boki obiektu oraz przestrzeni wyznaczonej przez pierwszą i ostatnią wartość w polu spine. Za zamknięcie tej pierwszej przestrzeni odpowiada pole beginCap, a za zamknięcie przestrzeni końcowej pole endCap. Pola te nie mają wpływu na wygląd obiektu, jeżeli punkty określone w polu crossSection będą tworzyły zamkniętą bryłę. 143 20/21 Tworzenie złożonych obiektów #VRML V2.0 utf8 Shape { appearance Appearance { material Material { diffuseColor 0 1 1 } } geometry Extrusion { creaseAngle 0 crossSection [0.92 -0.38,0.38 -0.92,-0.38 -0.92,-0.92 -0.38, -0.92 0.38, -0.38 0.92,0.38 0.92,0.92 0.38, 0.92 -0.38 ] spine [ 0 -2 0, 0 -1.5 0, 0 -1 0, 0 -0.5 0, 0 0 0, 0 0.5 0, 0 1 0, 0 1.5 0, 0 2 0 ] scale [ 2 2, 1.7 1.7, 1 1, 0.7 0.7, 1.5 1.5, 0.7 0.7, 1 1, 1.7 1.7, 1 1 ] } 21/21 } PRZYKŁAD 144 48 VRML/X3D jako język zapisu geometrii konstrukcji i nie tylko... KONIEC 145 49