首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >ThreeJS:从场景中移除对象

ThreeJS:从场景中移除对象
EN

Stack Overflow用户
提问于 2013-08-21 20:32:50
回答 12查看 125.3K关注 0票数 58

我正在使用ThreeJS开发一个web应用程序,它显示一个实体列表,每个实体都有相应的“查看”和“隐藏”按钮;例如,entityName 视图隐藏。当用户单击查看按钮时,将调用以下函数并将实体成功绘制到屏幕上。

代码语言:javascript
复制
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);
}

在单击Hide按钮时,将调用以下函数:

代码语言:javascript
复制
function removeEntity(object){
    scene.remove(object.name);
}

问题是,当Hide按钮被点击时,实体一旦加载就不会从屏幕中删除。要让隐藏按钮工作,我该怎么做?

我做了个小实验。我在addEntity函数中的scene.add(object);后面添加了scene.remove(object.name);,因此,当单击“查看”按钮时,没有绘制任何实体(正如预期的那样),这意味着scene.remove(object.name);addEntity中工作得很好。但是我仍然不知道如何在removeEntity(object)中使用它。

另外,我检查了scene.children的内容,结果显示: object Object,object object

完整代码:http://devplace.in/~harman/model_display1.php.html

如果需要更多细节,请询问。我使用ThreeJS的rev-59-dev和rev-60进行测试。

谢谢。:)

EN

回答 12

Stack Overflow用户

发布于 2013-08-21 23:12:28

我认为看到你对addEntity和removeEntity代码的使用会很有帮助,但我的第一个想法是,你实际上是在设置object.name吗?在scene.add(Object)之前尝试一下您的加载器;如下所示:

代码语言:javascript
复制
object.name = "test_name";
scene.add(object);

可能发生的情况是,Object3D的默认“名称”为"",因此,当您随后调用removeEntity函数时,由于场景对象名称为"“,因此调用失败。

另外,我注意到你把object.name传给了你的加载器?这是您存储资源的URL的地方吗?如果是这样的话,我建议使用Object3D内置的.userData方法来存储该信息,并保留name字段以用于场景识别。

编辑:对新添加的代码的响应

首先要注意的是,在你的对象名中包含"/“不是一个好主意,它似乎工作得很好,但你永远不知道是否有一些算法会决定转义该字符串并破坏你的项目。

第二件事就是我已经看过你的代码了,它实际上是直接的。您的删除函数正在尝试按名称删除,您需要一个Object3D才能删除。试试这个:

代码语言:javascript
复制
function removeEntity(object) {
    var selectedObject = scene.getObjectByName(object.name);
    scene.remove( selectedObject );
    animate();
}

在这里,您可以看到我通过传入Object3D标记的name属性在Three.js Scene中查找您的对象。希望这能有所帮助

票数 55
EN

Stack Overflow用户

发布于 2013-12-24 09:34:20

代码语言:javascript
复制
clearScene: function() {
    var objsToRemove = _.rest(scene.children, 1);
    _.each(objsToRemove, function( object ) {
          scene.remove(object);
    });
},

它使用undescore.js遍历场景中的所有子对象(第一个除外)(这是我用来清除场景的代码的一部分)。只需确保在删除后至少渲染一次场景,否则画布不会更改!不需要“特殊的”obj标志或类似的东西。

此外,您不能按名称删除对象,而只能按对象本身删除,因此调用

代码语言:javascript
复制
scene.remove(object); 

而不是scene.remove(object.name);就足够了

PS:_.eachunderscore.js的一个函数

票数 10
EN

Stack Overflow用户

发布于 2017-05-15 07:00:19

如果您的元素不直接位于场景中,请返回父级将其移除

代码语言:javascript
复制
  function removeEntity(object) {
        var selectedObject = scene.getObjectByName(object.name);
        selectedObject.parent.remove( selectedObject );
    }
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18357529

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档