UNPKG

three-stdlib

Version:

stand-alone library of threejs examples

170 lines (169 loc) 6.76 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; import { Vector3, BufferAttribute, BufferGeometry } from "three"; import * as BufferGeometryUtils from "../utils/BufferGeometryUtils.js"; import { mergeVertices } from "../utils/BufferGeometryUtils.js"; class EdgeSplitModifier { constructor() { __publicField(this, "A", new Vector3()); __publicField(this, "B", new Vector3()); __publicField(this, "C", new Vector3()); __publicField(this, "positions", []); __publicField(this, "normals", new Float32Array()); __publicField(this, "indexes", []); __publicField(this, "pointToIndexMap", []); __publicField(this, "splitIndexes", []); __publicField(this, "oldNormals", []); __publicField(this, "computeNormals", () => { this.normals = new Float32Array(this.indexes.length * 3); for (let i = 0; i < this.indexes.length; i += 3) { let index = this.indexes[i]; this.A.set(this.positions[3 * index], this.positions[3 * index + 1], this.positions[3 * index + 2]); index = this.indexes[i + 1]; this.B.set(this.positions[3 * index], this.positions[3 * index + 1], this.positions[3 * index + 2]); index = this.indexes[i + 2]; this.C.set(this.positions[3 * index], this.positions[3 * index + 1], this.positions[3 * index + 2]); this.C.sub(this.B); this.A.sub(this.B); const normal = this.C.cross(this.A).normalize(); for (let j = 0; j < 3; j++) { this.normals[3 * (i + j)] = normal.x; this.normals[3 * (i + j) + 1] = normal.y; this.normals[3 * (i + j) + 2] = normal.z; } } }); __publicField(this, "mapPositionsToIndexes", () => { this.pointToIndexMap = Array(this.positions.length / 3); for (let i = 0; i < this.indexes.length; i++) { const index = this.indexes[i]; if (this.pointToIndexMap[index] == null) { this.pointToIndexMap[index] = []; } this.pointToIndexMap[index].push(i); } }); __publicField(this, "edgeSplitToGroups", (indexes, cutOff, firstIndex) => { this.A.set( this.normals[3 * firstIndex], this.normals[3 * firstIndex + 1], this.normals[3 * firstIndex + 2] ).normalize(); const result = { splitGroup: [], currentGroup: [firstIndex] }; for (let j of indexes) { if (j !== firstIndex) { this.B.set(this.normals[3 * j], this.normals[3 * j + 1], this.normals[3 * j + 2]).normalize(); if (this.B.dot(this.A) < cutOff) { result.splitGroup.push(j); } else { result.currentGroup.push(j); } } } return result; }); __publicField(this, "edgeSplit", (indexes, cutOff, original = null) => { if (indexes.length === 0) return; const groupResults = []; for (let index of indexes) { groupResults.push(this.edgeSplitToGroups(indexes, cutOff, index)); } let result = groupResults[0]; for (let groupResult of groupResults) { if (groupResult.currentGroup.length > result.currentGroup.length) { result = groupResult; } } if (original != null) { this.splitIndexes.push({ original, indexes: result.currentGroup }); } if (result.splitGroup.length) { this.edgeSplit(result.splitGroup, cutOff, original || result.currentGroup[0]); } }); __publicField(this, "modify", (geometry, cutOffAngle, tryKeepNormals = true) => { let hadNormals = false; if (geometry.attributes.normal) { hadNormals = true; geometry = geometry.clone(); if (tryKeepNormals === true && geometry.index !== null) { this.oldNormals = geometry.attributes.normal.array; } geometry.deleteAttribute("normal"); } if (geometry.index == null) { if (BufferGeometryUtils === void 0) { throw "THREE.EdgeSplitModifier relies on BufferGeometryUtils"; } geometry = mergeVertices(geometry); } this.indexes = geometry.index.array; this.positions = geometry.getAttribute("position").array; this.computeNormals(); this.mapPositionsToIndexes(); this.splitIndexes = []; for (let vertexIndexes of this.pointToIndexMap) { this.edgeSplit(vertexIndexes, Math.cos(cutOffAngle) - 1e-3); } const newAttributes = {}; for (let name of Object.keys(geometry.attributes)) { const oldAttribute = geometry.attributes[name]; const newArray = new oldAttribute.array.constructor( (this.indexes.length + this.splitIndexes.length) * oldAttribute.itemSize ); newArray.set(oldAttribute.array); newAttributes[name] = new BufferAttribute(newArray, oldAttribute.itemSize, oldAttribute.normalized); } const newIndexes = new Uint32Array(this.indexes.length); newIndexes.set(this.indexes); for (let i = 0; i < this.splitIndexes.length; i++) { const split = this.splitIndexes[i]; const index = this.indexes[split.original]; for (let attribute of Object.values(newAttributes)) { for (let j = 0; j < attribute.itemSize; j++) { attribute.array[(this.indexes.length + i) * attribute.itemSize + j] = attribute.array[index * attribute.itemSize + j]; } } for (let j of split.indexes) { newIndexes[j] = this.indexes.length + i; } } geometry = new BufferGeometry(); geometry.setIndex(new BufferAttribute(newIndexes, 1)); for (let name of Object.keys(newAttributes)) { geometry.setAttribute(name, newAttributes[name]); } if (hadNormals) { geometry.computeVertexNormals(); if (this.oldNormals !== null) { const changedNormals = new Array(this.oldNormals.length / 3).fill(false); for (let splitData of this.splitIndexes) changedNormals[splitData.original] = true; for (let i = 0; i < changedNormals.length; i++) { if (changedNormals[i] === false) { for (let j = 0; j < 3; j++) { geometry.attributes.normal.array[3 * i + j] = this.oldNormals[3 * i + j]; } } } } } return geometry; }); } } export { EdgeSplitModifier }; //# sourceMappingURL=EdgeSplitModifier.js.map