Ponieważ wszystkie te węzły mają podobną budowę proponuję abyśmy zaczęli od wyjaśnienia elementów wspólnych dla tych trzech węzłów.
Po pierwsze każdy z nich posiada pole offset (typu SFVec3f) i autoOffset, które odpowiadają za zapamiętanie stanu ostatniego przesunięcia (lub obrotu) obiektu. Jeśli pole autoOffset ma ustawioną wartość TRUE (wartość domyślna) 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 rozpocznie się właśnie od tego miejsca.
Pola maxPosition i minPosition (oba typu SFVec2f) wyznaczają granice wychylenia obiektu. W momencie gdy pole autoOffset będzie miało wartość FALSE możemy zdefiniować własny punkt, z którego zacznie się przesuwanie obiektu przy uaktywnieniu tych węzłów czujnikowych. Punkt ten definiujemy w polu offset.
Po drugie wszystkie z tych węzłów zawierają zdarzenie trackPoint_changed (typu SFVec3F), które zostaje wysłane w chwili 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 jakiegoś obiektu, to obiekt będzie się przesuwał w ślad za kursorem myszki. Spójrzmy na przykład.
#VRML V2.0 utf8
DEF Obiekt Transform {
children [
Shape {
appearance Appearance {
material Material {
diffuseColor 0 1 0 }
}
geometry Cone {}
}
]
}
DEF Czujnik SphereSensor {}
ROUTE Czujnik.rotation_changed
TO Obiekt.set_rotation
ROUTE Czujnik.trackPoint_changed
TO Obiekt.set_translation
Powyższy przykład pozwala przy wciśniętym klawiszu myszki jednocześnie przesuwać obiekt jak i nim obracać. Za przesunięcie odpowiada tutaj powiązanie zdarzeń trackPoint_changed węzła SphereSensor ze zdarzeniem set_translation węzła Transform - takie rozwiązanie prowadzi do tego, że węzeł SphereSensor działa jak węzeł PlaneSensor (patrz niżej). Obrót obiektu uzyskujemy poprzez powiązanie zdarzeń rotation_changed węzła SphereSensor ze zdarzeniem set_rotation węzła Transform.
PlaneSensor {
exposedField SFBool
autoOffset TRUE
exposedField SFBool
enabled
TRUE
exposedField SFVec2f
maxPosition -1 -1
exposedField SFVec2f
minPosition 0 0
exposedField SFVec3f
offset
0 0 0
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.
Przesunięcia dokonuje użytkownik klikając i przytrzymując klawisz myszki
na aktywnym obiekcie. Tam gdzie użykownik skieruje myszkę tam powinien
przesunąć się obiekt. Oczywiście węzeł PlaneSensor
daje możliwość ograniczenia przesunięcia obiektu. W polach maxPosition
i minPosition
określamy granice, w których można obiekt przemieszczać. Pierwsza wartość
w tych polach dotyczy osi X a druga osi Y. Pozostawienie wartości domyślnych
spowoduje, że użytkownik będzie mógł przemieszczać aktywny obiekt bez ograniczeń.
Poniższy przykład przedstawia czerwony sześcian, który możemy przemieszczać w obszarze ograniczonym w polach maxPosition i minPosition. Ponadto została zmieniona domyślna wartość pola offset - po wyłączeniu wartości domyślnej poprzez nadanie polu autoOffset wartości FALSE - w polu offset określone zostało miejsce, z którego zacznie się przesuwanie obiektu, gdy po raz drugi uaktywnimy węzeł PlaneSensor.
#VRML V2.0 utf8
DEF Obiekt Transform {
children [
Shape {
appearance
Appearance { material Material {
diffuseColor 1 0 0 }
}
geometry Box
{size 2 2 0.1} }
]
}
DEF Czujnik PlaneSensor {
autoOffset
FALSE
offset 0 0
0
minPosition
-1 -1
maxPosition
2 2 }
ROUTE Czujnik.translation_changed TO Obiekt.set_translation
Proszę zobaczyć jak powyższy przykład wyświetli wasza przeglądarka.
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
}
Węzeł CylinderSensor
działa podobnie jak węzeł PlaneSensor
z tą tylko różnicą, że aktywny obiekt nie jest przesuwany a obracany i
to obracany tylko względem osi Y.
#VRML V2.0 utf8
DEF Obiekt Transform {
children [
Shape {
appearance Appearance {
material Material {
diffuseColor 1 0 0 }
}
geometry Box {size 2 2 0.1}
}
]
}
DEF Czujnik CylinderSensor
{
autoOffset
TRUE
minAngle -1
maxAngle 1
}
ROUTE Czujnik.rotation_changed TO Obiekt.set_rotation
Powyższy przykład przedstawia nam ten sam sześcian tym razem poddany działalności węzła CylinderSensor. Pola minAngle i maxAngle typu SFFloat mają tę samą funkcję co pola minPosition i maxPosition w węźle PlaneSensor, z tą tylko różnicą, że dotyczą one obrotu obiektu, a wartości tych pól wyrażamy w radianach.
SphereSensor {
exposedField SFBool
autoOffset TRUE
exposedField SFBool
enabled
TRUE
exposedField SFRotation
offset
0 1 0 0
eventOut
SFBool isActive
eventOut
SFRotation rotation_changed
eventOut
SFVec3f trackPoint_changed
}
Węzeł SphereSensor
działa prawie identycznie jak CylinderSensor.
Różnica polega na tym, że dzięki węzłowi SphereSensor możemy dany obiekt
obracać we wszystkich kierunkach.
Rozszyfrowanie pól w tym węźle, w świetle wcześniejszych wyjaśnień, nie powinny sprawić kłopotów. Przyjrzyjmy się więc przykładowi:
#VRML V2.0 utf8
DEF Obiekt Transform {
children [
Shape {
appearance Appearance {
material Material {
diffuseColor 0 0 1 }
}
geometry Cone { height 4
bottomRadius 1 }
}
]
}
DEF Czujnik SphereSensor {
enabled TRUE
autoOffset TRUE }
ROUTE Czujnik.rotation_changed
TO Obiekt.set_rotation