uniapp通过renderjs加载3D模型,支持FBX、GLB和GLTF模型,模型可自动适应。

这篇具有很好参考价值的文章主要介绍了uniapp通过renderjs加载3D模型,支持FBX、GLB和GLTF模型,模型可自动适应。。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

组件模板

  1. n-text-loading是我的自定义loading组件,可以自行替换
  2. id是threeView是模型显示的位置,
  3. props里面的url是模型链接,cameraZ是相机位置,默认100,一般不需要改,有些z轴很长的模型旋转的时候会有一部分相机看不到这个时候就需要调整这个值了,这两个要从后台上传。
  4. :prop=“url”,url就是你传给renderjs的值,不传的话renderjs中拿不到,
  5. :change:prop=“thress.updataModelUrl”,这个表示prop改变了会执行模块thress中的updataModelUrl方法,这个方法接收四个参数newValue, oldValue, ownerInstance, instance
<template>
    <view class="collection-bg">
		<n-text-loading v-if="loading"></n-text-loading>
        <view id="threeView" 
            @click="thress.onClick" 
            :prop="url" 
            :change:prop="thress.updataModelUrl"
            :propz="cameraZ" 
            :change:propz="thress.updataModelZ"
            class="media-wrap" 
            ></view>
    </view>
</template>
<script>
	export default{
		props:{
			url: String,
            cameraZ: Number
		},
		data(){
			return{
				loading: true,
			}
		},
        methods:{
            completed(option){
                this.loading = option.loading || false;
            }
        }
	}
</script>

renderjs

  1. script里面的module="thress"和上面template里面的thress是对应的,别写错了
  2. three自己npm下载就可以了
  3. template里面是用不了renderjs中的data的值的,所以控制加载中的属性loading我是放在上面的,加载完成之后调用id为threeView的点击事件,然后会执行renderjs中onClick方法,onClick会收到两个参数event, ownerInstance,再使用ownerInstance.callMethod()方法,可以传两个参数,第一个是上面方法名,第二个是你要传递的参数,比如这样: ownerInstance.callMethod(‘completed’, { loading: false });
  4. 好像也没啥了,其他直接复制就OK了。
<script module="thress" lang="renderjs">
	// import THREE from 'three/build/three.min.js'
	const THREE = require('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'
	export default {
    name:"ModelScale",
    data(){
        return{
            scene:null,
            camera:null,
            renderer:null,  
            cube:null,
            sphere:null,
            step:0,
            stats:null, 
            group:null,
			orbitcontrols: null,
        }
    },
    props:{
        width:{type:Number,default: 375},
        height:{type:Number,default: 380},
    },
    methods:{
        updataModelUrl(newValue, oldValue, ownerInstance, instance) {
            // 监听 service 层数据变更
            console.log(newValue,'层数据变更');
        },
        updataModelZ(newValue, oldValue, ownerInstance, instance){
           console.log(newValue,'层数据变更2');
        },
        onClick(event, ownerInstance){
            ownerInstance.callMethod('completed', {
                loading: false
            })
        },
        init(){
            const cameraZ = this.cameraZ <= 0 ? 100 : this.cameraZ;
            console.log(cameraZ,'cameraZ');
            this.scene = new THREE.Scene();
            this.camera = new THREE.PerspectiveCamera(45,this.width/this.height,0.1,1000);
            this.camera.position.set(0,0,cameraZ);
            this.renderer = new THREE.WebGLRenderer({antialias: true });           
			this.renderer.setClearColor(0xffffff,0);
            this.renderer.setSize(this.width/1.2,this.height/1.2);
            this.renderer.setPixelRatio(window.devicePixelRatio);
            this.renderer.shadowMapEnabled = true; 
            document.getElementById("threeView").appendChild(this.renderer.domElement);

            this.orbitcontrols = new OrbitControls(this.camera, this.renderer.domElement);  //移动控件
			this.orbitcontrols.enabled = true;
			this.orbitcontrols.enableRotate =true;
			this.orbitcontrols.enableZoom = false;
			this.orbitcontrols.autoRotate = true;
            this.orbitcontrols.minPolarAngle = Math.PI / 4;  
            this.orbitcontrols.maxPolarAngle = 3 - (Math.PI / 4);  

            // let axes = new THREE.AxesHelper(100);//辅助线
            // this.scene.add(axes);

			if(this.url.endsWith('gltf') || this.url.endsWith('glb')){
				//设置了六个平行光  有些材质不接受环境光会很暗
				const directionLight1 = new THREE.DirectionalLight(0xffffff, 1);
				directionLight1.position.set(-300,0,0)
				this.scene.add(directionLight1);
		
				const directionLight2 = new THREE.DirectionalLight(0xffffff, 1);
				directionLight2.position.set(300,0,0)
				this.scene.add(directionLight2);
				
				const directionLight3 = new THREE.DirectionalLight(0xffffff, 1);
				directionLight3.position.set(0,300,0)
				this.scene.add(directionLight3);
				
				const directionLight4 = new THREE.DirectionalLight(0xffffff, 1);
				directionLight4.position.set(0,300,0)
				this.scene.add(directionLight4);
		
				const directionLight5 = new THREE.DirectionalLight(0xffffff, 1);
				directionLight5.position.set(0,0,-300)
				this.scene.add(directionLight5);
		
				const directionLight6 = new THREE.DirectionalLight(0xffffff, 1);
				directionLight6.position.set(0,0,300)
				this.scene.add(directionLight6);
			}
			let Sun = new THREE.DirectionalLight(0xffffff, 1);
			Sun.position.set(0,300,0);
			Sun.castShadow = true;
			
			let Ambient = new THREE.AmbientLight(0xffffff, 1);
			this.scene.add(Ambient);
			this.scene.add(Sun);
        },
        loadModel(){
            let self = this; //这一点很重要。。
            let loader1 = new GLTFLoader();
			let FBXloader = new FBXLoader();
           	let rotateObj = [];
			const loadLoader = this.url.endsWith('fbx') ? FBXloader : loader1;
            loadLoader.load(this.url,function (gltf){
				
                const loadscene = gltf.scene || gltf;               
                
                loadscene.scale.set(1,1,1);   
                
                let group = new THREE.Group();
                group.add(loadscene);
                
                let bbox = new THREE.Box3().setFromObject(group);
                // console.log(bbox,'bbox---');
                let mdlen=bbox.max.x-bbox.min.x; //边界的最小坐标值 边界的最大坐标值
                let mdhei=bbox.max.y-bbox.min.y; 
                let mdwid=bbox.max.z-bbox.min.z;     
                group.position.set(0,0,0); 
                // console.log(self.camera,'相机的信息',group,'组的信息');
                let dist =Math.abs(self.camera.position.z - group.position.z- (mdwid/2));
                //console.log('dist值为:' + dist );
                let vFov = self.camera.fov * Math.PI/180;  //弧度=角度*Math.PI/180
                //console.log('vFov值为:' + vFov );
                let vheight = 2 * Math.tan(vFov * 0.5) *dist;
                //console.log('vheight值为:' + vheight );
                let fraction = mdhei / vheight;
                // console.log('fraction值为:' + fraction );
                let finalHeight = self.height * fraction ;                
                //console.log('finalHeight值为:' + finalHeight);
                let finalWidth = (finalHeight*mdlen) /mdhei;             
                //console.log('finalWidth值为:' + finalWidth );                

                let value1 = self.width/finalWidth;
                // console.log('value1缩放比例值为:' + value1);
                let value2 = self.height/finalHeight;
                // console.log('value2缩放比例值为:' + value2);

                if(value1 >= value2){
                    group.scale.set(value2,value2,value2);
                }
                else{
                    group.scale.set(value1 /2,value1/2,value1/2);
                    // group.scale.set(value1,value1,value1);
                } 
                let bbox2= new THREE.Box3().setFromObject(group)
				// console.log(bbox2,'bbox2');
                let mdlen2=bbox2.max.x-bbox2.min.x;
                let mdhei2=bbox2.max.y-bbox2.min.y;
                let mdwid2=bbox2.max.z-bbox2.min.z;
                group.position.set(-(bbox2.max.x+bbox2.min.x)/2,
                -(bbox2.max.y+bbox2.min.y)/2,
                -(bbox2.max.z+bbox2.min.z)/2);
                document.getElementById("threeView").click(); //去掉加载效果
                self.scene.add(group);
                // let boxhelper = new THREE.BoxHelper(group,0xbe1915); //辅助线外面红色框
                // self.scene.add(boxhelper);  
            });                       
        },
        animate(){
            requestAnimationFrame(this.animate);
			this.orbitcontrols.update();  //自动旋转
            this.renderer.render(this.scene,this.camera);  
        }
    },
    mounted(){
        window.ob = this;
        this.init();
        this.animate(); 
        this.loadModel();      
    }
}
</script>

文章来源地址https://www.toymoban.com/news/detail-628422.html

到了这里,关于uniapp通过renderjs加载3D模型,支持FBX、GLB和GLTF模型,模型可自动适应。的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 3dmax模型完美转glb模型,gltf格式模型转fbx格式转obj格式

    现在好多模型都是3dmax模型,但是客户要求是glb或者gltf模型 这个时候好多人直接导出glb模型,是没有颜色贴图的,这样的 这个时候是不能用的,怎么办,咱们要回到3dmax,把VR材质一个个重新上普通材质 当然也可以用插件一键转换 没有插件可以联系QQ 424081801也可以制作glb模

    2024年02月12日
    浏览(43)
  • Easy3dviewer三维模型(gltf/glb、osgb、fbx、x、shp、dxf)超轻量浏览和转换工具软件分享

    工作中经常需要用到不同格式的三维模型,比如3dmiax建模的3ds,倾斜摄影的osgb、bim转换的fbx,二维gis需要的shp、cad建模的dxf、三维gis需要的gltf等等,需要能快速方便的浏览和查看这些三维模型,也需要能将三维模型格式转换成其他三维模型格式。对三维浏览和转换的需求非

    2024年02月04日
    浏览(155)
  • Babylonjs Playground中动态加载自己的glb gltf模型(github、dropbox)

    目录 以下提供两种常用的方法 (使用科学梯子) 先说总结:对比 github和dropbox github外链使用方法 方法一:rootUrl添加链接路径。sceneFilename必须置空 方法二:rootUrl填写文件夹路径,sceneFileName填写对应的文件名字 方法三:gltf+bin文件 见案例: 额外补充:群友盲猜大佬整理的

    2024年02月04日
    浏览(36)
  • OpenGL Assimp加载各类型模型(.obj、.fbx、.glb、.3ds)

    1.简介 本博客以.glb格式为例,加载glb格式的3d模型,网上找了一圈,基本上都是根据OpenGL官方示例,加载.obj格式的3d模型。 下面以.obj和.glb格式的3D模型简单介绍一下。 常见的.obj格式的3D模型如下所示:纹理都已经被剥离出来了。所以在使用Assimp库加载的时候,加载了指定的

    2024年01月19日
    浏览(36)
  • open3d,读取stl/ply/obj/off/gltf/glb三维模型,并转换成点云,保存

    可以自己用建模软件建立一个模型 本案例使用模型的下载地址 可以从free3d免费下载,无需注册 效果: 效果: 均匀采样会在表面出现采样点聚集的现象,open3d实现了一种基于poisson_disk方法的采样,能实现表面的均匀采样 原理 :参数umber_of_points是最终采样的点数量,实际会先

    2024年02月11日
    浏览(53)
  • Unity加载gltf/glb文件

    1.打开包管理器窗口 2.点击添加 3.点击“按名称添加包” 4. 输入 com.unity.nuget.newtonsoft-json 包名称和 3.0.1 版本 第一种方法: 通过PackageManager的Git url的方式添加: \\\"com.siccity.gltfutility\\\": \\\"https://github.com/siccity/gltfutility.git\\\" 如果git访问不了,你可以用第二种方式手动下载; 第二种方

    2024年02月15日
    浏览(40)
  • 如何把glb格式模型gltf格式模型导入3dmax和C4D,U3D,UE4这些主流软件中

    咱有时候去glbxz.com添加链接描述 官网下载免费glb格式模型,gltf模型下载时候是没有通用格式,例如fbx,obj,这个时候3dmax和C4D直接打开导入是不行的,也可以制作glb模型,扣扣:424081801 这个时候,咱们用 glbxz.com 平台在线编辑功能,先导入glb 导入进来看看glb格式模型或者g

    2024年02月12日
    浏览(58)
  • cesium加载glb格式的3d模型

    官方示例: Cesium Sandcastle https://sandcastle.cesium.com/?src=3D%20Models.htmllabel=Tutorials glb模型下载:https://sandcastle.cesium.com/SampleData/models/CesiumAir/Cesium_Air.glb   

    2024年02月11日
    浏览(34)
  • 【Cesium学习(六)】Cesium加载3D模型(3D tiles和glTF模型)

    前面我们学习到了绘制基本的形状,但是Cesium还可以加载3D模型,因为像高德地图这种的技术来加载大型复杂的建筑模型性能不加,所有只能想Cesium这种专门做3D地图的技术。接下来就学习一下如何加载模型。 Cesium目前支持两种模型方案,一个是使用3D tiles, 另一个是加载g

    2024年02月07日
    浏览(46)
  • threejs加载.Fbx .OBJ 3D模型文件

    在threejs官网下载threejs的文件,可以选择直接下载,也可以跳转到GitHub拉取 拉取下来的完整文件就是这个样子 拉取成功后我们在本地安装启动服务,这样就能很快速的查看threejs的各种例子了 可以先看看官网里的例子,你想要的东西官方里面都有 后期在开发的时候需要用到b

    2023年04月08日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包