【发布时间】:2017-04-15 00:07:41
【问题描述】:
我正在开发一个将项目添加到 three.js 场景的程序,根据场景中已经存在的项目数量将它们定位在坐标上。目前,我遇到的问题是,当用户选择“高空工作”时,场景中会添加两个人。这是两个独立的函数调用,但是当场景结束时,两个人都在同一个坐标上。当用户点击添加多人并且不等待每个人加载时也会发生这种情况。
有没有办法强制我的加载函数等待第一个对象完成加载,以便一次只加载一个模型?
This mention of the LoadingManager 让我开始思考,并尝试通过将加载的文件数和总数保存为变量来使用它,然后在 while 循环中比较它们,但是,正如预期的那样,这只会减慢脚本的速度,以至于我的浏览器要我阻止它们。
// 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);
}
});
}
如果我遇到问题,则通过以下两行(间接)调用此代码:
objectAddRemove("person", "CWM_A");
objectAddRemove("person", "CWM_B");
然后执行这个调用 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 也会在用户单击代表所需对象的图像时被调用,因此我需要一种方法来等待先前单击的模型加载(除了通过代码自动加载的模型之外)。
要测试/查看更多代码,您可以访问this link。选择“高空作业”、重量单位,然后跳至“添加操作员”。它将显示篮子里有两个人(选中),但篮子里只有一个人可见。如果你点击“删除项目”然后可见的人删除可见的人,隐藏的将显示。
非常感谢!!!
【问题讨论】:
-
谢谢@Andy Ray,但我想我是这样调用函数的。我正在调用 objectAddRemove("person", "CWM_A"); objectAddRemove(“人”,“CWM_B”);。 objectAddRemove 使用上面列出的函数 (createObjectBasket) 创建一个对象。根据您给我的链接,这意味着功能应该同步运行吗?那么第二个调用不应该在第一个调用完成之前执行?除非我读错了。
-
没有。异步函数不会阻塞程序流。所有顶级语句按顺序执行,然后在稍后执行异步回调函数。
标签: javascript jquery three.js