概述

如有不明白的可以加QQ:2354528292;wx: aichitudousien
更多教学视频请访问:https://space.bilibili.com/236087412
源码获取: https://item.taobao.com/item.htm?spm=a21dvs.23580594.0.0.3c3a645eIMTaft&ft=t&id=714567873775

写一个Three.js 模型拆解项目,先看视频效果

three.js 模型拆解项目

初始化场景,相机,灯光,天空盒

此部分代码可在博客中的智慧城市项目中搜索到,就不在重复粘贴了,都是一样的,天空盒的素材是在three的demo素材里面,随便用一个就好了,这个无关紧要,加载模型的方法也是一样,前面博客的代码都有。
此时可以看到的效果是
在这里插入图片描述

拆解模型原理

实际拆解模型的原理很简单,只需要把每个模型的位置机型记录就好了,每个模型的mesh都拥有两个位置,一个是原位置,一个是需要移动的位置。

let model = await app.loaderGltfDracoModel(
      "model/",
      'Seahawk',
    );
    
let r = 60;

model.traverse(function (child) {
   child.fromPosition = [child.position.x,child.position.y,child.position.z]
   child.toPosition = [Math.random()* r, Math.random()* r, Math.random()* r]
})

从上面的代码我们可以看到,首先先加载了飞机模型,然后将飞机模型的子对象中绑定上fromPosition 和toPosition 两个对象,这样我们就可以使用tween将模型给移动到对应的位置。

拆解模型

app是实例化的对象,model是传入的飞机模型

export function openModel(app, model) {
  model.traverse(e => {
    if (e.isMesh) {
      let toPosition = e.toPosition;
      let fromPosition = e.fromPosition;
      app.modelMove({
        fromPosition,
        toPosition
      }, e);
    }
  })
}

app.modelMove主要就是使用tween来进行移动位置而已,很简单。
此时我们只需要点击拆解模型按钮时调用此函数就好了,效果:
在这里插入图片描述

合并模型

模型合并只是将模型的两个位置调换一下就好了

export function closeModel(app, model) {
  model.traverse(e => {
    if (e.isMesh) {
      let toPosition = e.toPosition;
      let fromPosition = e.fromPosition;
      app.modelMove({
        fromPosition: toPosition,
        toPosition: fromPosition
      }, e);
    }
  })
}

模型文本

现在我们来实现鼠标移动到模型上显示文本的效果,此处使用创建文本方法是CSS2DRenderer。
首先引入对应的包

import { CSS2DObject, CSS2DRenderer } from "three/examples/jsm/renderers/CSS2DRenderer";
	  const cssRenderer = new CSS2DRenderer()
	  const text= new THREE.CSS2DObject( document.getElementById("box") )
      cssRenderer.setSize(app.el.offsetWidth, app.el.offsetHeight)
      cssRenderer.domElement.style.position = 'absolute'
      cssRenderer.domElement.style.top = 0
      cssRenderer.domElement.style.pointerEvents = "none"
      app.el.appendChild(cssRenderer.domElement)

最后记得在动画函数中调用

css2DRenderer.render( scene, camera )

box的css样式自己写就好了~,此时这样的文本就写好了
在这里插入图片描述

鼠标移动时更新文本

只需要在鼠标移动的时候获取到当前的点位置,当前点位置有模型的时候更新位置和获取到模型的name名称更新文本就好了
app.initRaycaster 此函数在第一篇文章也有

app.initRaycaster("mousemove", (selectObj) => {
        if (selectObj) {
          let point = selectObj.point;
          text.position.set(point.x, point.y, point.z);
        } else {
          text.position.set(1000, 1000, 1000);
        }
      });

最后就完成了大部分功能,模型对应的文本只需要将name和我们需要的name做一个映射就好了,此处我随便下载的模型,太麻烦了就没弄数据了。

此篇文章结束,关于机翼旋转很简单,获取到机翼的mesh进行旋转就好了,没什么难得,后续考虑会出一个使用刚体来做游戏方面的文章,有时间在写吧~

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐