uniapp安卓app 导入vue dist 显示3D效果页面

vue相关的代码片段

<template>
  <div id="my-three"></div>
</template>

<script setup>
import {ref, onMounted, getCurrentInstance} from "vue";
import * as THREE from "three";
import {OrbitControls} from "three/examples/jsm/controls/OrbitControls"
import {FBXLoader} from "three/examples/jsm/loaders/FBXLoader";
import {GLTFLoader} from "three/examples/jsm/loaders/GLTFLoader"; //gltf
import {RGBELoader} from 'three/examples/jsm/loaders/RGBELoader';


import imgurl from "@/assets/bj.png"
import {ElMessage} from "element-plus";

let height = 0, width
const {proxy} = getCurrentInstance();

const emit = defineEmits(['change'])
const scene = new THREE.Scene();
const renderer = new THREE.WebGLRenderer({
  antialias: true
});

renderer.outputEncoding = THREE.sRGBEncoding;
// renderer.outputEncoding = THREE.sRGB;
const loader = new GLTFLoader();
var clock = new THREE.Clock();
var mixer = null;
let messagelog = null
let duration = 9999000000
let camera, controls;
onMounted(() => {
  document.getElementById("my-three")?.appendChild(renderer.domElement);
  height = document.getElementById("three").offsetHeight;
  width = document.getElementById("three").offsetWidth;
  // console.log(height);
  camera = new THREE.PerspectiveCamera(55, width / height, 0.1, 10000);
  controls = new OrbitControls(camera, renderer.domElement);
  controls.enableRotate = false; // 禁用旋转
  if (height > 0) {
    init();
    renderModel();
    gltfModel1();
    render();
  }
  messagelog = ElMessage({
    message: '第一步    点击选择养殖蚌',
    type: 'success',
    duration: duration,
    offset: window.screen.height / 2

  })
});


function init() {
  //光源
  const ambient = new THREE.AmbientLight(0xdddddd, 0.4);
  scene.add(ambient);
  //设置相机位置
  // camera.position.set(10, 337, 533);
  camera.position.set(30, 1017, 1599);

  // camera.position.set(200, 200, 200);
  //设置相机方向
  // camera.lookAt(0, 400, 0);

  //辅助坐标轴
  // const axesHelper = new THREE.AxesHelper(200); //参数200标示坐标系大小,可以根据场景大小去设置
  // scene.add(axesHelper);
  // scene.background = new THREE.Color(0xeaeaea);
  const sceneLoader = new THREE.TextureLoader();
  let sceneColorTexture = sceneLoader.load(imgurl);
  // sceneColorTexture.minFilter = THREE.LinearFilter;
  scene.background = sceneColorTexture;
  scene.background.matrixAutoUpdate = false;


  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.antialias = true;


}

let actions = []
// const segmentDurations = [2, 10.5,27.5]
const segmentDurations = [2, 2, 8.5, 57.5]
let currentActionIndex = 0
let currentIndex = 0
let isStop = false
// 关键代码
function fetchLocal(e) {
  return new Promise((resolve, reject) => {
    plus.io.resolveLocalFileSystemURL(e, entry => {
      var reader = null;
      entry.file(file => {
        reader = new plus.io.FileReader();
        reader.onloadend = (read) => {
          resolve(read.target.result)
        };
        reader.readAsDataURL(file);
      }, function (error) {
        alert(error.message);
      });
    }, err => {
      resolve(e)
    })
  })
}

function gltfModel1() {
  fetchLocal("./xiao.glb").then(res => {
    loader.load(res, function (obj) {
      // let scale = 100;
      // let scale = 300;
      let scale = 1000;
      obj.scene.scale.set(scale, scale, scale); // 将模型放大两倍
      obj.scene.position.set(0, -1000, 0); // 将模型位置设置为长方形模型的中心点/
      obj.scene.rotation.set(0, 0, 0); // 可以根据需要调整模型的旋转
      // obj.scene.rotation.y += 0.8; // 旋转

      obj.scene.translateY(-80);
      scene.add(obj.scene)
      // obj作为参数创建一个混合器,解析播放obj及其子对象包含的动画数据
      mixer = new THREE.AnimationMixer(obj.scene);
      // 获取模型中的动画剪辑
      const animations = obj.animations;
      // 查看动画数据
      // obj.animations[0]:获得剪辑对象clip
      for (let i = 0; i < animations.length; i++) {
        console.log(animations[i], animations[i].name, 'ok')
        actions.push(mixer.clipAction(animations[i]));
        if (animations[i].name == 'Z_初始锚点') {
          const clip = animations[i];
          if (clip) {
            // 创建动作并播放
            const action = mixer.clipAction(clip);
            action.play();

            // 将动画设置为第一帧
            mixer.setTime(0);
            action.paused = true;
          }
        }
      }
      // console.log(obj)

      camera = obj.cameras[0]


      // 获取第一个动画剪辑


    })
    //
  })

  const pmremGenerator = new THREE.PMREMGenerator(renderer); // 使用hdr作为背景色
  pmremGenerator.compileEquirectangularShader();
  const rgbeLoader = new RGBELoader();
  fetchLocal("./venice_sunset_1k.hdr").then(res => {
    rgbeLoader.load(res, function (texture) {
      const envMap = pmremGenerator.fromEquirectangular(texture).texture;
      pmremGenerator.dispose();
      scene.environment = envMap; // 给场景添加环境光效果
      console.log(envMap);
      // scene.background = envMap; // 给场景添加背景图
    })
  })
  // 根据模型名称
  window.addEventListener('click', onMouseClick, false);
}

// let duration = 2000

function onMouseClick(event) {
  let raycaster = new THREE.Raycaster();
  let mouse = new THREE.Vector2();
  event.preventDefault();

  mouse.x = (event.clientX / width) * 2 - 1;
  mouse.y = -(event.clientY / height) * 2 + 1; //这里为什么是-号,没有就无法点中
  // console.log(event)
  raycaster.setFromCamera(mouse, camera);

  const intersects = raycaster.intersectObjects(scene.children, true);

  if (intersects.length > 0) {
    // console.log(intersects)
    const intersectedObject = intersects[0].object;
    console.log(intersectedObject.name)
    if (
        intersectedObject.name == '钳子003'
        || intersectedObject.name == '钳子001'
        || intersectedObject.name == '钳子002'
        || intersectedObject.name == '钳子'
    ) {
      let num = currentActionIndex == 1 ? 2 :  4

      play(num)
    }
    if(intersectedObject.name == '固定钉'){
      play(3)
    }
    if(intersectedObject.name == '拨肉针'||intersectedObject.name == 'FBXASC230FBXASC139FBXASC168FBXASC232FBXASC130FBXASC137FBXASC229'){
      play(5)
    }
    if(intersectedObject.name == '取核针'||intersectedObject.name == 'FBXASC229FBXASC143FBXASC150FBXASC230FBXASC160FBXASC184FBXASC229'){
      play(6)
    }




  }
}

let crrshow = 0

function play(index) {
  // duration = 10

  // message.close()

  if (isStop) return;  // duration = 10
  if (currentIndex == index) {
    currentIndex = index + 1;
    crrshow = index + 1
    if (currentIndex >= 7) {
      currentIndex = 0;
    }
  } else {
    return false;
  }
  emit('change', 10)

  if (messagelog) {

    messagelog.close()
    messagelog = null
  }


  currentActionIndex = index;
  isStop = true;
  actions.forEach((action) => {
    // console.log(action)
    action.stop();
    if (
        (currentActionIndex == 0 && action._clip.name == "A_选蚌")
        || (currentActionIndex == 1 && action._clip.name == "B_选珍珠")
        || (currentActionIndex == 2 && action._clip.name == "C_开蚌")
        || (currentActionIndex == 3 && action._clip.name == "D_固定蚌壳")
        || (currentActionIndex == 4 && action._clip.name == "E_放回钳子")
        || (currentActionIndex == 5 && action._clip.name == "F_拨开蚌肉")
        || (currentActionIndex == 6 && action._clip.name == "G_种珍珠")
    ) {
      console.log(action)
      // 第一次调用 play 启动播放
      let num = parseFloat(action._clip.duration).toFixed(2)
      action.clampWhenFinished = true;
      action.loop = THREE.LoopOnce;
      action.enabled = true;
      action.clampWhenFinished = true;
      action.play()
      playNextSegment(num)
    }
  })
  // playNextSegment()
}

let Tem = null

function playNextSegment(num) {
  Tem = setTimeout(() => {
    isStop = false;
    if (currentActionIndex == 0) {
      messagelog = ElMessage({
        message: '第二步    点击选择珍珠核',
        type: 'success',
        duration: duration,
        offset: window.screen.height / 2

      })
    }
    if (currentActionIndex == 1 || currentActionIndex == 3 || currentActionIndex == 5) {
      let message = currentActionIndex == 1 ? "第三步    点击选择右侧托盘里的钳子" :
          currentActionIndex == 3 ? "第五步   点击上方钳子放回托盘" : "第七步   点击右侧托盘里的送片针"
      messagelog = ElMessage({
        message,
        type: 'success',
        duration: duration,
        offset: window.screen.height / 2


      })
    }
    if (currentActionIndex == 2 || currentActionIndex == 4) {
      let message = currentActionIndex == 2 ? "第四步    点击左侧托盘里的固定器" : "第六步   点击左侧托盘里的开口针"
      messagelog = ElMessage({
        message: message,
        type: 'success',
        duration: duration,
        offset: window.screen.height / 2


      })
    }
    if (currentActionIndex == 6) {
      messagelog = ElMessage({
        message: '育珠结束,请重新开始',
        type: 'success',
        duration: duration,
        offset: window.screen.height / 2


      })
      setTimeout(() => {
        initialization()
      }, 6000)
    }
    emit('change', crrshow)
  }, num * 1000);
}

function initialization() {
  if (messagelog) {

    messagelog.close()
    messagelog = null
  }
  isStop = false;
  crrshow = 0;
  currentActionIndex = 0;
  currentIndex = 0;
  if (Tem) {
    clearTimeout(Tem)
  }
  actions.forEach((action) => {
    // console.log(action)
    action.stop();
    if (action._clip.name == 'Z_初始锚点') {
      action.play();
      mixer.setTime(0);
      action.paused = true;
    }
  })
  messagelog = ElMessage({
    message: '第一步    点击选择养殖蚌',
    type: 'success',
    duration: duration,
    offset: window.screen.height / 2


  })
  emit('change', crrshow)

}

function renderModel() {
  //渲染
  renderer.setSize(width, height); //设置渲染区尺寸
  renderer.render(scene, camera); //执行渲染操作、指定场景、相机作为参数
  // renderer.setClearColor(0x00ff00); // 设置背景颜色为绿色
  renderer.toneMapping = THREE.ACESFilmicToneMapping;
  // 设置曝光度
  renderer.toneMappingExposure = 1.5; // 适当调整曝光度

  controls.minPolarAngle = Math.PI / 4; // 最小极角为 45 度
  controls.maxPolarAngle = Math.PI / 2; // 最大极角为 90 度
}

function render() {  //校正不同通道颜色

  requestAnimationFrame(render);
  if (mixer !== null) {
    //clock.getDelta()方法获得两帧的时间间隔
    // 更新混合器相关的时间
    mixer.update(clock.getDelta());
  }
  renderer.autoClear = false
  renderer.clear()
  renderer.outputEncoding = null //THREE.RGBDEncoding
  controls.update();
  renderer.render(scene, camera);
}

// 画布跟随窗口变化
window.onresize = function () {
  renderer.setSize(width, height);
  camera.aspect = width / height;
  camera.updateProjectionMatrix();
};

// 交互事件
// addEventListener("dblclick", onMouseDblclick, false);

function onMouseDblclick(event) {
  let intersects = getIntersects(event);

  if (intersects.length !== 0 && intersects[0].object instanceof THREE.Mesh) {
    const selectedObject = intersects[0].object;
    let selectedObjects = [];
    selectedObjects.push(selectedObject);
    // console.log(selectedObjects);
    // outlinePass.selectedObjects = selectedObjects;
  }
}

//获取与射线相交的对象数组
function getIntersects(event) {
  let rayCaster = new THREE.Raycaster();
  let mouse = new THREE.Vector2();

  //通过鼠标点击位置,计算出raycaster所需点的位置,以屏幕为中心点,范围-1到1
  mouse.x = (event.clientX / width) * 2 - 1;
  mouse.y = -(event.clientY / height) * 2 + 1; //这里为什么是-号,没有就无法点中

  //通过鼠标点击的位置(二维坐标)和当前相机的矩阵计算出射线位置
  rayCaster.setFromCamera(mouse, camera);
  return rayCaster.intersectObjects(scene.children);
}


defineExpose({
  play,
  initialization
})
</script>

<style scoped lang="scss"></style>

vue打包导入uniapp 的代码片段运行之后可以在安卓app正在运行显示

<template>
	<view class="">
		<web-view :src="src"></web-view>
	</view>

</template>

<script>
	export default {
		data() {
			return {
				src: ''
			}
		},
		onLoad() {
			let num =(new Date()).getTime()
			this.src = '/static/dist/index.html?id='+num;
		},
		methods: {

		}
	}
</script>

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值