当前位置: 首页 > news >正文

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

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.75this.scene.rotation.x = 10this.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.9this.camera.position.y = -100this.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 - 1mouse.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 = 1controls.maxDistance = 500controls.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) {// 设置nametexture.name = 'background'// 创建一个平面几何体(或其他几何体)const geometry = new THREE.PlaneGeometry(500, 500) // 假设你的场景宽度和高度是500const 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) => {// 设置nameobj.name = 'tank'// 设置模型的位置和缩放obj.position.set(0, 0, 0)obj.scale.set(5, 5, 5)// 设置模型的旋转角度obj.rotation.x = 1.6obj.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.mrgr.cn/news/44256.html

相关文章:

  • 【颜色平衡树 / E】
  • Java之二叉树的基本操作实现
  • LCD屏入门(基于ESP-IDF、SPI屏)
  • D29【python 接口自动化学习】- python基础之输入输出与文件操作
  • 菜鸟笔记004 获取目标对象的渐变颜色值
  • LeetCode讲解篇之139. 单词拆分
  • 设计模式之装饰器模式(Decorator)
  • history的pushState/replaceState理解
  • vSAN05:vSAN延伸集群简介与创建、资源要求与计算、高级功能配置、维护、故障处理
  • 突触可塑性与STDP:神经网络中的自我调整机制
  • 电子信息类专业技术学习及比赛路线总结(大一到大三)
  • LeetCode hot100---栈专题(C++语言)
  • 10月5日刷题记录
  • 数据结构与算法篇(树 - 常见术语)
  • vue.js组建开发
  • 数据结构与算法篇(图)(持续更新迭代)
  • 【LeetCode-热题100-128题】官方题解好像有误
  • 【重学 MySQL】五十八、文本字符串(包括 enum set)类型
  • 如 有 任 何 问 题 ,请 及 时 联 系 我 们 反 馈 !
  • 一个值得关注的3D生成新算法:速度和图像生成平齐,能生成合理的展开贴图和高质量mesh