three.js Raycaster(鼠标点击选中模型)

效果:

代码:

<template><div><el-container><el-main><div class="box-card-left"><div id="threejs" style="border: 1px solid red"></div><div class="box-right" style="text-align: left; padding: 10px"><div style="text-align: left">标准设备坐标系:</div><div>three.js Canvas画布具有一个标准设备坐标系,该坐标系的坐标原点是在canvas画布的中间位置,x轴水平向右,y轴竖直向上,标准设备坐标系的坐标值不是绝对值,是相对值,范围是[-1,1],也就是说canvas画布上任何一个位置的坐标,如果用标准设备坐标取衡量,那么坐标的所有值都在-1和 1之间;</div><div style="text-align: left; margin-top: 10px">屏幕坐标转为 标准设备坐标:</div><div style="text-align: left"><pre>// 坐标转化公式addEventListener('click',function(event){const px = event.offsetX;const py = event.offsetY;//屏幕坐标px、py转标准设备坐标x、y//width、height表示canvas画布宽高度const x = (px / width) * 2 - 1;const y = -(py / height) * 2 + 1;})</pre></div></div></div></el-main></el-container></div>
</template>
<script>
// 引入轨道控制器扩展库OrbitControls.js
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
// 效果制作器
import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer.js";
// 渲染通道
import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass.js";
// 发光描边OutlinePass
import { OutlinePass } from "three/examples/jsm/postprocessing/OutlinePass.js";export default {data() {return {name: "",scene: null,camera: null,renderer: null,effectComposer: null,mesh: null,geometry: null,group: null,material: null,texture: null,position: null,outlinePass: null,canvasWidth: 1000,canvasHeight: 800,color: [],meshArr: [],};},created() {},mounted() {this.name = this.$route.query.name;const numbers = Array.from({ length: 255 }, (_, i) => i);// const uppercaseLetters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');this.color = [...numbers];this.init();},methods: {goBack() {this.$router.go(-1);},addEventListenerFn() {// canvas画布添加监听事件document.getElementById("threejs").addEventListener("click", (event) => {// 1,坐标转换const point_x = event.offsetX; // 获取x方向当前点击点距离原点的距离;向右为正(原点是当前元素的左上角点)const point_y = event.offsetY; // 获取y方向当前点击点距离原点的距离;向下为正(原点是当前元素的左上角点)const x = (point_x / this.canvasWidth) * 2 - 1;const y = -(point_y / this.canvasHeight) * 2 + 1;// 2,创建射线投射器对象,const raycaster = new this.$three.Raycaster();// 3,射线计算,(参数是鼠标点击位置,相机参数)raycaster.setFromCamera(new this.$three.Vector2(x, y), this.camera);// 4,射线交叉计算// const mesh_arr = []// if(!this.scene)return;// this.scene.traverse(m => {//   console.log('m',m);//   if(m.isMesh != undefined && m.isMesh) {//     mesh_arr.push(m);//   }// })const intersects = raycaster.intersectObjects(this.meshArr);if (intersects.length > 0) {if (this.effectComposer) {// intersects[0].object.material.color.set(0xff0000);this.outlinePass.selectedObjects = [intersects[0].object];this.renderFun();}}});},// 随机颜色randomColor() {// 要生成min-max之间的随机数,公式为:Math.random()*(max-min+1)+minlet i = Math.floor(Math.random() * (this.color.length - 0 + 1) + 0);let j = Math.floor(Math.random() * (this.color.length - 0 + 1) + 0);let k = Math.floor(Math.random() * (this.color.length - 0 + 1) + 0);this.position = new this.$three.Vector3(i, j, k);return new this.$three.Color("rgb(" +this.color[i] +", " +this.color[j] +", " +this.color[k] +")");},init() {// 创建场景对象this.scene = new this.$three.Scene();// 创建立方缓存几何体对象for (let i = 0; i < 3; i++) {this.boxGeometry();}// 创建辅助坐标轴对象const axesHelper = new this.$three.AxesHelper(200);this.scene.add(axesHelper);// 创建正交投影相机对象// this.camera = new this.$three.PerspectiveCamera(60,1,0.01,1000);// this.camera.position.set(600,600,600);// this.camera.lookAt(0,0,0);// 创建透视投影相机对象this.camera = new this.$three.OrthographicCamera(-500,500,400,-400,0,1000);this.camera.position.set(200, 200, 200);this.camera.lookAt(0, 0, 0);// const helper = new this.$three.CameraHelper( this.camera );// this.scene.add( helper );// 创建渲染器对象this.renderer = new this.$three.WebGLRenderer();this.renderer.setSize(this.canvasWidth, this.canvasHeight);this.renderer.render(this.scene, this.camera);window.document.getElementById("threejs").appendChild(this.renderer.domElement);// 创建相机空间轨道控制器const controls = new OrbitControls(this.camera, this.renderer.domElement);controls.addEventListener("change", () => {// this.renderer.render(this.scene, this.camera);this.effectComposer.render();});// 调用后处理方法this.effectComposerFn();// 调用 监听  点击事件的方法this.addEventListenerFn();},// 创建盒模型的方法boxGeometry() {// 创建网格基础材质对象const material = new this.$three.MeshBasicMaterial({color: this.randomColor(),});// 创建立方几何体对象const geometry = new this.$three.BoxGeometry(this.position.x,this.position.y,this.position.z);// 创建网格模型对象const mesh = new this.$three.Mesh(geometry, material);if (this.position) {// 网格模型设置位置mesh.position.set(this.position.x, this.position.y, this.position.z);}this.meshArr.push(mesh);this.scene.add(mesh);},// 后处理方法effectComposerFn() {// 创建后处理对象this.effectComposer = new EffectComposer(this.renderer);// 创建后处理渲染器通道对象const renderPass = new RenderPass(this.scene, this.camera);// 后处理对象 添加渲染器通道this.effectComposer.addPass(renderPass);// 创建发光描边对象this.outlinePass = new OutlinePass(new this.$three.Vector2(this.canvasWidth, this.canvasHeight),this.scene,this.camera);// 设置发光描边颜色this.outlinePass.visibleEdgeColor.set(0xE0F409);// 设置发光描边厚度this.outlinePass.edgeThickness = 5;// 描边亮度this.outlinePass.edgeStrength = 20;// 设置发光描边频率this.outlinePass.pulsePeriod = 2;this.effectComposer.addPass(this.outlinePass);},renderFun() {// 调用后处理对象的render方法进行渲染,this.effectComposer.render();window.requestAnimationFrame(this.renderFun);},},
};
</script>
//
<style lang="less" scoped>
.box-card-left {display: flex;align-items: flex-start;flex-direction: row;width: 100%;.box-right {}
}
</style>

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

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

相关文章

URLConnection()和openStream()两个方法产生SSRF的原理和修复方法

今年是自主研发的第三个年份&#xff0c;也是重视安全的年份。 转一篇小文章&#xff1a; 0x00 前言 SSRF 形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。比如从指定 URL 地址获取网页文本内容&#xff0c;加载指定地址的图…

VR云游开启智慧旅游新纪元,打造“云旅游”新模式

元旦假期&#xff0c;全国文化和旅游市场平稳有序&#xff0c;家人和亲友的出游趋势稳步增加&#xff0c;演唱会、音乐节、跨年等活动的叠加让元旦出游更加吸引游客。在冰雪旅游热度持续攀升的时候&#xff0c;许多年轻群体已经开始使用VR云游进行智慧景区旅游&#xff0c;身临…

项目代码生成心得

1、如果一直ctrl B 生成不了代码&#xff0c;可能是卡住了&#xff0c;要run一下才行 2、sub chart里面千万不要加上内部自转移和en,du:不然里面的内容压根不会生成代码&#xff0c;Matlab认为它可以自己在里面自己转。 3、生成的代码跟设计图是不一样的&#xff01;&#xff…

Databend 的算力可扩展性

作者&#xff1a;尚卓燃&#xff08;PsiACE&#xff09; 澳门科技大学在读硕士&#xff0c;Databend 研发工程师实习生 Apache OpenDAL(Incubating) Committer PsiACE (Chojan Shang) GitHub 对于大规模分布式数据处理系统&#xff0c;为了更好应对数据、流量、和复杂性的增长…

CRYPTO现代密码学学习

CRYPTO现代密码学学习 RC4 加密算法RSA加密解密DES加密解密详解密钥的生成密文的生成 RC4 加密算法 简单介绍&#xff1a;RC4加密算法是一种对称加密算法&#xff0c;加密和解密使用同一个函数 初始化分为以下几个步骤 初始化存储0-255字节的Sbox(其实就是一个数组)填充key到…

爬虫工具(tkinter+scrapy+pyinstaller)

需求介绍输入&#xff1a;关键字文件&#xff0c;每一行数据为一爬取单元。若一行存在多个and关系的关键字 &#xff0c;则用|隔开处理&#xff1a;爬取访问6个网站的推送&#xff0c;获取推送内容的标题&#xff0c;发布时间&#xff0c;来源&#xff0c;正文第一段&#xff0…

excel中找出重复项,并标红

一、查找重复值 二、清除格式 还是通过添加规则的路径&#xff0c;清除格式&#xff0c;直接通过格式刷&#xff0c;刷不掉。

Windows重装升级Win11系统后 恢复Mysql数据

背景 因为之前电脑硬盘出现问题&#xff0c;换了盘重装了系统&#xff0c;项目的数据库全部没了&#xff0c;还好之前的Mysql是安装在的D盘里&#xff0c;还有留存文件 解决办法 1.设置环境变量 我的路径是 D:\SoftWare\Application\mysql-5.7.35-winx64 此电脑右键属性 …

基于SSM实现的社区论坛系统(附PPT、设计文档)

基于SSM实现的社区论坛系统&#xff08;附PPT、设计文档&#xff09; 文章目录 基于SSM实现的社区论坛系统&#xff08;附PPT、设计文档&#xff09;系统介绍技术选型成果展示设计文档用户端管理员端 源码获取账号地址及其他说明 系统介绍 基于SSM实现的社区论坛系统是一款前后…

pycharm远程开发调试(remote development)踩坑记录2

在一次我清理了服务器上一些老的pycharm版本之后 打算重新装3.2版本&#xff0c;就全部给清理了。结果坏了事了&#xff0c;新版的装不上了。 试了公司和中科院的服务器都出现这样的问题&#xff0c;100%复现。md。 一直在这一步循环&#xff1a; Downloading the IDE Backen…

echarts实现控制图(设置阈值上下限超出变色)

echarts实现控制图组件&#xff0c;拓展超出阈值变色显示&#xff0c;图中标记平均值及最大值和最小值 代码如下&#xff1a; <template><div :class"className" :style"{height:height,width:width}" /> </template><script>im…

基于Kettle开发的web版数据集成开源工具(data-integration)-介绍篇

目录 &#x1f4da;第一章 官网介绍&#x1f4d7;目标实现&#xff1a;让kettle使用更简单&#x1f4d7;架构及组成 &#x1f4da;第二章 核心功能&#x1f4da;第三章 对比Kettle&#x1f4d7;工具栏位比对&#x1f4d7;工具栏组件内容比对&#x1f4d7;扩展&#xff1a;WebSp…

多线程基础入门【Linux之旅】——下篇【死锁,条件变量,生产消费者模型,信号量】

目录 一&#xff0c;死锁 1. 死锁的必要条件 2&#xff0c;避免死锁 二&#xff0c;条件变量 同步概念与竞态条件 条件变量——初始化 静态初始化 动态初始化 pthread_cond_destroy (销毁) pthread_cond_wait (等待条件满足) pthread_cond_signal (唤醒线程) ph…

在Go语言中处理HTTPS请求

随着互联网的发展&#xff0c;安全性变得越来越重要。HTTPS作为安全的HTTP协议&#xff0c;已经被广泛使用。在Go语言中&#xff0c;处理HTTPS请求需要一些特定的步骤。本文将详细介绍如何在Go语言中处理HTTPS请求。 首先&#xff0c;确保你已经安装了Go语言的开发环境&#x…

10+免费图片素材/壁纸网站,搭一些图片处理工具,快收藏!

划到最后“阅读原文”——领取工具包&#xff08;超过1000工具&#xff0c;免费素材网站分享和行业报告&#xff09; Hi&#xff0c;我是胡猛夫~&#xff0c;专注于分享各类价值网站、高效工具&#xff01; 更多资源&#xff0c;更多内容&#xff0c;欢迎交流&#xff01;公 号…

threejs在透视相机模式下,绘制像素大小固定的元素

要求&#xff1a;在透视相机模式下绘制一个图标&#xff0c;图标大小始终为32*32px。图标如下&#xff1a; 实现思路&#xff1a; 使用THREE.Sprite。因为 SpriteMaterial 支持配置 sizeAttenuation 使Sprite大小不随相机的深度而衰减。所以我们只要保证sprite的初始的大小合适…

SpringCloud之Eureka组件工作原理详解

Eureka是一种服务注册与发现组件&#xff0c;最初由Netflix开发并开源出来。它主要用于构建分布式系统中的微服务架构&#xff0c;并提供了服务注册、服务发现、负载均衡等功能。在本文中&#xff0c;我们将详细解释Eureka的工作原理。 一、Eureka概述 Eureka是Netflix开源的一…

SAFe大规模敏捷企业级实训

课程简介 SAFe – Scaled Agile Framework是目前全球运用最广泛的大规模敏捷框架&#xff0c;也是成长最快、最被认可、最有价值的规模化敏捷框架&#xff0c;目前全球SAFe认证专业人士已达80万人&#xff0c;福布斯100强的70%都在实施SAFe。本课程是一个2天的 SAFe权威培训课…

老生常谈:Web 与低代码开发

Web技术和低代码平台是当前技术领域中的两个热门话题。它们在应用开发领域中扮演着重要的角色&#xff0c;不断被提及和讨论。本文将讨论为什么“Web与低代码”这个话题成为了“老生常谈”&#xff0c;探讨其背后的原因以及这两个概念的关系。 在当今技术飞速发展的时代&#x…

【UWB定位源码】工厂企业人员定位系统源码,实现安全区域管控、人员在岗监控、车辆实时轨迹监控

UWB高精度定位系统源码&#xff0c;企业工厂人员定位系统源码 概念&#xff1a; UWB (ULTRA WIDE BAND, UWB) 技术是一种无线载波通讯技术&#xff0c;它不采用正弦载波&#xff0c;而是利用纳秒级的非正弦波窄脉冲传输数据&#xff0c;因此其所占的频谱范围很宽。 UWB的主要特…