作为我的场景对象的基础,我有一个根Object3D。我的数据从此根加载为Object3D的树结构。使用BufferGeometry / MeshPhongMaterial将网格物体添加到叶子Object3Ds中。我通过将根Object3D传递给此方法来清除现有树:
clearScene:
function (obj) {
if (obj instanceof THREE.Mesh)
{
obj.geometry.dispose();
obj.geometry = undefined;
obj.material.dispose();
obj.material = undefined;
obj = undefined;
}
else
{
if (obj.children !== undefined) {
while (obj.children.length > 0) {
this.clearScene(obj.children[0]); // removing children changes the length of the array.
obj.remove(obj.children[0]);
}
}
}
}
考虑以下简单树:
一旦这个结构进入场景,我会观察堆(使用Chrome的开发工具)。我可以看到3个Object3Ds对象和2个Mesh对象(附加组件是原型)。
当我调用clearScene(Root)时,我看到它遍历树,删除了Object3Ds,并清理了网格物体。但是当我观察堆时,我看到尽管已删除了Object3D,但仍保留2个Mesh对象(及其相关的BufferGoemetry和Material对象)。如果我在清除后第二次加载数据,我会看到3个Object3D(好的)和4个Meshes(不行)。
我认为这意味着引用没有被正确清除,但我没有看到堆中的任何保留器会这样做。
我必须遗漏导致这些物体徘徊的其他东西。
r69dev(我在r68中看到的相同),在Chrome 36.0.1985.125中测试
答案 0 :(得分:2)
在github上提交的问题(关注):https://github.com/mrdoob/three.js/issues/5175
r69dev要求对网格物体的dispose方法进行显式调用,以正确删除渲染器所持有的引用。
工作代码:
clearScene:
function (obj) {
if (obj instanceof THREE.Mesh)
{
obj.geometry.dispose();
obj.geometry = null;
obj.material.dispose();
obj.material = null;
obj.dispose(); // required in r69dev to remove references from the renderer.
obj = null;
}
else
{
if (obj.children !== undefined) {
while (obj.children.length > 0) {
this.clearScene(obj.children[0]);
obj.remove(obj.children[0]);
}
}
}
}