Three.js анимирование объектов сцены
Доброго времени всем. Дали задание - есть чертёж фундамента из AutoCAD и необходимо сделать типо обучающего ресурса. Я конвертировал составляющие этого фундамента в формат .dae(collada). Долго бился над тем, как же в петле анимации сделать так, чтобы анимация(drop - объекты падают сверху) была для каждого объекта отдельно. Вроде бы получилось, но я уверен это не из лучших решений... Подскажите как улучшить следующий код(желательно чтобы были краткие примеры кода, чтобы по ним я мог ехать дальше...)
P.S. Заранее спасибо Собственно сам код: //container for render var container; //scene elements var camera, scene, renderer, controls; //downloaded items var objects = new Object(); //load manager var manager; //widnow size var SCREEN_WIDTH = window.innerWidth - document.getElementById('panel').offsetWidth; var SCREEN_HEIGHT = window.innerHeight; //list of files var filename = [ 'axes_1.dae', 'prepare_2.dae', 'base_3.dae', 'joint_4.dae', 'dump_course_5.dae', 'fbs_6.dae', 'joint_fbs_7.dae', 'joint_fbs_gor_8.dae', 'fbs_9.dae', 'joint_fbs_9.dae', 'joint_fbs_gor_10.dae', 'fbs_11.dae', 'joint_fbs_12.dae', 'joint_fbs_gor_13.dae', 'fbs_14.dae', 'joint_fbs_15.dae', 'air_course_16.dae', 'air_course_17.dae', ]; //path to files var path = 'stages/stage/'; // for animate objects var count = 0; var offset = 100; var step = 5; init(); load_models(); //function init() {...} function animate() { requestAnimationFrame(animate); controls.update(); render(); } function render() { if (selected !== null) { switch (selected.id) { case '1': if (count === 0) drop(objects['axes_1.dae'].children); if (count === 1) drop(objects['prepare_2.dae'].children); if (count === 2) selected = null; break; case '2': if (count === 0) drop(objects['base_3.dae'].children); if (count === 1) drop(objects['joint_4.dae'].children); if (count === 2) selected = null; break; case '3': if (count === 0) drop(objects['dump_course_5.dae'].children); if (count === 1) selected = null; break; case '4': if (count === 0) drop(objects['fbs_6.dae'].children); if (count === 1) drop(objects['joint_fbs_7.dae'].children); if (count === 2) drop(objects['joint_fbs_gor_8.dae'].children); if (count === 3) selected = null; break; case '5': if (count === 0) drop(objects['fbs_9.dae'].children); if (count === 1) drop(objects['joint_fbs_9.dae'].children); if (count === 2) drop(objects['joint_fbs_gor_10.dae'].children); if (count === 3) selected = null; break; case '6': if (count === 0) drop(objects['fbs_11.dae'].children); if (count === 1) drop(objects['joint_fbs_12.dae'].children); if (count === 2) selected = null; break; case '7': if (count === 0) drop(objects['joint_fbs_gor_13.dae'].children); if (count === 1) selected = null; break; case '8': if (count === 0) drop(objects['fbs_14.dae'].children); if (count === 1) drop(objects['joint_fbs_15.dae'].children); if (count === 2) selected = null; break; case '9': if (count === 0) drop(objects['air_course_16.dae'].children); if (count === 1) selected = null; break; case '10': if (count === 0) drop(objects['air_course_17.dae'].children); if (count === 1) selected = null; break; } } renderer.render(scene, camera); } //function onWindowResize() {...} function load_models() { manager = new THREE.LoadingManager(); manager.onProgress = function (item, loaded, total) { console.log(item, loaded, total); } manager.onLoad = function () { console.log('all items loaded'); animate(); //start animate } manager.onError = function() { console.log('there has been an onError'); } filename.forEach( function (filename) { var loader = new THREE.ColladaLoader(manager); loader.load(path + filename, function (collada) { var dae = collada.scene dae.scale.z = dae.scale.x = dae.scale.y = 1; dae.traverse( function (child) { if (child instanceof THREE.Mesh) { child.material = new THREE.MeshNormalMaterial(); child.material = new THREE.MeshLambertMaterial( {emissive: 0x111111, color:0x111111} ); child.material.transparent = true; child.material.opacity = 1; child.material.side = THREE.DoubleSide; } }); objects[filename] = dae; scene.add(dae); }); }); } var select = function (div) { if (selected !== null) { selected.className = 'scene'; } selected = div; selected.className = 'scene selected' allVisible(false); switch (selected.id) { case '1': count = 0; setPosition(objects[filename[0]].children); setPosition(objects[filename[1]].children); break; case '2': count = 0; setPosition(objects[filename[2]].children); setPosition(objects[filename[3]].children); for (var i = 0; i < 2; i++) objects[filename[i]].visible = true; break; case '3': count = 0; setPosition(objects[filename[4]].children); for (var i = 0; i < 4; i++) objects[filename[i]].visible = true; break; case '4': count = 0; setPosition(objects[filename[5]].children); setPosition(objects[filename[6]].children); setPosition(objects[filename[7]].children); for (var i = 0; i < 5; i++) objects[filename[i]].visible = true; break; case '5': count = 0; setPosition(objects[filename[8]].children); setPosition(objects[filename[9]].children); setPosition(objects[filename[10]].children); for (var i = 0; i < 8; i++) objects[filename[i]].visible = true; break; case '6': count = 0; setPosition(objects[filename[11]].children); setPosition(objects[filename[12]].children); for (var i = 0; i < 11; i++) objects[filename[i]].visible = true; break; case '7': count = 0; setPosition(objects[filename[13]].children); for (var i = 0; i < 13; i++) objects[filename[i]].visible = true; break; case '8': count = 0; setPosition(objects[filename[14]].children); setPosition(objects[filename[15]].children); for (var i = 0; i < 14; i++) objects[filename[i]].visible = true; break; case '9': count = 0; setPosition(objects[filename[16]].children); for (var i = 0; i < 16; i++) objects[filename[i]].visible = true; break; case '10': count = 0; setPosition(objects[filename[17]].children); for (var i = 0; i < 17; i++) objects[filename[i]].visible = true; break; } } function allVisible(visible) { filename.forEach( function (name) { objects[name].visible = visible; objects[name].children.forEach( function (item) { item.transparent = true; item.material.opacity = 1; }); }); } function setPosition (object) { for (var i = 0; i < object.length; i++) { object[i].position.z = offset; object[i].material.transparent = true; object[i].material.opacity = 0; } } function drop(object) { for (var i = 0; i < object.length; i++) { if (i == 0 && object[i].position.z > 0) { object[i].parent.visible = true; object[i].material.opacity += 0.5; object[i].position.z -= step; if (object[i].position.z < step) object[i].position.z = 0; break; } if (i > 0 && i < object.length - 3 && object[i].position.z > 0) { object[i].parent.visible = true; object[i].material.opacity += 0.5; object[i].position.z -= step; object[i+1].position.z -= step / 1.5; object[i+2].position.z -= step / 2.25; object[i+3].position.z -= step / 3; if (object[i].position.z < step) object[i].position.z = 0; break; } if (i > object.length - 4 && object[i].position.z > 0) { switch (i) { case (object.length - 3): object[i].parent.visible = true; object[i].material.opacity += 0.5; object[i].position.z -= step; object[i+1].position.z -= step / 1.5; object[i+2].position.z -= step / 2.25; if (object[i].position.z < step) object[i].position.z = 0; break; case (object.length - 2): object[i].parent.visible = true; object[i].material.opacity += 0.5; object[i].position.z -= step; object[i+1].position.z -= step / 1.5; if (object[i].position.z < step) object[i].position.z = 0; break; case (object.length - 1): object[i].parent.visible = true; object[i].material.opacity += 0.5; object[i].position.z -= step; if (object[i].position.z < step) { object[i].position.z = 0; count++; //animation finished. next animation } break; } } } } |
Часовой пояс GMT +3, время: 20:35. |