javascript Three.js LoadingManager onProgress只在完成后工作?

lx0bsm1f  于 2023-05-12  发布在  Java
关注(0)|答案(2)|浏览(222)

bounty将在21小时后到期。回答此问题可获得+50声望奖励。Halo想要引起更多关注这个问题:除了赏金,我从这个问题的支持者中获得的所有声誉都将用于接受的答案(通过赏金)

我试图在Three.js中创建一个带有HTML进度条的加载屏幕。我使用THREE.LoadingManager()传递到我的GLTFLoader。我使用onProgress方法来获取每个模型的加载时间,但它似乎不起作用。它只在最后工作,一旦所有内容都被加载(所以基本上它从0%跳到98%)。我想这和我使用了一个 Package 器函数有关。
下面是我的代码:

let loadingManager = new THREE.LoadingManager();

loadingManager.onProgress = function(url, loaded, total){
    document.getElementById('loading-progress').value = Math.round((loaded / total) * 100);
    document.getElementById('loading-progress-label').innerHTML = `${Math.round((loaded / total) * 100)}%`;
}

let loader = new THREE.GLTFLoader(loadingManager);

function load(asset, pos=[0, 0, 0], rot=[-Math.PI / 2, Math.PI, Math.PI], scale=[5, 5, 5], appendTo){
    loader.load(`Assets/${asset}.glb`, function(object){
        object.scene.position.set(pos[0], pos[1], pos[2]);
        object.scene.rotation.set(rot[0], rot[1], rot[2]);
        object.scene.scale.set(scale[0], scale[1], scale[2]);
        object.scene.name = asset;

        scene.add(object.scene);

        if(appendTo != undefined){
            appendTo.push(object.scene);
        }
    });
};

//Decoration
load('platform_grass', [-5, 4, -0.5]);
load('platform_grass', [-2, 3, -0.5], undefined, [5, 10, 5]);
load('rock_largeA', [1, 3, -1], undefined, [2, 2, 2]);
load('plant_bushDetailed', [-5, 1, -1], undefined, [3, 3, 3]);
load('plant_bushDetailed', [-2, 6, -1], undefined, [3, 3, 3]);

我很确定这个问题与我使用load()函数有关,而不是手动加载每个资产。任何帮助都很感激。
谢谢!

mxg2im7a

mxg2im7a1#

onProgress回调作为第二个参数传递给加载器。
参见https://threejs.org/docs/?q=gltfloa#examples/en/loaders/GLTFLoader

function onProgress(url, loaded, total){
    document.getElementById('loading-progress').value = Math.round((loaded / total) * 100);
    document.getElementById('loading-progress-label').innerHTML = `${Math.round((loaded / total) * 100)}%`;
}

function load(asset, pos=[0, 0, 0], rot=[-Math.PI / 2, Math.PI, Math.PI], scale=[5, 5, 5], appendTo){
    const assetUrl = `Assets/${asset}.glb`;
    loader.load(assetUrl, function(object){
        object.scene.position.set(pos[0], pos[1], pos[2]);
        object.scene.rotation.set(rot[0], rot[1], rot[2]);
        object.scene.scale.set(scale[0], scale[1], scale[2]);
        object.scene.name = asset;

        scene.add(object.scene);

        if(appendTo != undefined){
            appendTo.push(object.scene);
        }
    }, function(xhr){
       onProgress(assetUrl, xhr.loaded, xhr.total);
    }, function(error){
       // your code to handle error
    });
};

希望这有帮助!

am46iovg

am46iovg2#

LoadingManager文档实际上说:
onProgress -(可选)当一个项目完成时调用此函数。
尝试向加载器传递第二个回调函数(它将充当您的进度回调)。
以下是对我有效的方法:

const loadingManager = new THREE.LoadingManager()
const loader = new THREE.GLTFLoader(loadingManager)

loader.load(
    gltfPath,
    // on load handler
    async (gltf) => {
        // Do whatever you want with the glTF
    },
    // on progress handler
    (xhr) => {
        const progressXHR = xhr.loaded / xhr.total
        // ...
    }
)

下面是使用上述方法时代码的样子:

const loadingManager = new THREE.LoadingManager();
const loader = new THREE.GLTFLoader(loadingManager);
let loadedCount = 0;

const toLoad = [
    { asset: 'platform_grass', pos: [-5, 4, -0.5] },
    { asset: 'platform_grass', pos: [-2, 3, -0.5], rot: undefined, scale: [5, 10, 5] },
    { asset: 'rock_largeA', pos: [1, 3, -1], rot: undefined, scale: [2, 2, 2] },
    { asset: 'plant_bushDetailed', pos: [-5, 1, -1], rot: undefined, scale: [3, 3, 3] },
    { asset: 'plant_bushDetailed', pos: [-2, 6, -1], rot: undefined, scale: [3, 3, 3] },
];

function load(asset, pos=[0, 0, 0], rot=[-Math.PI / 2, Math.PI, Math.PI], scale=[5, 5, 5], appendTo) {
    loader.load(`Assets/${asset}.glb`, (object) => {
        loadedCount++;
        object.scene.position.set(pos[0], pos[1], pos[2]);
        object.scene.rotation.set(rot[0], rot[1], rot[2]);
        object.scene.scale.set(scale[0], scale[1], scale[2]);
        object.scene.name = asset;

        scene.add(object.scene);

        if (appendTo !== undefined) {
            appendTo.push(object.scene);
        }
    }, (xhr) => {
        const progress = Math.round(((xhr.loaded / xhr.total + loadedCount) / toLoad.length) * 100);
        document.getElementById('loading-progress').value =  progress;
        document.getElementById('loading-progress-label').innerHTML = `Loaded ${progress}%`;
    });
};

toLoad.forEach((item) => load(item.asset, item.pos, item.rot, item.scale));

相关问题