ThreeJS - 来自 .json 3D 文件的多个网格
ThreeJS - multiple meshes from a .json 3D file
我从在线 3D 编辑器导出了一个 .json,我正在尝试加载它并实例化它的 20 个版本,例如 this example。我的代码有缺陷,因为所有 20 个版本实际上都像同一个对象。不确定为什么不将它们作为给定 x、z 坐标中的单独对象添加到场景中。
var serverObject;
var allBrains = []
var xCenter;
var zCenter;
var spacing = .2;
var newServ;
var objectLoader = new THREE.ObjectLoader();
objectLoader.load("asset_src/model.json", function(obj) {
//give it a global name, so I can access it later?
serverObject = obj
//see what's inside of it
obj.traverse(function(child) {
if (child instanceof THREE.Mesh) {
console.log(child)
}
})
//was trying to add transparency this way, but ended up
//going through the online editor to apply it
// var cubeMaterial1 = new THREE.MeshBasicMaterial({
// color: 0xb7b7b7,
// refractionRatio: 0.98
// });
//Do i need to instantiate my mesh like this, if so, how do I make sure that it gets the materials from the json? The json has 6 children each with a different material
// serverObject = new THREE.Mesh( obj, cubeMaterial1 );
//make 20 versions of the file
for (var i = 0; i < 20; i++) {
xCenter = Math.cos(toRadians(i * spacing))
zCenter = Math.sin(toRadians(i * spacing))
serverObject.scale.set(.09, .09, .09)
//this amount of offset is correct for the scale of my world
//i was going to use my xCenter, zCenter but tried to simplify it till it works
serverObject.position.set((i * .1), controls.userHeight - 1, i * .1);
allBrains.push(serverObject)
//I've attempted a number of ways of adding the obj to the scene, this was just one
scene.add(allBrains[i]);
}
// see that there are 20 meshes
console.log(allBrains)
});
我最后一个控制台日志的 return 如下所示:
目前,您有一个对象 (serverObject
),您可以多次操作和添加该对象,但循环的每次迭代都只修改同一个对象,覆盖之前的参数。
您需要使用... clone()
方法克隆网格。然后您将能够修改 that 对象(副本)的设置,并且每个网格将保持独立。
或者,您可以 运行 循环内的 objectLoader.load
方法从 JSON 文件多次创建对象,但这可能是一种资源浪费。
这对我来说像是一个指针问题。
在 JavaScript 中,您可以将变量视为指针,这就是为什么您不必为变量分配类型以及函数如何成为变量并在普通计算机科学中仍然有效的原因。
在这种情况下,您为数组中的每个槽分配相同的指针。
这是一个超级简单的问题版本。 obj2.foo 从未改变,但因为我们改变了 obj.foo obj2.foo 改变了,因为 var 只是指向同一个对象。
var obj = {
foo : 1
}
var obj2 = obj;
obj.foo = 2;
console.log(obj2.foo);
我会做的是创建一个新对象,并在你的情况下用主对象的信息填充它 "serverObject"
allBrains.push(serverObject)
感谢@jcaor 的 clone() 想法,这是工作代码:
var objectLoader = new THREE.ObjectLoader();
objectLoader.load("asset_src/model.json", function(obj) {
//give it a global name, so I can access it later
serverObject = obj
//see what's inside of it
obj.traverse(function(child) {
if (child instanceof THREE.Mesh) {
console.log(child)
}
})
for (var i = 0; i < 20; i++) {
var tempNew = serverObject.clone()
xCenter = Math.cos(toRadians(i * spacing))
zCenter = Math.sin(toRadians(i * spacing))
tempNew.scale.set(.05, .05, .05)
tempNew.position.set(xCenter, controls.userHeight - 1, zCenter);
allBrains.push(tempNew)
scene.add(allBrains[i]);
}
console.log(allBrains)
});
我从在线 3D 编辑器导出了一个 .json,我正在尝试加载它并实例化它的 20 个版本,例如 this example。我的代码有缺陷,因为所有 20 个版本实际上都像同一个对象。不确定为什么不将它们作为给定 x、z 坐标中的单独对象添加到场景中。
var serverObject;
var allBrains = []
var xCenter;
var zCenter;
var spacing = .2;
var newServ;
var objectLoader = new THREE.ObjectLoader();
objectLoader.load("asset_src/model.json", function(obj) {
//give it a global name, so I can access it later?
serverObject = obj
//see what's inside of it
obj.traverse(function(child) {
if (child instanceof THREE.Mesh) {
console.log(child)
}
})
//was trying to add transparency this way, but ended up
//going through the online editor to apply it
// var cubeMaterial1 = new THREE.MeshBasicMaterial({
// color: 0xb7b7b7,
// refractionRatio: 0.98
// });
//Do i need to instantiate my mesh like this, if so, how do I make sure that it gets the materials from the json? The json has 6 children each with a different material
// serverObject = new THREE.Mesh( obj, cubeMaterial1 );
//make 20 versions of the file
for (var i = 0; i < 20; i++) {
xCenter = Math.cos(toRadians(i * spacing))
zCenter = Math.sin(toRadians(i * spacing))
serverObject.scale.set(.09, .09, .09)
//this amount of offset is correct for the scale of my world
//i was going to use my xCenter, zCenter but tried to simplify it till it works
serverObject.position.set((i * .1), controls.userHeight - 1, i * .1);
allBrains.push(serverObject)
//I've attempted a number of ways of adding the obj to the scene, this was just one
scene.add(allBrains[i]);
}
// see that there are 20 meshes
console.log(allBrains)
});
我最后一个控制台日志的 return 如下所示:
目前,您有一个对象 (serverObject
),您可以多次操作和添加该对象,但循环的每次迭代都只修改同一个对象,覆盖之前的参数。
您需要使用... clone()
方法克隆网格。然后您将能够修改 that 对象(副本)的设置,并且每个网格将保持独立。
或者,您可以 运行 循环内的 objectLoader.load
方法从 JSON 文件多次创建对象,但这可能是一种资源浪费。
这对我来说像是一个指针问题。
在 JavaScript 中,您可以将变量视为指针,这就是为什么您不必为变量分配类型以及函数如何成为变量并在普通计算机科学中仍然有效的原因。
在这种情况下,您为数组中的每个槽分配相同的指针。
这是一个超级简单的问题版本。 obj2.foo 从未改变,但因为我们改变了 obj.foo obj2.foo 改变了,因为 var 只是指向同一个对象。
var obj = {
foo : 1
}
var obj2 = obj;
obj.foo = 2;
console.log(obj2.foo);
我会做的是创建一个新对象,并在你的情况下用主对象的信息填充它 "serverObject"
allBrains.push(serverObject)
感谢@jcaor 的 clone() 想法,这是工作代码:
var objectLoader = new THREE.ObjectLoader();
objectLoader.load("asset_src/model.json", function(obj) {
//give it a global name, so I can access it later
serverObject = obj
//see what's inside of it
obj.traverse(function(child) {
if (child instanceof THREE.Mesh) {
console.log(child)
}
})
for (var i = 0; i < 20; i++) {
var tempNew = serverObject.clone()
xCenter = Math.cos(toRadians(i * spacing))
zCenter = Math.sin(toRadians(i * spacing))
tempNew.scale.set(.05, .05, .05)
tempNew.position.set(xCenter, controls.userHeight - 1, zCenter);
allBrains.push(tempNew)
scene.add(allBrains[i]);
}
console.log(allBrains)
});