javascript ThreeJS:从场景中删除对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18357529/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ThreeJS: Remove object from scene
提问by harman052
I'm using ThreeJS to develop a web application that displays a list of entities, each with corresponding "View" and "Hide" button; e.g. entityName View Hide. When user clicks Viewbutton, following function is called and entity drawn on screen successfully.
我正在使用 ThreeJS 开发一个显示实体列表的 Web 应用程序,每个实体都有相应的“查看”和“隐藏”按钮;例如entityName查看隐藏。当用户单击View按钮时,调用以下函数并成功在屏幕上绘制实体。
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);
}
And on clicking Hidebutton, following function is called:
在单击隐藏按钮时,调用以下函数:
function removeEntity(object){
scene.remove(object.name);
}
The problem is, entity is not removed from screen once loaded when Hidebutton is clicked. What can I do to make Hidebutton to work?
问题是,单击“隐藏”按钮后,实体不会从屏幕中删除。我该怎么做才能使“隐藏”按钮起作用?
I did small experiment. I added scene.remove(object.name);
right after scene.add(object);
within addEntity
function and as result, when "View" button clicked, no entity drawn (as expected) meaning that scene.remove(object.name);
worked just fine within addEntity
. But still I'm unable to figure out how to use it in removeEntity(object).
我做了个小实验。我在函数scene.remove(object.name);
之后立即添加,结果,当“查看”按钮被点击时,没有绘制实体(如预期的那样),这意味着在. 但我仍然无法弄清楚如何在 removeEntity(object) 中使用它。scene.add(object);
addEntity
scene.remove(object.name);
addEntity
Also, I checked contents of scene.children and it shows: [object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
另外,我检查了scene.children的内容,它显示:[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Complete code: http://devplace.in/~harman/model_display1.php.html
完整代码:http: //devplace.in/~harman/model_display1.php.html
Please ask, if more detail is needed. I tested with rev-59-dev and rev-60 of ThreeJS.
请询问,是否需要更多详细信息。我用 ThreeJS 的 rev-59-dev 和 rev-60 进行了测试。
Thanks. :)
谢谢。:)
回答by Darryl_Lehmann
I think seeing your usage for addEntity and removeEntity code would be helpful, but my first thought is are you actually setting the object.name? Try in your loader just before scene.add(object); something like this:
我认为看到您对 addEntity 和 removeEntity 代码的使用会有所帮助,但我的第一个想法是您实际上是在设置 object.name 吗?在 scene.add(object); 之前尝试在您的加载器中;像这样:
object.name = "test_name";
scene.add(object);
What might be happening is the default "name" for an Object3D is "", so when you then call your removeEntity function it fails due to the scene objects name being ""
可能发生的情况是 Object3D 的默认“名称”为“”,因此当您调用 removeEntity 函数时,由于场景对象名称为“”而失败
Also, I notice you pass in object.name to your loader? Is this where your storing the URL to the resource? If so, I would recommend using the Object3D's built in .userData method to store that information and keep the name field for scene identification purposes.
另外,我注意到您将 object.name 传递给您的加载程序?这是您存储资源 URL 的地方吗?如果是这样,我会建议使用 Object3D 的内置 .userData 方法来存储该信息并保留名称字段以用于场景识别目的。
Edit: Response to newly added Code
编辑:响应新添加的代码
First thing to note is it's not a great idea to have "/" in your object name, it seems to work fine but you never know if some algorithm will decide to escape that string and break your project.
首先要注意的是,在对象名称中包含“/”并不是一个好主意,它似乎工作正常,但您永远不知道某些算法是否会决定转义该字符串并破坏您的项目。
Second item is now that I've seen your code, its actually straight forward whats going on. Your delete function is trying to delete by name, you need an Object3D to delete. Try this:
第二项是现在我已经看到了你的代码,它实际上是直接发生的事情。您的删除功能正在尝试按名称删除,您需要一个 Object3D 才能删除。试试这个:
function removeEntity(object) {
var selectedObject = scene.getObjectByName(object.name);
scene.remove( selectedObject );
animate();
}
Here you see I lookup your Object3D
in the Three.js Scene
by passing in your object tag's name
attribute. Hope that helps
在这里你看到我通过传入你的对象标签的属性Object3D
在 Three.js 中查找你Scene
的name
。希望有帮助
回答by MJB
clearScene: function() {
var objsToRemove = _.rest(scene.children, 1);
_.each(objsToRemove, function( object ) {
scene.remove(object);
});
},
this uses undescore.js to iterrate over all children (except the first) in a scene (it's part of code I use to clear a scene). just make sure you renderthe scene at least once afterdeleting, because otherwise the canvas does not change! There is no need for a "special" obj flag or anything like this.
这使用 undescore.js 迭代场景中的所有孩子(除了第一个)(这是我用来清除场景的代码的一部分)。只要确保在删除后至少渲染一次场景,否则画布不会改变!不需要“特殊” obj 标志或类似的东西。
Also you don't delete the object by name, just by the object itself, so calling
此外,您不会按名称删除对象,而是按对象本身删除,因此调用
scene.remove(object);
instead of scene.remove(object.name);
can be enough
而不是scene.remove(object.name);
就足够了
PS: _.each
is a function of underscore.js
PS:_.each
是underscore.js的一个函数
回答by Роман Зыков
THIS WORKS GREAT - I tested it so, please SET NAME for every object
这很好用 - 我已经测试过了,请为每个对象设置名称
give the name to the object upon creation
在创建时为对象命名
mesh.name = 'nameMeshObject';
and use this if you have to delete an object
如果您必须删除一个对象,请使用它
delete3DOBJ('nameMeshObject');
function delete3DOBJ(objName){
var selectedObject = scene.getObjectByName(objName);
scene.remove( selectedObject );
animate();
}
回答by Alex Melluzzo
I started to save this as a function, and call it as needed for whatever reactions require it:
我开始将它保存为一个函数,并根据需要在任何反应需要时调用它:
function Remove(){
while(scene.children.length > 0){
scene.remove(scene.children[0]);
}
}
Now you can call the Remove(); function where appropriate.
现在你可以调用 Remove(); 在适当的地方发挥作用。
回答by Sylvain Lugez
When you use : scene.remove(object); The object is removed from the scene, but the collision with it is still enabled !
当你使用:scene.remove(object); 该对象已从场景中移除,但仍启用与它的碰撞!
To remove also the collsion with the object, you can use that (for an array) : objectsArray.splice(i, 1);
要删除与对象的碰撞,您可以使用它(对于数组):objectsArray.splice(i, 1);
Example :
例子 :
for (var i = 0; i < objectsArray.length; i++) {
//::: each object ::://
var object = objectsArray[i];
//::: remove all objects from the scene ::://
scene.remove(object);
//::: remove all objects from the array ::://
objectsArray.splice(i, 1);
}
}
回答by Victor Santos
If your element is not directly on you scene go back to Parent to remove it
如果您的元素不直接在您的场景中,请返回父级以将其删除
function removeEntity(object) {
var selectedObject = scene.getObjectByName(object.name);
selectedObject.parent.remove( selectedObject );
}
回答by juanpscotto
I had The same problem like you have. I try this code and it works just fine: When you create your object put this object.is_ob = true
我有和你一样的问题。我试试这个代码,它工作得很好:当你创建你的对象时,把这个 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);
}
And then then you delete your object try this code:
然后你删除你的对象试试这个代码:
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);
}
}
}
Try that and tell me if that works, it seems that three js doesn't recognize the object after added to the scene. But with this trick it works.
试试然后告诉我这是否有效,似乎三个js在添加到场景后无法识别该对象。但有了这个技巧,它就起作用了。
回答by Dabby
You can use this
你可以用这个
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
}