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

124. Raycaster(射线拾取模型)

上节课给大家介绍过射线Ray,下面给大家介绍另一个和射线相关的API射线投射器Raycaster

准备三个mesh用于射线拾取

const geometry = new THREE.SphereGeometry(25, 50, 50);
const material = new THREE.MeshLambertMaterial({
    color: 0x009999,
});
const mesh1 = new THREE.Mesh(geometry, material);
const mesh2 = mesh1.clone();
mesh2.position.y = 100;
const mesh3 = mesh1.clone();
mesh3.position.x = 100;
const model = new THREE.Group();
// 三个网格模型mesh1,mesh2,mesh3用于射线拾取测试
model.add(mesh1, mesh2, mesh3);
model.updateMatrixWorld(true);

射线投射器Raycaster

射线投射器Raycaster具有一个射线属性.ray,该属性的值就是上节课讲解的射线对象Ray

const raycaster = new THREE.Raycaster();
console.log('射线属性',raycaster.ray);
// 设置射线起点
raycaster.ray.origin = new THREE.Vector3(-100, 0, 0);
// 设置射线方向射线方向沿着x轴
raycaster.ray.direction = new THREE.Vector3(1, 0, 0);

射线交叉计算(.intersectObjects()方法)

射线投射器Raycaster通过.intersectObjects()方法可以计算出来与自身射线.ray相交的网格模型。

.intersectObjects([mesh1, mesh2, mesh3])对参数中的网格模型对象进行射线交叉计算,未选中对象返回空数组[],选中一个对象,数组1个元素,选中多个对象,数组多个元素,如果选中多个对象,对象在数组中按照先后排序。

const raycaster = new THREE.Raycaster();
raycaster.ray.origin = new THREE.Vector3(-100, 0, 0);
raycaster.ray.direction = new THREE.Vector3(1, 0, 0);
// 射线发射拾取模型对象
const intersects = raycaster.intersectObjects([mesh1, mesh2, mesh3]);
console.log("射线器返回的对象", intersects);

.intersectObjects()射线拾取返回信息

射线拾取返回的intersects里面的元素包含多种信息,你可以通过threejs文档查看,或者在浏览器控制台打印查看。

.intersectObjects().intersectObject()功能相同,只是具体语法不同,.intersectObjects()返回数组元素包含的信息,可以参考文档关于.intersectObject()的介绍。

console.log("射线器返回的对象", intersects);
// intersects.length大于0说明,说明选中了模型
if (intersects.length > 0) {
    console.log("交叉点坐标", intersects[0].point);
    console.log("交叉对象",intersects[0].object);
    console.log("射线原点和交叉点距离",intersects[0].distance);
}

射线选中的模型对象改变材质颜色

const intersects = raycaster.intersectObjects([mesh1, mesh2, mesh3]);
if (intersects.length > 0) {
    // 选中模型的第一个模型,设置为红色
    intersects[0].object.material.color.set(0xff0000);
}

提醒

注意射线拾取的时候,mesh1, mesh2, mesh3位置要确保更新的情况下,执行射线计算,threejs一般是渲染器执行一次.render()之后,你设置的mesh.position或者mesh父对象的position才会真实生效。

...
// 注意更新下模型的世界矩阵,你设置的mesh.position生效,再进行射线拾取计算
model.updateMatrixWorld(true);
...
const intersects = raycaster.intersectObjects([mesh1, mesh2, mesh3]);
mesh2.position.y = 100;
mesh3.position.x = 100;
const model = new THREE.Group();
// 三个网格模型mesh1,mesh2,mesh3用于射线拾取测试
model.add(mesh1, mesh2, mesh3);

//注意更新下模型的世界矩阵,你设置的position生效,再进行射线拾取计算
model.updateMatrixWorld(true);

const raycaster = new THREE.Raycaster();
raycaster.ray.origin = new THREE.Vector3(-100, 0, 0);
raycaster.ray.direction = new THREE.Vector3(1, 0, 0);
const intersects = raycaster.intersectObjects([mesh1, mesh2, mesh3]);

http://www.kler.cn/a/386697.html

相关文章:

  • FBX福币交易所恒指收跌1.96% 半导体股继续回调
  • uni-app之数据驱动的picker选择器( uni-data-picker)之可以选择到任意级别
  • 排序算法 -快速排序
  • 【JAVA基础】JVM是什么?
  • 用友U8-Cloud uapbd.refdef.query sql注入漏洞复现
  • 论文翻译 | The Capacity for Moral Self-Correction in Large Language Models
  • Guarding the Chessboard(UVA 11214)
  • uniapp—android原生插件开发(3Android真机调试)
  • 网络--传输层协议--TCP
  • 【LeetCode每日一题】——802.找到最终的安全状态
  • C++学习笔记----10、模块、头文件及各种主题(三)---- 连接
  • VMWARE ESXI VMFS阵列故障 服务器数据恢复
  • aosp15系统窗口闪屏原生bug-dim图层相关-你会修改吗?
  • Qt教程(007):资源文件添加
  • nodejs:下载,安装,系统环境配置,更换镜像
  • Leetcode - 周赛422
  • Kafka集群的安装与部署
  • 《Android 车载 Launcher 开发 - 显示 Widget》
  • docker pull/build 失败 设置国内镜像源
  • 《C++ 网络编程:高效实现 TCP/IP 与 UDP 通信》
  • 数据分析-39-时间序列分解之经验小波分解EWT
  • 发顶会首选:大模型+时间序列!掌握这3大切入点,小白也能轻松上手!
  • 排序算法基础
  • C/C++ 中的预处理器指令有哪些?举例说明其用途
  • ssm基于JAVA的网上订餐管理系统+vue
  • Git进阶(十八):git rebase详解