three-particle-geometry
Version:
An npm package that allows users to represent threeJS geometry instances as particles.
1 lines • 4.1 kB
JavaScript
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("THREE")):"function"==typeof define&&define.amd?define("three-particle-geometry",["THREE"],e):"object"==typeof exports?exports["three-particle-geometry"]=e(require("THREE")):t["three-particle-geometry"]=e(t.THREE)}(this,(t=>(()=>{"use strict";var e={824:e=>{e.exports=t}},r={};function i(t){var o=r[t];if(void 0!==o)return o.exports;var n=r[t]={exports:{}};return e[t](n,n.exports,i),n.exports}i.d=(t,e)=>{for(var r in e)i.o(e,r)&&!i.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},i.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),i.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var o={};return(()=>{i.r(o),i.d(o,{ParticleGeometry:()=>l});var t=i(824);const e=new t.Triangle,r=new t.Vector3,n=new t.Vector2,u=new t.Vector2,s=new t.Vector2;class a{constructor(t){this.geometry=t.geometry,this.randomFunction=Math.random,this.indexAttribute=this.geometry.index,this.positionAttribute=this.geometry.getAttribute("position"),this.normalAttribute=this.geometry.getAttribute("normal"),this.colorAttribute=this.geometry.getAttribute("color"),this.uvAttribute=this.geometry.getAttribute("uv"),this.weightAttribute=null,this.distribution=null}setWeightAttribute(t){return this.weightAttribute=t?this.geometry.getAttribute(t):null,this}build(){const t=this.indexAttribute,r=this.positionAttribute,i=this.weightAttribute,o=t?t.count/3:r.count/3,n=new Float32Array(o);for(let u=0;u<o;u++){let o=1,s=3*u,a=3*u+1,c=3*u+2;t&&(s=t.getX(s),a=t.getX(a),c=t.getX(c)),i&&(o=i.getX(s)+i.getX(a)+i.getX(c)),e.a.fromBufferAttribute(r,s),e.b.fromBufferAttribute(r,a),e.c.fromBufferAttribute(r,c),o*=e.getArea(),n[u]=o}const u=new Float32Array(o);let s=0;for(let t=0;t<o;t++)s+=n[t],u[t]=s;return this.distribution=u,this}setRandomGenerator(t){return this.randomFunction=t,this}sample(t,e,r,i){const o=this.sampleFaceIndex();return this.sampleFace(o,t,e,r,i)}sampleFaceIndex(){const t=this.distribution[this.distribution.length-1];return this.binarySearch(this.randomFunction()*t)}binarySearch(t){const e=this.distribution;let r=0,i=e.length-1,o=-1;for(;r<=i;){const n=Math.ceil((r+i)/2);if(0===n||e[n-1]<=t&&e[n]>t){o=n;break}t<e[n]?i=n-1:r=n+1}return o}sampleFace(t,i,o,a,c){let d=this.randomFunction(),l=this.randomFunction();d+l>1&&(d=1-d,l=1-l);const b=this.indexAttribute;let h=3*t,f=3*t+1,m=3*t+2;return b&&(h=b.getX(h),f=b.getX(f),m=b.getX(m)),e.a.fromBufferAttribute(this.positionAttribute,h),e.b.fromBufferAttribute(this.positionAttribute,f),e.c.fromBufferAttribute(this.positionAttribute,m),i.set(0,0,0).addScaledVector(e.a,d).addScaledVector(e.b,l).addScaledVector(e.c,1-(d+l)),void 0!==o&&(void 0!==this.normalAttribute?(e.a.fromBufferAttribute(this.normalAttribute,h),e.b.fromBufferAttribute(this.normalAttribute,f),e.c.fromBufferAttribute(this.normalAttribute,m),o.set(0,0,0).addScaledVector(e.a,d).addScaledVector(e.b,l).addScaledVector(e.c,1-(d+l)).normalize()):e.getNormal(o)),void 0!==a&&void 0!==this.colorAttribute&&(e.a.fromBufferAttribute(this.colorAttribute,h),e.b.fromBufferAttribute(this.colorAttribute,f),e.c.fromBufferAttribute(this.colorAttribute,m),r.set(0,0,0).addScaledVector(e.a,d).addScaledVector(e.b,l).addScaledVector(e.c,1-(d+l)),a.r=r.x,a.g=r.y,a.b=r.z),void 0!==c&&void 0!==this.uvAttribute&&(n.fromBufferAttribute(this.uvAttribute,h),u.fromBufferAttribute(this.uvAttribute,f),s.fromBufferAttribute(this.uvAttribute,m),c.set(0,0).addScaledVector(n,d).addScaledVector(u,l).addScaledVector(s,1-(d+l))),this}}var c=new t.PointsMaterial({color:"black"}),d={numParticles:1e4},l=function(e,r,i){for(var o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:d,n=new t.InstancedMesh(r,i,o.numParticles),u=new t.Points(e,c),s=new a(u).build(),l=new t.Vector3,b=new t.Object3D,h=[],f=0;f<o.numParticles;f++)s.sample(l),h.push(l.clone()),b.position.set(l.x,l.y,l.z),b.scale.setScalar(.5*Math.random()+.5),b.updateMatrix(),n.setMatrixAt(f,b.matrix);return n}})(),o})()));