Three.js模型导入与视角切换

在这里插入图片描述

<!--  -->
<template>
  <div id="threeBox">
    <n-spin v-if="loading" size="medium" class="absolute left-1/2 top-1/2" />
  </div>
  <div class="absolute right-20 z-50 bottom-20">
    <div v-for="item in btnGroup" :key="item.name" @click="camreaAnimateTo(item.xyz)">{{ item.name }}</div>
  </div>
</template>

<script lang='ts' setup>
import * as THREE from 'THREE'
import TWEEN from '@tweenjs/tween.js';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'

const width = window.innerWidth - 300
const height = window.innerHeight - 104
const loading = ref(false)
const scene = new THREE.Scene()
const btnGroup = [
  {
    name: '海鲜寿司店',
    xyz: {
      x: -152, y: -150, z: 350
    }
  },
  {
    name: '书店',
    xyz: {
      x: 102, y: -50, z: 300
    }
  },
  {
    name: '我的车',
    xyz: {
      x: 452, y: 0, z: -150
    }
  }
]
let mixer: any;
/** 坐标系 */
// const axesHelper = new THREE.AxesHelper(150)
// scene.add(axesHelper) // 坐标系

/** 相机 */
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 10000);
camera.position.z = 100;

/** 灯光 */
const lingt = new THREE.AmbientLight(0xffffff, 2)
scene.add(lingt) // 坐标系

/** 渲染器 */
const renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0xBFE3DD, 1)
renderer.setSize(width, height);

/** 解码器 */
const dracoLoader = new DRACOLoader()
dracoLoader.setDecoderPath('jsm/gltf/') // 设置public下的解码路径,注意最后面的/

/** 控制器 */
const controls = new OrbitControls(camera, renderer.domElement);

/** 房子 */
const loader = new GLTFLoader()
loader.setDRACOLoader(dracoLoader)
loader.load(
  'moudle/LittlestTokyo.glb',
  (gltf: any) => {
    console.log(gltf)
    const model = gltf.scene;
    console.log('模型加载完成')
    camera.position.setZ(600);
    scene.add(model)
    mixer = new THREE.AnimationMixer(model);
    mixer.clipAction(gltf.animations[0]).play();
    animate();
    loading.value = false
  },
  () => {
    loading.value = true
    console.log('模型加载中')
  },
  function (error: any) {
    console.log('模型加载失败')
    loading.value = false
    console.error(error);
  }
)

// 汽车
loader.load(
  'moudle/moskvich_407.glb',
  (gltf: any) => {
    const model = gltf.scene
    model.position.set(300, -200)
    model.scale.set(0.45, 0.45, 0.45)
    scene.add(model)
    loading.value = false
  },
  () => {
    loading.value = true
    console.log('模型加载中')
  },
  function (error: any) {
    console.log('模型加载失败')
    loading.value = false
    console.error(error);
  }
)
const clock = new THREE.Clock();
const animate = () => {
  requestAnimationFrame(animate);
  const delta = clock.getDelta();
  mixer.update(delta);
  controls.update();
  renderer.render(scene, camera);
}
/** 增加鼠标事件 */
const useAddOrbitControls = () => {
  //监听鼠标、键盘事件
  controls.addEventListener('change', function () {
    renderer.render(scene, camera); //执行渲染操作
  });
}

const render = () => {
  console.log(123)
  TWEEN.update();
  renderer.render(scene, camera);
  requestAnimationFrame(render);
}

/** 右侧鼠标 */
const camreaAnimateTo = (xyz: any) => {
  new TWEEN.Tween(camera.position)
    .to(xyz, 500)
    .onUpdate(function () {
      // camera.lookAt(500, 100, 100);
    })
    .start()
  render()
}

onMounted(() => {
  useAddOrbitControls() // 增加鼠标事件
  renderer.render(scene, camera);
  document.getElementById('threeBox')?.appendChild(renderer.domElement);
})
</script>

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值