【Threejs】获取相交网格相交线

本文介绍了如何在Three.js中使用three-mesh-bvh库实现两个Mesh对象之间的碰撞检测,通过计算boundsTree并利用加速的raycast方法,实时更新动态场景中物体间的路径。
摘要由CSDN通过智能技术生成

BVH-INTER

在这里插入图片描述

1 导入threejs-mesh-bvh库

import * as THREE from "three";
import { SAH, acceleratedRaycast, computeBoundsTree, disposeBoundsTree } from "three-mesh-bvh";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";

THREE.Mesh.prototype.raycast = acceleratedRaycast;
THREE.BufferGeometry.prototype.computeBoundsTree = computeBoundsTree;
THREE.BufferGeometry.prototype.disposeBoundsTree = disposeBoundsTree;

2获取对比物

假设我们需要将mesh1和mesh2做对比
	getMeshBuffer(mesh1)
	getMeshBuffer(mesh2)
	function getMeshBuffer(mesh) {
    mesh.geometry.computeBoundsTree({ maxLeafTris: 1, strategy: SAH });
    return  mesh 
    }
	

3对比mesh获取路径

	   let r = []

            const matrix2to1 = new Matrix4()
                .copy(mesh1.matrixWorld)
                .invert()
                .multiply(mesh2.matrixWorld);


            const edge = new Line3();
            // console.log({ buff1, buff2 });
            mesh1.geometry.boundsTree.bvhcast(mesh2.geometry.boundsTree, matrix2to1, {

                intersectsTriangles(triangle1, triangle2) {

                    if (triangle1.intersectsTriangle(triangle2, edge)) {

                        const { start, end } = edge;
                        r.push(
                            start.x,
                            start.y,
                            start.z,
                            end.x,
                            end.y,
                            end.z,
                        );

                    }

                }

            });

4渲染结果


	 if (r.length > 0) {
                let results = r
                const lineGeometry = new BufferGeometry();
                lineGeometry.setFromPoints([new Vector3(0, 1, 0), new Vector3(0, - 1, 0)]);
                const line = new LineSegments(lineGeometry, new LineBasicMaterial({ color: 0xE91E63 }));

                const bgLine = line.clone();
                bgLine.material = new LineBasicMaterial({
                    color: 0xE91E63,
                    transparent: true,
                    // opacity: 0.25,
                    depthFunc: GreaterDepth,
                });
                bgLine.renderOrder = 3;
                const geometry = line.geometry;
                const posArray = geometry.attributes.position.array;
                if (posArray.length < results.length) {

                    geometry.dispose();
                    geometry.setAttribute('position', new BufferAttribute(new Float32Array(results), 3, false));

                } else {

                    posArray.set(results);

                }


                geometry.setDrawRange(0, results.length / 3);
                geometry.attributes.position.needsUpdate = true;
将bgLine放入场景即可
	scene.add(bgLine,line)

关于动态场景

  const loop = () => {
    requestAnimationFrame(loop)
   
    const matrix2to1 = new THREE.Matrix4()
      .copy(mesh1.matrixWorld)
      .invert()
      .multiply(mesh2.matrixWorld);


    const edge = new THREE.Line3();
    let results = [];
    mesh1.geometry.boundsTree.bvhcast(mesh2.geometry.boundsTree, matrix2to1, {

      intersectsTriangles(triangle1, triangle2) {

        if (triangle1.intersectsTriangle(triangle2, edge)) {

          const { start, end } = edge;
          results.push(
            start.x,
            start.y,
            start.z,
            end.x,
            end.y,
            end.z,
          );

        }

      }

    });


    if (results.length) {
....更新视图
    }	



  }

	loop()
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鸢_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值