I am working on a program that adds items to a three.js scene, positioning them at coordinates based on how many items already exist in the scene. Currently, the problem I'm running into is that when the user chooses a "Work at Height", two people are added to the scene. These are two separate function calls, but when the scene finishes, both people are at the same coordinates. This also happens when the user clicks to add multiple people and does not wait for each to load.
Is there a way I can force my loading function to wait for the first object to finish loading so that it loads only one model at a time?
This mention of the LoadingManager got me thinking, and tried I to use that by saving the number of files loaded and total as variables, then comparing them in a while loop, but, as expected, that just slowed the scripts down so much that my browser wanted me to stop them.
// adds objects to the basket with the appropriate rotation
function createObjectBasket(filePath, scale, position, name, type) {
// Load in the object and add it to the scene.
var loader = new THREE.ObjectLoader(manager);
/*while (gl_itemsLoaded < gl_itemsTotal) {
}*/
loader.load( filePath, function(object, materials){
// rotate
object.rotation.x = - ((Math.PI / 2) - (Math.PI / 18));
object.rotation.y = - (Math.PI - (Math.PI / 5));
object.rotation.z = 0; //- (Math.PI / 120);
// scale
object.scale.set(scale, scale, scale);
// translate
object.position.set(position.x, position.y, position.z);
// set name for easy access
object.name = name;
// add to scene
scene.add(object);
if (type == "basket") {
// add to object array for easy access
basketContents["basket"].push(object);
}
else if (type == "person") {
// add to object array for easy access
basketContents["people"].push(object);
}
else if (type == "tool") {
// add to object array for easy access
basketContents["tools"].push(object);
}
else if (type == "attachment") {
// add to object array for easy access
basketContents["attachments"].push(object);
}
});
}
Where I'm having the issue, this code is called (indirectly) via the following two lines:
objectAddRemove("person", "CWM_A");
objectAddRemove("person", "CWM_B");
Which then execute this function that calls createObjectBasket:
// add/remove objects to/from basket on click
function objectAddRemove(type, objectName) {
// if adding items
if (addRemove == "add") {
// determine if there is still room to add more objects
var room = true;
// can have <= 3 people total, so if there are 3, can't add more
if ((type == "person") && basketContents["people"].length >= 3) {
room = false;
return;
}
// no current restrictions on tools
/*else if ((type == "tool")) {
}*/
// can only have 1 of each attachment
else if ((type == "attachment") && (object[objectName]["contentsCount"] > 0)) {
room = false;
return;
}
if (room == true) {
// if it's a person
if (type == "person") {
// if it's a man
if (objectName.indexOf("M") >= 0) {
// add model
createObjectBasket(("models/" + objectName + ".json"), 1.5, personCoordsMan[basketContents["people"].length + 1], objectName, "person");
}
// if it's a woman
else {
// add model
createObjectBasket(("models/" + objectName + ".json"), 1.5, personCoordsWoman[basketContents["people"].length + 1], objectName, "person");
}
}
// if it's a tool
else if (type == "tool") {
/*createObjectBasket(("models/" + objectName + ".json"), 1.5, toolCoords[basketContents["tools"].length + 1], objectName, "tool");*/
createObjectBasket(("models/" + objectName + ".json"), 1.5, toolCoords, objectName, "tool");
}
// if it's an attachment
else if (type == "attachment") {
createObjectBasket(("models/" + objectName + ".json"), .04, attachmentCoords[objectName], objectName, "attachment");
}
// increase count
object[objectName]["contentsCount"] += 1;
console.log(objectName);
$('#' + objectName).children('.status').children('.checkMark').show();
}
}
// if removing items
else if (addRemove == "remove") {
// remove objects from arrays
if (type == "person") {
removeObjectArray("people", objectName);
// if person is found (and removed), rearrange all people to accommodate
if (itemFound == true) {
for (i = 0; i < basketContents["people"].length; ++i) {
if (basketContents["people"][i].name.indexOf("M") >= 0) {
basketContents["people"][i].position.set(personCoordsMan[i+1].x, personCoordsMan[i+1].y, personCoordsMan[i+1].z);
}
else {
basketContents["people"][i].position.set(personCoordsWoman[i+1].x, personCoordsWoman[i+1].y, personCoordsWoman[i+1].z);
}
}
}
}
else if (type == "tool") {
removeObjectArray("tools", objectName);
// if tool is found (and removed), rearrange all tools to accommodate
/*if (itemFound == true) {
}*/
}
else if (type == "attachment") {
removeObjectArray("attachments", objectName);
}
// if all objects of that id have been removed, hide remove x mark
if (object[objectName]["contentsCount"] <= 0) {
$('#' + objectName).children('.status').children('.xMark').hide();
}
// if, after removing, person/object count is now 0, no remaining items can be removed, so switch to add
if ((steps[currentStep] == "people") && (basketContents["people"].length <= 0)) {
addItems();
}
else if ((steps[currentStep] == "objects") && ((basketContents["tools"].length + basketContents["attachments"].length) <= 0)) {
addItems();
}
}
// if no remaining items can be removed on this page
else {
addItems();
}
}
objectAddRemove is also called whenever a person clicks on an image representing the desired object, so I need a way to wait for models from previous clicks to load, also (in addition to models loaded automatically through the code).
To test/view further code, you can visit this link. Select a "Work at Height", weight unit, then skip to "Add Operators". It will show that two people are in the basket (checked) but only one is visible in the basket. If you click "Remove Items" then the visible person to remove the visible person, the hidden one will show.
Thank you so much!!!