本文介绍了在uniapp中使用tree.js时遇到的模型加载不出来的问题,并最终发现是由于缩放问题导致的,通过调用getFitScaleValue()方法解决了这个问题,感兴趣的朋友一起看看吧
**
GPT4.0+Midjourney绘画+国内大模型 会员永久免费使用!
【 如果你想靠AI翻身,你先需要一个靠谱的工具! 】
网上有很多uniapp使用tree.js的教程,但是我在使用测试中,发现tree.js的官方3d模型中有很多加载不出来,但是也没有报错,全网搜也没搜到方法,最后发现是缩放的问题,这里将代码贴出来,关键的方法是getFitScaleValue
```js
````<template>`
` ``<view id=``"app"``>`
` ``<canvas id=``"webgl"` `ref=``"webgl"` `canvas-id=``"webgl"` `type=``"webgl"`
` ``:style=``"'width:'+mSceneWidth+'px; height:'+mSceneHeight+'px;'"``>`
` ``</canvas>`
` ``</view>`
`</template>`
`<script>`
` `` import * as THREE from ``'three'`
` ``import {`
` ``OrbitControls`
` `` } from ``'three/examples/jsm/controls/OrbitControls.js'`
` ``import {`
` ``GLTFLoader`
` `` } from ``'three/examples/jsm/loaders/GLTFLoader.js'``;`
` ``import {`
` ``FBXLoader`
` `` } from ``'three/examples/jsm/loaders/FBXLoader.js'``;`
` ``import {`
` ``DRACOLoader`
` `` } from ``"three/examples/jsm/loaders/DRACOLoader.js"``;`
` ``import {`
` ``OBJLoader`
` `` } from ``"three/examples/jsm/loaders/OBJLoader.js"``;`
` `` export ``default` `{`
` ``//Soldier`
` ``data() {`
` ``return` `{`
` `` mSceneWidth: 0, ``// 手机屏幕宽度`
` `` mSceneHeight: 0, ``// 手机屏幕高度`
` `` canvas: ``null``,`
` `` worldFocus: ``null`` , ``// 世界焦点(模型放置,相机围绕的中心)`
` `` renderer: ``null``,`
` `` mCanvasId: ``null``,`
` `` scene: ``null``,`
` `` mesh: ``null``,`
` `` camera: ``null``,`
` `` clock: ``null``,`
` `` renderAnimFrameId: ``null`` , ``// 渲染帧动画id`
` `` controls: ``null``,`
` ``timeS: 0,`
` `` changeFlag: ``true``,`
` `` mixer: ``null``,`
` ``previousTime: 0,`
` `` modelUrl: ``"/static/Soldier.glb"`
` ``};`
` ``},`
` ``mounted() {`
` ``// uni.createSelectorQuery().in(this).select('#webgl').fields({`
` ``// node: true`
` ``// }).exec(res=> {`
` ``// console.log(JSON.stringify(res))`
` ``// this.mCanvasId = res[0].node.id;`
` ``// // 注册画布`
` ``// const mCanvas = THREE.global.registerCanvas(this.mCanvasId, res[0].node);`
` ``// // 开始初始化`
` ``// this.init(mCanvas);`
` ``// }) `
` ``},`
` ``// 页面加载时`
` ``onLoad(option) {`
` ``// 获取手机屏幕宽高`
` ``this``.mSceneWidth = uni.getWindowInfo().windowWidth;`
` ``this``.mSceneHeight = uni.getWindowInfo().windowHeight;`
` ``// 设置世界中心`
` ``this`` .worldFocus = ``new` `THREE.Vector3(0, 0, 0);`
` ``},`
` ``// 页面加载完毕后`
` ``onReady() {`
` ``this``.init()`
` ``},`
` ``onShow() {`
` ``},`
` ``onHide() {`
` ``this``.disposes()`
` ``cancelAnimationFrame(``this``.animate())`
` ``},`
` ``methods: {`
` ``// 在不需要时释放资源`
` ``disposes() {`
` ``// 释放几何体`
` ``this``.scene.traverse((object) => {`
` ``if` `(object.geometry) {`
` ``object.geometry.dispose();`
` ``}`
` ``// 释放材质`
` ``if` `(object.material) {`
` ``if` `(Array.isArray(object.material)) {`
` ``object.material.forEach(material => material.dispose());`
` `` } ``else` `{`
` ``object.material.dispose();`
` ``}`
` ``}`
` ``});`
` ``// 释放渲染器`
` ``if` `(``this``.renderer) {`
` ``this``.renderer.dispose();`
` ``}`
` ``// 清除场景`
` ``while` `(``this``.scene.children.length > 0) {`
` ``this``.scene.remove(``this``.scene.children[0]);`
` ``}`
` ``},`
` ``getFitScaleValue(scene) {`
` ``let box=``new` `THREE.BoxGeometry(3,3,3)`
` ``let mail=``new` `THREE.MeshBasicMaterial({color:0xff6600})`
` ``let mesh=``new` `THREE.Mesh(box,mail)`
` ``var` ` boxes = ``new` `THREE.Box3().setFromObject( scene );`
` ``var` ` maxDiameter = Math.max((boxes.max.x - boxes.min.x), (boxes.max.y - boxes.min.y), (boxes.max.z - boxes.min.z)); ``//数值越大,模型越小`
` ``console.log(maxDiameter)`
` ``return` `Math.ceil(``this``.mSceneHeight / maxDiameter/4);`
` ``},`
` ``init() {`
` ``// 创建一个场景`
` ``this`` .scene = ``new` `THREE.Scene()`
` ``//三位坐标线`
` ``// const axesHelper = new THREE.AxesHelper(5);`
` ``// this.scene.add(axesHelper);`
` ``//创建相机对象,45是相机的视角 , 宽高比是屏幕的宽高比 , 最近能看到0.1 , 最远能看到10000`
` ``// this.camera = new THREE.OrthographicCamera(-s * k, s * k, s , -s, 1, 1000);`
` ``// this.camera.position.set(0, 20, 300);`
` `` const lod = ``new` `THREE.LOD();`
` ``// 创建不同细节级别的几何体`
` `` const highDetailGeometry = ``new` `THREE.BoxGeometry(1, 1, 1);`
` `` const mediumDetailGeometry = ``new` `THREE.BoxGeometry(0.5, 0.5, 0.5);`
` `` const lowDetailGeometry = ``new` `THREE.BoxGeometry(0.25, 0.25, 0.25);`
` ``// 创建材质`
` `` const material = ``new` `THREE.MeshBasicMaterial({`
` ``color: 0xff0000`
` ``});`
` ``// 创建不同细节级别的网格`
` `` const highDetailMesh = ``new` `THREE.Mesh(highDetailGeometry, material);`
` `` const mediumDetailMesh = ``new` `THREE.Mesh(mediumDetailGeometry, material);`
` `` const lowDetailMesh = ``new` `THREE.Mesh(lowDetailGeometry, material);`
` ``// 将不同细节级别的网格添加到LOD对象中`
` `` lod.addLevel(highDetailMesh, 0); ``// 距离0`
` `` lod.addLevel(mediumDetailMesh, 5); ``// 距离5`
` `` lod.addLevel(lowDetailMesh, 10); ``// 距离10`
` ``this``.scene.add(lod);`
` ``this`` .camera = ``new` ` THREE.PerspectiveCamera(75, ``this`` .mSceneWidth / ``this``.mSceneHeight, 0.1, 2000);`
` ``//100,300 ,500`
` ``this`` .camera.position.set(0, 0, 5); ``//设置相机位置`
` ``//this.camera.position.set(100, -800, 500);`
` ``this``.scene.add(``this``.camera)`
` ``this``.camera.lookAt(``this`` .scene.position); ``//设置相机方向(指向的场景对象)`
` ``// 执行一个渲染函数`
` ``this``.rendererGLR()`
` ``/* 光源设置*/`
` ``this``.pointLight()`
` ``this`` .clock = ``new` `THREE.Clock()`
` ``//创建控件对象`
` ``this``.change()`
` ``//更新轨道控件`
` `` let fileName = ``this``.modelUrl.lastIndexOf(``"."``)`
` `` let fileFormat = ``this`` .modelUrl.substring(fileName + 1, ``this``.modelUrl.length).toLowerCase()`
` ``if` ` (fileFormat == ``'fbx'``) {`
` ``this``.fbxLoader()`
` `` } ``else` `if` ` (fileFormat == ``'glb'``) {`
` ``this``.gblLoader()`
` `` } ``else` `if` ` (fileFormat == ``'obj'``) {`
` ``this``.objLoader()`
` ``}`
` ``//this.renderer.render(this.scene, this.camera);`
` ``},`
` ``pointLight() {`
` `` let ambientLight = ``new` `THREE.AmbientLight(0xffffff, 1);`
` ``this``.scene.add(ambientLight);`
` `` const directional_light = ``new` `THREE.DirectionalLight(0xffffff, 1);`
` ``directional_light.position.set(0, 1, 0);`
` `` directional_light.castShadow = ``true``;`
` ``this``.scene.add(directional_light);`
` ``let a = 1,`
` ``b = 0.6,`
` ``c = 10;`
` `` let directionalLight1 = ``new` `THREE.DirectionalLight(0xffffff, b);`
` ``directionalLight1.position.set(-a, -a, a * c).normalize();`
` `` let directionalLight2 = ``new` `THREE.DirectionalLight(0xffffff, b);`
` ``directionalLight2.position.set(a, -a, -a * c).normalize();`
` `` let directionalLight3 = ``new` `THREE.DirectionalLight(0xffffff, b);`
` ``directionalLight3.position.set(-a, a, -a * c).normalize();`
` `` let directionalLight4 = ``new` `THREE.DirectionalLight(0xffffff, b);`
` ``directionalLight4.position.set(a, a, a * c).normalize();`
` ``this``.scene.add(directionalLight1);`
` ``this``.scene.add(directionalLight2);`
` ``this``.scene.add(directionalLight3);`
` ``this``.scene.add(directionalLight4);`
` ``},`
` ``//渲染函数`
` ``rendererGLR() {`
` ``this``.$nextTick(() => {`
` ``const element = document.getElementById(``'webgl'``)`
` ``this``.canvas = element`
` ``this``.renderer.setSize(element.clientWidth, element.clientHeight);`
` ``element.appendChild(``this``.renderer.domElement);`
` ``})`
` ``this`` .renderer = ``new` `THREE.WebGLRenderer({`
` `` alpha: ``true``,`
` `` antialias: ``true``,`
` `` powerPreference: ``"high-performance"``,`
` `` precision: ``"mediump"`
` `` }); ``//alpha:true背景透明`
` ``this``.renderer.setPixelRatio(window.devicePixelRatio * 2);`
` ``this``.renderer.toneMapping = THREE.ACESFilmicToneMapping;`
` ``this``.renderer.toneMappingExposure = 1.0;`
` ``this``.renderer.outputColorSpace = THREE.SRGBColorSpace;`
` ``this`` .renderer.shadowMap.enabled = ``true``;`
` ``this``.renderer.shadowMap.type = THREE.PCFSoftShadowMap;`
` ``},`
` ``//创建控件对象`
` ``change() {`
` ``this`` .controls = ``new` `OrbitControls(``this`` .camera, ``this``.renderer.domElement);`
` ``this``.controls.minDistance = 300`
` ``this``.controls.maxDistance = 1000`
` ``this``.controls.addEventListener(``'change'``, () => {`
` ``this``.renderer.render(``this`` .scene, ``this``.camera);`
` `` }); ``//监听鼠标、键盘事件`
` ``//禁止缩放`
` ``this`` .controls.enableZoom = ``this``.changeFlag`
` ``//禁止旋转`
` ``this`` .controls.enableRotate = ``this``.changeFlag`
` ``//禁止右键拖拽`
` ``this`` .controls.enablePan = ``this``.changeFlag`
` ``},`
` ``//更新轨道控件`
` ``animate() {`
` ``if` `(``this``.renderer) {`
` ``// console.log(this.stats)`
` ``// this.stats.update()`
` `` let T = ``this``.clock.getDelta()`
` ``let renderT = 1 / 30`
` ``this`` .timeS = ``this``.timeS + T`
` ``if` `(``this``.timeS > renderT) {`
` ``this``.controls.update();`
` ``this``.renderer.render(``this`` .scene, ``this``.camera);`
` ``this``.timeS = 0`
` ``}`
` ``requestAnimationFrame(``this``.animate);`
` ``if` `(!``this``.changeFlag) {`
` ``this``.controls.autoRotateSpeed = 16`
` ``}`
` ``this`` .controls.autoRotate = ``false` `// 是否自动旋转`
` ``}`
` ``//创建一个时钟对象`
` ``//this.clock = new THREE.Clock()`
` ``//this.scene.rotateY(0.01)`
` ``//获得两帧的时间间隔 更新混合器相关的时间`
` ``if` `(``this``.mixer) {`
` ``this``.mixer.update(``this``.clock.getDelta()*100)`
` ``}`
` ``},`
` ``objLoader() {`
` `` let that = ``this`
` `` const loader = ``new` `OBJLoader();`
` ``uni.showLoading({`
` `` title: ``"正在加载"`
` ``})`
` ``// load a resource`
` ``loader.load(`
` ``// resource URL`
` ``that.modelUrl,`
` ``// called when resource is loaded`
` ``function``(object) {`
` ``console.log(object)`
` ``uni.hideLoading()`
` ``var` `scale = that.getFitScaleValue(object)`
` ``console.log(scale)`
` ``object.scale.set(scale, scale, scale);`
` ``that.scene.add(object);`
` ``setTimeout(``function``() {`
` ``//that.renderer.render(that.scene, that.camera);`
` ``that.animate()`
` ``}, 1000);`
` ``},`
` ``// called when loading is in progress`
` ``function``(xhr) {`
` `` console.log((xhr.loaded / xhr.total * 100) + ``'% loaded'``);`
` ``},`
` ``// called when loading has errors`
` ``function``(error) {`
` ``console.log(``'An error happened'``);`
` ``}`
` ``);`
` ``},`
` ``//导入FBX模型文件`
` ``fbxLoader() {`
` `` let that = ``this`
` `` const loader = ``new` `FBXLoader();`
` ``loader.load(``this`` .modelUrl, ``function``(mesh) {`
` ``that.scene.add(mesh);`
` ``that.ownerInstance.callMethod(``'onload'``)`
` ``})`
` ``},`
` ``//导入GLB模型文件`
` ``gblLoader() {`
` ``uni.showLoading({`
` `` title: ``"正在加载"``,`
` ``})`
` `` let that = ``this`
` `` const loader = ``new` `GLTFLoader();`
` `` const dracoloader = ``new` `DRACOLoader();`
` ``dracoloader.setDecoderPath(``"/static/draco/"``);`
` ``loader.setDRACOLoader(dracoloader);`
` `` loader.load(that.modelUrl, ``function``(gltf) {`
` ``uni.hideLoading()`
` ``//that.mesh = gltf.scene`
` ``if` `(gltf.animations.length > 0) {`
` `` that.mixer = ``new` `THREE.AnimationMixer(gltf.scene)`
` ``const action = that.mixer.clipAction(gltf.animations[0])`
` ``// 让动画进入播放状态`
` ``action.play()`
` ``}`
` ``var` `scale = that.getFitScaleValue(gltf.scene)`
` ``console.log(scale)`
` ``gltf.scene.scale.set(scale, scale, scale);`
` ``that.scene.add(gltf.scene);`
` ``setTimeout(``function``() {`
` ``//that.renderer.render(that.scene, that.camera);`
` ``that.animate()`
` ``}, 1000);`
` `` }, ``function``(xhr) {`
` `` console.log((xhr.loaded / xhr.total * 100) + ``'% loaded'``);`
` `` }, ``function``(err) {`
` ``console.log(err)`
` ``});`
` ``},`
` ``// 触摸开始`
` ``// 触摸事件处理`
` ``onTouchStart(event) {`
` ``const touch = event.touches[0];`
` `` const rect = ``this``.canvas.getBoundingClientRect();`
` ``const x = touch.clientX - rect.left;`
` ``const y = touch.clientY - rect.top;`
` ``// 在这里处理触摸开始事件`
` ``},`
` ``onTouchMove(event) {`
` ``const touch = event.touches[0];`
` `` const rect = ``this``.canvas.getBoundingClientRect();`
` ``const x = touch.clientX - rect.left;`
` ``const y = touch.clientY - rect.top;`
` ``// 在这里处理触摸移动事件`
` ``},`
` ``onTouchEnd() {`
` ``// 在这里处理触摸结束事件`
` ``}`
` ``}`
` ``}`
`</script>`
`<style lang=``"scss"``>`
`</style>`
未调用缩放方法,就是空白,调用后:
到此这篇关于uniapp 使用 tree.js 解决模型加载不出来的问题的文章就介绍到这了,更多相关uniapp tree.js 模型加载不出来内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!