Saving, Loading and Manipulating.

3+

Доработал функцию сохранения сцены. Файл сцены, созданной в редакторе 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() и добавлять выделяемые объекты в группу.

— реализовать или использовать существующую библиотеку по отслеживанию состояний приложения.

3+