Pada modul ini kita akan membahas hierarchy object pada three.js. Sebelum membahas lebih jauh, pada modul ini akan digunakan class Clock, yang berguna untuk melakukan animasi.
Ada dua method Clock yang akan digunakan, yaitu
- getElapsedTime(), untuk menghitung waktu berlalu (elapsed) semenjak aplikasi dijalankan.
- getDelta(), untuk menghitung elapsed time, sejak fungsi clock dipanggil.
Untuk lebih detail bisa lihat dokumentasi di https://threejs.org/docs/#api/en/core/Clock
Untuk membuat object clock, gunakan perintah
clock = new THREE.Clock();
Perhatikan pada fungsi update(), untuk melakukan animasi, digunakan fungsi getElapsedTime, yang dimasukan kedalam fungsi sin(), agar mendapatkan nilai antara -1 s/d 1.
const theta = Math.sin(clock.getElapsedTime());
Gunakan template berikut untuk memulai tutorial.
var scene, camera, renderer, parts, clock;
init();
function init(){
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
camera.position.set(0, 3, 10);
const ambient = new THREE.HemisphereLight(0xffffbb, 0x080820);
scene.add(ambient);
const light = new THREE.DirectionalLight(0xFFFFFF, 1);
light.position.set( 1, 10, 6);
scene.add(light);
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
const controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.target.set(0,4,0);
controls.update();
//Add meshes here
clock = new THREE.Clock();
window.addEventListener( 'resize', resize, false);
update();
}
function update(){
requestAnimationFrame( update );
renderer.render( scene, camera );
const theta = Math.sin(clock.getElapsedTime());
}
function resize(){
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
Berikutnya buat box dengan ukuran pxlxt 1x1x3 sebanyak 4. Silakan gunakan material yang Anda inginkan, pada tutorial digunakan phong material.
Berikut code untuk menambahkan 4 box.
const geometry = new THREE.BoxBufferGeometry(1,2,1);
const material = new THREE.MeshPhongMaterial();
const box = new THREE.Mesh(geometry, material);
parts=[];
for(i=0; i<4; i++){
const mesh = box.clone();
parts.push(mesh);
mesh.position.y = i*2;
scene.add(mesh);
}
Lalu untuk animasi, pada fungsi update gunakan nilai theta untuk melakukan rotasi pada masing-masing box.
parts.forEach(part=>
part.rotation.z = theta
) ;
Kita berhasil menganimasikan box, dimana masing-masing box berotasi sendiri-sendiri. Yang ingin ditampilkan pada modul ini adalah seperti tangkai pohon, dimana rotasi box children dipengaruhi oleh rotasi box parent.

Mengatur Hierarchy Box
Untuk itu kita perlu memodifikasi code saat menambahkan box kedalam array parts.
parts=[];
for(i=0; i<4; i++){
const mesh = box.clone();
parts.push(mesh);
if(i==0){
scene.add(mesh);
}else{
mesh.position.y = 2;
parts[i-1].add(mesh);
}
}
JIka dijalankan, maka box akan beranimasi mengikuti parent dari masing-masing box.

Saat ini sumbu(origin point) dari box adalah center dari box. Anda bisa bereksperimen dengan mengubah origin point, dan animasi yang diperoleh akan sedikit berbeda.
Mengubah Origin Point
Perhatikan, box geometry menggunakan BoxBufferGeometry, karena lebih baik terhadap performa. Oleh karena itu untuk menggeser posisi origin agak sedikit rumit.
const pos = geometry.getAttribute('position');
for(let i=1; i<pos.array.length; i+=3){
pos.array[i] += 1;
}
Pertama ambil nilai attribute position dengan perintah getAttribute(‘position’);
Kemudian ambil value y (karena kita ingin mengubah nilai y dari titik origin. Untuk lebih jelas isi data dari array position yang diambil adalah.
vertex 0 = (array[0], array[1], array[2])
vertex 1 = (array[3], array[4], array[5])
Jadi untuk mengubah nilai y, kita perlu mengambil array ke-1, kemudian array ke-4 dan seterusnya.
Oleh karena itu for loop diatas dimulai dari i=1 dengan incremental i += 3.
Karena tinggi box adalah 2, untuk menggeser origin point, posisi y harus ditambah 1 (tinggi box dibagi 2).
TIPS
Jika Anda menggunakan BoxGeometry, maka untuk menggeser origin point digunakan code berikut:
geometry.vertices.forEach(vertex => vertex.y += 1);
Berikut code akhir dari tutorial ini.
See the Pen Hierarchy by SkillPlus (@SkillPlus) on CodePen.