vue3使用three.js加载.obj模型示例

news2024/11/25 22:42:22

vue3使用three.js加载.obj模型示例

效果:
在这里插入图片描述
在这里插入图片描述
代码:
需要先安装three.js

npm install three
<template>
  <div ref="threeContainer" class="three-container"></div>
</template>

<script>
import * as THREE from 'three'
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
let scene = null // 场景需要定义到全局

const raycaster = new THREE.Raycaster()
const mouse = new THREE.Vector2()

export default {
  name: 'ThreeModel',
  data() {
    return {
      camera: null,
      renderer: null,
      controls: null
    }
  },
  mounted() {
    this.initThree()
    this.loadModel()
    this.initControls()
    this.addBackground()
    this.animate()
  },
  unmounted() {
    this.renderer.domElement.removeEventListener('click', this.onClick)
  },
  methods: {
    /**
     * 创建场景
     */
    initThree() {
      this.scene = new THREE.Scene()
      this.scene.rotation.y = 20.75
      this.scene.rotation.x = 10
      this.scene.rotation.z = 0

      // 创建相机
      this.camera = new THREE.PerspectiveCamera(
        75,
        this.$refs.threeContainer.clientWidth / this.$refs.threeContainer.clientHeight,
        1,
        1000
      )
      this.camera.position.z = 13.9
      this.camera.position.y = -100
      this.camera.position.x = 45

      // 把画面放大一点
      // this.camera.zoom = 1
      // this.camera.updateProjectionMatrix()

      // 创建渲染器
      this.renderer = new THREE.WebGLRenderer()
      this.renderer.setSize(
        this.$refs.threeContainer.clientWidth,
        this.$refs.threeContainer.clientHeight
      )
      this.$refs.threeContainer.appendChild(this.renderer.domElement)

      // 添加光源
      const light = new THREE.DirectionalLight(0xa1a1a1, 1)
      light.position.set(10, 5, 5).normalize()
      this.scene.add(light)

      // 注册点击事件
      this.renderer.domElement.addEventListener('click', this.onClick, false)
    },
    /**
     * 点击事件
     * @param {*} event
     */
    onClick(event) {
      // 将鼠标位置归一化到-1到1的范围(相对于渲染器的尺寸)
      mouse.x = (event.clientX / window.innerWidth) * 2 - 1
      mouse.y = -(event.clientY / window.innerHeight) * 2 + 1

      // 使用相机和鼠标向量来投射射线
      raycaster.setFromCamera(mouse, this.camera)

      // 检查与哪些对象相交,并处理相交的对象
      const intersects = raycaster.intersectObjects(this.scene.children)
      if (intersects.length > 0) {
        intersects.forEach((o) => {
          const intersectedObject = o.object
          // 在这里处理被点击的对象,例如改变颜色、显示信息等
          console.log('点击-on object:', intersectedObject)
          if (intersectedObject.parent.name == 'tank') {
            // 改变颜色
            intersectedObject.material.color.set(0xffffff)
          }
        })
      }
    },
    /**
     * 鼠标互动
     */
    initControls() {
      // 假设你已经有了相机、渲染器和场景
      const controls = new OrbitControls(this.camera, this.renderer.domElement)

      // 设置控制器的属性,例如最小和最大距离、旋转速度等
      controls.minDistance = 1
      controls.maxDistance = 500
      controls.enableDamping = true // 启用阻尼效果,使互动更加流畅
      controls.dampingFactor = 0.25 // 阻尼系数
      controls.screenSpacePanning = true // 是否允许平面移动
      this.controls = controls
    },
    /**
     * 场景增加背景
     */
    addBackground() {
      // 添加纯色为背景
      this.renderer.setClearColor(0xcccccc) // 设置背景颜色为天空色

      // 创建一个新的纹理加载器
      const textureLoader = new THREE.TextureLoader()

      const scene = this.scene

      // 加载图像纹理
      textureLoader.load(
        'http://cdn.yhxweb.cn/3d-sucai/BA_64_D.jpg', // 图像路径
        function (texture) {
          // 设置name
          texture.name = 'background'

          // 创建一个平面几何体(或其他几何体)
          const geometry = new THREE.PlaneGeometry(500, 500) // 假设你的场景宽度和高度是500
          const material = new THREE.MeshBasicMaterial({ map: texture })

          // 创建一个网格并添加到场景中
          const plane = new THREE.Mesh(geometry, material)
          plane.position.z = 0 // 根据你的场景深度调整位置
          scene.add(plane)
        },
        // 可选的加载进度回调函数
        undefined,
        // 可选的加载错误回调函数
        function (err) {
          console.error('An error happened while loading the texture.')
        }
      )
    },
    /**
     * 初始化模型
     */
    loadModel() {
      const loader = new OBJLoader()

      // 加载.obj模型文件
      loader.load(
        'http://cdn.yhxweb.cn/3d-sucai/OBJ_7020.obj', // 替换为你的.obj文件的URL(园林)
        (obj) => {
          // 设置name
          obj.name = 'tank'

          // 设置模型的位置和缩放
          obj.position.set(0, 0, 0)
          obj.scale.set(5, 5, 5)

          // 设置模型的旋转角度

          obj.rotation.x = 1.6
          obj.rotation.y = 2

          // 设置模型颜色
          obj.traverse((child) => {
            console.log('child:', child)

            if (child instanceof THREE.Mesh) {
              child.material.color.set(0xffd4db) // 设置颜色
            }
          })

          // 将加载的模型添加到场景中
          this.scene.add(obj)
        },
        (xhr) => {
          console.log((xhr.loaded / xhr.total) * 100 + '% loaded')
        },
        (error) => {
          console.error('An error happened', error)
        }
      )
    },
    /**
     * 动画
     */
    animate() {
      // 可以在这里添加动画逻辑,例如模型旋转
      // this.scene.rotation.y += 0.002
      // this.scene.rotation.x += 0.001

      // 更新控制器
      this.controls.update()

      this.renderer.render(this.scene, this.camera)
      // console.log(this.scene.rotation.x, this.scene.rotation.y)

      requestAnimationFrame(this.animate)
    }
  }
}
</script>

<style>
.three-container {
  width: 100%;
  height: calc(100vh - 175px);
  overflow: hidden;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2193260.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

男单新老对决:林诗栋VS马龙,巅峰之战

听闻了那场激动人心的新老对决&#xff0c;不禁让人热血沸腾。在这场乒乓球的巅峰之战中&#xff0c;林诗栋与马龙的对决无疑是一场视觉与技术的盛宴。 3:3的决胜局&#xff0c;两位选手的每一次挥拍都充满了策略与智慧&#xff0c;他们的每一次得分都让人心跳加速。 林诗栋&am…

10.6学习

1.Hystrix / Sentinel ●服务雪崩场景 自己即是服务消费者&#xff0c;同时也是服务提供者&#xff0c;同步调用等待结果导致资源耗尽 ●解决方案 服务方&#xff1a;扩容、限流&#xff0c;排查代码问题&#xff0c;增加硬件监控 消费方&#xff1a;使用Hystrix资源隔离&a…

JavaSE——面向对象10:抽象类、接口

目录 一、抽象类 (一)抽象类的引出 (二)抽象类基本介绍 (三)注意事项和使用细节 (四)抽象类的最佳实践——模板设计模式 二、接口 (一)接口快速入门 (二)基本介绍 (三)注意事项与使用细节 (四)接口VS继承 (五)接口的多态性 1.多态参数 2.多态数组 3.接口存在多态…

CoreGen项目实战——代码提交信息生成

数据与相关代码见文末 1.概述 源代码与自然语言之间的语义鸿沟是生成高质量代码提交信息的一个重大挑战。代码提交信息对于开发者来说非常重要,因为它们简明扼要地描述了代码更改的高层次意图,帮助开发人员无需深入了解具体实现即可掌握软件的演变过程。手动编写高质量的提交…

Vite多环境配置与打包:

环境变量必须以VITE开头 1.VITE_BASE_API&#xff1a; 在开发环境中设置为 /dev-api&#xff0c;这是一个本地 mock 地址&#xff0c;通常用于模拟后端接口。 2.VITE_ENABLE_ERUDA&#xff1a; 设置为 "true"&#xff0c;表示启用调试工具&#xff0c;通常是为了…

Elasticsearch学习笔记(六)使用集群令牌将新加点加入集群

随着业务的增长&#xff0c;陆续会有新的节点需要加入集群。当我们在集群中的某个节点上使用命令生成令牌时会出现报错信息。 # 生成令牌 /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s node出现报错信息&#xff1a; Unable to create enrollment…

VMware WorkStation Pro 15.5(低版本安装) 教学用

VMware WorkStation Pro 15.5(低版本安装) 教学用 文章目录 VMware WorkStation Pro 15.5(低版本安装) 教学用前言安装使用 前言 VMware Workstation Pro 15.5 是一款功能强大的桌面虚拟化软件&#xff0c;适用于在单台物理电脑上运行多个操作系统。它被广泛应用于软件开发、测…

【文献阅读】Attention Bottlenecks for Multimodal Fusion

Abstract 在多模态视频分类中&#xff0c;将各模态的最终表示或预测进行后期融合&#xff08;“后期融合”&#xff09;仍然是主流范式。为此&#xff0c;本文提出了一种基于 Transformer 的新型架构&#xff0c;该架构使用“融合瓶颈”在多个层次进行模态融合。与传统的成对自…

科研必备语料库

1. Corpus of Contemporary American English 链接&#xff1a;https://www.english-corpora.org/coca/ 2. Purdue Online Writing Lab 链接&#xff1a;https://owl.purdue.edu/owl/ 3. Academic Phrases and Vocabulary 链接&#xff1a;https://www.ref-n-write.com/blog…

IntelliJ IDE 插件开发 | (十三)自定义项目脚手架(下)

系列文章 本系列文章已收录到专栏&#xff0c;交流群号&#xff1a;689220994&#xff0c;也可点击链接加入。 前言 在上一篇文章中介绍了如何在 IDEA 中自定义项目脚手架&#xff0c;本文将介绍如何在WebStorm、PyCharm、CLion等其它 IntelliJ 主流平台中如何自定义项目脚手…

【论文速看】DL最新进展20241006-视频深度估计、3D、自监督学习

目录 【视频深度估计】【3D】【自监督学习】 【视频深度估计】 [TPAMI 2024] NVDS: Towards Efficient and Versatile Neural Stabilizer for Video Depth Estimation 论文链接&#xff1a;https://arxiv.org/pdf/2307.08695 代码链接&#xff1a;https://github.com/RaymondW…

地理空间数据存储与处理:MySQL空间数据类型的优化与应用!

在 MySQL 数据库中&#xff0c;空间数据类型用于存储和处理地理空间数据。这些数据类型允许我们在开发时可在数据库中存储和操作地理位置、几何形状和地理空间关系等信息。 一、什么是空间数据类型 MySQL 中的空间数据类型主要包括以下几种&#xff1a; GEOMETRY&#xff1a…

【无人水面艇路径跟随控制3】(C++)USV代码阅读: ROS包的构建和管理:包的依赖关系、包含目录、库文件以及链接库

【无人水面艇路径跟随控制3】&#xff08;C&#xff09;USV代码阅读&#xff1a; ROS包的构建和管理&#xff1a;包的依赖关系、包含目录、库文件以及链接库 写在最前面ROS是什么CMakeLists.txt总结详细解释CMake最低版本和项目名称编译选项查找catkin包catkin包配置包含目录添…

(刷题记录5)盛最多水的容器

盛最多水的容器 题目信息&#xff1a;题目思路(环境来自力扣OJ的C)&#xff1a;暴力枚举&#xff1a;双指针&#xff1a;移动高度较高的指针移动高度较低的指针 复杂度&#xff1a;代码与注释&#xff1a;暴力枚举&#xff1a;双指针&#xff1a; 题目信息&#xff1a; 给定一…

windows 找不到文件 Microsoft Net Framework 3.5 windows Driver Foundation(WDF).exe

问题 正常更新windows 11的时候发现这个问题。 重启也无法完成下面的更新&#xff0c;重启之后还是显然要更新&#xff1a; 解决方法 中文网站没有找到解决方案。微软官网总是给不靠谱的解决方案。 从有关上看到一个印度语音的视频&#xff0c;用的方法可行。借鉴过来。 …

【机器学习】机器学习框架

机器学习框架是支持开发、训练、和部署机器学习模型的工具集和库&#xff0c;以下是一些主流的机器学习框架及其特点&#xff1a; 1. TensorFlow 特点: 由 Google 开发&#xff0c;支持从研究到生产的大规模部署&#xff0c;广泛应用于深度学习模型。优势: 强大的可扩展性&am…

golang gin入门

gin是个小而精的web开发框架 官方文档 安装 go get -u github.com/gin-gonic/gin最简单的起手代码 package mainimport ("net/http""github.com/gin-gonic/gin" )func main() {r : gin.Default()r.GET("/ping", func(c *gin.Context) {c.JSON…

【自用】王道文件管理强化笔记

文章目录 操作系统引导:磁盘初始化文件打开过程角度1文件的打开过程角度2 内存映射的文件访问 操作系统引导: ①CPU从一个特定主存地址开始&#xff0c;取指令&#xff0c;执行ROM中的引导程序(先进行硬件自检&#xff0c;再开机) ②)将磁盘的第一块–主引导记录读入内存&…

【机器学习】深度学习、强化学习和深度强化学习?

深度学习、强化学习和深度强化学习是机器学习的三个重要子领域。它们有着各自独特的应用场景和研究目标&#xff0c;虽然都属于机器学习的范畴&#xff0c;但各自的实现方式和侧重点有所不同。 1. 深度学习&#xff08;Deep Learning&#xff09; 深度学习是一种基于神经网络的…

2024 年在线翻译谁称霸?论文翻译场景大揭秘!

现在这世界&#xff0c;语言就是把我们连在一起的绳子&#xff0c;挺关键的。不管搞研究、做生意还是传文化&#xff0c;翻译得又快又准。2024年&#xff0c;翻译这行竞争挺猛的&#xff0c;各种在线翻译工具都挺拼的。咱们今天就聊聊论文翻译&#xff0c;瞅瞅谁能在这场翻译比…