Saving, Loading and Manipulating.
Доработал функцию сохранения сцены. Файл сцены, созданной в редакторе TertiusAxis, имеет расширение «.trxs». Сейчас это текстовый файл с данными в виде массива с элементами в формате JSON, представляющими собой объекты сцены. Сохраняются только объекты, созданные пользователем. Для этого осуществляется проверка элементов массива children сцены, в которых userData = true.
function saveSceneToDisk () { // Savig scene, created in TertiusAxis let ta_entities = new TA_Entities(); if ( ta_scene.currentSelection.object ) { ta_entities.removeSelection(ta_scene.currentSelection); } let children = ta_scene.scene.children; let elemToExport = []; children.forEach( element => { if ( element.userData.createdByUser ) { elemToExport.push( element.toJSON() ); if ( element.userData.selectable ){ ta_scene.selectableObjects.push( element ); } } }); let blob = new Blob([JSON.stringify( elemToExport, null, 2)], {type: 'text/plain'}); saveFile( blob , 'Scene', 'trxs' ); }
По этому же принципу сделана очистка сцены в модуле TA_Scene:
clearScene(){ let taEntities = new TA_Entities(); if (this.currentSelection.object) { this.transformControls.detach(this.currentSelection.object); taEntities.removeSelection(this.currentSelection); } let children = this.scene.children; let elementsToRemove = []; children.forEach( element => { if ( element.userData.createdByUser ) { elementsToRemove.push( element ); this.selectableObjects.splice( this.selectableObjects.indexOf( element )); } }); this.scene.remove( ...elementsToRemove ); }
Сохранение файла вынесено в отдельную функцию
function saveFile( blob, name, fileExtention ){ let fileName = name + '.' + fileExtention; let link = document.createElement('a'); link.download = fileName; if (window.navigator && window.navigator.msSaveOrOpenBlob) { window.navigator.msSaveOrOpenBlob( blob, fileName ); } else { link.href = URL.createObjectURL( blob ); link.click(); URL.revokeObjectURL( link.href ); } }
Добавлена функция «Merge with scene from disk», которая добавляет в существующую сцену объекты из другой сцены.
function loadSceneFromDisk( e ) { // Loading scene, created in TertiusAxis ta_scene.clearScene(); loadScene( e ); } function mergeScenes ( e ) { // Merge scenes, created in TertiusAxis loadScene( e ); } function clearScene () { if( confirm("Al objects will be deleted. Are you shure?")){ ta_scene.clearScene(); } } function loadScene( e ){ let file = e.srcElement.files[0]; if( !file.name.endsWith( '.trxs') ){ alert( 'File is not a TertiusAxis Scene'); return; } let reader = new FileReader(); reader.readAsText(file); reader.onload = function() { let loader = new THREE.ObjectLoader(); let loadedObjectsJSON = JSON.parse( reader.result); loadedObjectsJSON.forEach( element => { let loadedObject = loader.parse( element); ta_scene.scene.add( loadedObject ); if ( loadedObject.userData.selectable ){ ta_scene.selectableObjects.push( loadedObject ); } }); }; reader.onerror = function() { alert(reader.error); }; }
При загрузке сцены проверяется только расширение файла “.trsx”, но в будущем, когда формат файла изменится, будет проверяться структура файла.
Вся сцена может быть экспортирована в GLtf формат
function exportGLTF(){ let gltfExporter = new GLTFExporter(); gltfExporter.parse( ta_scene.scene, function ( result ) { let gltf = JSON.stringify( result, null, 2 ); let blob = new Blob( [gltf], {type: 'text/plain'}); saveFile( blob , 'Scene', 'gltf' ); } ); }
Реализовал функциональность кнопок манипуляции объектом: перемещения, вращения, масштабирования и перетаскивания, подключив соответствующие модули библиотеки three.js. Реализовано клонирование объекта нажатием на клавишу “с”, а также выбором соответствующего пункта меню вкладки Edit. При этом геометрия клонов независима, а материал один и тот же, то есть, меняя цвет одного объекта — меняется цвет у всех.
cloneObject( ta_scene ) { let copiedObjectID = ta_scene.currentSelection.object.id; this.removeSelection( ta_scene.currentSelection ); let copiedObject = ta_scene.scene.getObjectById( copiedObjectID ); let newObject = copiedObject.clone( false ); ta_scene.selectableObjects.push( newObject ); ta_scene.scene.add( newObject ); this.selectEntity( copiedObject, ta_scene.currentSelection ); }
TODO:
— Сделать выделение нескольких объектов и манипулирование ими, а так же клонирование всех выделенных объектов. Для этого в объекте currentSelection создать поле multiselect: new Group() и добавлять выделяемые объекты в группу.
— реализовать или использовать существующую библиотеку по отслеживанию состояний приложения.