主页 > 手机  > 

Threejs之射线拾取模型

Threejs之射线拾取模型
参考资料 射线Ray…射线拾取Sprite控制场景 知识点

注:基于Three.jsv0.155.0

射线RayRaycaster(射线拾取模型)屏幕坐标转标准设备坐标Raycaster(鼠标点击选中模型)Canvas尺寸变化(射线坐标计算)射线拾取层级模型(模型描边)射线拾取Sprite控制场景 代码实现 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Three.js</title> </head> <body> </body> <!-- 具体路径配置,你根据自己文件目录设置,我的是课件中源码形式 --> <script type="importmap"> { "imports": { "three": "./js/three.module.js", "three/addons/": "../three.js/examples/jsm/" } } </script> <script type="module"> import * as THREE from 'three'; import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; const width = 800 const height = 500 // 场景 const scene = new THREE.Scene(); // 几何体 const geometry = new THREE.BoxGeometry(50, 50, 50); // 材质 const material = new THREE.MeshBasicMaterial({ color: 0x00ff00, transparent: true, opacity: 0.5 }); // 网格模型:物体 const mesh = new THREE.Mesh(geometry, material); mesh.position.set(0, 0, 0); scene.add(mesh); const mesh1 = mesh.clone() mesh1.position.set(100, 0, 0); mesh1.material = mesh.material.clone(); scene.add(mesh1); const mesh2 = mesh.clone() mesh2.position.set(0, 100, 0); mesh2.material = mesh.material.clone(); scene.add(mesh2); // 坐标系 const axes = new THREE.AxesHelper(200); scene.add(axes); // 相机 const camera = new THREE.PerspectiveCamera(75, width/height, 0.1, 1000); camera.position.set(200, 200, 200); camera.lookAt(scene.position); // 渲染器 const renderer = new THREE.WebGLRenderer(); renderer.setSize(width, height); renderer.render(scene, camera); // 设置设备像素比,避免canvas画布输出模糊 renderer.setPixelRatio(window.devicePixelRatio); document.body.appendChild(renderer.domElement); // 射线Ray Start // 创建射线对象Ray const ray = new THREE.Ray() // 设置射线起点 ray.origin = new THREE.Vector3(1,0,3); // 表示射线沿着x轴正方向 ray.direction = new THREE.Vector3(1,0,0); // 三角形三个点坐标 const p1 = new THREE.Vector3(100, 25, 0); const p2 = new THREE.Vector3(100, -25, 25); const p3 = new THREE.Vector3(100, -25, -25); const point = new THREE.Vector3();//用来记录射线和三角形的交叉点 // `.intersectTriangle()`计算射线和三角形是否相交叉,相交返回交点,不相交返回null const result = ray.intersectTriangle(p1,p2,p3,true,point); console.log('交叉点坐标', point); console.log('查看是否相交', result); // 射线Ray End // 3. 屏幕坐标转标准设备坐标 Start addEventListener('click',function(event){ // event对象有很多鼠标事件相关信息 console.log('event',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; console.log('🚀 ~ file: 14.射线拾取模型.html:96 ~ addEventListener ~ y:', y) //创建一个射线投射器`Raycaster` const raycaster = new THREE.Raycaster(); //.setFromCamera()计算射线投射器`Raycaster`的射线属性.ray // 形象点说就是在点击位置创建一条射线,射线穿过的模型代表选中 raycaster.setFromCamera(new THREE.Vector2(x, y), camera); //.intersectObjects([mesh1, mesh2, mesh3])对参数中的网格模型对象进行射线交叉计算 // 未选中对象返回空数组[],选中一个对象,数组1个元素,选中两个对象,数组两个元素 const intersects = raycaster.intersectObjects([mesh1, mesh2, mesh]); console.log("射线器返回的对象", intersects); // intersects.length大于0说明,说明选中了模型 if (intersects.length > 0) { // 选中模型的第一个模型,设置为红色 intersects[0].object.material.color.set(0x0000ff); } }) // 3. 屏幕坐标转标准设备坐标 Ene // Raycaster(射线拾取模型) Start 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); // 射线发射拾取模型对象 const intersects = raycaster.intersectObjects([mesh1, mesh2, mesh]); 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); intersects[0].object.material.color.set(0xff0000); } // Raycaster(射线拾取模型) End // 动画渲染 // 跟踪时间 var clock = new THREE.Clock(); function render() { const spt = clock.getDelta() * 1000; // mesh.rotation.y += 0.01; renderer.render(scene, camera); requestAnimationFrame(render); } render(); // 控制器 const controls = new OrbitControls(camera, renderer.domElement); controls.addEventListener('change', () => { // 因为动画渲染了,所以这里可以省略 // renderer.render(scene, camera); }); </script> </html>
标签:

Threejs之射线拾取模型由讯客互联手机栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“Threejs之射线拾取模型