|
VRML (2) Tworzenie ANIMACJI |
|||
Kamil D▒bkowski | |||
W poprzednim odcinku naszego kursu zobaczyli╢my, jak z najprostszych bry│ (kula, sto┐ek, walec) mo┐na tworzyµ obiekty z│o┐one. Oczywi╢cie, w VRML mo┐emy definiowaµ obiekty o dowolnych kszta│tach.
W
tym celu musimy zdefiniowaµ punkty w przestrzeni tr≤jwymiarowej oraz metodΩ, jak▒ te punkty bΩdziemy │▒czyµ. MetodΩ ustanawiamy poprzez zastosowanie odpowiedniego wΩz│a. I tak, wΩze│ IndexedFaceSet │▒czy te punkty tworz▒c bry│y, wΩze│ IndexedLineSet │▒czy zdefiniowane punkty liniami, a wΩze│ PointSet powoduje, ┐e zdefiniowane punkty wy╢wietlane s▒ jako pojedyncze punkciki. Przyk│ad zwyk│ego prostopad│o╢cianu - tym razem wykorzystuj▒cego wΩze│ IndexedFaceSet, a nie wΩze│ Box (kt≤rego zastosowanie by│oby oczywi╢cie o wiele prostsze), przedstawia Listing 1 znajduj▒cy siΩ na kr▒┐ku ENTER CD 1/98 w katalogu LISTINGI.
Wprowadzamy ruch
Skupmy siΩ na temacie wprowadzania w ruch zdefiniowanych obiekt≤w. Aby dokonaµ animacji musimy, po pierwsze, ustaliµ warunki trwania animacji w czasie (czas pocz▒tku, ko±ca, szybko╢µ itd.) u┐ywaj▒c w tym celu wΩz│a TimeSensor oraz okre╢liµ trasΩ animacji, czyli drogΩ po jakiej bΩdzie porusza│ siΩ obiekt - a tego dokonujemy z kolei definiuj▒c wΩz│y interpolacji. Interpolacja polega na tym, ┐e po okre╢leniu kilku punkt≤w, do kt≤rych obiekt ma zmierzaµ, przegl▒darka sama oblicza trasΩ miΩdzy tymi punktami. W zale┐no╢ci od zastosowanego typu wΩz│a interpolacji trasa ta mo┐e prowadziµ zar≤wno po prostej, jak i po krzywej.
1. Zdarzenia, kt≤re wysy│aj▒ zdarzenie posiadaj▒ etykietΩ event_ out, natomiast zdarzenia, kt≤re przyjmuj▒ zdarzenie maj▒ etykietΩ event_in. Zdarzenia (lub pola), kt≤re mog▒ jednocze╢nie wysy│aµ i przyjmowaµ zdarzenia maj▒ etykietΩ exposedField.
Przejd╝my do praktyki Fragment programu, kt≤rego listing zamieszczono na kr▒┐ku ENTER CD 1/98 (Listing 2), pokazuje przyk│ad najprostszej animacji. Na pocz▒tku mamy zdefiniowane dwa wΩz│y, kt≤re jeszcze s▒ nam nie znane. Pierwszy z nich to NavigationInfo, kt≤ry m≤wi przegl▒darce o warunkach, w jakich u┐ytkownik bΩdzie eksplorowa│ ╢wiat wirtualny. Mo┐na tu okre╢liµ takie opcje jak: wymiary avatara (uczestnika ╢wiata), w│./wy│. ╢wiat│o headlight, prΩdko╢µ poruszania siΩ po ╢wiecie, rodzaj eksploracji (chodzenie, badanie, latanie), ograniczenie widoczno╢ci. W naszym przyk│adzie mamy wy│▒czone ╢wiat│o headlight i mamy jedynie mo┐liwo╢µ badania (EXAMINE) obiekt≤w na scenie. Drugim nie stosowanym przez nas jeszcze wΩz│em jest wΩze│ Viewpoint. Mo┐emy w nim zdefiniowaµ (bardzo wiele) punkt≤w patrzenia na ╢wiat VRML. WΩze│ ten jest szalenie pomocny przy eksploracji ╢wiata, zw│aszcza dla os≤b, kt≤re jeszcze nie najlepiej s▒ zapoznane z przegl▒dark▒ VRML. W naszym przyk│adzie pierwszy viewpoint nazywa siΩ START i umieszczony jest na dodatniej osi Z, a "kamera" skierowana jest domy╢lnie w prz≤d. NastΩpnie widzimy dobrze znany nam wΩze│ DirectionalLight, kt≤ry odpowiada za o╢wietlenie obiekt≤w zgromadzonych w wΩ╝le grupuj▒cym - w tym przypadku o╢wietli on nasz▒ kulΩ w kierunku ujemnej strony osi X, czyli z prawej strony na lew▒. Definiowanie element≤w animacji
Najpierw okre╢lamy warunki "czasowe" dla ruchu naszego obiektu wprowadzaj▒c wΩze│ TimeSensor. Jak widzimy przed definicj▒ wΩz│a umieszczona jest (ju┐ nam znajoma) komenda DEF i nazwa wΩz│a "CzasRuchu". DEFiniowanie, czyli "wrzucanie do pamiΩci" nazw, kt≤re bΩd▒ reprezentowaµ dane wΩz│y jest niezbΩdne potem przy u┐yciu komendy ROUTE. W wΩ╝le TimeSensor najistotniejszymi obecnie dla nas s▒: loop i cycleInterval. Pole loop odpowiada za to, czy animacja ma siΩ ci▒gle powtarzaµ (pole to mo┐e przybieraµ warto╢ci typu SFBool, czyli TRUE lub FALSE). Pole cycleInterval odpowiada za prΩdko╢µ animacji - im wiΩksza warto╢µ w tym polu, tym animacja bΩdzie wolniejsza.
ROUTE [nazwa zDEFiniowanego wΩz│a].[zdarzenie_changed] TO [nazwa zDEFiniowanego wΩz│a].[set_zdarzenie] W pierwszej linii widzimy powi▒zanie zdarzenia wΩz│a TimeSensor fraction_changed ze zdarzeniem wΩz│a OrientationInterpolator set_fraction (warto╢ci typu SFFloat). Stworzyli╢my wiΩc podstawΩ animacji: czas powi▒zali╢my z tras▒. W drugiej linii komend▒ ROUTE do trasy animacji przyporz▒dkowujemy ju┐ konkretny obiekt │▒cz▒c zdarzenie value_changed wΩz│a OrientationInterpolator z polem exposedField rotation (zapisuj[KD1]▒c jako set_rotation) wΩz│a Transform (warto╢ci typu SFRotation). Aby dok│adnie przeanalizowaµ po│▒czenie tych zdarze±, proponujΩ siΩgn▒µ do szczeg≤│owego opisu wΩz│≤w TimeSensor, OrientationInterpolator i Transform, kt≤ry mo┐na znale╝µ w specyfikacji VRML 97 (www.vrml.org/Specifications/VRML97/DIS/index.html). Tworzymy karuzelΩ
Skoro ju┐ wiemy, jak wprowadziµ dany obiekt w ruch, spr≤bujmy trochΩ rozbudowaµ nasz przyk│ad i stworzyµ cyberkaruzelΩ. Wyobra╝my sobie, ┐e siedzeniami bΩd▒ cztery kule, punkt obrotu karuzeli bΩdzie stanowi│ walec, a siedzenia do punktu centralnego po│▒czymy prΩtami (bardzo w▒skimi walcami). Zacznijmy od pomno┐enia liczby siedze± (kul). Zastosujemy tutaj dobrze nam znany
(i lubiany) mechanizm DEF/USE. WΩze│, kt≤ry bΩdziemy chcieli ponownie przywo│aµ jest ju┐ zDEFiniowany i nazywa siΩ "ObrotKuli" - pozostaje nam wiΩc tylko przywo│aµ ten wΩze│ jeszcze trzykrotnie w innych miejscach. Poni┐sze linie dopiszmy przed (lub po) definicji tras:
LISTING 3 - znajduje siΩ na kr▒┐ku ENTER CD 1/98
w katalogu LISTINGI.
DEF Karuzela Viewpoint { orientation 0 1 0 1.57 position 0 2 0 description "Siedzenie" } A do definicji tras animacji dodajmy liniΩ: ROUTE CzasRuchu.isActive TO Karuzela.set_bind
Transform { translation 20 -1 0 children Inline { url "drzewko.wrl" } }
Zadanie dla Czytelnik≤w: stw≤rzcie drzewko (np. ze sto┐ka i kuli), sw≤j plik nazwijcie drzewko.wrl i uruchomcie w waszej przegl▒darce powy┐ej zdefiniowany ╢wiat. Powinno dzia│aµ. PS. Zastosujcie mechanizm DEF/USE do zwiΩkszenia liczby drzew. Wszelkie pytania do mnie mo┐na kierowaµ pod adres bombadil@novell.ibin.uw.edu.pl. (c) Copyright LUPUS |