<template>
<view class="">
<view :prop="threeData" :change:prop="threeModule.getNfrUrl" :clearFlag="clearFlag" :change:clearFlag="threeModule.clear">
</view>
<view ref="threeView" id="threeView" class="three" >
<!-- <u-loading-page class="aaa" mode="circle" loadingText="加载中" :loading="true" bgColor="transparent"></u-loading-page> -->
</view>
</view>
</template>
<script>
export default {
props:{
modelUrl:{
type: String,
default: ''
},
changeFlag:{
type: Boolean,
default: true
},
},
data(){
return {
threeData: {
changeFlag: true,
modelUrl: '',
},
clearFlag: false,
}
},
methods: {
onload(){
uni.hideLoading()
},
clear(){
uni.hideLoading()
this.clearFlag = true
}
},
// beforeDestroy(){
// this.threeData = {
// ...this.threeData,
// clearFlag: 'aaaa'
// }
// this.clearFlag = true
// console.log('beforeDestroy2')
// },
watch: {
modelUrl:{
handler(val){
if (val) {
let routes = getCurrentPages()
let curRoute = routes[routes.length - 1].route
uni.showLoading({
title: '3D模型加载中...',
mask: true,
})
if (curRoute == 'pageA/home/hcpDetails/index') {
this.threeData = {
changeFlag: false,
modelUrl: val,
}
} else {
this.threeData = {
changeFlag: true,
modelUrl: val,
}
}
}
},
immediate: true,
},
}
}
</script>
<script module="threeModule" lang="renderjs">
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';
export default {
data() {
return {
camera: null,
scene: null,
renderer: null,
controls: null,
clock: null,
timeS: 0,
modelUrl: '',
changeFlag: true,
ownerInstance: null
}
},
methods: {
clear(newValue){
cancelAnimationFrame(this.animate)
this.renderer.forceContextLoss()
this.renderer.dispose()
this.scene.clear()
this.scene = null
this.camera = null
this.controls = null
this.renderer.domElement = null
this.renderer = null
},
getNfrUrl(newValue, oldValue, ownerInstance){
this.modelUrl = newValue.modelUrl
this.changeFlag = newValue.changeFlag
this.ownerInstance = ownerInstance
this.init()
// this.$nextTick(() => {
// })
},
init() {
// 创建一个场景
this.scene = new THREE.Scene()
//三位坐标线
// const axesHelper = new THREE.AxesHelper(5);
// this.scene.add(axesHelper);
/**相机设置*/
var width = window.innerWidth; //窗口宽度
var height = window.innerHeight; //窗口高度
// var k = width / height; //窗口宽高比
var k = 345 / 400
var s = 380; //三维场景显示范围控制系数,系数越大,显示的范围越大
//创建相机对象,45是相机的视角 , 宽高比是屏幕的宽高比 , 最近能看到0.1 , 最远能看到10000
// this.camera = new THREE.OrthographicCamera(-s * k, s * k, s , -s, 1, 1000);
// this.camera.position.set(0, 20, 300);
this.camera = new THREE.PerspectiveCamera()
//100,300 ,500
this.camera.position.set(500, 0, 700); //设置相机位置
// this.camera.position.set(100, -800, 500);
// this.scene.position.set(0,40,0)
console.log(this.scene.position)
this.camera.lookAt(this.scene.position); //设置相机方向(指向的场景对象)
/* 光源设置*/
this.pointLight()
this.gblLoader()
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()
}
this.clock = new THREE.Clock()
//导入模型文件
// this.gblLoader()
// this.objLoader()
// 执行一个渲染函数
this.rendererGLR()
//创建控件对象
this.change()
//更新轨道控件
this.animate()
},
//导入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(){
console.log(1111)
let that=this
const loader = new GLTFLoader();
loader.load(this.modelUrl, function(gltf) {
console.log(gltf)
that.mesh = gltf.scene
let model = gltf.scene
that.scene.add(model);
that.ownerInstance.callMethod('onload')
});
},
//渲染函数
rendererGLR(){
this.$nextTick(() => {
const element = document.getElementById('threeView')
this.renderer.setSize(element.clientWidth, element.clientHeight);
element.appendChild(this.renderer.domElement);
})
this.renderer = new THREE.WebGLRenderer({alpha:true, antialias: true});//alpha:true背景透明
this.renderer.setPixelRatio( window.devicePixelRatio * 2);
this.renderer.toneMapping = THREE.ACESFilmicToneMapping;
this.renderer.toneMappingExposure = 1.0;
this.renderer.shadowMap.enabled = true;
this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
// // #ifdef H5
// // #endif
// // #ifdef APP-PLUS
// this.$refs.threeView.appendChild(this.renderer.domElement);
// // #endif
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);
},
//创建控件对象
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() {
// this.controls.update();
// this.renderer.render(this.scene, this.camera);
// requestAnimationFrame(()=>{
// this.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 = 15
}
this.controls.autoRotate = true // 是否自动旋转
}
//创建一个时钟对象
// this.clock = new THREE.Clock()
// this.scene.rotateY(0.01)
//获得两帧的时间间隔 更新混合器相关的时间
// if (this.mixer) {this.mixer.update(this.clock.getDelta())}
},
},
// watch: {
// modelUrl:{
// handler(val){
// console.log(88)
// console.log(val.toString())
// if (val) {
// this.init()
// }
// },
// immediate: true,
// }
// }
}
</script>
<style scoped>
.three{
width: 100%;
height:690rpx;
}
</style>

4***@qq.com
- 发布:2023-09-14 15:06
- 更新:2023-09-14 15:06
- 阅读:542
0 个回复