har*_*052 45 javascript three.js
我正在使用ThreeJS开发一个显示实体列表的Web应用程序,每个实体都有相应的"查看"和"隐藏"按钮; 例如,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);
}
Run Code Online (Sandbox Code Playgroud)
在单击" 隐藏"按钮时,将调用以下函数:
function removeEntity(object){
scene.remove(object.name);
}
Run Code Online (Sandbox Code Playgroud)
问题是,单击" 隐藏"按钮后,一旦加载,实体就不会从屏幕中删除.如何使" 隐藏"按钮起作用?
我做了小实验.我在函数内部scene.remove(object.name);之后添加,结果,当点击"查看"按钮时,没有实体绘制(如预期的那样)意味着内部工作正常.但我仍然无法弄清楚如何在removeEntity(object)中使用它.scene.add(object);addEntityscene.remove(object.name);addEntity
另外,我检查了scene.children的内容,它显示:[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
完整代码:http://devplace.in/~harman/model_display1.php.html
如果需要更多细节,请询问.我用revJ-59-dev和rev-60测试了ThreeJS.
谢谢.:)
Dar*_*ann 42
我认为看到你对addEntity和removeEntity代码的使用会有所帮助,但我首先想到的是你实际上是在设置object.name吗?在scene.add(object)之前尝试加载你的加载器; 这样的事情:
object.name = "test_name";
scene.add(object);
Run Code Online (Sandbox Code Playgroud)
可能发生的事情是Object3D的默认"名称"为"",因此当您调用removeEntity函数时,由于场景对象名称为""而失败
另外,我注意到你将object.name传递给你的加载器?这是您将URL存储到资源的位置吗?如果是这样,我建议使用Object3D的内置.userData方法来存储该信息并保留名称字段以用于场景识别.
编辑:对新添加的代码的响应
首先要注意的是,在对象名称中包含"/"并不是一个好主意,它似乎工作正常,但你永远不知道某些算法是否会决定转义该字符串并破坏你的项目.
现在第二项是我见过你的代码,它实际上是直截了当的.您的删除功能正在尝试按名称删除,您需要删除一个Object3D.试试这个:
function removeEntity(object) {
var selectedObject = scene.getObjectByName(object.name);
scene.remove( selectedObject );
animate();
}
Run Code Online (Sandbox Code Playgroud)
在这里,您可以看到我通过传入对象标签的属性来查找Object3DThree.js .希望有所帮助Scenename
Ibr*_* W. 12
我来晚了,但在阅读了答案后,需要说更多的澄清。
function removeEntity(object) {
// scene.remove(); it expects as a parameter a THREE.Object3D and not a string
scene.remove(object.name); // you are giving it a string => it will not remove the object
}
Run Code Online (Sandbox Code Playgroud)
function removeObject3D(object3D) {
if (!(object3D instanceof THREE.Object3D)) return false;
// for better memory management and performance
if (object3D.geometry) object3D.geometry.dispose();
if (object3D.material) {
if (object3D.material instanceof Array) {
// for better memory management and performance
object3D.material.forEach(material => material.dispose());
} else {
// for better memory management and performance
object3D.material.dispose();
}
}
object3D.removeFromParent(); // the parent might be the scene or another Object3D, but it is sure to be removed this way
return true;
}
Run Code Online (Sandbox Code Playgroud)
MJB*_*MJB 10
clearScene: function() {
var objsToRemove = _.rest(scene.children, 1);
_.each(objsToRemove, function( object ) {
scene.remove(object);
});
},
Run Code Online (Sandbox Code Playgroud)
这使用了unexcore.js来对场景中的所有子节点(除了第一个)进行迭代(它是我用来清除场景的代码的一部分).只需确保在删除后至少渲染一次场景,否则画布不会改变!不需要"特殊"obj标志或类似的东西.
此外,您不会通过名称删除对象,只是通过对象本身,所以调用
scene.remove(object);
Run Code Online (Sandbox Code Playgroud)
而不是scene.remove(object.name);
足够的
PS:_.each是underscore.js的函数