首页 > 编程语言 >记录--uniapp微信小程序引入threeJs并导入模型

记录--uniapp微信小程序引入threeJs并导入模型

时间:2022-11-28 17:03:49浏览次数:45  
标签:uniapp threeJs obj -- 模型 THREE scene canvas new

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

前言

我的需求是使用uniapp写微信小程序,在小程序中使用threeJs就行了,目前暂不考虑兼容app什么的。
1.引入小程序版的threejs库实现
2.使用webview实现(推荐)

重点

我的建议是使用这个库
https://github.com/deepkolos/three-platformize
为什么?我试了uniapp推荐的和threejs-miniprogram这个小程序官方库,都加载不出来我的obj模型。所有我推荐不要用obj模型最好,挺多都支持GLTF模型的,但是我不能改。

使用three-platformize加载obj模型的案例:

 核心代码:

html:
<canvas type="webgl" id="webgl" style="width: 100vw; height: 100vh;" 
	@touchstart="touchStart" 
	@touchmove="touchMove" 
	@touchend="touchEnd"
/>
script:
<script>
	import * as THREE from 'three-platformize';
	import { WechatPlatform } from 'three-platformize/src/WechatPlatform';
	import { OBJLoader } from 'three-platformize/examples/jsm/loaders/OBJLoader';
	import { GLTFLoader } from 'three-platformize/examples/jsm/loaders/GLTFLoader';
	import {OrbitControls} from 'three-platformize/examples/jsm/controls/OrbitControls';
	export default {
		data() {
			return {
				canvas:null,
				camera:null,
				scene:null,
				renderer:null,
				model:null,
				controls:null,
				loopIndex:null
			}
		},
		onLoad() {

		},
		methods: {
			async init() { 
				const { canvas }= await this.getCanvas();
				this.canvas = canvas;
				const platform = new WechatPlatform(canvas); // webgl canvas
				platform.enableDeviceOrientation('game'); // 开启DeviceOrientation
				THREE.PLATFORM.set(platform);
				this.platform = platform;
				this.renderModel();
		    },
			//获取画布
			async getCanvas(delay = 200) {
			  return new Promise((resolve, reject) => {
				const t = setTimeout(() => {
				  clearTimeout(t);
				  uni.createSelectorQuery().in(this)
					.select('#webgl')
					.fields({ node: true })
					.exec((res) => {
						console.log('res',res)
					  if (res && res[0] && res[0].node) {
						const canvas = res[0].node;
						resolve({ canvas });
					  } else {
						reject("获取canvas失败");
					  }
					});
				}, delay);
			  });
			},
			renderModel () {
				this.camera = new THREE.PerspectiveCamera(45, this.canvas.width / this.canvas.height, 0.25, 100);
				this.camera.position.set(- 5, 3, 10);
				this.camera.lookAt(new THREE.Vector3(0, 2, 0));
				this.scene = new THREE.Scene();
				this.scene.background = new THREE.Color(0xe0e0e0);
				this.scene.fog = new THREE.Fog(0xe0e0e0, 20, 100);
				this.clock = new THREE.Clock();
				// lights
				var light = new THREE.HemisphereLight(0xffffff, 0x444444);
				light.position.set(0, 20, 0);
				this.scene.add(light);
				// 改变外壳颜色
				var AmbientLight = new THREE.AmbientLight(0x815800); // 环境光
				this.scene.add(AmbientLight);
				// 平行光
				light = new THREE.DirectionalLight(0xffffff);
				light.position.set(0, 20, 10);
				this.scene.add(light);
				// // ground
				// var mesh = new THREE.Mesh(new THREE.PlaneBufferGeometry(2000, 2000), new THREE.MeshPhongMaterial({ color: 0x999999, depthWrite: false }));
				// mesh.rotation.x = - Math.PI / 2;
				// this.scene.add(mesh);
				// var grid = new THREE.GridHelper(200, 40, 0x000000, 0x000000);
				// grid.material.opacity = 0.6;
				// grid.material.transparent = true;
				// this.scene.add(grid);
				// model
				var loader = new OBJLoader();
				loader.load('http://localhost:8888/obj3/file.obj', (obj) => {
					console.log("obj+=")
					console.log(obj)
					// console.log(this.model)
					obj.position.set(0, -2, 0);//模型摆放的位置
					obj.scale.set(0.2, 0.2, 0.2);
					// this.model = obj;
					this.scene.add(obj);
				}, undefined, function (e) {
					console.log("模型加载错误")
					console.error(e);
				});
				// var loader = new GLTFLoader();
				// 	loader.load('https://dtmall-tel.alicdn.com/edgeComputingConfig/upload_models/1591673169101/RobotExpressive.glb', (gltf) => {
				// 		this.model = gltf.scene;
				// 		this.scene.add(this.model);
				// 	}, undefined, function (e) {
				// 		console.error(e);
		  //       });
				// var geometry = new THREE.BoxGeometry( 5, 5, 5 );
				// var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
				// var mesh = new THREE.Mesh( geometry, material );
				// this.scene.add(mesh);
		
				this.renderer = new THREE.WebGLRenderer({antialias: true });
				this.renderer.setPixelRatio(wx.getSystemInfoSync().pixelRatio);
				this.renderer.setSize(this.canvas.width, this.canvas.height);
				//this.renderer.outputEncoding = true;
				this.renderer.gammaFactor = 2.2;
		
				this.controls = new OrbitControls(this.camera, this.renderer.domElement );
				this.camera.position.set( 5, 5, 10 );
				this.animate();
			},
		animate() {
		        this.loopIndex = this.canvas.requestAnimationFrame(this.animate);
		        this.renderer.render(this.scene, this.camera);
		        this.controls.update();
		    },
		
		    touchStart(e) {
		        this.platform.dispatchTouchEvent(e);
		    },
		    touchMove(e) {
		        this.platform.dispatchTouchEvent(e);
		    },
		    touchEnd(e) {
		        this.platform.dispatchTouchEvent(e);
		    }
		},
		mounted() {
			this.$nextTick(()=>  {
			      this.init();
			    });
		}
	}
</script>

上面的案例中使用了两个模型,一个obj模型,obj模型的地址是自己写的本地服务器地址,需要自己配置,GLTF模型地址是网络地址,可以把注释解开查看。

注意点

1.加载外部模型与threeJs官网api是一致的
2.使用此方法加载外部模型,可能在真机调试时遇到模型不展示,或者微信闪退的情况(原因未知)

webview实现引入threejs库

效果图

实现:
1.使用vue实现threejs导入obj模型(pc端可完美实现),
2.在webview中引入相应的模型展示地址,

完结,就这两步即可,但是我是动态加载,所以在加载模型的时候,你需要在小程序端传值给pc端,让pc端加载相应的模型,这里就只需要用get在地址栏中传参就行了。

以下两个方法可能会用到:
1.模型大小自适应

setScaleToFitSize (obj) {
      const boxHelper = new THREE.BoxHelper(obj);
      boxHelper.geometry.computeBoundingBox();
      const box = boxHelper.geometry.boundingBox;
      const maxDiameter = Math.max((box.max.x - box.min.x), (box.max.y - box.min.y), (box.max.z - box.min.z));
      const scaleValue = camera.position.z / maxDiameter;
      obj.position.set(0, -10, 0);//模型摆放的位置
      obj.scale.set(scaleValue, scaleValue, scaleValue);
      scene.add(obj);
    },

2.禁止小程序展示webview时候向下拉动:
mounted中添加:

document.body.addEventListener('touchmove', function (e) {
        e.preventDefault();
      }, { passive: false });

本文转载于:

https://blog.csdn.net/hzqzzz/article/details/126428029

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 

标签:uniapp,threeJs,obj,--,模型,THREE,scene,canvas,new
From: https://www.cnblogs.com/smileZAZ/p/16932638.html

相关文章

  • hosts修改
    1、需要设置文件管理器打开:C:\Windows\System32\drivers\etc右击hosts文件   2、使用工具操作下载工具:https://swh.app/zh工具的使用很简单,就不介绍了~ ......
  • iOS开发之字数不一的多标签Demo
    有朋友让帮他写一个封装的字数不一的多标签视图,所以今天将代码展示一下,供大家学习代码中封装了两种方法,分别是:1.传递数组,数组中是NSString类型的方法;2.传递数组,数组中是NSDi......
  • JAVA-API概述-Scanner类键盘录入数据
    代码一packagecom.itheima.api;importjava.util.Scanner;publicclassDemo1Scanner{/*next():遇到了空格,就不再录入数据了结......
  • Swift基础之Delegate方法的使用
    本文简单介绍了使用Delegate方法的进行值的传递,改变上一个界面的字体大小和颜色首先创建一个导航视图:letviewC=ViewController();       letnavigationC=UIN......
  • UD PCIe-402全国产化信号处理模块
    一、产品概述UDPCIe-402全国产化信号处理模块为标准PCIe全高半长的结构,对外支持PCIe2.0×8通信,也可以采用千兆以太网接口进行通信,模块为100%国产化设计。FPGA芯片选用国......
  • 自定义UICollectionViewController之后如何设置布局方式
    今天使用了自定义UICollectionViewController,发现了布局问题,所以给初学者讲解一下,当我们自定义了UICollectionViewController就无法设置UICollectionView的布局样式的问题......
  • 软件开发版本号常用的简洁命名规则和方案
    软件开发版本号常用的简洁命名规则和方案一,一般版本号命名的简洁规则:三段式命名规则软件版本号命名一般采用三段式命名规则,三段式命名规则也是最常用的规则,大体上,如某个......
  • Swift基础之对FMDB第三方的使用方法
    相信大家都熟悉OC使用FMDB第三方库,进行数据库操作,增、删、改、查,现在我就来利用代码展示一下Swift对此库的使用方法,我是通过Pods添加的第三方库,如果手动添加记得创建桥接文......
  • 运行tensorflow出现This TensorFlow binary is optimized with oneAPI Deep Neural Ne
    ThisTensorFlowbinaryisoptimizedwithoneAPIDeepNeuralNetworkLibrary(oneDNN)tousethefollowingCPUinstructionsinperformance-criticaloperations:......
  • Swift基础之PickerView(时间)选择器
    代码讲解:(后面有额外代码讲解)首页设计UIPickerView的样式设计:leftArray=["花朵","颜色","形状"];              letarray1=["茉莉","玫瑰","郁金香"......