返回顶部
首页 > 资讯 > 前端开发 > JavaScript >Webgl&Three.js中物体拾取的示例分析
  • 556
分享到

Webgl&Three.js中物体拾取的示例分析

2024-04-02 19:04:59 556人浏览 八月长安
摘要

小编给大家分享一下webGL&Three.js中物体拾取的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1、引子

小编给大家分享一下webGL&Three.js中物体拾取的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

1、引子:

在传统的web开发中,由于存在DOM树以及事件捕获冒泡等机制,我们可以很方便的在某个DOM节点上注册事件,并且执行父元素事件代理等一系列操作。但是在WEBgl的三维世界里,用户使用鼠标或者touch事件,事件接收方是canvas容器,如何将这种点击行为映射到三维世界,就需要借助三维世界的能力了,并且建立从canvas平面容器到三维世界的桥梁,进行所谓的物体拾取

2、基础知识:

DOM与NDC坐标转换,相机射线,观察者模式。熟悉这部分知识的同学,可以直接跳过到下面的代码实现。

  • a、DOM坐标和NDC坐标转换:在这里,我们知道DOM坐标的(0,0)点在容器左上角,NDC坐标的(0,0)点在容器中心,需要进行坐标转换。具体定义可以参考下面两个链接

三维坐标变换 屏幕坐标定义

  • b、相机射线:  根据Three.js的官方定义,射线就是用来做物体拾取的机制。相比较于传统的颜色拾取,射线拾取可以识别多个物体,得到先后顺序,在使用上更加方便并且符合人的直觉。?  下面看一个官方的code example?

javascript

const raycaster = new THREE.Raycaster(); const mouse = new THREE.Vector2(); function onMouseMove( event ) {     // 这里实现了DOM坐标系到NDC坐标系的转换     mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;     mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1; } function render() {     // 从相机位置,发出一条射线     raycaster.setFromCamera( mouse, camera );     // 检测相机发出射线相交的obj列表     const intersects = raycaster.intersectObjects( scene.children );     for ( let i = 0; i < intersects.length; i ++ ) {         // 将相交物体的材质颜色设置为红色         intersects[ i ].object.material.color.set( 0xff0000 );     }     renderer.render( scene, camera ); } window.addEventListener( 'mousemove', onMouseMove, false ); window.requestAnimationFrame(render);

c、观察者模式:与dom事件机制类似,观察者模式非常是适合做这种注册-触发机制的。

3、具体实现:

考虑到每次遍历intersects数组非常的不方便,特别是当场景中有实际上百个Object3D的时候。所以这里我们定义一个全局的对象存储注册事件,然后修改Object3D的原型链,增加on和on和on和off方法,来实现类似于DOM元素的事件注册和销毁。

const globalEvent = {click: {}} Object.assign(Object3D.prototype, {     $on(eventType, cb) {        if(globalEvent.hasOwnProperty(eventType)) {             globalEvent[eventType][this.id] = {                 object3d: this,                 callback: cb             };        } else { // error warn}     }     $off(eventType) {         if (!eventType) throw new Error('')         if(globalEvent.hasOwnProperty(eventType)) {             delete globalEvent[eventType][this.id]         } else {             throw new Error('')         }     } }) init(camera) function init(camera, container) {     let intersectPoint, obj, mouseX, mouseY, clicked;     const targetObj = globalEvent.click     const rayCaster = new Raycaster();     function down(e) {         obj = null;         e.preventDefault();         mouseX = event.clientX;         mouseY = event.clientY;         if (!globalEvent.click) return;         rayCaster.setFromCamera(             new Vector2(                 (mouseX / window.innerWidth) * 2 - 1,                 -(mouseY / window.innerHeight) * 2 + 1             ),             camera         );          let intersects = rayCaster.intersectsObjects(getVisibleList(targetObj));         if (intersects.length > 0) {             if (clicked) {                 obj = null;                 return;             }             clicked = true;             obj = intersects[0].object;             intersectPoint = intersects[0].point;                                 } else {             clicked = false;         }     }     function move(e) {         event.preventDefault();         // 这里针对移动端做一些优化      }     function up(e) {         event.preventDefault();         if (clicked && !!obj && obj.callback) {             obj.callback(obj.object3d, intersectPoint);         }         clicked = false     }    const eventOption = {      passive: false    };    container.addEventListener('mousedown', down, {passive: false});    container.addEventListener('mousemove', move, {passive: false});    container.addEventListener('mouseup', up, {passive: false});    container.addEventListener('touchstart', down, {passive: false});    container.addEventListener('touchmove', move, {passive: false});    container.addEventListener('touchend', up, {passive: false});}  function getVisibleList(targetObj) {     const list = []     for (const key in targetObj) {         const target = targetObj[key].object3d;         if (target.visible) list.push(target);     }     return list }   mesh.$on('click', (target, point)) {  }

以上是“Webgl&Three.js中物体拾取的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网JavaScript频道!

--结束END--

本文标题: Webgl&Three.js中物体拾取的示例分析

本文链接: https://lsjlt.com/news/81881.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Webgl&Three.js中物体拾取的示例分析
    小编给大家分享一下Webgl&Three.js中物体拾取的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1、引子...
    99+
    2024-04-02
  • WebGL中three.js的示例分析
    小编给大家分享一下WebGL中three.js的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧! 1、WebGL 可以...
    99+
    2024-04-02
  • WebGL中three.js怎么实现物体的阴影动画效果
    小编给大家分享一下WebGL中three.js怎么实现物体的阴影动画效果,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!实现物体的...
    99+
    2024-04-02
  • Three.js基础的示例分析
    这篇文章给大家分享的是有关Three.js基础的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、Three.js官网及使用Three.js必备的三个条件1.Three....
    99+
    2024-04-02
  • Javascript中 “&” 和 “|” 的示例分析
    这篇文章主要为大家展示了“Javascript中 “&” 和 “|” 的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Javascript中 “...
    99+
    2024-04-02
  • Three.js加载外部模型的示例分析
    这篇文章主要介绍了Three.js加载外部模型的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1.  首先我们要在官网: ...
    99+
    2024-04-02
  • javascript中逻辑运算符&&和||返回值的示例分析
    这篇文章主要介绍了javascript中逻辑运算符&&和||返回值的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。v...
    99+
    2024-04-02
  • Mysql-InnoDB事物的示例分析
    这篇文章给大家分享的是有关Mysql-InnoDB事物的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。事物基本概念事物的特性(ACID)原子性 atomicity一致性 ...
    99+
    2024-04-02
  • nw.js中localStorage物理储存的示例分析
    这篇文章将为大家详细讲解有关nw.js中localStorage物理储存的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。储存位置nw.js打包出来的应用的loca...
    99+
    2024-04-02
  • &&、()、||决定linux命令执行顺序的示例分析
    小编给大家分享一下&&、()、||决定linux命令执行顺序的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!在执行某个命令时,有时需要依赖...
    99+
    2023-06-09
  • HTML主体的示例分析
    小编给大家分享一下HTML主体的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!HTML主体<body> 标签...
    99+
    2024-04-02
  • PostgreSQL物化视图的示例分析
    这篇文章主要介绍PostgreSQL物化视图的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1、创建视图CREATE MATERIALIZED VIEW&...
    99+
    2024-04-02
  • WCF事物操作的示例分析
    这篇文章将为大家详细讲解有关WCF事物操作的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。指定了TransactionFlow(TransactionFlowOption.Mandatory),而...
    99+
    2023-06-17
  • mysql中日志体系的示例分析
    这篇文章主要介绍了mysql中日志体系的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。 一、 mysql...
    99+
    2024-04-02
  • CSS3中媒体特性的示例分析
    这篇文章主要介绍了CSS3中媒体特性的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。CSS3 媒体特性与Responsive设计随着...
    99+
    2024-04-02
  • CSS3中媒体查询的示例分析
    这篇文章将为大家详细讲解有关CSS3中媒体查询的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。   媒体查询   CSS3中的媒体查询,它可以根据用户设备的尺...
    99+
    2024-04-02
  • JVM中体系结构的示例分析
    小编给大家分享一下JVM中体系结构的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!什么是JVM?JVM(Java Virtual Machine)是一个抽...
    99+
    2023-06-20
  • JAVA中集合体系的示例分析
    这篇文章给大家分享的是有关JAVA中集合体系的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、集合概况Java是一种面向对象语言,如果我们要针对多个对象进行操作,那么首先必要将多个对象进行保存起来之后,...
    99+
    2023-05-30
    java
  • Three.js中网格对象MESH属性与方法的示例分析
    这篇文章给大家分享的是有关Three.js中网格对象MESH属性与方法的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。创建一个网格需要一个几何体,以及一个或多个材质。当网...
    99+
    2024-04-02
  • CSS3中多媒体查询的示例分析
    小编给大家分享一下CSS3中多媒体查询的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!   CSS2多媒体查询:  ...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作