Three.js implements the model file loading progress bar and total is 0, lengthComputable is false, and handles the situation

The load method of three.js GLTFLoader, FBXLoader, GLTFLoader and OBJLoader provides a method function to obtain the progress of the current file.

Based on the previous article Three.js loads external glb, fbx, gltf, obj model files, add a new onModelProgress (get model loading progress bar method)

  onModelProgress(progressEvent ){
    
    
      const {
    
     loaded ,total ,lengthComputable } = progressEvent 
        //lengthComputable  true 可以获取到当前文件的总字节大小
       if(lengthComputable ){
    
    
        const progress = loaded / total * 100
        console.log( progress + '% loaded' )
        }else{
    
    
            console.log('已加载'+loaded+'字节' )
      }
   }

Progress bar key parameters:

1. loaded : indicates the number of bytes loaded.
2. total : Indicates the total number of bytes to be loaded.
3. lengthComputable : A Boolean value indicating whether the total number of bytes to be loaded can be determined.

Note: lengthComputable is false, which means that the total byte (total) size of the current file cannot be obtained.

The possible reasons are as follows:

1. The file resources are in the project local folder public (vue project)
2. The server did not provide Content-Length: The server did not provide the correct Content-Length field in the response header, or the value provided was invalid. In this case, the browser cannot determine the total number of bytes to load, so lengthComputable is set to false
3. Streaming transmission: In some loading scenarios, data is loaded through streaming transmission, so the total number of bytes to be loaded cannot be known in advance. For example, when loading data via WebSocket or SSE (Server-Sent Events), it is often impossible to determine the total number of bytes.

The complete code is as follows:

import * as THREE from 'three' //导入整个 three.js核心库
import {
    
     GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader' 
import {
    
     DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'
import {
    
     OBJLoader } from 'three/examples/jsm/loaders/OBJLoader'
import {
    
     FBXLoader } from 'three/examples/jsm/loaders/FBXLoader'
// 定义一个 class类
class renderModel {
    
    
    	constructor(selector) {
    
    
    	    this.container = document.querySelector(selector)
		    // 相机
	    	this.camera
		    // 场景
		    this.scene
		    //渲染器
		    this.renderer
		    // 控制器
		    this.controls
		    // 模型
		    this.model    
		     //文件加载器类型
		    this.fileLoaderMap = {
    
    
			'glb': new GLTFLoader(),
			'fbx': new FBXLoader(),
			'gltf': new GLTFLoader(),
			'obj': new OBJLoader(),
		}
         }
         // 初始化加载模型方法
        init(){
    
    
         	return new Promise(async (reslove, reject) => {
    
    
			//初始化场景
			this.initScene()
			//初始化相机
			this.initCamera()
			//初始化渲染器
			this.initRender()
			// 添加物体模型 TODO:初始化时需要默认一个  filePath:'threeFile/glb/glb-3.glb' 放在 vue项目中的public/threeFile文件下
			const load = await this.setModel({
    
     filePath: 'threeFile/glb/glb-3.glb', fileType: 'glb',scale:0.5})
			//监听场景大小改变,跳转渲染尺寸
			window.addEventListener("resize", this.onWindowResize.bind(this))
			//场景渲染
			this.sceneAnimation()
			reslove(load)
	   	  })
        }
        //创建场景
	initScene() {
    
    
        this.scene = new THREE.Scene()
		const texture = new THREE.TextureLoader().load(require('@/assets/image/view-4.png'))
		texture.mapping = THREE.EquirectangularReflectionMapping
		// texture.colorSpace = THREE.SRGBColorSpace
		this.scene.background = texture
		this.scene.environment = texture

	}
		// 创建相机
	initCamera() {
    
    
		const {
    
     clientHeight, clientWidth } = this.container
		this.camera = new THREE.PerspectiveCamera(45, clientWidth / clientHeight, 0.25, 100)
	}
	 // 创建渲染器
	initRender() {
    
    
		this.renderer = new THREE.WebGLRenderer({
    
     antialias: true, alpha: true }) //设置抗锯齿
		//设置屏幕像素比
		this.renderer.setPixelRatio(window.devicePixelRatio)
		//渲染的尺寸大小
		const {
    
     clientHeight, clientWidth } = this.container
		this.renderer.setSize(clientWidth, clientHeight)
		//色调映射
		this.renderer.toneMapping = THREE.ACESFilmicToneMapping
		//曝光
		this.renderer.toneMappingExposure = 3
		this.renderer.shadowMap.enabled = true
		this.renderer.shadowMap.type = THREE.PCFSoftShadowMap
		this.container.appendChild(this.renderer.domElement)
	}
	// 使用动画器不断更新场景
	 sceneAnimation() {
    
    
		this.renderer.setAnimationLoop(this.render.bind(this))
	 }
     //渲染场景
	render(){
    
    
	  this.renderer.render(this.scene, this.camera)
	}
	//加载模型
	setModel({
     
      filePath, fileType, scale,  position }) {
    
    
		return new Promise((resolve, reject) => {
    
    
			const loader = this.fileLoaderMap[fileType]
			loader.load(filePath, (result) => {
    
    
			  //加载不同类型的文件
				switch (fileType) {
    
    
					case 'glb':
						this.model = result.scene		
						break;
					case 'fbx':
						this.model = result
						break;
					case 'gltf':
						this.model = result.scene
						break;
					case 'obj':
						this.model = result
						break;
					default:
						break;
				}
				// 设置模型大小
				if (scale) {
    
    
					this.model.scale.set(scale, scale, scale);
				}
				// 设置模型位置 
				if (position) {
    
    
					const {
    
     x, y, z } = position
					this.model.position.set(x, y, z)
				}
				// 设置相机位置
				this.camera.position.set(0, 2, 6)
				// 设置相机坐标系
				this.camera.lookAt(0, 0, 0)
	             // 将模型添加到场景中去   
				this.scene.add(this.model)
				resolve(true)
			}, this.onModelProgress, (err) => {
    
    
				console.log(err)
				reject()
			})
		})
	}
   onModelProgress(progressEvent ){
    
    
      const {
    
     loaded ,total ,lengthComputable } = progressEvent 
        //lengthComputable  true 可以获取到当前文件的总字节大小
       if(lengthComputable ){
    
    
        const progress = loaded / total * 100
        console.log( progress + '% loaded' )
        }else{
    
    
            console.log('已加载'+loaded+'字节' )
      }
   }
}

The complete code can be found at: https://gitee.com/ZHANG_6666/Three.js3D

Interface effect:
Insert image description here

Guess you like

Origin blog.csdn.net/weixin_43835425/article/details/132859274