Węzeł Script jest jednym z tych elementów języka VRML (obok tworzenia prototypów), które stanowią o jego rozszerzalności. Dzięki temu węzłowi można w świecie VRML zainicjować dowolne działanie, wykonać dowolną operację. Wszystko dlatego, że węzeł Script daje możliwość zastosowania funkcji JavaScript lub VRMLScript (klonu JavaScript) oraz programów napisanych w Javie. W węźle Script możemy utworzyć nowe pola i zdarzenia oraz przetwarzać ich wartości za pomocą funkcji skryptu.
Script {
exposedField MFString
url []
field
SFBool directOutput FALSE
field
SFBool mustEvaluate FALSE
# i dowolną liczbę
eventIn
nazwatypuzdarzenia eventName
field
nazwatypupola fieldName wartośćPoczątkowa
eventOut
nazwatypuzdarzenia eventName
}
Skrypt umieszczamy w polu url i jeżeli znajdzie się on bezpośrednio w pliku źródłowym, będzie to wyglądać mniej więcej tak:
Script { eventIn SFBool start
url "javascript:
function start (value, timestamp) { ... }"
}
Jeżeli skrypt umieszczony jest w innym miejscu sieci, musimy podać jego dokładny adres, na przykład:
...
url [ "http://www.enter.pol.pl/Java.class",
#dla programu Javy
"http://www.enter.pol.pl/JavaScript.js" ]
#dla skryptu JavaScript
...
Pożądany skrypt może być umieszczony w dowolnym miejscu sieci. Jak widać w polu url, może znaleźć się więcej odnośników do skryptów. W przypadku gdy przeglądarka nie zdoła połączyć się z plikiem określonym w pierwszej ścieżce dostępu, będzie próbowała ściągnąć kolejny plik itd.
Wartość FALSE w polu mustEvaluate będzie oznaczać, że przeglądarka może zwlekać z wysłaniem zdarzeń do skryptu, do czasu gdy to będzie konieczne, tzn. gdy jakieś zdarzenie będzie szukało miejsca, w którym może być odebrane. Wartość TRUE w polu mustEvaluate oznacza, że przeglądarka ma wysłać zdarzenia do skryptu najszybciej jak to tylko możliwe. Należy się wystrzegać używania wartości TRUE w tym polu, gdyż wpływa to niekorzystnie na płynność wyświetlania świata VRML.
Zanim przystąpimy do stosowania języka JavaScript przy tworzeniu scen VRML, warto jest się zapoznać z samym językiem JavaScript (książek na ten temat jest wiele). Jednak skrypty, które widzimy na stronach HTML różnią się nieco od tych, które możemy zastosować w VRML. Na przykład w VRML nie ma dostępnych większości metod JavaScriptu, takich jak alert() czy prompt(). O konwersji danych z JavaScriptu znanego z HTML-u na JavaScript stosowany w VRML jest mowa w ankesie specyfikacji.
Uruchamianie i dezaktywowanie skryptów
Korzystając z języka skryptu można zdefiniować metodę Initialize(). Jest to operacja, która powoduje uruchomienie skryptu zaraz po jego przeczytaniu przez przeglądarkę, a przed pokazaniem świata użytkownikowi i przed wysłaniem jakiegokolwiek innego zdarzenia. Wartość etykiety czasowej zdarzenia wygenerowanego przez metodę Initialize() jest mniejsza niż etykiet czasowych innych zdarzeń w skrypcie.
Skrypt może również zawierać metodę Shutdown(). Metoda ta powoduje, że działanie skryptu zostaje przerwane w momencie, gdy odpowiedni węzeł Script zostanie wykasowany lub gdy obecny świat VRML zostanie zastąpiony przez inny. Po wykonaniu tej operacji skrypt nie będzie już mógł wysłać żadnego zdarzenia, chociaż może to jeszcze zrobić podczas wykoanywania metody Shutdown(). Zdarzenia wysyłane podczas wykonywania operacji zamknięcia skryptu, które są połączone (ROUTE) ze zdarzeniami węzłów mającymi również w tej samej operacji zostać zamknięte, nie wywołują żadnego efektu.
Zasady dostępu do pól i zdarzeń
Zdarzenia przyjmowane przez węzeł Script są przesyłane do odpowiedniej metody zastosowanego języka skryptu. Nazwa metody zależy od rodzaju używanego języka. W niektórych przypadkach jest ona tożsama ze zdarzeniem eventIn, a czasem pełni rolę odwołującą się do wszystkim zdarzeń eventIn. Funkcja posiada dwa argumenty: wartość zdarzenia (value) i etykietę czasową zdarzenia (timestamp).
Pola i zdarzenia zdefiniowane w węźle Script mogą być użyte przy definiowaniu metody języka skryptu. Ponadto używając zdarzeń eventIn i eventOut węzeł Script może być normalnie łączony za pomocą tras z innymi węzłami. Pola zdefiniowane w węźle Script są dostępne dla skryptu poprzez specyficzny dla każdego języka mechanizm. Zdarzenia eventOut zdefiniowane w węźle skryptu mogą również być czytane, a wartość powracająca do tego zdarzenia staje się jej wartością ostatnią, czyli wartością, która zostanie wysłana do innego węzła, jeżeli jest zdefiniowana odpowiednia trasa.
Skrypt może mieć dostęp do wszystkich pól i zdarzeń węzłów, do których ten dostęp jest zdefiniowany. Składnia mechanizmu zależna jest od używanego języka. Poniższy przykład prezentuje jak węzeł Script ingeruje i modyfikuje pola w innym węźle (wysyła zdarzenie set_translation do węzła Transform) używając języka JavaScript:
DEF Przesun Transform { }
Script
{
field SFNode trnode USE Przesun
eventIn SFVec3f pos
directOutput TRUE
url "javascript:
function pos(value, timestamp) {
trnode.set_translation = value;
}"
}
Każdy język skryptu posiada mechanizm pozwalający skryptom wysyłać wartość poprzez pole eventOut zdefiniowane w węźle Script. Efekt wysyłania wielu wartości poprzez zdarzenie eventOut podczas wykonywania jednego skryptu okaże się dopiero w ostatnim zdarzeniu, które zostanie przez skrypt wysłane.
Skrypty JavaScript w węźle Anchor (patrz też część III )
W kodzie źródłowym VRML skrypty możemy umieszczać w dwóch miejscach: w polu url węzła Anchor lub Script. W obu przypadkach skrypty te nie mogą jednak wyglądać jednakowo i nie mogą pełnić tej samej funkcji. Węzeł Script nie umożliwia na przykład dostępu do metod JavaScipt nie opisanych w aneksie do specyfikacji VRML (czyli praktycznie do żadnych - patrz niżej). Skrypty JavaScriptu umieszczone w węźle Script w ogóle nie wyglądają jak skrypty na stronach HTML i nie możemy ich tak stosować. Jedynymi elementami, których możemy użyć z JavaScipt w węźle Script, są tak naprawdę tylko główne zasady, zarys działania oraz sposób myślenia. Zmienne, funkcje i metody musimy samodzielnie utworzyć, konwertując przy tym typy danych występujących w JavaScipt na typy pól i zdarzeń VRML (co opisuje aneks do specyfikacji).
Inaczej sprawa wygląda, kiedy zaczniemy używać skryptów w węźle Anchor. Przypomnijmy, że jest to węzeł odpowiadający za tworzenie odsyłaczy między światem VRML a innymi dokumentami odczytywanymi przez przeglądarkę VRML lub WWW. W polu url tego węzła możemy umieścić skrypty JavaScript dokładnie w tej samej postaci, w jakiej występują one na stronach HTML. Należy jedynie pamiętać, aby wszystkie znaki cudzysłowu zastąpić znakiem apostrofu - inaczej przeglądarka VRML takiego skryptu nie zaakceptuje.
Dzięki temu mamy możliwość dostępu do metod JavaScript takich jak alert() czy confirm().W łatwy sposób można pobierać dane od użytkownika i przetwarzać je, sprawdzając ich poprawność i podając wynik. Skrypty te jednak nie mogą przetwarzać zdarzeń VRML, a okna dialogowe wyświetlane na ekranie są oczywiście zwykłymi dwuwymiarowymi oknami windows, a nie trójwymiarowymi obiektami VRML. Pomimo to, możliwość zastosowania JavaScript w węźle Anchor daje bardzo wiele możliwości.
Niestety skryptów w węźle Anchor nie obsługuje przeglądarka WorldView 2.1
Przykłady
Poniższy skrypt umożliwia ustalenie wartości typu SFBool w zależności od jej obecnej warotści. Oznacza to, że możemy np. utworzyć włącznik światła, który będzie włączał światło gdy jest ono wyłączone i wyłączał gdy światło się pali. Zobaczmy na praktyczne zastosowanie tego skryptu.
DEF OnOff Script {
directOutput
FALSE
eventIn
SFTime lightswitch
mustEvaluate
FALSE
eventOut
SFBool on
field
SFBool onoroff FALSE
url "vrmlscript:
function lightswitch(){
if (onoroff==true) {
onoroff=false;
on=false; }
else{
onoroff=true;
on=true;}
}
"
}
Kolejny skrypt stanowi podobny mechanizm do powyższego ale tym razem możemy żonglować między wartościami typu SFTime co daje nam większe możliwości. Możemy dzięki temu skryptowi m.in otwierać i zamykać drzwi.
DEF OtworzZamknijDrzwi Script {
eventIn SFTime
touched
field SFTime
time 0
field SFInt32
mode 0
field SFTime
delay 1.0
eventOut SFTime
openStart
eventOut SFTime
closeStart
url "vrmlscript:
function
touched (value) {
if (value >= (time+delay))
{
time=value+.5;
mode=mode+1;
if (mode==1)
{
openStart=value; }
if (mode==2)
{
closeStart=value;
mode=0;
}
}
}
"
}
Więcej ciekawych skryptów znajdziecie w książce o VRML, która wkrótce
się ukaże nakładem wydawnictwa MIKOM.
Pozdrawiam
Kamil Dąbkowski