Fedja Hadzibegovic
Fedja Hadzibegovic

Reputation: 1

gltfLoader with progress counter (loading bar)

I'm am trying to set loading counter for gltf file. Problem is that, my file is gltf, not glb, so I have three files (.gltf .bin .jpg). When I set onProgress callback for gltf file, it does not handle those files (.bin and .jpg), so I get 100% on the start of loading. How can I set onProgress callback to calculate all three files?

const gltfLoader = new GLTFLoader();

// Show loader while the glTF is loading
document.getElementById('loader').style.display = 'block';

// Hide loader when done
  function hideLoader() {
    const loaderContainer = document.getElementById('loader');
    loaderContainer.style.display = 'none';
  }

// LOADING ELEMENTS FROM GLTF //
gltfLoader.load('./Model/Model.gltf', function (gltf) {
    scene.add(gltf.scene);
   // Hide the loader when loading completes
   hideLoader();

function (xhr) {
    // Update progress percentage
    const loaderText = document.getElementById('loader-text');
    
    let progress = 0;
    if (xhr.total && xhr.total > 0) {
      progress = Math.round((xhr.loaded / xhr.total) * 100);
    }     
    loaderText.textContent = `${progress}%`;
},
function (error) {
// Handle loading error
console.error('An error occurred while loading the model:', error);
}
);

Upvotes: 0

Views: 73

Answers (1)

Łukasz Daniel Mastalerz
Łukasz Daniel Mastalerz

Reputation: 2217

You should use LoadingManager since it handles the progress of all associated files.

import * as THREE from "three";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);
camera.position.z = 1;
camera.position.y = 0.5;

const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

const loadingManager = new THREE.LoadingManager();

const loaderContainer = document.getElementById("loader");
const loaderText = document.getElementById("loader-text");

loadingManager.onStart = function () {
  loaderContainer.style.display = "flex";
  loaderText.textContent = `Loading... 0%`;
};

loadingManager.onProgress = function (url, itemsLoaded, itemsTotal) {
  const progress = Math.round((itemsLoaded / itemsTotal) * 100);
  loaderText.textContent = `Loading... ${progress}%`;
};

loadingManager.onLoad = function () {
  loaderContainer.style.display = "none";
};

const gltfLoader = new GLTFLoader(loadingManager);

gltfLoader.load("./static/FlightHelmet.gltf", (gltf) => {
  scene.add(gltf.scene);
});

const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(5, 5, 5);
scene.add(light);

function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}
animate();

Sandbox

Upvotes: 0

Related Questions