threejs + vue 倒入ade文件实现动画效果

threejs + vue 倒入ade文件实现动画效果

<template>
<div class="modelsBox">
  <div class="modelsBox_wrapper"></div>
  <div class="opara-pannel">
    <div>
      <button @click="save">保存</button>
      <button @click="show">回显</button>
    </div>
    <div>
      三维坐标点信息
      <p>{{point3d}}</p>
    </div>
  </div>
</div>
</template>

<script>
import * as THREE from 'three';
// import {AnimationMixer} from 'three';
import { RoomEnvironment } from 'three/examples/jsm/environments/RoomEnvironment.js';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { ColladaLoader } from 'three/examples/jsm/loaders/ColladaLoader.js';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { KTX2Loader } from 'three/examples/jsm/loaders/KTX2Loader.js';
import { MeshoptDecoder } from 'three/examples/jsm/libs/meshopt_decoder.module.js';
import { webglOBJ, labelTag, getPointRay, getFitScaleValue, deepCopyObject } from '@/utils/webGL/webGL.js';
export default {
  name: 'modelsBox',
  data () {
    return {
      point3d: {},
      zoom: 1,
      target: '',
      sence: null,
      camera: '',
      renderer: '',
      obj: {
        sence: '',
        camera: ''
      },
      labels: [
        {x: 381.0111567102036, y: 41.66598867957452, z: -248.63694417317873},
        {x: 383.39332161333544, y: 41.37982005491592, z: -380.9167972387805},
        {x: 384.19846417704997, y: 41.50664881726524, z: -466.0620455548741}
      ]
    };
  },
  beforeDestroy () {
    document.removeEventListener('click', this.get3D);
  },
  mounted () {
    this.int();
    this.bind3Dpoint();
  },
  methods: {
    // 点击模型获取三维坐标点的信息
    bind3Dpoint() {
      const vm = this;
      document.addEventListener('click', this.get3Dmode, false);
    },
    get3Dmode () {
      console.log(getPointRay(this.sence, this.camera), 'getPointRay');
      this.point3d = getPointRay(this.sence, this.camera).point;
    },
    view (dir) {
      if (dir == 'top') {
        // this.sence.rotation.x = 10;
        this.renderer.render(this.sence, this.camera);
      }
    },
    show () {
      const {x, y, z} = JSON.parse(window.sessionStorage.getItem('position'));
      this.camera.position.set(x, y, z);
      this.camera.lookAt(this.target);
      this.renderer.render(this.sence, this.camera);
    },
    save () {
      // this.oCamera = deepCopyObject(this.camera);
      const {zoom, position, rotation} = this.camera;
      this.target = {...this.controls.target};
      window.sessionStorage.setItem('position', JSON.stringify(position));
      window.sessionStorage.setItem('target', JSON.stringify(this.target));
    },
    dele () {
      // this.sence.remove(this.plane); // 删除模型
      // this.sence.add(this.plane); // 添加模型
      console.log(this.camera, this.renderer, 'this.renderer');
    },
    int () {
      const position = window.sessionStorage.getItem('position');
      const target = window.sessionStorage.getItem('target');
  
      const webGLdom = document.querySelector('.modelsBox_wrapper');
      const sence = webglOBJ.createSence(webGLdom);
      const camera = webglOBJ.createCamera({
        fov: 45,
        aspect: 1,
        near: 2,
        far: 5000,
        position: {
          x: 10,
          y: 10,
          z: 10
        }
      });

      if (position) {
        camera.position.set(JSON.parse(position).x, JSON.parse(position).y, JSON.parse(position).z);
        camera.lookAt(JSON.parse(target));
      }

      const renderer = webglOBJ.createRenderer();
      const directionalLight = webglOBJ.createDirectionalLight({ x: 100000, y: 100000, z: 100000 }, 1);
      const ambient = webglOBJ.createAmbient();
      const datGui = webglOBJ.createDatGui();
      const controls = webglOBJ.createControls();
      const axisHelper = webglOBJ.createAxisHelper();

      const grid = new THREE.GridHelper( 500, 10, 0xffffff, 0xffffff );
			grid.material.opacity = 0.5;
			grid.material.depthWrite = false;
			grid.material.transparent = true;
			sence.add( grid );
      const vm = this;
      const loader = new ColladaLoader();
      const clock = new THREE.Clock();
			loader.load('https://threejs.org/examples/models/collada/stormtrooper/stormtrooper.dae', (collada) => {
				const avatar = collada.scene;
        console.log(collada, avatar, 'collada.sence');
				const animations = collada.animations;
				avatar.traverse(function (node) {
					if ( node.isSkinnedMesh ) {
						node.frustumCulled = false;
					}
				});
				vm.mixer = new THREE.AnimationMixer(avatar);
				vm.mixer.clipAction(animations[0]).play();
				sence.add(avatar);
			});

      // 滚动缩小获取比例
      controls.addEventListener('change', function(evt) {
        // console.log(controls.target, evt, 'zoom');
      });

      this.sence = sence;
      this.controls = controls;
      this.camera = camera;
      this.renderer = renderer;

      // webglOBJ.loadMIT(mtl, obj, (obj) => {
      //   // console.log(getFitScaleValue(obj, camera), 'adasd');
      // });
      // 将对象添加到场景中去
      webglOBJ.senceAdd([ directionalLight, ambient, datGui, controls, axisHelper]);
      // webglOBJ.webglRender(sence, camera, renderer);
      function render (html) {
        vm.$nextTick(() => {
          vm.labels.forEach((val, idx) => {
            const {x, y, z} = val;
            labelTag(camera, {x,  y, z}, `sign${idx + 1}`, val, webGLdom);
          });
        });

        const delta = clock.getDelta();
        if (vm.mixer) {
          vm.mixer.update(delta);
        }

        renderer.render(sence, camera);
        vm.sence = sence;
        vm.camera = camera;
        requestAnimationFrame(render);
      };


      this.render = render;
      render();

    }
  }
};
</script>
<style lang="scss" scoped>
.modelsBox_wrapper {
  position: relative;
  width: 100%;
  height: 100vh;
  border: 1px solid #ccc;
  overflow: hidden;
}
.opara-pannel {
  position: absolute;
  right: 15px;
  top: 100px;
  width: 200px;
  height: 400px;
  background: rgba(0, 0, 0, 0.7);
  div, p{
    color: #fff;
  }
}
.modelsBox {
  position:relative;
  overflow: hidden;
}
div[id *= "sign"] {
  width: 250px;
  height: 100px;
  padding:10px 10px 10px 70px;
  background: rgba(0, 0, 0, .65);
  background: url('~assets/label-bg.png') center center no-repeat;
  .sign{
    div {
      color: #fff;
      text-align: left;
      padding: 0 5px;
    }
  }
}
</style>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值