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