Węzeł Extrusion, który omówimy na końcu tworzy obiekty trójwymiarowe z dwuwymiarowego planu obiektu.
W węźle IndexedfaceSet można utworzyć trójwymiarowy obiekt poprzez osobne zdefiniowanie każdej jego ściany. Ściany te sładają się z wielokątów, których wierzchołki wyznaczamy w polu coord typu SFNode (węzeł Coordinate). Zdefiniowane punkty łączymy 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 indeksie (pole coordIndex) powinna być N-1. Dzieje się tak dlatego, że indeksowanie przebiega 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.
Spójrzmy na przykład definiujący jeden wielokąt - kwadrat, bok sześcianu:
#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]
}
}
]
}
Na początku występuje standardowy opis węzła grupującego i węzła Shape odpowiadającego za tworzenie i wyświetlanie obiektów. Następnie w polu coord węzła IndexedfaceSet widzimy zdefiniowane w przestrzeni trójwymiarowej cztery punkty. W polu coordIndex następuje ich połączenie w odpowiedniej kolejności i zamknięcie wielokątu cyfrą -1.
Przyjrzyjmy się teraz innym polom węzła IndexedfaceSet. W polu ccw typu SFBool określamy 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.
W polach color, normal, texCoord możemy 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 (typu MFInt32), colorPerVertex, normalIndex, normalPerVertex, texCoordIndex. Zależności między tymi wszystkimi elementami opisują dosyć złożone zasady.
Zdarzenia, które węzeł IndexedfaceSet może przyjąć, można wykorzystać do przekształceń (animowania) każdego z pól, którego zdarzenia te dotyczą.
Za pomocą węzła IndexedfaceSet można tworzyć obiekty o dowolnych kształtach. Jednak węzeł ten żadko jest używany przez programistów piszących kody źródłowe światów z klawiatury. Węzeł ten jest natomiast nagminnie wykorzystywany przes edytory VRML (VRCreator, Home Space Designer) bo czyjest coś prostszego dla programu komputerowego niż zapisanie obiektów trójwymiarowych za pomocą liczb?
Stosowanie węzła IndexedfaceSet ma jednak pewien poważny minus. Tworzenie obiektów za pomocą tego węzła bardzo zwiększa wielkość pliku VRML, co tym samym wydłuża czas potrzebny na ściągnięcie pliku. Dlatego bardzo uważajcie ze stosowaniem tego węzła. Powyżej widzieliście zdefiniowany jeden bok sześcianu. Wyobraźcie sobie teraz, że chcecie utworzyć cały sześcian, czyli do powyższego przykładu należy dodać jeszcze definicję siedmiu ścian. Porównajcie to teraz z definicją węzła Box:
Box { size 2 2 2 }
Rezultat wizualny ten sam a o ile bardziej ekonomiczny.
IndexedLineSet {
eventIn
MFInt32 set_colorIndex
eventIn
MFInt32 set_coordIndex
exposedField SFNode
color
NULL
exposedField SFNode
coord
NULL
field
MFInt32 colorIndex []
field
SFBool colorPerVertex TRUE
field
MFInt32 coordIndex []
}
Węzeł IndexedLineSet
tworzy linie w przestrzeni trójwymiarowej przebiegające między zdefiniowanymi
wierzchołkami. Wierzchołki te definiujemy w polu coord,
w którym umieszczamy definicję węzła Coordinate.
Kolejność łączenia wierzchołków ustanawiamy tworząc indeks w polu coordIndex,
gdzie definiowanie jednej linii kończymy 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.
#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,
0 1 0 ]
}
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 }
]
}
]
}
Powyższy przykład pokazuje jak można uzyskać w miarę ciekawy efekt stosując węzeł IndexedLineSet i mechanizm DEF/USE.
Zasady użycia pól color, colorIndex i colorPerVertex opisane są tutaj.
PointSet {
exposedField SFNode
color NULL
exposedField SFNode
coord NULL
}
Węzeł PointSet definiuje punkty w przestrzeni trójwymiarowej. Każdemu z punktów możemy nadać inny kolor. W polu coord możemy zdefiniować węzeł Coordinate, w którym wprowadzamy współrzędne punktów. W polu color natomiast umieszczamy węzeł Color, w którym każdemu z punktów określonych w polu coord przypisujemy określony kolor.
Jeżeli pole color będzie miało wartość NULL, a w węźle Shape, w którym definiujemy 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.
Na punkty zdefiniowane w węźle PointSet nie mają wpływu światła zdefiniowane na scenie.
Wspaniałym przykładem wykorzystania węzła PointSet jest świat znajdujący się w naszej galerii Czarnej Dziury, pt: Virtual Head II.
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 0 0 1 0
field MFVec2f
scale
1 1
field SFBool
solid
TRUE
field MFVec3f
spine
[ 0 0 0, 0 1 0 ]
}
Dzięki węzłowi Extrusion możemy tworzyć trójwymiarowe obiekty o dowolnym wyglądzie. Najpierw w polu crossSection typu MFVec2f tworzymy dwuwymiarowy przekrój naszej bryły. Następnie w polu spine definiując trójwymiarowe wektory nadajemy przekrojowi trzeci wymiar.
Każdemu punktowi opisanemu w polu spine typu MFVec3f możemy przypisać operację skalowania (pole scale) lub obrotu (pole orientation). Jeżeli zdecydujemy się na zastosowanie tych pól, to 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ę zasadniczo 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łę.
Sposób działania pól ccw, solid i convex opisany został przy okazji omawiania węzła IndexedFaceSet.
Zobaczmy na przykład zastosowania węzła Extrusion:
#VRML V2.0 utf8
Shape {
appearance
Appearance { material Material {
diffuseColor 0 0 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, 2 2 ]
}
}
Bardzo namawiam do ekperymentów z tym węzłem gdyż można w nim uzyskać bardzo ciekawe efekty tworząc w sumie niewielki kod źródłowy. Plik, w którym ten sam obiekt utworzony by został węzłem IndexedFaceSet byłby o wiele większy.