Arsip mwmag[Files]  [Up]© 2002 PT Masterweb Media

Tutorial VRML Bagian 3:

Goyang Dong!

  1. Node Sensor Lingkungan
  2. Node TimeSensor
  3. Mengenal InterpolatorNode
  4. Membuat Animasi Warna
  5. Prototipe
  6. Membuat Animasi Gerak Putar
  7. Penutup

Figures

  1. Cara kerja field node TimeSensor
  2. Fungsi linear pada interpolator
  3. Pendekatan relasi tidak linear dengan beberapa fungsi linear
  4. Routing untuk menggunakan node interpolator
  5. Animasi warna permukaan kerucut
  6. Animasi gerak putar

Files

  1. demo_1.wrl
  2. demo_2.wrl

 

Oleh Eko Bono Suprijadi

Setelah mengenal cara berkomunikasi pada VRML lewat even, pada bagian ketiga kita akan membahas tema yang lebih kompleks, yaitu cara membuat animasi. Basis dari animasi adalah node timer sebagai pemberi perintah kapan scene berikut harus dibangun. Sedang untuk memanipulasi objek 3D dalam setiap scene, secara prinsip ada dua cara yang dapat digunakan, yaitu dengan node interpolator dan bahasa skrip. Artikel kali ini akan mengenalkan cara pembuatan animasi memakai cara pertama, yaitu dengan node interpolator. Setelah pembahasan node TimeSensor serta node interpolator, di akhir artikel ditunjukkan urutan kerja pembuatan sebuah animasi.

Node Sensor Lingkungan

Pada artikel terdahulu telah diterangkan tentang jenis node sensor pointing device di mana TouchSensor termasuk salah satu node jenis ini. Kali ini kita akan membahas sedikit tentang jenis node sensor yang satu lagi yaitu node sensor lingkungan.

Komunikasi yang kita bahas sebelumnya hanya dapat terjadi kalau user dengan mousenya melakukan aksi. Tentu saja ini belum cukup. Bayangkan seandainya Anda sedang berjalan-jalan di dunia virtual ini, dan Anda ingin merasakan “enaknya” bertumbukan dengan objek 3D yang telah Anda buat. Atau jika Anda menginginkan berapa lama Anda telah menghabiskan waktu Anda berjalan-jalan. Jangan kuatir, masalah demikian sudah diantipasi oleh para pembuat VRML. Node yang digunakan untuk kepentingan ini dimasukkan dalam jenis node sensor lingkungan. Termasuk dalam node jenis ini antara lain: Collision, ProximitySensor, TimeSensor, dan VisibilitySensor. Namun di sini kita hanya akan membahas node TimeSensor lebih detil, karena memegang peranan yang penting dalam pembuatan animasi.

Node TimeSensor

Node ini, seperti namanya, bekerja dengan memanfaatkan timer sebagai basisnya. Di VRML, titik waktu (timestamp) dihitung sejak tanggal 1 Januari 1970 dengan satuan detik. Jadi titik waktu 0.0 identik dengan waktu 00:00:00 1 Januari 1970. Field dari node ini adalah seperti berikut:

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
}

Untuk menentukan agar kerja node lain dari defaultnya, Anda dapat mengeset beberapa field seperti di bawah ini.

Field enabled. Jika nilai field ini FALSE maka node tidak berfungsi lagi sebagai penggenerasi even.

Field startTime menentukan kapan even pertama digenerasi.

Field stopTime menentukan kapan node ini berhenti menggenerasi even.

Field cycleInterval menspesifikasi jarak waktu ke penggenerasian even berikutnya dalam detik. Kerja field ini berhubungan dengan field loop. Jika nilai ini TRUE maka field cycleInterval akan dipakai untuk menstart timer secara berulang sampai titik waktu stopTime tercapai.

Setelah nilai field di atas diset, kita dapat memanfaatkan field even untuk melakukan penyambungan. Kegunaan utama even ini untuk merealisasikan animasi yang aktifitasnya dikontrol secara periodik ataupun cuma sekali saja (one shoot).

Field isActive akan mengirim even bernilai TRUE jika TimeSensor menstart timernya, dan bernilai FALSE jika timer berhenti.

Field cycleTime akan mengirim even pada saat timer pertama distart dan pada titik waktu timerStart + k*cycleInterval di mana k=1,2,..., dengan waktu aktual sebagai nilainya.

Field fraction_changed digunakan untuk mensimulasikan penggenerasian even yang terus-menerus (kontinu). Bergantung pada kemampuan komputer, even ini akan digenerasi (secepat dan sebisanya hardware komputer) pada titik waktu sebelum even cycleTime digenerasi. Untuk lebih mengerti, coba Anda simak Gambar 1.


Fig 1. Cara kerja field node TimeSensor

Seperti terlihat pada gambar, even fraction_changed ini mempunyai nilai antara 0,0 dan 1,0. Sebagai ilustrasi, seandainya nilai cycleInterval diset 10 detik, sedang hardware komputer Anda hanya mampu menghasilkan even fraction_changed tiap 2 detik, maka nilai fraction_changed adalah kelipatan dari 0,2, yaitu 0,2, 0,4, 0,6 dan 0,8. Biasanya even ini dimanfaatkan untuk menghasilkan animasi yang kontinu, seperti yang dibutuhkan oleh node interpolator.

Mengenal InterpolatorNode

Node interpolator didesain untuk dapat membuat animasi dengan VRML berbasiskan metode interpolasi linear. Jenis variabel yang diinterpolasi bisa bermacam-macam, seperti variabel warna, koordinat, posisi maupun orientasi. Untuk itu didefinisikan beberapa jenis node interpolator: ColorInterpolator, CoordinateInterpolator, NormalInterpolator, OrientationInterpolator, PositionInterpolator, dan ScalarInterpolator. Walau demikian, semua jenis node di atas mempunyai jumlah field yang sama seperti berikut:

eventIn      SFFloat      set_fraction
exposedField MFFloat key [...]
exposedField MF<type> keyValue [...]
eventOut [S|M]F<type> value_changed

Kolom <type> di atas menunjukkan tipe data dari node interpolator yang bersangkutan, seperti pada ColorInterpolator mempunyai tipe data Color, node OrientationInterpolator mempunyai tipe data Rotation, node ScalarInterpolator mempunyai tipe data Float, serta node CoordinateInterpolator, NormalInterpolator maupun PositionInterpolator yang mempunyai tipe data sama yaitu Vec3f. Karena cara kerja semua node di atas sama, untuk menjelaskannya kita akan memakai node interpolator ScalarInterpolator yang mempunyai tipe data sederhana Float.

Dua field yang memegang peranan penting pada node interpolator ini adalah key dan keyValue. Kedua field tersebut merupakan field vektor (multifield) yang membentuk sebuah kamus (hash atau dictionary) yang mempunyai hubungan 1:1, artinya jumlah elemen dari field key harus sama dengan jumlah elemen keyValue. Atau dengan kata lain, relasi antara kedua field ini dapat dituliskan dengan fungsi:

keyValue = f(key)

di mana f(key) adalah fungsi linear.

Jika nilai key ini sudah tertentu, yaitu antara 0,0 dan 1,0, maka nilai keyValue ditentukan oleh user. Berikut contoh pendefinisian kamus dari kedua field tersebut:

key     [ 0.0  6.0]
keyValue[ 1.0 3.0]

Nilai 0,0 dari key menghasilkan nilai 1,0 di keyValue dan nilai 6,0 dari key menghasilkan nilai 3,0 di keyValue. Sedang nilai antara 0,0 dan 6,0 di key menghasilkan nilai antara 1,0 dan 3,0 di keyValue. Untuk mendapatkan nilai antara ini digunakan metode interpolasi linear, yang cara penghitungannya dapat memakai bantuan persamaan garis lurus. Seperti terlihat di Gambar 2, fungsi yang memetakan field key ke keyValue adalah:


Fig 2. Fungsi linear pada interpolator

keyValue = f(key) = (2/6) x key + 1

Secara umum, jika dua nilai batas key dan keyValue sudah didefinisikan seperti berikut:

key     [ k1  k2]
keyValue[ v1 v2]

maka nilai antara dari keyValue didapatkan dari fungsi berikut:

keyValue = f(key) = (v2-v1)/(k2-k1) x (key - k1) + v1

Pertanyaan yang mungkin timbul, apakah relasi tidak linear antara field key dengan keyValue juga dapat direalisasikan, dan jika ya bagaimana? Jawabnya bisa, tapi hanya sekedar pendekatan. Artinya fungsi tidak linear yang menggambarkan relasi itu harus diaproximasi dengan beberapa fungsi linear. Gambar 3 menjelaskan hal ini.


Fig 3. Pendekatan relasi tidak linear dengan beberapa fungsi linear

Fungsi nonlinear keyValue=f(key) diaproksimasi dengan tiga fungsi linear f1(key), f2(key) dan f3(key). Kamus dari key dan keyValue dapat didefinisikan seperti berikut:

key     [ 0.0  1.5  4.5  6.0] 
keyValue[ 1.0 2.7 2.7 1.0]

Untuk mendapatkan nilai yang tidak tercantum dalam kamus di atas, kembali digunakan interpolasi linear dari fungsi linear yang bersangkutan.

Oke, lalu bagaimana cara menggunakan nodenya sendiri dalam animasi? Untuk ini Anda harus tahu cara melakukan penyambungan (routing) pada node interpolator. Rantai routing pada interpolator biasanya mempunyai bentuk seperti terlihat pada Gambar 4.


Fig 4. Routing untuk menggunakan node interpolator

Field set_fraction sebagai penerima even harus disambungkan dengan field sumber even. Pada gambar di atas, sumber even fraction_changed dari node TimeSensor disambungkan ke even set_fraction dari node interpolator. Kemudian sumber even value_changed dari node interpolator harus disambungkan ke penerima even dari node objek yang diinginkan. Nah, jika field set_fraction menerima even, maka nilainya akan dijadikan nilai dari field key. Dari sini didapatkan nilai keyValue dengan cara melihat kamus yang sebelumnya sudah didefinisikan. Jika nilainya tidak tercantum, maka dilakukan interpolasi linear. Selanjutnya node interpolator akan mengirimkan even value_changed dengan nilai yang dipunyai keyValue.

Membuat Animasi Warna

Cukup dengan teori, sekarang kita akan membuat animasi sederhana menggunakan node TimeSensor dan ColorInterpolator. Animasi pertama yang akan kita buat di sini adalah objek kerucut yang warna permukaannya harus berubah-ubah dari merah ke hijau lalu ke biru, untuk kemudian balik lagi ke hijau dan kembali ke warna awal merah. Waktu yang dibutuhkan dalam perubahan warna dari merah ke merah lagi ini adalah 10 detik. Untuk itu mula-mula kita buat objek node TimeSensor.

# node TimeSensor dengan intervall 10 detik
DEF MyTimer TimeSensor {
cycleInterval 10
loop FALSE
}

Kita tidak membutuhkan loop, karena timer ini akan bekerja dengan mode one shoot, dan pengaktifannya dengan cara menekan tombol mouse yang akan kita lihat nanti.

Selanjutnya kita membuat objek ColorInterpolator. Karena kita ingin mendefinisikan 5 warna, maka jumlah elemen key juga harus 5. Yang harus Anda perhatikan di sini adalah tipe data field dari keyValue. Karena tipe datanya MFColor, maka nilai tiap elemen keyValue adalah juga bertipe data Color yang terdiri dari nilai merah (R), hijau (G) dan biru (B) yang masing.masing mempunyai nilai antara 0,0 dan 1,0.

# interpolator ini akan memberikan warna
# merah->hijau->biru->hijau->merah
DEF MyColInt ColorInterpolator {
key [0 0.25 0.5 0.75 1] # 5 elemen
keyValue [1 0 0, # 1.elemen warna merah
0 1 0, # 2.elemen warna hijau
0 0 1, # 3.elemen warna biru
0 1 0, # 4.elemen warna hijau
1 0 0 ] # 5.elemen warna merah
}

Sekarang saatnya kita membuat objek 3D yang berupa kerucut. Karena animasi akan diaktifkan dengan menekan tombol mouse di atas kerucut, maka kita juga harus mendefinisikan objek TouchSensor dalam objek kerucut kita.

DEF MyCone Transform {
children [
# Objek sensor
DEF MySensor TouchSensor {}
# Objek kerucut
Shape {
# Appearance
appearance Appearance {
material DEF MyColObj Material {
diffuseColor 1 1 1 # Warna awal adalah putih
}
}
# Geometry
geometry Cone {
bottomRadius 1
height 2
}
}
]
}

Setelah selesai membuat objek yang diperlukan, langkah terakhir adalah membangun sambungan antara node-node yang telah kita definisikan.

ROUTE MySensor.touchTime       TO MyTimer.startTime
ROUTE MyTimer.fraction_changed TO MyColInt.set_fraction
ROUTE MyColInt.value_changed TO MyColObj.set_diffuseColor

Dengan routing pertama, maka animasi warna akan dimulai setelah Anda menekan tombol mouse di atas objek kerucut yang mengaktifkan timer pada node TimeSensor. Pada routing kedua, nilai fraction_changed dari node TimeSensor akan dipakai sebagai nilai key dari node ColorInterpolator dengan cara menyambungnya ke penerima even set_fraction. Dengan routing ketiga yang menyambungkan even value_changed dari node ColorInterpolator ke even set_diffuseColor maka perubahan nilai warna keyValue akan mengubah warna permukaan kerucut.

Program di atas dapat Anda dapatkan di file demo_1.wrl (ambil dari mwmag.com/issue/07/content/tutorial-vrml-3/file/). Setelah diload, maka kerucut mula-mula mempunyai warna putih seperti terlihat pada Gambar 5. Setelah animasi diaktifkan, maka dalam waktu 10 detik warna permukaan kerucut berubah dari merah, hijau, biru dan balik lagi ke hijau, merah.


Fig 5. Animasi warna permukaan kerucut

Prototipe

Sebelum kita membahas contoh berikutnya berupa animasi gerak, ada baiknya kita mengetahui apa itu prototipe di VRML. Tujuan utama prototipe adalah penggunaan kembali kode yang sama di VRML. Selain itu dengan prototipe maka user dimungkinkan untuk mendefinisikan jenis node yang baru. Anda bisa membayangkannya sebagai fungsi pada bahasa pemrograman di C atau Pascal (bagi yang sudah mengenal bahasa pemrograman ini).

Pendeklarasian dengan prototipe dapat dilakukan di dalam file yang sama atau di file yang lain dari file utama VRML. Setiap prototipe dimulai dengan kata PROTO dan nama prototipe, kemudian dapat diikuti dengan sejumlah interface yang berada di dalam tanda kurung []. Interface ini berupa field yang diberi nilai default. Sesuai dengan perumpamaan fungsi, maka interface dapat dibayangkan sebagai parameter fungsi. Kemudian pendefinisian objek sendiri dapat dilakukan di dalam tanda kurung {}. Untuk menggunakan interface, digunakan kata IS di belakang field yang diinginkan. Berikut contoh pendeklarasian prototipe dengan interface boxColor yang nilai defaultnya berwarna hijau:

# KotakPanjang adalah nama prototipe
PROTO KotakPanjang [
field SFColor boxColour 0 1 0
]
# Pendefinisian objek
{
Shape {
appearance Appearance {
material Material {
# menggunakan interface sebagai nilai
# field diffuseColor
diffuseColor IS boxColour
}
}
geometry Box {
size 4 1 1
}
}
}

Untuk menggunakan prototipe, Anda tinggal menuliskan nama prototipenya diikuti dengan interface yang nilainya ingin Anda ganti di dalam tanda {}. Sebagai contoh, jika Anda ingin menggunakan prototipe KotakPanjang dengan warna merah maka Anda tinggal menuliskan:

KotakPanjang {boxColour 1 0 0}

Sederhana bukan? Oke, kita sekarang akan membuat animasi gerakan sekaligus memanfaatkan prototipe KotakPanjang di atas.

Membuat Animasi Gerak Putar

Berbasiskan animasi warna sebelumnya, sekarang kita akan membuat animasi gerak putar dengan memanfaatkan node OrientationInterpolator. Untuk itu kita definisikan objek node ini demikian:

# interpolator ini akan memberikan putaran sebesar
# 0->90->180->90->0 derajat
DEF MyOriInt OrientationInterpolator {
key [ 0, 0.25, .5, 0.75, 1.0 ]
keyValue [ 0 0 1 0,
0 0 1 1.57,
0 0 1 3.14,
0 0 1 1.57,
0 0 1 0 ]
}

Nilai keyValue di atas akan memutar objek dengan sumbu putar z sebesar 180 derajat, kemudian memutar objek ke posisi awal sebesar -180 derajat (berputar dengan arah berlawanan dari putaran pertama). Dengan objek TimeSensor yang sama seperti pada animasi warna, maka gerakan di atas juga dilakukan dalam waktu 10 detik.

Selanjutnya kita akan membuat objek kotak dengan panjang sisi 1 x 1 x 1. Objek yang kita beri warna biru ini akan diputar dengan sumbu putar Z yang merupakan sumbu center z dari objek kotak sendiri. Untuk mendapatkan animasi gerakan putar seperti lengan robot, maka kita membuat lagi sebuah objek KotakPanjang, yang pendefinisiannya dilakukan dengan prorotype seperti Anda lihat sebelumnya. Objek KotakPanjang ini dibuat dengan posisi centernya ditranslasi sebesar 2.5 0 0 relatif terhadap koordinat center dari objek kotak biru. Berikut ini adalah kode yang melakukan pekerjaan di atas:

# Ini adalah node Transform yang akan diputar 
DEF MyJoint Transform {
children [
# Objek sensor
DEF MySensor TouchSensor {}
# Objek kotak biru
Shape {
# Objek kotak biru
# Appearance
appearance Appearance {
material Material {
diffuseColor 0 0 1
}
}
# Geometry
geometry Box{ size 1 1 1 }
}
 
Transform {
translation 2.5 0 0
children [
# Objek kotakpanjang sebagai lengan robot
# kita beri warna merah
KotakPanjang {boxColour 1 0 0}
]
}
]
}

Setelah kita membuat semua objek yang diperlukan, tentunya kita masih harus melakukan routing. Dua routing pertama di animasi warna dapat kita gunakan dengan perubahan pada nama objeknya, sedang even yang dipakai tetap sama.

ROUTE MySensor.touchTime       TO MyTimer.startTime
ROUTE MyTimer.fraction_changed TO MyOriInt.set_fraction

Untuk menghasilkan gerakan putar, maka even value_changed harus kita sambung ke even set_rotation dari node Transform.

ROUTE MyOriInt.value_changed   TO MyJoint.set_rotation

Program di atas bisa Anda dapatkan dari mwmag.com juga, dengan nama demo_2.wrl. Setelah Anda berhasil meloadnya, maka dengan mengklik tombol mouse di atas objek, maka Anda akan melihat gerakan putar dari kedua objek kotak dan kotak panjang seperti pada Gambar 6.


Fig 6. Animasi gerak putar

Penutup

Untuk pembuatan animasi sederhana, maka node interpolator sudah mencukupi. Namun Anda akan segera menemui kesulitan begitu Anda ingin membuat animasi yang lebih kompleks yang memerlukan perhitungan rumit. Ini tidak terlepas dari VRML sebagai bahasa pemrograman deskripsi. Untuk merealisasikan animasi yang kompleks kita harus beralih ke konsep pemrograman sekuensial atau pemrograman fungsional. Ini dapat direalisasikan dengan bahasa skrip VRMLScript atau bahasa Java.

Artikel depan akan membahas tentang pemakaian bahasa skrip dan Java di VRML. Jika Anda masih bingung perbedaan antara Javascript, VRMLScript dan ECMAscript maka ikuti artikel berikut untuk mengetahuinya.

Eko Bono Suprijadi, programer C, sedang menempuh studi S3 di Jerman. Aktif di milis Linux, sering menulis artikel-artikel komputer di berbagai publikasi, dan juga menyempatkan diri menulis program. Dapat dihubungi di ekobono@yahoo.de.

mw

[Last-Modified: Wed Aug 14 12:26:27 2002]

Arsip mwmag[Files]  [Up]www.master.web.id/mwmag