Reputation: 614
I exported a .json from the online 3D editor and I'm trying to load it and instantiate 20 versions of it, like this example. My code is flawed bc all 20 versions are actually acting like the same object. Not sure why they're not being added to the scene as separate objects in their given x,z coordinates.
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)
});
The return of my last console log looks like this:
Upvotes: 0
Views: 591
Reputation: 614
Thanks to @jcaor for the clone() idea, here is the working code:
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)
});
Upvotes: 1
Reputation: 4225
This looks like a pointer issue to me.
In JavaScript you can think of variables like pointers that is why you don't have to assign types to variables and how functions can be variables and still work in normal computer science.
In this case you are assigning the same pointer to each slot in the array.
This is a super simple version of the problem. obj2.foo was never changed but because we changed obj.foo obj2.foo changed because of the var simply pointing to the same object.
var obj = {
foo : 1
}
var obj2 = obj;
obj.foo = 2;
console.log(obj2.foo);
What I would do is create a new object and popluate it with the information of the master object in you case "serverObject"
allBrains.push(serverObject)
Upvotes: 0
Reputation: 17710
At the moment, you have a single object (serverObject
) which you manipulate and add multiple times, but each iteration of the loop just modifies the same object, overriding previous parameters.
You need to clone your mesh, using the... clone()
method. You'll then be able to modify the settings of that object (the copy), and each of the meshes will remain independent.
Alternatively, you could run the objectLoader.load
method inside the loop to create the object multiple times from the JSON file, but it's probably a waste of resources.
Upvotes: 1