In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
Editor to share with you the example analysis of object picking in Webgl&Three.js, I believe that most people do not know much about it, so share this article for your reference, I hope you can learn a lot after reading this article, let's go to know it!
1. Introduction:
In traditional web development, due to the existence of DOM tree and event capture bubbling mechanism, we can easily register events on a DOM node and perform a series of operations such as parent element event agents. But in the three-dimensional world of webgl, the user uses the mouse or touch event, and the event receiver is the canvas container. How to map this click behavior to the three-dimensional world requires the ability of the three-dimensional world, and build a bridge from the canvas plane container to the three-dimensional world for so-called object picking.
2. Basic knowledge:
DOM and NDC coordinate conversion, camera ray, observer mode. Students who are familiar with this part of the knowledge can skip directly to the following code implementation.
A, DOM coordinate and NDC coordinate conversion: here, we know that the point of DOM coordinate is in the upper left corner of the container, and the point of NDC coordinate is in the center of the container, so coordinate conversion is needed. For specific definition, please refer to the following two links
3D coordinate transformation screen coordinate definition
B, camera rays: according to the official definition of Three.js, rays are the mechanism used to pick up objects. Compared with the traditional color pickup, ray pickup can identify multiple objects and get the sequence, which is more convenient to use and in line with human intuition. ? Let's take a look at an official code example?
Javascript
Const raycaster = new THREE.Raycaster (); const mouse = new THREE.Vector2 (); function onMouseMove (event) {/ / this implements the conversion from DOM coordinate system to NDC coordinate system mouse.x = (event.clientX / window.innerWidth) * 2-1; mouse.y =-(event.clientY / window.innerHeight) * 2 + 1;} function render () {/ / emits a ray raycaster.setFromCamera (mouse, camera) from the camera position / / detect the obj list of intersecting rays emitted by the camera 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 (); / / make some optimizations here for mobile} 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} / * usage: register the event target directly on mesh: hit the object point: the 3D coordinates of the hit point * / mesh.$on ('click', (target, point)) {} above are all the contents of the article "sample Analysis of object picking in Webgl&Three.js". Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.