{"version":3,"file":"EdgeSplitModifier.cjs","sources":["../../src/modifiers/EdgeSplitModifier.ts"],"sourcesContent":["import { BufferAttribute, BufferGeometry, Vector3 } from 'three'\nimport * as BufferGeometryUtils from '../utils/BufferGeometryUtils'\n\ninterface EdgeSplitToGroupsResult {\n  splitGroup: number[]\n  currentGroup: number[]\n}\n\ninterface SplitIndexes {\n  original: number\n  indexes: number[]\n}\n\nclass EdgeSplitModifier {\n  private A = new Vector3()\n  private B = new Vector3()\n  private C = new Vector3()\n\n  private positions: ArrayLike<number> = []\n  private normals: Float32Array = new Float32Array()\n  private indexes: ArrayLike<number> = []\n  private pointToIndexMap: number[][] = []\n  private splitIndexes: SplitIndexes[] = []\n  private oldNormals: ArrayLike<number> = []\n\n  constructor() {}\n\n  private computeNormals = (): void => {\n    this.normals = new Float32Array(this.indexes.length * 3)\n\n    for (let i = 0; i < this.indexes.length; i += 3) {\n      let index = this.indexes[i]\n\n      this.A.set(this.positions[3 * index], this.positions[3 * index + 1], this.positions[3 * index + 2])\n\n      index = this.indexes[i + 1]\n      this.B.set(this.positions[3 * index], this.positions[3 * index + 1], this.positions[3 * index + 2])\n\n      index = this.indexes[i + 2]\n      this.C.set(this.positions[3 * index], this.positions[3 * index + 1], this.positions[3 * index + 2])\n\n      this.C.sub(this.B)\n      this.A.sub(this.B)\n\n      const normal = this.C.cross(this.A).normalize()\n\n      for (let j = 0; j < 3; j++) {\n        this.normals[3 * (i + j)] = normal.x\n        this.normals[3 * (i + j) + 1] = normal.y\n        this.normals[3 * (i + j) + 2] = normal.z\n      }\n    }\n  }\n\n  private mapPositionsToIndexes = (): void => {\n    this.pointToIndexMap = Array(this.positions.length / 3)\n\n    for (let i = 0; i < this.indexes.length; i++) {\n      const index = this.indexes[i]\n\n      if (this.pointToIndexMap[index] == null) {\n        this.pointToIndexMap[index] = []\n      }\n\n      this.pointToIndexMap[index].push(i)\n    }\n  }\n\n  private edgeSplitToGroups = (indexes: number[], cutOff: number, firstIndex: number): EdgeSplitToGroupsResult => {\n    this.A.set(\n      this.normals[3 * firstIndex],\n      this.normals[3 * firstIndex + 1],\n      this.normals[3 * firstIndex + 2],\n    ).normalize()\n\n    const result: EdgeSplitToGroupsResult = {\n      splitGroup: [],\n      currentGroup: [firstIndex],\n    }\n\n    for (let j of indexes) {\n      if (j !== firstIndex) {\n        this.B.set(this.normals[3 * j], this.normals[3 * j + 1], this.normals[3 * j + 2]).normalize()\n\n        if (this.B.dot(this.A) < cutOff) {\n          result.splitGroup.push(j)\n        } else {\n          result.currentGroup.push(j)\n        }\n      }\n    }\n\n    return result\n  }\n\n  private edgeSplit = (indexes: number[], cutOff: number, original: number | null = null): void => {\n    if (indexes.length === 0) return\n\n    const groupResults: EdgeSplitToGroupsResult[] = []\n\n    for (let index of indexes) {\n      groupResults.push(this.edgeSplitToGroups(indexes, cutOff, index))\n    }\n\n    let result = groupResults[0]\n\n    for (let groupResult of groupResults) {\n      if (groupResult.currentGroup.length > result.currentGroup.length) {\n        result = groupResult\n      }\n    }\n\n    if (original != null) {\n      this.splitIndexes.push({\n        original,\n        indexes: result.currentGroup,\n      })\n    }\n\n    if (result.splitGroup.length) {\n      this.edgeSplit(result.splitGroup, cutOff, original || result.currentGroup[0])\n    }\n  }\n\n  public modify = (geometry: BufferGeometry, cutOffAngle: number, tryKeepNormals = true): BufferGeometry => {\n    let hadNormals = false\n\n    if (geometry.attributes.normal) {\n      hadNormals = true\n\n      geometry = geometry.clone()\n\n      if (tryKeepNormals === true && geometry.index !== null) {\n        this.oldNormals = geometry.attributes.normal.array\n      }\n\n      geometry.deleteAttribute('normal')\n    }\n\n    if (geometry.index == null) {\n      if (BufferGeometryUtils === undefined) {\n        throw 'THREE.EdgeSplitModifier relies on BufferGeometryUtils'\n      }\n\n      geometry = BufferGeometryUtils.mergeVertices(geometry)\n    }\n\n    this.indexes = (geometry.index as BufferAttribute).array\n    this.positions = geometry.getAttribute('position').array\n\n    this.computeNormals()\n    this.mapPositionsToIndexes()\n\n    this.splitIndexes = []\n\n    for (let vertexIndexes of this.pointToIndexMap) {\n      this.edgeSplit(vertexIndexes, Math.cos(cutOffAngle) - 0.001)\n    }\n\n    const newAttributes: {\n      [key: string]: BufferAttribute\n    } = {}\n    for (let name of Object.keys(geometry.attributes)) {\n      const oldAttribute = geometry.attributes[name]\n      // @ts-ignore\n      const newArray = new oldAttribute.array.constructor(\n        (this.indexes.length + this.splitIndexes.length) * oldAttribute.itemSize,\n      )\n\n      newArray.set(oldAttribute.array)\n      newAttributes[name] = new BufferAttribute(newArray, oldAttribute.itemSize, oldAttribute.normalized)\n    }\n\n    const newIndexes = new Uint32Array(this.indexes.length)\n    newIndexes.set(this.indexes)\n\n    for (let i = 0; i < this.splitIndexes.length; i++) {\n      const split = this.splitIndexes[i]\n      const index = this.indexes[split.original]\n\n      for (let attribute of Object.values(newAttributes)) {\n        for (let j = 0; j < attribute.itemSize; j++) {\n          // @ts-ignore ArrayLike can't be mutated, but this works – https://github.com/three-types/three-ts-types/issues/35\n          attribute.array[(this.indexes.length + i) * attribute.itemSize + j] =\n            attribute.array[index * attribute.itemSize + j]\n        }\n      }\n\n      for (let j of split.indexes) {\n        newIndexes[j] = this.indexes.length + i\n      }\n    }\n\n    geometry = new BufferGeometry()\n    geometry.setIndex(new BufferAttribute(newIndexes, 1))\n\n    for (let name of Object.keys(newAttributes)) {\n      geometry.setAttribute(name, newAttributes[name])\n    }\n\n    if (hadNormals) {\n      geometry.computeVertexNormals()\n\n      if (this.oldNormals !== null) {\n        const changedNormals = new Array(this.oldNormals.length / 3).fill(false)\n\n        for (let splitData of this.splitIndexes) changedNormals[splitData.original] = true\n\n        for (let i = 0; i < changedNormals.length; i++) {\n          if (changedNormals[i] === false) {\n            for (let j = 0; j < 3; j++) {\n              // @ts-ignore ArrayLike can't be mutated, but this works – https://github.com/three-types/three-ts-types/issues/35\n              geometry.attributes.normal.array[3 * i + j] = this.oldNormals[3 * i + j]\n            }\n          }\n        }\n      }\n    }\n\n    return geometry\n  }\n}\n\nexport { EdgeSplitModifier }\n"],"names":["Vector3","BufferGeometryUtils.mergeVertices","BufferAttribute","BufferGeometry"],"mappings":"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"}