{"version":3,"file":"MeshSurfaceSampler.cjs","sources":["../../src/math/MeshSurfaceSampler.js"],"sourcesContent":["import { Triangle, Vector3 } from 'three'\n\n/**\n * Utility class for sampling weighted random points on the surface of a mesh.\n *\n * Building the sampler is a one-time O(n) operation. Once built, any number of\n * random samples may be selected in O(logn) time. Memory usage is O(n).\n *\n * References:\n * - http://www.joesfer.com/?p=84\n * - https://stackoverflow.com/a/4322940/1314762\n */\n\nconst _face = /* @__PURE__ */ new Triangle()\nconst _color = /* @__PURE__ */ new Vector3()\n\nclass MeshSurfaceSampler {\n constructor(mesh) {\n let geometry = mesh.geometry\n\n if (geometry.index) {\n console.warn('THREE.MeshSurfaceSampler: Converting geometry to non-indexed BufferGeometry.')\n\n geometry = geometry.toNonIndexed()\n }\n\n this.geometry = geometry\n this.randomFunction = Math.random\n\n this.positionAttribute = this.geometry.getAttribute('position')\n this.colorAttribute = this.geometry.getAttribute('color')\n this.weightAttribute = null\n\n this.distribution = null\n }\n\n setWeightAttribute(name) {\n this.weightAttribute = name ? this.geometry.getAttribute(name) : null\n\n return this\n }\n\n build() {\n const positionAttribute = this.positionAttribute\n const weightAttribute = this.weightAttribute\n\n const faceWeights = new Float32Array(positionAttribute.count / 3)\n\n // Accumulate weights for each mesh face.\n\n for (let i = 0; i < positionAttribute.count; i += 3) {\n let faceWeight = 1\n\n if (weightAttribute) {\n faceWeight = weightAttribute.getX(i) + weightAttribute.getX(i + 1) + weightAttribute.getX(i + 2)\n }\n\n _face.a.fromBufferAttribute(positionAttribute, i)\n _face.b.fromBufferAttribute(positionAttribute, i + 1)\n _face.c.fromBufferAttribute(positionAttribute, i + 2)\n faceWeight *= _face.getArea()\n\n faceWeights[i / 3] = faceWeight\n }\n\n // Store cumulative total face weights in an array, where weight index\n // corresponds to face index.\n\n this.distribution = new Float32Array(positionAttribute.count / 3)\n\n let cumulativeTotal = 0\n\n for (let i = 0; i < faceWeights.length; i++) {\n cumulativeTotal += faceWeights[i]\n\n this.distribution[i] = cumulativeTotal\n }\n\n return this\n }\n\n setRandomGenerator(randomFunction) {\n this.randomFunction = randomFunction\n return this\n }\n\n sample(targetPosition, targetNormal, targetColor) {\n const faceIndex = this.sampleFaceIndex()\n return this.sampleFace(faceIndex, targetPosition, targetNormal, targetColor)\n }\n\n sampleFaceIndex() {\n const cumulativeTotal = this.distribution[this.distribution.length - 1]\n return this.binarySearch(this.randomFunction() * cumulativeTotal)\n }\n\n binarySearch(x) {\n const dist = this.distribution\n let start = 0\n let end = dist.length - 1\n\n let index = -1\n\n while (start <= end) {\n const mid = Math.ceil((start + end) / 2)\n\n if (mid === 0 || (dist[mid - 1] <= x && dist[mid] > x)) {\n index = mid\n\n break\n } else if (x < dist[mid]) {\n end = mid - 1\n } else {\n start = mid + 1\n }\n }\n\n return index\n }\n\n sampleFace(faceIndex, targetPosition, targetNormal, targetColor) {\n let u = this.randomFunction()\n let v = this.randomFunction()\n\n if (u + v > 1) {\n u = 1 - u\n v = 1 - v\n }\n\n _face.a.fromBufferAttribute(this.positionAttribute, faceIndex * 3)\n _face.b.fromBufferAttribute(this.positionAttribute, faceIndex * 3 + 1)\n _face.c.fromBufferAttribute(this.positionAttribute, faceIndex * 3 + 2)\n\n targetPosition\n .set(0, 0, 0)\n .addScaledVector(_face.a, u)\n .addScaledVector(_face.b, v)\n .addScaledVector(_face.c, 1 - (u + v))\n\n if (targetNormal !== undefined) {\n _face.getNormal(targetNormal)\n }\n\n if (targetColor !== undefined && this.colorAttribute !== undefined) {\n _face.a.fromBufferAttribute(this.colorAttribute, faceIndex * 3)\n _face.b.fromBufferAttribute(this.colorAttribute, faceIndex * 3 + 1)\n _face.c.fromBufferAttribute(this.colorAttribute, faceIndex * 3 + 2)\n\n _color\n .set(0, 0, 0)\n .addScaledVector(_face.a, u)\n .addScaledVector(_face.b, v)\n .addScaledVector(_face.c, 1 - (u + v))\n\n targetColor.r = _color.x\n targetColor.g = _color.y\n targetColor.b = _color.z\n }\n\n return this\n }\n}\n\nexport { MeshSurfaceSampler }\n"],"names":["Triangle","Vector3"],"mappings":"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"}