-
Notifications
You must be signed in to change notification settings - Fork 17
/
get-positions-and-indices.ts
73 lines (54 loc) · 1.89 KB
/
get-positions-and-indices.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import { BufferAttribute, Mesh, Vector3 } from 'three';
const tmpVec3 = new Vector3();
export const getPositionsAndIndices = (
meshes: Mesh[]
): [positions: Float32Array, indices: Uint32Array] => {
const meshesToMerge: Mesh[] = [];
for (const mesh of meshes) {
const positionAttribute = mesh.geometry.attributes
.position as BufferAttribute;
if (!positionAttribute || positionAttribute.itemSize !== 3) {
continue;
}
let meshToMerge = mesh;
const index: ArrayLike<number> | undefined = mesh.geometry.getIndex()?.array;
if (index === undefined) {
meshToMerge = meshToMerge.clone();
meshToMerge.geometry = mesh.geometry.clone();
// this will become indexed when merging with other meshes
const ascendingIndex: number[] = [];
for (let i = 0; i < positionAttribute.count; i++) {
ascendingIndex.push(i);
}
meshToMerge.geometry.setIndex(ascendingIndex);
}
meshesToMerge.push(meshToMerge);
}
const mergedPositions: number[] = [];
const mergedIndices: number[] = [];
const positionToIndex: { [hash: string]: number } = {};
let indexCounter = 0;
for (const mesh of meshesToMerge) {
mesh.updateMatrixWorld();
const positions = mesh.geometry.attributes.position.array;
const index = mesh.geometry.getIndex()!.array;
for (let i = 0; i < index.length; i++) {
const pt = index[i] * 3;
const pos = tmpVec3.set(
positions[pt],
positions[pt + 1],
positions[pt + 2]
);
mesh.localToWorld(pos);
const key = `${pos.x}_${pos.y}_${pos.z}`;
let idx = positionToIndex[key];
if (!idx) {
positionToIndex[key] = idx = indexCounter;
mergedPositions.push(pos.x, pos.y, pos.z);
indexCounter++;
}
mergedIndices.push(idx);
}
}
return [Float32Array.from(mergedPositions), Uint32Array.from(mergedIndices)];
};