Подтвердить что ты не робот

ThreeJS: удалить объект из сцены

Я использую ThreeJS для разработки веб-приложения, которое отображает список сущностей, каждый из которых имеет соответствующие кнопки "Вид" и "Скрыть"; например entityName Показать Скрыть. Когда пользователь нажимает кнопку Вид, вызывается следующая функция и объект, нарисованный на экране успешно.

function loadOBJFile(objFile){            
    /* material of OBJ model */                                          
    var OBJMaterial = new THREE.MeshPhongMaterial({color: 0x8888ff});
    var loader = new THREE.OBJLoader();
    loader.load(objFile, function (object){
        object.traverse (function (child){
            if (child instanceof THREE.Mesh) {
                child.material = OBJMaterial;
            }
        });
        object.position.y = 0.1;
        scene.add(object);
    });     
}

function addEntity(object) {
    loadOBJFile(object.name);
}

И при нажатии кнопки Скрыть вызывается следующая функция:

function removeEntity(object){
    scene.remove(object.name);
}

Проблема заключается в том, что объект не удаляется с экрана после загрузки, когда нажата кнопка Скрыть. Что я могу сделать, чтобы сделать кнопку Скрыть работать?

Я сделал небольшой эксперимент. Я добавил scene.remove(object.name); сразу после scene.add(object); внутри функции addEntity, и в результате, когда нажата кнопка "Вид", ни один объект не нарисован (как ожидалось), что означает, что scene.remove(object.name); отлично работал в пределах addEntity. Но все же я не могу понять, как использовать его в removeEntity (object).

Кроме того, я проверил содержимое scene.children, и он показывает: [Object Object], [Object Object], [Object Object], [Object Object], [Object Object], [Object Object]

Полный код: http://devplace.in/~harman/model_display1.php.html

Пожалуйста, спросите, требуется ли более подробная информация. Я тестировал с rev-59-dev и rev-60 от ThreeJS.

Спасибо.:)

4b9b3361

Ответ 1

Я думаю, что ваше использование для addEntity и removeEntity кода было бы полезно, но, по моему мнению, вы на самом деле устанавливаете object.name? Попробуйте в своем загрузчике непосредственно перед scene.add(object); что-то вроде этого:

object.name = "test_name";
scene.add(object);

Что может быть, это "имя" для объекта Object3D по умолчанию ", поэтому, когда вы вызываете функцию removeEntity, она терпит неудачу из-за того, что имя объекта сцены"

Кроме того, я замечаю, что вы передаете object.name своему загрузчику? Это где вы храните URL-адрес ресурса? Если это так, я бы рекомендовал использовать Object3D, встроенный в метод .userData, чтобы сохранить эту информацию и сохранить поле имени для целей идентификации сцены.

Изменить: ответ на новый код

Первое, что нужно отметить, - это отличная идея иметь "/" в имени вашего объекта, кажется, что он работает нормально, но вы никогда не знаете, будет ли какой-то алгоритм решить эту строку и разорвать ваш проект.

Вторым пунктом является то, что я видел ваш код, его фактическое прямо вперед, что происходит. Ваша функция удаления пытается удалить по имени, вам нужно удалить Object3D. Попробуйте следующее:

function removeEntity(object) {
    var selectedObject = scene.getObjectByName(object.name);
    scene.remove( selectedObject );
    animate();
}

Здесь вы видите, что я просматриваю ваш Object3D в файле Three.js Scene, передавая атрибут тега name. Надеюсь, что поможет

Ответ 2

clearScene: function() {
    var objsToRemove = _.rest(scene.children, 1);
    _.each(objsToRemove, function( object ) {
          scene.remove(object);
    });
},

это использует undescore.js для итерации по всем дочерним элементам (кроме первого) в сцене (это часть кода, которую я использую для очистки сцены). просто убедитесь, что вы визуализируете сцену по крайней мере один раз после, потому что в противном случае холст не изменяется! Нет необходимости в специальном флагов obj или что-то в этом роде.

Также вы не удаляете объект по имени, просто самим объектом, поэтому вызываете

scene.remove(object); 

вместо scene.remove(object.name); может быть достаточно

PS: _.each является функцией underscore.js

Ответ 3

У меня была та же проблема, что и у вас. Я пробую этот код, и он работает отлично: Когда вы создаете свой объект, поставьте этот object.is_ob = true

function loadOBJFile(objFile){            
    /* material of OBJ model */                                          
    var OBJMaterial = new THREE.MeshPhongMaterial({color: 0x8888ff});
    var loader = new THREE.OBJLoader();
    loader.load(objFile, function (object){
        object.traverse (function (child){
            if (child instanceof THREE.Mesh) {
                child.material = OBJMaterial;
            }
        });
        object.position.y = 0.1;
      // add this code
        object.is_ob = true;

        scene.add(object);
    });     
}

function addEntity(object) {
    loadOBJFile(object.name);
}

И затем вы удалите свой объект, попробуйте этот код:

function removeEntity(object){
    var obj, i;
            for ( i = scene.children.length - 1; i >= 0 ; i -- ) {
                obj = scene.children[ i ];
                if ( obj.is_ob) {
                    scene.remove(obj);

                }
            }
}

Попробуйте и скажите, работает ли это, кажется, что три js не распознают объект после добавления в сцену. Но с этим трюком это работает.

Ответ 4

Если ваш элемент не находится на вашей сцене, вернитесь к родительскому, чтобы удалить его.

  function removeEntity(object) {
        var selectedObject = scene.getObjectByName(object.name);
        selectedObject.parent.remove( selectedObject );
    }

Ответ 5

ЭТО БОЛЬШАЯ РАБОТА - я тестирую это поэтому, пожалуйста, НАЗВАНИЕ НАЗНАЧЕНИЯ для каждого объекта

укажите имя объекта при создании

    mesh.name = 'nameMeshObject';

и использовать это, если вы удаляете объект

    delete3DOBJ('nameMeshObject');



    function delete3DOBJ(objName){
        var selectedObject = scene.getObjectByName(objName);
        scene.remove( selectedObject );
        animate();
    }

открыть новую сцену, добавить объект открыть новую сцену, добавить объект

удалить объект и создать новый удалить объект и создать новый

Ответ 6

Вы можете использовать этот

function removeEntity(object) {
    var scene = document.querySelectorAll("scene");                               //clear the objects from the scene
    for (var i = 0; i < scene.length; i++) {                                    //loop through to get all object in the scene
    var scene =document.getElementById("scene");                                  
    scene.removeChild(scene.childNodes[0]);                                        //remove all specified objects
  }