UNPKG

three-stdlib

Version:

stand-alone library of threejs examples

1 lines 44.7 kB
{"version":3,"file":"BufferGeometryUtils.cjs","sources":["../../src/utils/BufferGeometryUtils.ts"],"sourcesContent":["import {\n BufferAttribute,\n BufferGeometry,\n Float32BufferAttribute,\n InterleavedBuffer,\n InterleavedBufferAttribute,\n TriangleFanDrawMode,\n TriangleStripDrawMode,\n TrianglesDrawMode,\n Vector3,\n Mesh,\n Line,\n Points,\n Material,\n SkinnedMesh,\n} from 'three'\n\nimport { getWithKey } from '../types/helpers'\nimport type { TypedArrayConstructors, TypedArray } from '../types/shared'\n\n/**\n * @param {Array<BufferGeometry>} geometries\n * @param {Boolean} useGroups\n * @return {BufferGeometry}\n */\nexport const mergeBufferGeometries = (geometries: BufferGeometry[], useGroups?: boolean): BufferGeometry | null => {\n const isIndexed = geometries[0].index !== null\n\n const attributesUsed = new Set(Object.keys(geometries[0].attributes))\n const morphAttributesUsed = new Set(Object.keys(geometries[0].morphAttributes))\n\n const attributes: { [key: string]: Array<InterleavedBufferAttribute | BufferAttribute> } = {}\n const morphAttributes: { [key: string]: Array<BufferAttribute | InterleavedBufferAttribute>[] } = {}\n\n const morphTargetsRelative = geometries[0].morphTargetsRelative\n\n const mergedGeometry = new BufferGeometry()\n\n let offset = 0\n\n geometries.forEach((geom, i) => {\n let attributesCount = 0\n\n // ensure that all geometries are indexed, or none\n\n if (isIndexed !== (geom.index !== null)) {\n console.error(\n 'THREE.BufferGeometryUtils: .mergeBufferGeometries() failed with geometry at index ' +\n i +\n '. All geometries must have compatible attributes; make sure index attribute exists among all geometries, or in none of them.',\n )\n return null\n }\n\n // gather attributes, exit early if they're different\n\n for (let name in geom.attributes) {\n if (!attributesUsed.has(name)) {\n console.error(\n 'THREE.BufferGeometryUtils: .mergeBufferGeometries() failed with geometry at index ' +\n i +\n '. All geometries must have compatible attributes; make sure \"' +\n name +\n '\" attribute exists among all geometries, or in none of them.',\n )\n return null\n }\n\n if (attributes[name] === undefined) {\n attributes[name] = []\n }\n\n attributes[name].push(geom.attributes[name])\n\n attributesCount++\n }\n\n // ensure geometries have the same number of attributes\n\n if (attributesCount !== attributesUsed.size) {\n console.error(\n 'THREE.BufferGeometryUtils: .mergeBufferGeometries() failed with geometry at index ' +\n i +\n '. Make sure all geometries have the same number of attributes.',\n )\n return null\n }\n\n // gather morph attributes, exit early if they're different\n\n if (morphTargetsRelative !== geom.morphTargetsRelative) {\n console.error(\n 'THREE.BufferGeometryUtils: .mergeBufferGeometries() failed with geometry at index ' +\n i +\n '. .morphTargetsRelative must be consistent throughout all geometries.',\n )\n return null\n }\n\n for (let name in geom.morphAttributes) {\n if (!morphAttributesUsed.has(name)) {\n console.error(\n 'THREE.BufferGeometryUtils: .mergeBufferGeometries() failed with geometry at index ' +\n i +\n '. .morphAttributes must be consistent throughout all geometries.',\n )\n return null\n }\n\n if (morphAttributes[name] === undefined) morphAttributes[name] = []\n\n morphAttributes[name].push(geom.morphAttributes[name])\n }\n\n // gather .userData\n\n mergedGeometry.userData.mergedUserData = mergedGeometry.userData.mergedUserData || []\n mergedGeometry.userData.mergedUserData.push(geom.userData)\n\n if (useGroups) {\n let count\n\n if (geom.index) {\n count = geom.index.count\n } else if (geom.attributes.position !== undefined) {\n count = geom.attributes.position.count\n } else {\n console.error(\n 'THREE.BufferGeometryUtils: .mergeBufferGeometries() failed with geometry at index ' +\n i +\n '. The geometry must have either an index or a position attribute',\n )\n return null\n }\n\n mergedGeometry.addGroup(offset, count, i)\n\n offset += count\n }\n })\n\n // merge indices\n\n if (isIndexed) {\n let indexOffset = 0\n const mergedIndex: number[] = []\n\n geometries.forEach((geom) => {\n const index = geom.index as BufferAttribute\n\n for (let j = 0; j < index.count; ++j) {\n mergedIndex.push(index.getX(j) + indexOffset)\n }\n\n indexOffset += geom.attributes.position.count\n })\n\n mergedGeometry.setIndex(mergedIndex)\n }\n\n // merge attributes\n\n for (let name in attributes) {\n const mergedAttribute = mergeBufferAttributes(attributes[name] as BufferAttribute[])\n\n if (!mergedAttribute) {\n console.error(\n 'THREE.BufferGeometryUtils: .mergeBufferGeometries() failed while trying to merge the ' + name + ' attribute.',\n )\n return null\n }\n\n mergedGeometry.setAttribute(name, mergedAttribute)\n }\n\n // merge morph attributes\n\n for (let name in morphAttributes) {\n const numMorphTargets = morphAttributes[name][0].length\n\n if (numMorphTargets === 0) break\n\n mergedGeometry.morphAttributes = mergedGeometry.morphAttributes || {}\n mergedGeometry.morphAttributes[name] = []\n\n for (let i = 0; i < numMorphTargets; ++i) {\n const morphAttributesToMerge = []\n\n for (let j = 0; j < morphAttributes[name].length; ++j) {\n morphAttributesToMerge.push(morphAttributes[name][j][i])\n }\n\n const mergedMorphAttribute = mergeBufferAttributes(morphAttributesToMerge as BufferAttribute[])\n\n if (!mergedMorphAttribute) {\n console.error(\n 'THREE.BufferGeometryUtils: .mergeBufferGeometries() failed while trying to merge the ' +\n name +\n ' morphAttribute.',\n )\n return null\n }\n\n mergedGeometry.morphAttributes[name].push(mergedMorphAttribute)\n }\n }\n\n return mergedGeometry\n}\n\n/**\n * @param {Array<BufferAttribute>} attributes\n * @return {BufferAttribute}\n */\nexport const mergeBufferAttributes = (attributes: BufferAttribute[]): BufferAttribute | null | undefined => {\n let TypedArray: TypedArrayConstructors | undefined = undefined\n let itemSize: number | undefined = undefined\n let normalized: boolean | undefined = undefined\n let arrayLength = 0\n\n attributes.forEach((attr) => {\n if (TypedArray === undefined) {\n TypedArray = attr.array.constructor\n }\n if (TypedArray !== attr.array.constructor) {\n console.error(\n 'THREE.BufferGeometryUtils: .mergeBufferAttributes() failed. BufferAttribute.array must be of consistent array types across matching attributes.',\n )\n return null\n }\n\n if (itemSize === undefined) itemSize = attr.itemSize\n if (itemSize !== attr.itemSize) {\n console.error(\n 'THREE.BufferGeometryUtils: .mergeBufferAttributes() failed. BufferAttribute.itemSize must be consistent across matching attributes.',\n )\n return null\n }\n\n if (normalized === undefined) normalized = attr.normalized\n if (normalized !== attr.normalized) {\n console.error(\n 'THREE.BufferGeometryUtils: .mergeBufferAttributes() failed. BufferAttribute.normalized must be consistent across matching attributes.',\n )\n return null\n }\n\n arrayLength += attr.array.length\n })\n\n if (TypedArray && itemSize) {\n // @ts-ignore this works in JS and TS is complaining but it's such a tiny thing I can live with the guilt\n const array = new TypedArray(arrayLength)\n let offset = 0\n\n attributes.forEach((attr) => {\n array.set(attr.array, offset)\n offset += attr.array.length\n })\n\n return new BufferAttribute(array, itemSize, normalized)\n }\n}\n\n/**\n * @param {Array<BufferAttribute>} attributes\n * @return {Array<InterleavedBufferAttribute>}\n */\nexport const interleaveAttributes = (attributes: BufferAttribute[]): InterleavedBufferAttribute[] | null => {\n // Interleaves the provided attributes into an InterleavedBuffer and returns\n // a set of InterleavedBufferAttributes for each attribute\n let TypedArray: TypedArrayConstructors | undefined = undefined\n let arrayLength = 0\n let stride = 0\n\n // calculate the the length and type of the interleavedBuffer\n for (let i = 0, l = attributes.length; i < l; ++i) {\n const attribute = attributes[i]\n\n if (TypedArray === undefined) TypedArray = attribute.array.constructor\n if (TypedArray !== attribute.array.constructor) {\n console.error('AttributeBuffers of different types cannot be interleaved')\n return null\n }\n\n arrayLength += attribute.array.length\n stride += attribute.itemSize\n }\n\n // Create the set of buffer attributes\n // @ts-ignore this works in JS and TS is complaining but it's such a tiny thing I can live with the guilt\n const interleavedBuffer = new InterleavedBuffer(new TypedArray(arrayLength), stride)\n let offset = 0\n const res = []\n const getters = ['getX', 'getY', 'getZ', 'getW']\n const setters = ['setX', 'setY', 'setZ', 'setW']\n\n for (let j = 0, l = attributes.length; j < l; j++) {\n const attribute = attributes[j]\n const itemSize = attribute.itemSize\n const count = attribute.count\n const iba = new InterleavedBufferAttribute(interleavedBuffer, itemSize, offset, attribute.normalized)\n res.push(iba)\n\n offset += itemSize\n\n // Move the data for each attribute into the new interleavedBuffer\n // at the appropriate offset\n for (let c = 0; c < count; c++) {\n for (let k = 0; k < itemSize; k++) {\n const set = getWithKey(iba, setters[k] as keyof InterleavedBufferAttribute) as InterleavedBufferAttribute[\n | 'setX'\n | 'setY'\n | 'setZ'\n | 'setW']\n const get = getWithKey(attribute, getters[k] as keyof BufferAttribute) as BufferAttribute[\n | 'getX'\n | 'getY'\n | 'getZ'\n | 'getW']\n set(c, get(c))\n }\n }\n }\n\n return res\n}\n\n/**\n * @param {Array<BufferGeometry>} geometry\n * @return {number}\n */\nexport function estimateBytesUsed(geometry: BufferGeometry): number {\n // Return the estimated memory used by this geometry in bytes\n // Calculate using itemSize, count, and BYTES_PER_ELEMENT to account\n // for InterleavedBufferAttributes.\n let mem = 0\n for (let name in geometry.attributes) {\n const attr = geometry.getAttribute(name)\n mem += attr.count * attr.itemSize * (attr.array as TypedArray).BYTES_PER_ELEMENT\n }\n\n const indices = geometry.getIndex()\n mem += indices ? indices.count * indices.itemSize * (indices.array as TypedArray).BYTES_PER_ELEMENT : 0\n return mem\n}\n\n/**\n * @param {BufferGeometry} geometry\n * @param {number} tolerance\n * @return {BufferGeometry>}\n */\nexport function mergeVertices(geometry: BufferGeometry, tolerance = 1e-4): BufferGeometry {\n tolerance = Math.max(tolerance, Number.EPSILON)\n\n // Generate an index buffer if the geometry doesn't have one, or optimize it\n // if it's already available.\n const hashToIndex: {\n [key: string]: number\n } = {}\n const indices = geometry.getIndex()\n const positions = geometry.getAttribute('position')\n const vertexCount = indices ? indices.count : positions.count\n\n // next value for triangle indices\n let nextIndex = 0\n\n // attributes and new attribute arrays\n const attributeNames = Object.keys(geometry.attributes)\n const attrArrays: {\n [key: string]: []\n } = {}\n const morphAttrsArrays: {\n [key: string]: Array<Array<BufferAttribute | InterleavedBufferAttribute>>\n } = {}\n const newIndices = []\n const getters = ['getX', 'getY', 'getZ', 'getW']\n\n // initialize the arrays\n for (let i = 0, l = attributeNames.length; i < l; i++) {\n const name = attributeNames[i]\n\n attrArrays[name] = []\n\n const morphAttr = geometry.morphAttributes[name]\n if (morphAttr) {\n morphAttrsArrays[name] = new Array(morphAttr.length).fill(0).map(() => [])\n }\n }\n\n // convert the error tolerance to an amount of decimal places to truncate to\n const decimalShift = Math.log10(1 / tolerance)\n const shiftMultiplier = Math.pow(10, decimalShift)\n for (let i = 0; i < vertexCount; i++) {\n const index = indices ? indices.getX(i) : i\n\n // Generate a hash for the vertex attributes at the current index 'i'\n let hash = ''\n for (let j = 0, l = attributeNames.length; j < l; j++) {\n const name = attributeNames[j]\n const attribute = geometry.getAttribute(name)\n const itemSize = attribute.itemSize\n\n for (let k = 0; k < itemSize; k++) {\n // double tilde truncates the decimal value\n // @ts-ignore no\n hash += `${~~(attribute[getters[k]](index) * shiftMultiplier)},`\n }\n }\n\n // Add another reference to the vertex if it's already\n // used by another index\n if (hash in hashToIndex) {\n newIndices.push(hashToIndex[hash])\n } else {\n // copy data to the new index in the attribute arrays\n for (let j = 0, l = attributeNames.length; j < l; j++) {\n const name = attributeNames[j]\n const attribute = geometry.getAttribute(name)\n const morphAttr = geometry.morphAttributes[name]\n const itemSize = attribute.itemSize\n const newarray = attrArrays[name]\n const newMorphArrays = morphAttrsArrays[name]\n\n for (let k = 0; k < itemSize; k++) {\n const getterFunc = getters[k]\n // @ts-ignore\n newarray.push(attribute[getterFunc](index))\n\n if (morphAttr) {\n for (let m = 0, ml = morphAttr.length; m < ml; m++) {\n // @ts-ignore\n newMorphArrays[m].push(morphAttr[m][getterFunc](index))\n }\n }\n }\n }\n\n hashToIndex[hash] = nextIndex\n newIndices.push(nextIndex)\n nextIndex++\n }\n }\n\n // Generate typed arrays from new attribute arrays and update\n // the attributeBuffers\n const result = geometry.clone()\n for (let i = 0, l = attributeNames.length; i < l; i++) {\n const name = attributeNames[i]\n const oldAttribute = geometry.getAttribute(name)\n //@ts-expect-error something to do with functions and constructors and new\n const buffer = new (oldAttribute.array as TypedArray).constructor(attrArrays[name])\n const attribute = new BufferAttribute(buffer, oldAttribute.itemSize, oldAttribute.normalized)\n\n result.setAttribute(name, attribute)\n\n // Update the attribute arrays\n if (name in morphAttrsArrays) {\n for (let j = 0; j < morphAttrsArrays[name].length; j++) {\n const oldMorphAttribute = geometry.morphAttributes[name][j]\n //@ts-expect-error something to do with functions and constructors and new\n const buffer = new (oldMorphAttribute.array as TypedArray).constructor(morphAttrsArrays[name][j])\n const morphAttribute = new BufferAttribute(buffer, oldMorphAttribute.itemSize, oldMorphAttribute.normalized)\n result.morphAttributes[name][j] = morphAttribute\n }\n }\n }\n\n // indices\n\n result.setIndex(newIndices)\n\n return result\n}\n\n/**\n * @param {BufferGeometry} geometry\n * @param {number} drawMode\n * @return {BufferGeometry}\n */\nexport function toTrianglesDrawMode(geometry: BufferGeometry, drawMode: number): BufferGeometry {\n if (drawMode === TrianglesDrawMode) {\n console.warn('THREE.BufferGeometryUtils.toTrianglesDrawMode(): Geometry already defined as triangles.')\n return geometry\n }\n\n if (drawMode === TriangleFanDrawMode || drawMode === TriangleStripDrawMode) {\n let index = geometry.getIndex()\n\n // generate index if not present\n\n if (index === null) {\n const indices = []\n\n const position = geometry.getAttribute('position')\n\n if (position !== undefined) {\n for (let i = 0; i < position.count; i++) {\n indices.push(i)\n }\n\n geometry.setIndex(indices)\n index = geometry.getIndex()\n } else {\n console.error(\n 'THREE.BufferGeometryUtils.toTrianglesDrawMode(): Undefined position attribute. Processing not possible.',\n )\n return geometry\n }\n }\n\n //\n\n const numberOfTriangles = (index as BufferAttribute).count - 2\n const newIndices = []\n\n if (index) {\n if (drawMode === TriangleFanDrawMode) {\n // gl.TRIANGLE_FAN\n\n for (let i = 1; i <= numberOfTriangles; i++) {\n newIndices.push(index.getX(0))\n newIndices.push(index.getX(i))\n newIndices.push(index.getX(i + 1))\n }\n } else {\n // gl.TRIANGLE_STRIP\n\n for (let i = 0; i < numberOfTriangles; i++) {\n if (i % 2 === 0) {\n newIndices.push(index.getX(i))\n newIndices.push(index.getX(i + 1))\n newIndices.push(index.getX(i + 2))\n } else {\n newIndices.push(index.getX(i + 2))\n newIndices.push(index.getX(i + 1))\n newIndices.push(index.getX(i))\n }\n }\n }\n }\n\n if (newIndices.length / 3 !== numberOfTriangles) {\n console.error('THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unable to generate correct amount of triangles.')\n }\n\n // build final geometry\n\n const newGeometry = geometry.clone()\n newGeometry.setIndex(newIndices)\n newGeometry.clearGroups()\n\n return newGeometry\n } else {\n console.error('THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unknown draw mode:', drawMode)\n return geometry\n }\n}\n\n/**\n * Calculates the morphed attributes of a morphed/skinned BufferGeometry.\n * Helpful for Raytracing or Decals.\n * @param {Mesh | Line | Points} object An instance of Mesh, Line or Points.\n * @return {Object} An Object with original position/normal attributes and morphed ones.\n */\nexport type ComputedMorphedAttribute = {\n positionAttribute: BufferAttribute | InterleavedBufferAttribute\n normalAttribute: BufferAttribute | InterleavedBufferAttribute\n morphedPositionAttribute: Float32BufferAttribute\n morphedNormalAttribute: Float32BufferAttribute\n}\n\nexport function computeMorphedAttributes(object: Mesh | Line | Points): ComputedMorphedAttribute | null {\n if (object.geometry.isBufferGeometry !== true) {\n console.error('THREE.BufferGeometryUtils: Geometry is not of type BufferGeometry.')\n return null\n }\n\n const _vA = new Vector3()\n const _vB = new Vector3()\n const _vC = new Vector3()\n\n const _tempA = new Vector3()\n const _tempB = new Vector3()\n const _tempC = new Vector3()\n\n const _morphA = new Vector3()\n const _morphB = new Vector3()\n const _morphC = new Vector3()\n\n function _calculateMorphedAttributeData(\n object: Mesh | Line | Points,\n material: Material,\n attribute: BufferAttribute | InterleavedBufferAttribute,\n morphAttribute: (BufferAttribute | InterleavedBufferAttribute)[],\n morphTargetsRelative: boolean,\n a: number,\n b: number,\n c: number,\n modifiedAttributeArray: Float32Array,\n ): void {\n _vA.fromBufferAttribute(attribute, a)\n _vB.fromBufferAttribute(attribute, b)\n _vC.fromBufferAttribute(attribute, c)\n\n const morphInfluences = object.morphTargetInfluences\n\n if (\n // @ts-ignore\n material.morphTargets &&\n morphAttribute &&\n morphInfluences\n ) {\n _morphA.set(0, 0, 0)\n _morphB.set(0, 0, 0)\n _morphC.set(0, 0, 0)\n\n for (let i = 0, il = morphAttribute.length; i < il; i++) {\n const influence = morphInfluences[i]\n const morph = morphAttribute[i]\n\n if (influence === 0) continue\n\n _tempA.fromBufferAttribute(morph, a)\n _tempB.fromBufferAttribute(morph, b)\n _tempC.fromBufferAttribute(morph, c)\n\n if (morphTargetsRelative) {\n _morphA.addScaledVector(_tempA, influence)\n _morphB.addScaledVector(_tempB, influence)\n _morphC.addScaledVector(_tempC, influence)\n } else {\n _morphA.addScaledVector(_tempA.sub(_vA), influence)\n _morphB.addScaledVector(_tempB.sub(_vB), influence)\n _morphC.addScaledVector(_tempC.sub(_vC), influence)\n }\n }\n\n _vA.add(_morphA)\n _vB.add(_morphB)\n _vC.add(_morphC)\n }\n\n if ((object as SkinnedMesh).isSkinnedMesh) {\n // @ts-ignore – https://github.com/three-types/three-ts-types/issues/37\n object.boneTransform(a, _vA)\n // @ts-ignore – https://github.com/three-types/three-ts-types/issues/37\n object.boneTransform(b, _vB)\n // @ts-ignore – https://github.com/three-types/three-ts-types/issues/37\n object.boneTransform(c, _vC)\n }\n\n modifiedAttributeArray[a * 3 + 0] = _vA.x\n modifiedAttributeArray[a * 3 + 1] = _vA.y\n modifiedAttributeArray[a * 3 + 2] = _vA.z\n modifiedAttributeArray[b * 3 + 0] = _vB.x\n modifiedAttributeArray[b * 3 + 1] = _vB.y\n modifiedAttributeArray[b * 3 + 2] = _vB.z\n modifiedAttributeArray[c * 3 + 0] = _vC.x\n modifiedAttributeArray[c * 3 + 1] = _vC.y\n modifiedAttributeArray[c * 3 + 2] = _vC.z\n }\n\n const geometry = object.geometry\n const material = object.material\n\n let a, b, c\n const index = geometry.index\n const positionAttribute = geometry.attributes.position\n const morphPosition = geometry.morphAttributes.position\n const morphTargetsRelative = geometry.morphTargetsRelative\n const normalAttribute = geometry.attributes.normal\n const morphNormal = geometry.morphAttributes.position\n\n const groups = geometry.groups\n const drawRange = geometry.drawRange\n let i, j, il, jl\n let group, groupMaterial\n let start, end\n\n const modifiedPosition = new Float32Array(positionAttribute.count * positionAttribute.itemSize)\n const modifiedNormal = new Float32Array(normalAttribute.count * normalAttribute.itemSize)\n\n if (index !== null) {\n // indexed buffer geometry\n\n if (Array.isArray(material)) {\n for (i = 0, il = groups.length; i < il; i++) {\n group = groups[i]\n groupMaterial = material[group.materialIndex as number]\n\n start = Math.max(group.start, drawRange.start)\n end = Math.min(group.start + group.count, drawRange.start + drawRange.count)\n\n for (j = start, jl = end; j < jl; j += 3) {\n a = index.getX(j)\n b = index.getX(j + 1)\n c = index.getX(j + 2)\n\n _calculateMorphedAttributeData(\n object,\n groupMaterial,\n positionAttribute,\n morphPosition,\n morphTargetsRelative,\n a,\n b,\n c,\n modifiedPosition,\n )\n\n _calculateMorphedAttributeData(\n object,\n groupMaterial,\n normalAttribute,\n morphNormal,\n morphTargetsRelative,\n a,\n b,\n c,\n modifiedNormal,\n )\n }\n }\n } else {\n start = Math.max(0, drawRange.start)\n end = Math.min(index.count, drawRange.start + drawRange.count)\n\n for (i = start, il = end; i < il; i += 3) {\n a = index.getX(i)\n b = index.getX(i + 1)\n c = index.getX(i + 2)\n\n _calculateMorphedAttributeData(\n object,\n material,\n positionAttribute,\n morphPosition,\n morphTargetsRelative,\n a,\n b,\n c,\n modifiedPosition,\n )\n\n _calculateMorphedAttributeData(\n object,\n material,\n normalAttribute,\n morphNormal,\n morphTargetsRelative,\n a,\n b,\n c,\n modifiedNormal,\n )\n }\n }\n } else if (positionAttribute !== undefined) {\n // non-indexed buffer geometry\n\n if (Array.isArray(material)) {\n for (i = 0, il = groups.length; i < il; i++) {\n group = groups[i]\n groupMaterial = material[group.materialIndex as number]\n\n start = Math.max(group.start, drawRange.start)\n end = Math.min(group.start + group.count, drawRange.start + drawRange.count)\n\n for (j = start, jl = end; j < jl; j += 3) {\n a = j\n b = j + 1\n c = j + 2\n\n _calculateMorphedAttributeData(\n object,\n groupMaterial,\n positionAttribute,\n morphPosition,\n morphTargetsRelative,\n a,\n b,\n c,\n modifiedPosition,\n )\n\n _calculateMorphedAttributeData(\n object,\n groupMaterial,\n normalAttribute,\n morphNormal,\n morphTargetsRelative,\n a,\n b,\n c,\n modifiedNormal,\n )\n }\n }\n } else {\n start = Math.max(0, drawRange.start)\n end = Math.min(positionAttribute.count, drawRange.start + drawRange.count)\n\n for (i = start, il = end; i < il; i += 3) {\n a = i\n b = i + 1\n c = i + 2\n\n _calculateMorphedAttributeData(\n object,\n material,\n positionAttribute,\n morphPosition,\n morphTargetsRelative,\n a,\n b,\n c,\n modifiedPosition,\n )\n\n _calculateMorphedAttributeData(\n object,\n material,\n normalAttribute,\n morphNormal,\n morphTargetsRelative,\n a,\n b,\n c,\n modifiedNormal,\n )\n }\n }\n }\n\n const morphedPositionAttribute = new Float32BufferAttribute(modifiedPosition, 3)\n const morphedNormalAttribute = new Float32BufferAttribute(modifiedNormal, 3)\n\n return {\n positionAttribute: positionAttribute,\n normalAttribute: normalAttribute,\n morphedPositionAttribute: morphedPositionAttribute,\n morphedNormalAttribute: morphedNormalAttribute,\n }\n}\n\n/**\n * Modifies the supplied geometry if it is non-indexed, otherwise creates a new,\n * non-indexed geometry. Returns the geometry with smooth normals everywhere except\n * faces that meet at an angle greater than the crease angle.\n *\n * Backwards compatible with code such as @react-three/drei's `<RoundedBox>`\n * which uses this method to operate on the original geometry.\n *\n * As of this writing, BufferGeometry.toNonIndexed() warns if the geometry is\n * non-indexed and returns `this`, i.e. the same geometry on which it was called:\n * `BufferGeometry is already non-indexed.`\n *\n * @param geometry\n * @param creaseAngle\n */\nexport function toCreasedNormals(geometry: BufferGeometry, creaseAngle = Math.PI / 3 /* 60 degrees */): BufferGeometry {\n const creaseDot = Math.cos(creaseAngle)\n const hashMultiplier = (1 + 1e-10) * 1e2\n\n // reusable vectors\n const verts = [new Vector3(), new Vector3(), new Vector3()]\n const tempVec1 = new Vector3()\n const tempVec2 = new Vector3()\n const tempNorm = new Vector3()\n const tempNorm2 = new Vector3()\n\n // hashes a vector\n function hashVertex(v: Vector3): string {\n const x = ~~(v.x * hashMultiplier)\n const y = ~~(v.y * hashMultiplier)\n const z = ~~(v.z * hashMultiplier)\n return `${x},${y},${z}`\n }\n\n const resultGeometry = geometry.index ? geometry.toNonIndexed() : geometry\n const posAttr = resultGeometry.attributes.position\n const vertexMap: { [key: string]: Vector3[] } = {}\n\n // find all the normals shared by commonly located vertices\n for (let i = 0, l = posAttr.count / 3; i < l; i++) {\n const i3 = 3 * i\n const a = verts[0].fromBufferAttribute(posAttr, i3 + 0)\n const b = verts[1].fromBufferAttribute(posAttr, i3 + 1)\n const c = verts[2].fromBufferAttribute(posAttr, i3 + 2)\n\n tempVec1.subVectors(c, b)\n tempVec2.subVectors(a, b)\n\n // add the normal to the map for all vertices\n const normal = new Vector3().crossVectors(tempVec1, tempVec2).normalize()\n for (let n = 0; n < 3; n++) {\n const vert = verts[n]\n const hash = hashVertex(vert)\n if (!(hash in vertexMap)) {\n vertexMap[hash] = []\n }\n\n vertexMap[hash].push(normal)\n }\n }\n\n // average normals from all vertices that share a common location if they are within the\n // provided crease threshold\n const normalArray = new Float32Array(posAttr.count * 3)\n const normAttr = new BufferAttribute(normalArray, 3, false)\n for (let i = 0, l = posAttr.count / 3; i < l; i++) {\n // get the face normal for this vertex\n const i3 = 3 * i\n const a = verts[0].fromBufferAttribute(posAttr, i3 + 0)\n const b = verts[1].fromBufferAttribute(posAttr, i3 + 1)\n const c = verts[2].fromBufferAttribute(posAttr, i3 + 2)\n\n tempVec1.subVectors(c, b)\n tempVec2.subVectors(a, b)\n\n tempNorm.crossVectors(tempVec1, tempVec2).normalize()\n\n // average all normals that meet the threshold and set the normal value\n for (let n = 0; n < 3; n++) {\n const vert = verts[n]\n const hash = hashVertex(vert)\n const otherNormals = vertexMap[hash]\n tempNorm2.set(0, 0, 0)\n\n for (let k = 0, lk = otherNormals.length; k < lk; k++) {\n const otherNorm = otherNormals[k]\n if (tempNorm.dot(otherNorm) > creaseDot) {\n tempNorm2.add(otherNorm)\n }\n }\n\n tempNorm2.normalize()\n normAttr.setXYZ(i3 + n, tempNorm2.x, tempNorm2.y, tempNorm2.z)\n }\n }\n\n resultGeometry.setAttribute('normal', normAttr)\n return resultGeometry\n}\n"],"names":["BufferGeometry","BufferAttribute","InterleavedBuffer","InterleavedBufferAttribute","getWithKey","buffer","TrianglesDrawMode","TriangleFanDrawMode","TriangleStripDrawMode","Vector3","object","material","morphTargetsRelative","a","b","c","i","il","Float32BufferAttribute"],"mappings":"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"}