Hi everyone, i try to change index of BufferGeometry , after change i caal index.needsUpdate=true, then now i can not raycaster it.Here is my code :
import * as THREE from “three”;
import {IMergeMesh, IMergeMeshBufferGeometry} from “./types”;
import {BVH} from “./BVH”;
import {ModelGroup} from “./ModelGroup”;
export class MergeMesh extends THREE.Mesh implements IMergeMesh {
material: THREE.Material;
geometry: IMergeMeshBufferGeometry;
meshes: Map<string, MergeMesh> = new Map();
modelGroup?: ModelGroup;
/**
*
/
constructor(
public ElementIdIndexMap: Map<number, Map<number, number>>,
geometry: IMergeMeshBufferGeometry,
material: THREE.Material
) {
super();
this.geometry = geometry;
this.material = material;
}
/*
*
*/
dispose() {
this.removeFromParent();
this.material.dispose();
(this.material as any) = null;
BVH.dispose(this.geometry);
this.geometry?.dispose();
(this.geometry as any) = null;
this.ElementIdIndexMap.clear();
for (const [_name, mergeMesh] of this.meshes) {
mergeMesh.dispose();
}
this.meshes.clear();
(this.modelGroup as any) = null;
}
/**
*
*/
setVisibility(visible: boolean, itemIDs: Set, isolate = false) {
if (!this.geometry) throw new Error();
//@ts-ignore
const index = this.geometry.index;
if (isolate) index.array.fill(0);
for (const elementId of itemIDs) {
const elementIdMap = this.ElementIdIndexMap.get(elementId);
if (elementIdMap === undefined) continue;
for (const [i, originalIndex] of elementIdMap) {
index.array[i] = visible ? originalIndex : 0;
}
}
index.needsUpdate = true;
}
/**
*
- @param name
- @param material
- @returns
*/
addMesh(name: string, material = this.material) {
if (!this.meshes.has(name)) {
const newGeometry =
new THREE.BufferGeometry() as IMergeMeshBufferGeometry;
newGeometry.setAttribute(“position”, this.geometry.attributes.position);
newGeometry.setAttribute(“color”, this.geometry.attributes.color);
newGeometry.setAttribute(“elementId”, this.geometry.attributes.elementId);
newGeometry.setIndex(Array.from(this.geometry.index.array));
BVH.apply(newGeometry);
const mergeMesh = new MergeMesh(
this.ElementIdIndexMap,
newGeometry,
material
);
this.meshes.set(name, mergeMesh);
}
return this.meshes.get(name);
}
public static newMergeMeshInstance(
material: THREE.Material,
config: {
ElementIdIndexMap: Map<number, Map<number, number>>;
PositionArray: number;
ColorArray: number;
ElementIdArray: number;
IndexArray: number;
}
) {
const {
ElementIdIndexMap,
PositionArray,
ColorArray,
ElementIdArray,
IndexArray,
} = config;
const geometry = MergeMesh.newModelGeometry(
PositionArray,
ColorArray,
ElementIdArray,
IndexArray
);
return new MergeMesh(ElementIdIndexMap, geometry, material);
}
/**
*
*/
private static newModelGeometry(
PositionArray: number,
ColorArray: number,
ElementIdArray: number,
IndexArray: number
) {
const geometry = new THREE.BufferGeometry() as IMergeMeshBufferGeometry;
geometry.setAttribute(
“position”,
new THREE.BufferAttribute(new Float32Array(PositionArray), 3)
);
geometry.setAttribute(
“color”,
new THREE.BufferAttribute(new Float32Array(ColorArray), 3)
);
geometry.setAttribute(
“elementId”,
new THREE.BufferAttribute(new Uint32Array(ElementIdArray), 1)
);
geometry.setIndex(IndexArray);
BVH.apply(geometry);
geometry.computeVertexNormals();
geometry.computeBoundingBox();
geometry.computeBoundingSphere();
return geometry;
}
}
import {BufferGeometry} from “three”;
// Source: GitHub - gkjohnson/three-mesh-bvh: A BVH implementation to speed up raycasting and enable spatial queries against three.js meshes.
export class BVH {
static apply(geometry: BufferGeometry) {
//@ts-ignore
if (!geometry.boundsTree) {
//@ts-ignore
geometry.computeBoundsTree();
}
}
static dispose(geometry: BufferGeometry) {
//@ts-ignore
geometry.disposeBoundsTree();
}
}