个人技术分享

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()