mergeVertics.js
2.19 KB
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
import { Float32BufferAttribute } from 'three';
/**
* 刪除重複頂點,更新網格拓樸
* @param {*BufferGeometry} geometry three.js幾何模型
* @param {*Number} precisionPoints
* 等同於 import { BufferGeometryUtils } from 'three/examples/jsm/utils/BufferGeometryUtils.js' 裡的 BufferGeometryUtils.mergeVertices
* 但這個函式有bug,會讓有些模型網格破損,所以重寫一個
*/
export const mergeVertices = (geometry, precisionPoints = 4) => {
const verticesMap = {};
const unique = [],
changes = [];
const colorunique = [];
const uvunique = [];
const precision = Math.pow(10, precisionPoints);
let position = geometry.getAttribute('position');
let color = geometry.getAttribute('color');
let uv = geometry.getAttribute('uv');
let vertexLength = position.count;
let i = 0;
while (i < vertexLength) {
const key =
Math.round(position.getX(i) * precision) +
'_' +
Math.round(position.getY(i) * precision) +
'_' +
Math.round(position.getZ(i) * precision);
if (verticesMap[key] === undefined) {
verticesMap[key] = i;
unique.push(position.getX(i), position.getY(i), position.getZ(i));
if (color) {
colorunique.push(color.getX(i), color.getY(i), color.getZ(i));
}
if (uv) {
uvunique.push(uv.getX(i), uv.getY(i));
}
changes[i] = unique.length / 3 - 1;
} else {
changes[i] = changes[verticesMap[key]];
}
++i;
}
if (unique.length == vertexLength * 3) {
return; //頂點數量不變,原始模型沒有重複頂點,使用原始的拓樸即可
}
if (unique.length > 0) {
geometry.setAttribute('position', new Float32BufferAttribute(unique, 3));
}
if (colorunique.length > 0) {
geometry.setAttribute('color', new Float32BufferAttribute(colorunique, 3));
}
if (uvunique.length > 0) {
geometry.setAttribute('uv', new Float32BufferAttribute(uvunique, 2));
}
if (changes.length > 0) {
geometry.setIndex(changes);
}
geometry.computeVertexNormals();
};