我正在开发一个程序,它将项添加到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);
}
});
}
&#13;
如果我遇到问题,可以通过以下两行(间接)调用此代码:
objectAddRemove("person", "CWM_A");
objectAddRemove("person", "CWM_B");
&#13;
然后执行调用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();
}
}
&#13;
每当一个人点击代表所需对象的图像时,也会调用objectAddRemove,因此我还需要一种方法来等待先前点击的模型加载(除了通过代码自动加载的模型)。
要测试/查看更多代码,您可以访问this link。选择&#34;高度工作&#34;,权重单位,然后跳到&#34;添加运营商&#34;。它将显示两个人在篮子里(已检查)但在篮子中只能看到一个人。如果单击&#34;删除项目&#34;然后是可见的人去除可见的人,隐藏的人将会显示。
非常感谢!!!
答案 0 :(得分:1)
加载外部数据几乎总是异步发生,因此确保在另一个模型加载后需要处理onLoad事件。
我不确定LoadingManager是否支持一个接一个地加载模型。
但您可以自己实现一个简单的加载队列。以下内容:
var myQueue = ['model1.dae', 'model2.dae'];
function loadFromQueue()
{
if (myQueue.length == 0) return;
// Takes the first name from array and remove it from the array
var name = myQueue.shift();
// Call the loader and provide an onLoad event handler
loader.load(name, function(model){
// Do what you need to do with the model,
// usually it's scene.add(model) and some transformations.
// Call the next item in the queue
loadFromQueue();
});
}
现在这是一个非常粗糙的队列,有更好的方法来做到这一点。但我正在使用它最简单的演示如何使用onLoad事件处理程序一个接一个地加载模型。
我认为你将遇到的下一个障碍是如何将一些值传递给事件处理程序。那么回来吧!
答案 1 :(得分:0)
我实际上通过采用不同的方法来解决这个问题 - 我需要变量来跟踪对象,所以我检查了对象是否已根据变量值(快速设置)而不是数量加载three.js对象(加载时间更长)。与使用超时相比,这在系统中工作得更好,更好,更可靠。