我已经加载了一个 OBJ 文件,并从原始文件中将其
.clone()
放入数组中。后来我想将其中一些的vertexColor
更改为不同的颜色,但是更改一个会改变所有的颜色。
var oload = new OBJLoader();
oload.load("objects/tunnel1.obj", function(data)
{
tunnels[0] = data;
tunnels[0].traverse(function(titem)
{
if(titem.isMesh)
{
if(titem.name.toUpperCase().indexOf("INNER")>-1)
{
titem.material = new THREE.MeshBasicMaterial(map: wnewtex, vertexColors: true);
}
}
});
});
for(var x = 0; x < width; x++)
{
for(var y = 0; y < height; y++)
{
if(leveldata[x][y] == 15)
{
tunnels.push(tunnels[0].clone());
tunnels[tunnels.length-1].position.set(-x*2,newh,(height-y-1)*2);
scene.add(tunnels[tunnels.length-1]);
}
else if(leveldata[x][y] == 16)
{
tunnels.push(tunnels[0].clone());
tunnels[tunnels.length-1].position.set(-x*2,newh,(height-y-1)*2);
tunnels[tunnels.length-1].rotation.set(0,Math.PI/2,0);
scene.add(tunnels[tunnels.length-1]);
}
else if(leveldata[x][y] == 23)
{
tunnels.push(tunnels[0].clone());
tunnels[tunnels.length-1].position.set(-x*2,newh,(height-y-1)*2);
tunnels[tunnels.length-1].rotation.set(0,Math.PI/2,0);
tunnels[tunnels.length-1].traverse(function(titem)
{
if(titem.isMesh)
{
if(titem.name.toUpperCase().indexOf("INNER")>-1)
{
titem.geometry.setAttribute("color",new THREE.BufferAttribute(new Float32Array(item.geometry.attributes.position.count*3), 3 ));
var colort = titem.geometry.attributes.color.array;
for(var v2 = 0; v2 < titem.geometry.attributes.position.count*3; v2+=3)
{ // Make Red
colort[v2+0] = 1;
colort[v2+1] = 0;
colort[v2+2] = 0;
}
titem.geometry.attributes.color.needsUpdate = true;
}
}
});
scene.add(tunnels[tunnels.length-1]);
}
else if(leveldata[x][y] == 26)
{
tunnels.push(tunnels[0].clone());
tunnels[tunnels.length-1].position.set(-x*2,newh,(height-y-1)*2);
tunnels[tunnels.length-1].rotation.set(0,Math.PI/2,0);
tunnels[tunnels.length-1].traverse(function(titem)
{
if(titem.isMesh)
{
if(titem.name.toUpperCase().indexOf("INNER")>-1)
{
titem.geometry.setAttribute("color",new THREE.BufferAttribute(new Float32Array(item.geometry.attributes.position.count*3), 3 ));
var colort = titem.geometry.attributes.color.array;
for(var v2 = 0; v2 < titem.geometry.attributes.position.count*3; v2+=3)
{ // Make Green
colort[v2+0] = 0;
colort[v2+1] = 1;
colort[v2+2] = 0;
}
titem.geometry.attributes.color.needsUpdate = true;
} // If 26 was the last tunnel adjusted
} // then even 23 turns green
});
scene.add(tunnels[tunnels.length-1]);
}
}
}
我认为
.clone()
不会为新对象创建属性的新副本。在属性未链接的情况下制作克隆的另一种方法是什么?
你是对的,
clone
维护参考,而不是制作副本。并且 clone
调用对象的 copy
函数,因此即使 Mesh.copy
也保留对原始 geometry
和 material
的引用,而不是制作副本。这样做是为了提高内存效率。
参考:https://github.com/mrdoob/third.js/blob/a2e9ee8204b67f9dca79f48cf620a34a05aa8126/src/objects/Mesh.js#L68(三.js r164)
但这还不是结束。您始终可以通过在执行
geometry
后取消引用 material
和/或 clone
来解决这个问题。如果你再降低一步,clone
实际上就能达到你想要的效果。
const original = new Mesh( geo, mat )
const theClone = original.clone()
console.log( original.geometry === theClone.geometry ) // true
console.log( original.material === theClone.material ) // true
theClone.geometry = theClone.geometry.clone()
theClone.material = theClone.material.clone()
console.log( original.geometry === theClone.geometry ) // false
console.log( original.material === theClone.material ) // false