hz-particles 1.4.2 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -55,9 +55,12 @@ HZ editor (manual or prompt) → preset (JSON / .hzfx) → faithful WebGPU r
55
55
  - **GLB model support** — use 3D models as particle shapes, with automatic texture extraction
56
56
  - **Skeletal animations** — animated GLB models with full animation control
57
57
  - **20+ emitter shapes** — volumes & surfaces: sphere, cube, cylinder, cone, torus, capsule,
58
- frustum, hemisphere, disc, annulus, arc, spiral, polygon, `cubeSurface`, `sphereSurface`,
59
- `boxFrame`, and more
58
+ frustum, `frustumSurface`, hemisphere, disc, annulus, arc, spiral, polygon, `cubeSurface`,
59
+ `sphereSurface`, `boxFrame`, and more
60
+ - **Shape contour strokes** — render a textured ribbon along the full contour of planar emitters
61
+ (`circle`, `disc`, `annulus`, `arc`, `square`, `rectangle`, `plain`, `line`, `polygon`)
60
62
  - **Real-time physics** — gravity, attractors, drag, velocity, lifetime
63
+ - **Reverse attractors** — the same attractor API can repel away from a point (`reverse=true`)
61
64
  - **Particle orientation modes** — `billboard` (fixed/random/velocity-aligned), `oriented` (a fixed
62
65
  world angle via Euler `orientX/Y/Z`), and `cylindrical` (upright, faces the camera horizontally)
63
66
  - **Keyframe animation** — animate per-system parameters over time with curves + easing
@@ -291,7 +294,7 @@ Presets are plain `SceneData`. A few key per-system fields:
291
294
  | `particleCount` | `number` | Number of active particles |
292
295
  | `lifetime` | `number` | Particle lifetime in seconds |
293
296
  | `emissionRate` | `number` | Particles emitted per second |
294
- | `emissionShape` | `string` | Emitter shape (default `cube`). Volumes: `cube`/`box`, `sphere`, `cylinder`, `cone`, `torus`, `capsule`, `frustum`, `hemisphere`, `spiral`. Flat: `circle`, `square`, `rectangle`, `disc`, `annulus`, `arc`, `polygon`, `plain`, `line`. Surfaces: `cubeSurface`, `sphereSurface`, `boxFrame` |
297
+ | `emissionShape` | `string` | Emitter shape (default `cube`). Volumes: `cube`/`box`, `sphere`, `cylinder`, `cone`, `torus`, `capsule`, `frustum`, `hemisphere`, `spiral`. Flat: `circle`, `square`, `rectangle`, `disc`, `annulus`, `arc`, `polygon`, `plain`, `line`. Surfaces: `frustumSurface`, `cubeSurface`, `sphereSurface`, `boxFrame` |
295
298
  | `particleSize` | `number` | Base size of each particle |
296
299
  | `colors` | `string[]` | Hex colors interpolated over lifetime |
297
300
  | `fadeIn` | `number` | Opacity fade-in duration (0–1, fraction of lifetime) |
@@ -307,6 +310,11 @@ Presets are plain `SceneData`. A few key per-system fields:
307
310
  | `emissionTrailEnabled` | `boolean` | Enable particle trail rendering |
308
311
  | `emissionTrailDuration` | `number` | How long trail segments persist (seconds) |
309
312
  | `emissionTrailWidth` | `number` | Width of the emission trail |
313
+ | `shapeStrokeEnabled` | `boolean` | Draw a contour ribbon along supported emitter shapes |
314
+ | `shapeStrokeWidth` | `number` | World-space width of the contour ribbon |
315
+ | `shapeStrokeSegments` | `number` | Sampling resolution of the contour path |
316
+ | `shapeStrokeShape` | `string` | Stroke deformation: `straight`, `zigzag`, `sine`, `spiral` |
317
+ | `shapeStrokeAmplitude` / `shapeStrokeFrequency` / `shapeStrokeSpeed` | `number` | Stroke deformation amplitude, tiling frequency, and animation speed. In `straight`, `shapeStrokeSpeed` scrolls the stroke along the contour |
310
318
 
311
319
  `serializeSystemConfig(config)` is the single source of truth for the full set of serializable
312
320
  fields (used by `saveScene` and the editor's code export).
@@ -348,7 +356,7 @@ class ParticleSystem {
348
356
  | `updateParticles(deltaTime)` | Execute a physics simulation step on the GPU. |
349
357
  | `spawnParticles()` | Emit new particles according to emitter configuration. |
350
358
  | `setGravity(value)` | Set gravity strength (default `9.8`). |
351
- | `setAttractor(strength, position)` | Set an attractor point `[x, y, z]`. |
359
+ | `setAttractor(strength, position, reverse?)` | Set an attractor or repulsor point `[x, y, z]`. |
352
360
  | `render(renderPass)` | Render particles to the current render pass. |
353
361
 
354
362
  ### `ParticleSystemManager`
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("react"),Z=require("@react-three/fiber"),X=require("hz-particles"),K=require("react/jsx-runtime"),Q=require("three");function Y(r){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(r){for(const s in r)if(s!=="default"){const e=Object.getOwnPropertyDescriptor(r,s);Object.defineProperty(t,s,e.get?e:{enumerable:!0,get:()=>r[s]})}}return t.default=r,Object.freeze(t)}const p=Y(Q);function J(r,t){if(t===1)return r;const s=(e,u)=>e!=null?e*t:u*t;return{...r,systems:r.systems.map(e=>({...e,particleSize:s(e.particleSize,.5),minSize:e.minSize!=null?e.minSize*t:void 0,maxSize:e.maxSize!=null?e.maxSize*t:void 0,particleSpeed:(e.particleSpeed??1)*t,minSpeed:e.minSpeed!=null?e.minSpeed*t:void 0,maxSpeed:e.maxSpeed!=null?e.maxSpeed*t:void 0,cubeLength:e.cubeLength!=null?e.cubeLength*t:void 0,outerLength:e.outerLength!=null?e.outerLength*t:void 0,innerLength:e.innerLength!=null?e.innerLength*t:void 0,outerRadius:e.outerRadius!=null?e.outerRadius*t:void 0,innerRadius:e.innerRadius!=null?e.innerRadius*t:void 0,squareSize:e.squareSize!=null?e.squareSize*t:void 0,squareInnerSize:e.squareInnerSize!=null?e.squareInnerSize*t:void 0,circleInnerRadius:e.circleInnerRadius!=null?e.circleInnerRadius*t:void 0,circleOuterRadius:e.circleOuterRadius!=null?e.circleOuterRadius*t:void 0,cylinderInnerRadius:e.cylinderInnerRadius!=null?e.cylinderInnerRadius*t:void 0,cylinderOuterRadius:e.cylinderOuterRadius!=null?e.cylinderOuterRadius*t:void 0,cylinderHeight:e.cylinderHeight!=null?e.cylinderHeight*t:void 0,emissionTrailWidth:(e.emissionTrailWidth??.3)*t,emissionTrailDuration:(e.emissionTrailDuration??1)*t,emissionTrailMinDistance:e.emissionTrailMinDistance!=null?e.emissionTrailMinDistance*t:void 0,emissionTrailShapeAmplitude:e.emissionTrailShapeAmplitude!=null?e.emissionTrailShapeAmplitude*t:void 0}))}}function $({preset:r,positionRef:t,position:s=[0,0,0],scale:e=1,active:u=!0,renderPriority:w=1,noOcclusion:I=!1,respectReducedMotion:z=!0}){const R=c.useRef(null),g=c.useRef(null),T=c.useRef(!1),C=c.useRef(0),y=c.useRef(u);y.current=u;const P=c.useRef(s);P.current=s;const H=c.useRef(!1),q=c.useMemo(()=>e&&e!==1?J(r,e):r,[r,e]),V=i=>t?i.addMovingEmitter(q,{getPosition:()=>{const o=t.current;return y.current&&o?[o.x,o.y,o.z]:null}}):i.addEmitter(q,P.current);return c.useEffect(()=>{var l,m;const i=R.current;if(!i)return;let o=!1;return(m=(l=g.current)==null?void 0:l.remove)==null||m.call(l),g.current=null,V(i).then(d=>{var A;o?(A=d==null?void 0:d.remove)==null||A.call(d):g.current=d}),()=>{o=!0}},[q]),c.useEffect(()=>{var l;if(typeof window>"u"||!window.matchMedia)return;const i=window.matchMedia("(prefers-reduced-motion: reduce)"),o=()=>{H.current=i.matches};return o(),(l=i.addEventListener)==null||l.call(i,"change",o),()=>{var m;return(m=i.removeEventListener)==null?void 0:m.call(i,"change",o)}},[]),c.useEffect(()=>()=>{var i,o,l,m;(o=(i=g.current)==null?void 0:i.remove)==null||o.call(i),(m=(l=R.current)==null?void 0:l.destroy)==null||m.call(l),R.current=null,g.current=null,T.current=!1},[]),Z.useFrame(i=>{var n,f;i.gl.render(i.scene,i.camera);const o=performance.now(),l=C.current?Math.min(.05,(o-C.current)/1e3):.016;C.current=o;const m=i.gl,d=m.backend,A=(d==null?void 0:d.context)||((f=(n=m.domElement)==null?void 0:n.getContext)==null?void 0:f.call(n,"webgpu"));!R.current&&!T.current&&(d!=null&&d.device)&&A&&(T.current=!0,X.initHzFxOverlay({device:d.device,context:A,canvas:m.domElement},{getSceneDepth:I?()=>null:X.makeThreeSceneDepth(m)}).then(h=>(R.current=h,V(h))).then(h=>{g.current=h}).catch(h=>console.error("[HZFaithfulFX] init failed:",h)));const D=R.current;if(D){const h=i.camera;D.setCamera(h.projectionMatrix.elements,h.matrixWorldInverse.elements,h.position),z&&H.current||D.render(l)}},w),null}const ee=`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=require("react"),Z=require("@react-three/fiber"),N=require("hz-particles"),Q=require("react/jsx-runtime"),Y=require("three");function $(r){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(r){for(const l in r)if(l!=="default"){const e=Object.getOwnPropertyDescriptor(r,l);Object.defineProperty(t,l,e.get?e:{enumerable:!0,get:()=>r[l]})}}return t.default=r,Object.freeze(t)}const p=$(Y);function K(r,t){if(t===1)return r;const l=(e,o)=>e!=null?e*t:o*t;return{...r,systems:r.systems.map(e=>({...e,particleSize:l(e.particleSize,.5),minSize:e.minSize!=null?e.minSize*t:void 0,maxSize:e.maxSize!=null?e.maxSize*t:void 0,particleSpeed:(e.particleSpeed??1)*t,minSpeed:e.minSpeed!=null?e.minSpeed*t:void 0,maxSpeed:e.maxSpeed!=null?e.maxSpeed*t:void 0,cubeLength:e.cubeLength!=null?e.cubeLength*t:void 0,outerLength:e.outerLength!=null?e.outerLength*t:void 0,innerLength:e.innerLength!=null?e.innerLength*t:void 0,outerRadius:e.outerRadius!=null?e.outerRadius*t:void 0,innerRadius:e.innerRadius!=null?e.innerRadius*t:void 0,squareSize:e.squareSize!=null?e.squareSize*t:void 0,squareInnerSize:e.squareInnerSize!=null?e.squareInnerSize*t:void 0,circleInnerRadius:e.circleInnerRadius!=null?e.circleInnerRadius*t:void 0,circleOuterRadius:e.circleOuterRadius!=null?e.circleOuterRadius*t:void 0,cylinderInnerRadius:e.cylinderInnerRadius!=null?e.cylinderInnerRadius*t:void 0,cylinderOuterRadius:e.cylinderOuterRadius!=null?e.cylinderOuterRadius*t:void 0,cylinderHeight:e.cylinderHeight!=null?e.cylinderHeight*t:void 0,rectangleWidth:e.rectangleWidth!=null?e.rectangleWidth*t:void 0,rectangleHeight:e.rectangleHeight!=null?e.rectangleHeight*t:void 0,coneOuterRadius:e.coneOuterRadius!=null?e.coneOuterRadius*t:void 0,coneInnerRadius:e.coneInnerRadius!=null?e.coneInnerRadius*t:void 0,coneHeight:e.coneHeight!=null?e.coneHeight*t:void 0,torusMajorRadius:e.torusMajorRadius!=null?e.torusMajorRadius*t:void 0,torusMinorRadius:e.torusMinorRadius!=null?e.torusMinorRadius*t:void 0,lineLength:e.lineLength!=null?e.lineLength*t:void 0,hemisphereOuterRadius:e.hemisphereOuterRadius!=null?e.hemisphereOuterRadius*t:void 0,hemisphereInnerRadius:e.hemisphereInnerRadius!=null?e.hemisphereInnerRadius*t:void 0,discRadius:e.discRadius!=null?e.discRadius*t:void 0,annulusInnerRadius:e.annulusInnerRadius!=null?e.annulusInnerRadius*t:void 0,annulusOuterRadius:e.annulusOuterRadius!=null?e.annulusOuterRadius*t:void 0,capsuleRadius:e.capsuleRadius!=null?e.capsuleRadius*t:void 0,capsuleHeight:e.capsuleHeight!=null?e.capsuleHeight*t:void 0,arcInnerRadius:e.arcInnerRadius!=null?e.arcInnerRadius*t:void 0,arcOuterRadius:e.arcOuterRadius!=null?e.arcOuterRadius*t:void 0,spiralRadiusStart:e.spiralRadiusStart!=null?e.spiralRadiusStart*t:void 0,spiralRadiusEnd:e.spiralRadiusEnd!=null?e.spiralRadiusEnd*t:void 0,spiralHeight:e.spiralHeight!=null?e.spiralHeight*t:void 0,frustumRadiusNear:e.frustumRadiusNear!=null?e.frustumRadiusNear*t:void 0,frustumRadiusFar:e.frustumRadiusFar!=null?e.frustumRadiusFar*t:void 0,frustumHeight:e.frustumHeight!=null?e.frustumHeight*t:void 0,cubeSurfaceSize:e.cubeSurfaceSize!=null?e.cubeSurfaceSize*t:void 0,sphereSurfaceRadius:e.sphereSurfaceRadius!=null?e.sphereSurfaceRadius*t:void 0,boxFrameSize:e.boxFrameSize!=null?e.boxFrameSize*t:void 0,polygonRadius:e.polygonRadius!=null?e.polygonRadius*t:void 0,emissionTrailWidth:(e.emissionTrailWidth??.3)*t,emissionTrailDuration:(e.emissionTrailDuration??1)*t,emissionTrailMinDistance:e.emissionTrailMinDistance!=null?e.emissionTrailMinDistance*t:void 0,emissionTrailShapeAmplitude:e.emissionTrailShapeAmplitude!=null?e.emissionTrailShapeAmplitude*t:void 0,shapeStrokeWidth:e.shapeStrokeWidth!=null?e.shapeStrokeWidth*t:void 0,shapeStrokeAmplitude:e.shapeStrokeAmplitude!=null?e.shapeStrokeAmplitude*t:void 0}))}}function y({preset:r,positionRef:t,position:l=[0,0,0],scale:e=1,active:o=!0,renderPriority:z=1,noOcclusion:O=!1,respectReducedMotion:w=!0}){const v=d.useRef(null),g=d.useRef(null),A=d.useRef(!1),L=d.useRef(0),H=d.useRef(o);H.current=o;const C=d.useRef(l);C.current=l;const P=d.useRef(!1),q=d.useMemo(()=>e&&e!==1?K(r,e):r,[r,e]),V=i=>t?i.addMovingEmitter(q,{getPosition:()=>{const u=t.current;return H.current&&u?[u.x,u.y,u.z]:null}}):i.addEmitter(q,C.current);return d.useEffect(()=>{var c,m;const i=v.current;if(!i)return;let u=!1;return(m=(c=g.current)==null?void 0:c.remove)==null||m.call(c),g.current=null,V(i).then(s=>{var x;u?(x=s==null?void 0:s.remove)==null||x.call(s):g.current=s}),()=>{u=!0}},[q]),d.useEffect(()=>{var c;if(typeof window>"u"||!window.matchMedia)return;const i=window.matchMedia("(prefers-reduced-motion: reduce)"),u=()=>{P.current=i.matches};return u(),(c=i.addEventListener)==null||c.call(i,"change",u),()=>{var m;return(m=i.removeEventListener)==null?void 0:m.call(i,"change",u)}},[]),d.useEffect(()=>()=>{var i,u,c,m;(u=(i=g.current)==null?void 0:i.remove)==null||u.call(i),(m=(c=v.current)==null?void 0:c.destroy)==null||m.call(c),v.current=null,g.current=null,A.current=!1},[]),Z.useFrame(i=>{var n,h;i.gl.render(i.scene,i.camera);const u=performance.now(),c=L.current?Math.min(.05,(u-L.current)/1e3):.016;L.current=u;const m=i.gl,s=m.backend,x=(s==null?void 0:s.context)||((h=(n=m.domElement)==null?void 0:n.getContext)==null?void 0:h.call(n,"webgpu"));!v.current&&!A.current&&(s!=null&&s.device)&&x&&(A.current=!0,N.initHzFxOverlay({device:s.device,context:x,canvas:m.domElement},{getSceneDepth:O?()=>null:N.makeThreeSceneDepth(m)}).then(f=>(v.current=f,V(f))).then(f=>{g.current=f}).catch(f=>console.error("[HZFaithfulFX] init failed:",f)));const F=v.current;if(F){const f=i.camera;F.setCamera(f.projectionMatrix.elements,f.matrixWorldInverse.elements,f.position),w&&P.current||F.render(c)}},z),null}const ee=`
2
2
  attribute vec4 aColor;
3
3
  varying vec4 vColor;
4
4
  void main() {
@@ -10,4 +10,4 @@ varying vec4 vColor;
10
10
  void main() {
11
11
  gl_FragColor = vColor;
12
12
  }
13
- `;function ne({positionRef:r,duration:t=1,width:s=.3,color:e=[1,1,1],maxPoints:u=256,minDistance:w=.05,opacity:I=1,blending:z=p.AdditiveBlending,visible:R=!0}){const{camera:g}=Z.useThree(),T=c.useRef(null),C=c.useRef({positions:new Float32Array(u*3),times:new Float32Array(u),head:0,count:0,lastPos:new p.Vector3(1/0,1/0,1/0),elapsed:0}),{geometry:y,posAttr:P,colorAttr:H,indexBuf:q}=c.useMemo(()=>{const A=u*2,D=new Float32Array(A*3),n=new Float32Array(A*4),f=new p.BufferGeometry,h=new p.BufferAttribute(D,3);h.setUsage(p.DynamicDrawUsage),f.setAttribute("position",h);const x=new p.BufferAttribute(n,4);x.setUsage(p.DynamicDrawUsage),f.setAttribute("aColor",x);const b=(u-1)*6,v=new Uint32Array(b);for(let O=0;O<u-1;O++){const a=O*2,M=O*6;v[M]=a,v[M+1]=a+1,v[M+2]=a+2,v[M+3]=a+1,v[M+4]=a+3,v[M+5]=a+2}const E=new p.BufferAttribute(v,1);return f.setIndex(E),f.setDrawRange(0,0),{geometry:f,posAttr:h,colorAttr:x,indexBuf:E}},[u]),V=c.useMemo(()=>new p.ShaderMaterial({vertexShader:ee,fragmentShader:te,transparent:!0,depthWrite:!1,side:p.DoubleSide,blending:z}),[z]),i=c.useMemo(()=>new p.Vector3,[]),o=c.useMemo(()=>new p.Vector3,[]),l=c.useMemo(()=>new p.Vector3,[]),m=c.useMemo(()=>new p.Vector3(0,1,0),[]),d=c.useMemo(()=>new p.Vector3,[]);return Z.useFrame((A,D)=>{if(!T.current)return;const n=C.current;if(n.elapsed+=D,!R){n.count=0,n.head=0,n.lastPos.set(1/0,1/0,1/0),y.setDrawRange(0,0);return}const f=r.current;if(!f)return;if(n.lastPos.distanceTo(f)>=w){const a=(n.head+n.count)%u;n.positions[a*3]=f.x,n.positions[a*3+1]=f.y,n.positions[a*3+2]=f.z,n.times[a]=n.elapsed,n.count<u?n.count++:n.head=(n.head+1)%u,n.lastPos.copy(f)}for(;n.count>0;){const a=n.head;if(n.elapsed-n.times[a]>t)n.head=(n.head+1)%u,n.count--;else break}if(n.count<2){y.setDrawRange(0,0);return}const x=P.array,b=H.array;let v=null;const E=n.count;for(let a=0;a<E;a++){const M=(n.head+a)%u,j=n.positions[M*3],B=n.positions[M*3+1],U=n.positions[M*3+2],_=1-(n.elapsed-n.times[M])/t;if(a<E-1){const W=(n.head+a+1)%u;i.set(n.positions[W*3]-j,n.positions[W*3+1]-B,n.positions[W*3+2]-U);const N=i.length();N>1e-6?i.divideScalar(N):v&&i.copy(v)}else v&&i.copy(v);l.set(g.position.x-j,g.position.y-B,g.position.z-U),o.crossVectors(i,l);let L=o.length();L<1e-6&&(d.crossVectors(i,m),o.copy(d),L=o.length(),L<1e-6&&(o.set(1,0,0),L=1)),o.divideScalar(L);const F=s*_,G=I*_*_,S=a*2;x[S*3]=j+o.x*F,x[S*3+1]=B+o.y*F,x[S*3+2]=U+o.z*F,x[(S+1)*3]=j-o.x*F,x[(S+1)*3+1]=B-o.y*F,x[(S+1)*3+2]=U-o.z*F,b[S*4]=e[0],b[S*4+1]=e[1],b[S*4+2]=e[2],b[S*4+3]=G,b[(S+1)*4]=e[0],b[(S+1)*4+1]=e[1],b[(S+1)*4+2]=e[2],b[(S+1)*4+3]=G,v=v||new p.Vector3,v.copy(i)}const O=(E-1)*6;y.setDrawRange(0,O),P.needsUpdate=!0,H.needsUpdate=!0}),K.jsx("mesh",{ref:T,geometry:y,material:V,frustumCulled:!1,renderOrder:101,visible:R})}function k(r){return Math.abs(Math.sin(r*12.9898)*43758.5453)%1}function re(r){const t=Math.sin(r*54321.67)*43758.5453%1;return t<0?t+1:t}function ie(r,t,s,e){if(s<=0)return 0;const u=t/s;let w=r.particleSize??.5;if(r.randomSize){const z=r.minSize??.1,R=r.maxSize??.5;w=z+(R-z)*re(s)}const I=Math.max(.01,Math.min(10,r.sizeLifetimeSpeed??1));if(r.fadeSizeEnabled&&(w*=1-Math.pow(u,1/I)),r.increaseSizeEnabled&&(w*=1+Math.pow(u,1/I)),r.pulseEnabled){const z=r.pulseAmplitude??.5,R=r.pulseFrequency??1,T=(r.pulsePhaseRandom??0)*k(e)*Math.PI*2;w*=1+z*Math.sin(t*R*Math.PI*2+T)}return Math.max(0,w)}function oe(r,t,s,e){if(s<=0)return 0;let u=r.opacity??1;const w=t/s;if(r.fadeEnabled&&(u*=Math.max(0,1-w)),r.pulseEnabled&&r.pulseOpacity){const I=r.pulseAmplitude??.5,z=r.pulseFrequency??1,g=(r.pulsePhaseRandom??0)*k(e)*Math.PI*2;u*=Math.max(0,1+I*Math.sin(t*z*Math.PI*2+g))}return Math.max(0,Math.min(1,u))}Object.defineProperty(exports,"fetchPreset",{enumerable:!0,get:()=>X.fetchPreset});exports.HZFaithfulFX=$;exports.HZTrailRibbon=ne;exports.computeParticleOpacity=oe;exports.computeParticleSize=ie;exports.particleHash=k;exports.scalePreset=J;
13
+ `;function ne({positionRef:r,duration:t=1,width:l=.3,color:e=[1,1,1],maxPoints:o=256,minDistance:z=.05,opacity:O=1,blending:w=p.AdditiveBlending,visible:v=!0}){const{camera:g}=Z.useThree(),A=d.useRef(null),L=d.useRef({positions:new Float32Array(o*3),times:new Float32Array(o),head:0,count:0,lastPos:new p.Vector3(1/0,1/0,1/0),elapsed:0}),{geometry:H,posAttr:C,colorAttr:P,indexBuf:q}=d.useMemo(()=>{const x=o*2,F=new Float32Array(x*3),n=new Float32Array(x*4),h=new p.BufferGeometry,f=new p.BufferAttribute(F,3);f.setUsage(p.DynamicDrawUsage),h.setAttribute("position",f);const I=new p.BufferAttribute(n,4);I.setUsage(p.DynamicDrawUsage),h.setAttribute("aColor",I);const b=(o-1)*6,R=new Uint32Array(b);for(let T=0;T<o-1;T++){const a=T*2,M=T*6;R[M]=a,R[M+1]=a+1,R[M+2]=a+2,R[M+3]=a+1,R[M+4]=a+3,R[M+5]=a+2}const E=new p.BufferAttribute(R,1);return h.setIndex(E),h.setDrawRange(0,0),{geometry:h,posAttr:f,colorAttr:I,indexBuf:E}},[o]),V=d.useMemo(()=>new p.ShaderMaterial({vertexShader:ee,fragmentShader:te,transparent:!0,depthWrite:!1,side:p.DoubleSide,blending:w}),[w]),i=d.useMemo(()=>new p.Vector3,[]),u=d.useMemo(()=>new p.Vector3,[]),c=d.useMemo(()=>new p.Vector3,[]),m=d.useMemo(()=>new p.Vector3(0,1,0),[]),s=d.useMemo(()=>new p.Vector3,[]);return Z.useFrame((x,F)=>{if(!A.current)return;const n=L.current;if(n.elapsed+=F,!v){n.count=0,n.head=0,n.lastPos.set(1/0,1/0,1/0),H.setDrawRange(0,0);return}const h=r.current;if(!h)return;if(n.lastPos.distanceTo(h)>=z){const a=(n.head+n.count)%o;n.positions[a*3]=h.x,n.positions[a*3+1]=h.y,n.positions[a*3+2]=h.z,n.times[a]=n.elapsed,n.count<o?n.count++:n.head=(n.head+1)%o,n.lastPos.copy(h)}for(;n.count>0;){const a=n.head;if(n.elapsed-n.times[a]>t)n.head=(n.head+1)%o,n.count--;else break}if(n.count<2){H.setDrawRange(0,0);return}const I=C.array,b=P.array;let R=null;const E=n.count;for(let a=0;a<E;a++){const M=(n.head+a)%o,W=n.positions[M*3],B=n.positions[M*3+1],U=n.positions[M*3+2],k=1-(n.elapsed-n.times[M])/t;if(a<E-1){const _=(n.head+a+1)%o;i.set(n.positions[_*3]-W,n.positions[_*3+1]-B,n.positions[_*3+2]-U);const J=i.length();J>1e-6?i.divideScalar(J):R&&i.copy(R)}else R&&i.copy(R);c.set(g.position.x-W,g.position.y-B,g.position.z-U),u.crossVectors(i,c);let j=u.length();j<1e-6&&(s.crossVectors(i,m),u.copy(s),j=u.length(),j<1e-6&&(u.set(1,0,0),j=1)),u.divideScalar(j);const D=l*k,G=O*k*k,S=a*2;I[S*3]=W+u.x*D,I[S*3+1]=B+u.y*D,I[S*3+2]=U+u.z*D,I[(S+1)*3]=W-u.x*D,I[(S+1)*3+1]=B-u.y*D,I[(S+1)*3+2]=U-u.z*D,b[S*4]=e[0],b[S*4+1]=e[1],b[S*4+2]=e[2],b[S*4+3]=G,b[(S+1)*4]=e[0],b[(S+1)*4+1]=e[1],b[(S+1)*4+2]=e[2],b[(S+1)*4+3]=G,R=R||new p.Vector3,R.copy(i)}const T=(E-1)*6;H.setDrawRange(0,T),C.needsUpdate=!0,P.needsUpdate=!0}),Q.jsx("mesh",{ref:A,geometry:H,material:V,frustumCulled:!1,renderOrder:101,visible:v})}function X(r){return Math.abs(Math.sin(r*12.9898)*43758.5453)%1}function re(r){const t=Math.sin(r*54321.67)*43758.5453%1;return t<0?t+1:t}function ie(r,t,l,e){if(l<=0)return 0;const o=t/l;let z=r.particleSize??.5;if(r.randomSize){const w=r.minSize??.1,v=r.maxSize??.5;z=w+(v-w)*re(l)}const O=Math.max(.01,Math.min(10,r.sizeLifetimeSpeed??1));if(r.fadeSizeEnabled&&(z*=1-Math.pow(o,1/O)),r.increaseSizeEnabled&&(z*=1+Math.pow(o,1/O)),r.pulseEnabled){const w=r.pulseAmplitude??.5,v=r.pulseFrequency??1,A=(r.pulsePhaseRandom??0)*X(e)*Math.PI*2;z*=1+w*Math.sin(t*v*Math.PI*2+A)}return Math.max(0,z)}function ue(r,t,l,e){if(l<=0)return 0;let o=r.opacity??1;const z=t/l;if(r.fadeEnabled&&(o*=Math.max(0,1-z)),r.pulseEnabled&&r.pulseOpacity){const O=r.pulseAmplitude??.5,w=r.pulseFrequency??1,g=(r.pulsePhaseRandom??0)*X(e)*Math.PI*2;o*=Math.max(0,1+O*Math.sin(t*w*Math.PI*2+g))}return Math.max(0,Math.min(1,o))}Object.defineProperty(exports,"fetchPreset",{enumerable:!0,get:()=>N.fetchPreset});exports.HZFaithfulFX=y;exports.HZTrailRibbon=ne;exports.computeParticleOpacity=ue;exports.computeParticleSize=ie;exports.particleHash=X;exports.scalePreset=K;
@@ -1,110 +1,139 @@
1
- import { useRef as I, useMemo as b, useEffect as X } from "react";
2
- import { useFrame as J, useThree as N } from "@react-three/fiber";
3
- import { initHzFxOverlay as Q, makeThreeSceneDepth as Y } from "hz-particles";
4
- import { fetchPreset as he } from "hz-particles";
5
- import { jsx as $ } from "react/jsx-runtime";
6
- import * as s from "three";
7
- function ee(r, n) {
8
- if (n === 1) return r;
9
- const S = (e, a) => e != null ? e * n : a * n;
1
+ import { useRef as A, useMemo as O, useEffect as _ } from "react";
2
+ import { useFrame as J, useThree as Q } from "@react-three/fiber";
3
+ import { initHzFxOverlay as Y, makeThreeSceneDepth as $ } from "hz-particles";
4
+ import { fetchPreset as fe } from "hz-particles";
5
+ import { jsx as y } from "react/jsx-runtime";
6
+ import * as c from "three";
7
+ function ee(r, t) {
8
+ if (t === 1) return r;
9
+ const v = (e, o) => e != null ? e * t : o * t;
10
10
  return {
11
11
  ...r,
12
12
  systems: r.systems.map((e) => ({
13
13
  ...e,
14
14
  // Particle visual size
15
- particleSize: S(e.particleSize, 0.5),
16
- minSize: e.minSize != null ? e.minSize * n : void 0,
17
- maxSize: e.maxSize != null ? e.maxSize * n : void 0,
15
+ particleSize: v(e.particleSize, 0.5),
16
+ minSize: e.minSize != null ? e.minSize * t : void 0,
17
+ maxSize: e.maxSize != null ? e.maxSize * t : void 0,
18
18
  // Speed
19
- particleSpeed: (e.particleSpeed ?? 1) * n,
20
- minSpeed: e.minSpeed != null ? e.minSpeed * n : void 0,
21
- maxSpeed: e.maxSpeed != null ? e.maxSpeed * n : void 0,
19
+ particleSpeed: (e.particleSpeed ?? 1) * t,
20
+ minSpeed: e.minSpeed != null ? e.minSpeed * t : void 0,
21
+ maxSpeed: e.maxSpeed != null ? e.maxSpeed * t : void 0,
22
22
  // Emission shape dimensions
23
- cubeLength: e.cubeLength != null ? e.cubeLength * n : void 0,
24
- outerLength: e.outerLength != null ? e.outerLength * n : void 0,
25
- innerLength: e.innerLength != null ? e.innerLength * n : void 0,
26
- outerRadius: e.outerRadius != null ? e.outerRadius * n : void 0,
27
- innerRadius: e.innerRadius != null ? e.innerRadius * n : void 0,
28
- squareSize: e.squareSize != null ? e.squareSize * n : void 0,
29
- squareInnerSize: e.squareInnerSize != null ? e.squareInnerSize * n : void 0,
30
- circleInnerRadius: e.circleInnerRadius != null ? e.circleInnerRadius * n : void 0,
31
- circleOuterRadius: e.circleOuterRadius != null ? e.circleOuterRadius * n : void 0,
32
- cylinderInnerRadius: e.cylinderInnerRadius != null ? e.cylinderInnerRadius * n : void 0,
33
- cylinderOuterRadius: e.cylinderOuterRadius != null ? e.cylinderOuterRadius * n : void 0,
34
- cylinderHeight: e.cylinderHeight != null ? e.cylinderHeight * n : void 0,
23
+ cubeLength: e.cubeLength != null ? e.cubeLength * t : void 0,
24
+ outerLength: e.outerLength != null ? e.outerLength * t : void 0,
25
+ innerLength: e.innerLength != null ? e.innerLength * t : void 0,
26
+ outerRadius: e.outerRadius != null ? e.outerRadius * t : void 0,
27
+ innerRadius: e.innerRadius != null ? e.innerRadius * t : void 0,
28
+ squareSize: e.squareSize != null ? e.squareSize * t : void 0,
29
+ squareInnerSize: e.squareInnerSize != null ? e.squareInnerSize * t : void 0,
30
+ circleInnerRadius: e.circleInnerRadius != null ? e.circleInnerRadius * t : void 0,
31
+ circleOuterRadius: e.circleOuterRadius != null ? e.circleOuterRadius * t : void 0,
32
+ cylinderInnerRadius: e.cylinderInnerRadius != null ? e.cylinderInnerRadius * t : void 0,
33
+ cylinderOuterRadius: e.cylinderOuterRadius != null ? e.cylinderOuterRadius * t : void 0,
34
+ cylinderHeight: e.cylinderHeight != null ? e.cylinderHeight * t : void 0,
35
+ rectangleWidth: e.rectangleWidth != null ? e.rectangleWidth * t : void 0,
36
+ rectangleHeight: e.rectangleHeight != null ? e.rectangleHeight * t : void 0,
37
+ coneOuterRadius: e.coneOuterRadius != null ? e.coneOuterRadius * t : void 0,
38
+ coneInnerRadius: e.coneInnerRadius != null ? e.coneInnerRadius * t : void 0,
39
+ coneHeight: e.coneHeight != null ? e.coneHeight * t : void 0,
40
+ torusMajorRadius: e.torusMajorRadius != null ? e.torusMajorRadius * t : void 0,
41
+ torusMinorRadius: e.torusMinorRadius != null ? e.torusMinorRadius * t : void 0,
42
+ lineLength: e.lineLength != null ? e.lineLength * t : void 0,
43
+ hemisphereOuterRadius: e.hemisphereOuterRadius != null ? e.hemisphereOuterRadius * t : void 0,
44
+ hemisphereInnerRadius: e.hemisphereInnerRadius != null ? e.hemisphereInnerRadius * t : void 0,
45
+ discRadius: e.discRadius != null ? e.discRadius * t : void 0,
46
+ annulusInnerRadius: e.annulusInnerRadius != null ? e.annulusInnerRadius * t : void 0,
47
+ annulusOuterRadius: e.annulusOuterRadius != null ? e.annulusOuterRadius * t : void 0,
48
+ capsuleRadius: e.capsuleRadius != null ? e.capsuleRadius * t : void 0,
49
+ capsuleHeight: e.capsuleHeight != null ? e.capsuleHeight * t : void 0,
50
+ arcInnerRadius: e.arcInnerRadius != null ? e.arcInnerRadius * t : void 0,
51
+ arcOuterRadius: e.arcOuterRadius != null ? e.arcOuterRadius * t : void 0,
52
+ spiralRadiusStart: e.spiralRadiusStart != null ? e.spiralRadiusStart * t : void 0,
53
+ spiralRadiusEnd: e.spiralRadiusEnd != null ? e.spiralRadiusEnd * t : void 0,
54
+ spiralHeight: e.spiralHeight != null ? e.spiralHeight * t : void 0,
55
+ frustumRadiusNear: e.frustumRadiusNear != null ? e.frustumRadiusNear * t : void 0,
56
+ frustumRadiusFar: e.frustumRadiusFar != null ? e.frustumRadiusFar * t : void 0,
57
+ frustumHeight: e.frustumHeight != null ? e.frustumHeight * t : void 0,
58
+ cubeSurfaceSize: e.cubeSurfaceSize != null ? e.cubeSurfaceSize * t : void 0,
59
+ sphereSurfaceRadius: e.sphereSurfaceRadius != null ? e.sphereSurfaceRadius * t : void 0,
60
+ boxFrameSize: e.boxFrameSize != null ? e.boxFrameSize * t : void 0,
61
+ polygonRadius: e.polygonRadius != null ? e.polygonRadius * t : void 0,
35
62
  // Trail
36
- emissionTrailWidth: (e.emissionTrailWidth ?? 0.3) * n,
37
- emissionTrailDuration: (e.emissionTrailDuration ?? 1) * n,
38
- emissionTrailMinDistance: e.emissionTrailMinDistance != null ? e.emissionTrailMinDistance * n : void 0,
39
- emissionTrailShapeAmplitude: e.emissionTrailShapeAmplitude != null ? e.emissionTrailShapeAmplitude * n : void 0
63
+ emissionTrailWidth: (e.emissionTrailWidth ?? 0.3) * t,
64
+ emissionTrailDuration: (e.emissionTrailDuration ?? 1) * t,
65
+ emissionTrailMinDistance: e.emissionTrailMinDistance != null ? e.emissionTrailMinDistance * t : void 0,
66
+ emissionTrailShapeAmplitude: e.emissionTrailShapeAmplitude != null ? e.emissionTrailShapeAmplitude * t : void 0,
67
+ shapeStrokeWidth: e.shapeStrokeWidth != null ? e.shapeStrokeWidth * t : void 0,
68
+ shapeStrokeAmplitude: e.shapeStrokeAmplitude != null ? e.shapeStrokeAmplitude * t : void 0
40
69
  }))
41
70
  };
42
71
  }
43
- function de({
72
+ function le({
44
73
  preset: r,
45
- positionRef: n,
46
- position: S = [0, 0, 0],
74
+ positionRef: t,
75
+ position: v = [0, 0, 0],
47
76
  scale: e = 1,
48
- active: a = !0,
49
- renderPriority: g = 1,
50
- noOcclusion: T = !1,
51
- respectReducedMotion: x = !0
77
+ active: o = !0,
78
+ renderPriority: z = 1,
79
+ noOcclusion: H = !1,
80
+ respectReducedMotion: I = !0
52
81
  }) {
53
- const h = I(null), R = I(null), D = I(!1), V = I(0), C = I(a);
54
- C.current = a;
55
- const H = I(S);
56
- H.current = S;
57
- const O = I(!1), U = b(
82
+ const f = A(null), S = A(null), b = A(!1), C = A(0), F = A(o);
83
+ F.current = o;
84
+ const V = A(v);
85
+ V.current = v;
86
+ const W = A(!1), U = O(
58
87
  () => e && e !== 1 ? ee(r, e) : r,
59
88
  [r, e]
60
- ), q = (i) => n ? i.addMovingEmitter(U, {
89
+ ), q = (i) => t ? i.addMovingEmitter(U, {
61
90
  getPosition: () => {
62
- const o = n.current;
63
- return C.current && o ? [o.x, o.y, o.z] : null;
91
+ const u = t.current;
92
+ return F.current && u ? [u.x, u.y, u.z] : null;
64
93
  }
65
- }) : i.addEmitter(U, H.current);
66
- return X(() => {
67
- var c, l;
68
- const i = h.current;
94
+ }) : i.addEmitter(U, V.current);
95
+ return _(() => {
96
+ var d, p;
97
+ const i = f.current;
69
98
  if (!i) return;
70
- let o = !1;
71
- return (l = (c = R.current) == null ? void 0 : c.remove) == null || l.call(c), R.current = null, q(i).then((d) => {
72
- var A;
73
- o ? (A = d == null ? void 0 : d.remove) == null || A.call(d) : R.current = d;
99
+ let u = !1;
100
+ return (p = (d = S.current) == null ? void 0 : d.remove) == null || p.call(d), S.current = null, q(i).then((l) => {
101
+ var x;
102
+ u ? (x = l == null ? void 0 : l.remove) == null || x.call(l) : S.current = l;
74
103
  }), () => {
75
- o = !0;
104
+ u = !0;
76
105
  };
77
- }, [U]), X(() => {
78
- var c;
106
+ }, [U]), _(() => {
107
+ var d;
79
108
  if (typeof window > "u" || !window.matchMedia) return;
80
- const i = window.matchMedia("(prefers-reduced-motion: reduce)"), o = () => {
81
- O.current = i.matches;
109
+ const i = window.matchMedia("(prefers-reduced-motion: reduce)"), u = () => {
110
+ W.current = i.matches;
82
111
  };
83
- return o(), (c = i.addEventListener) == null || c.call(i, "change", o), () => {
84
- var l;
85
- return (l = i.removeEventListener) == null ? void 0 : l.call(i, "change", o);
112
+ return u(), (d = i.addEventListener) == null || d.call(i, "change", u), () => {
113
+ var p;
114
+ return (p = i.removeEventListener) == null ? void 0 : p.call(i, "change", u);
86
115
  };
87
- }, []), X(() => () => {
88
- var i, o, c, l;
89
- (o = (i = R.current) == null ? void 0 : i.remove) == null || o.call(i), (l = (c = h.current) == null ? void 0 : c.destroy) == null || l.call(c), h.current = null, R.current = null, D.current = !1;
116
+ }, []), _(() => () => {
117
+ var i, u, d, p;
118
+ (u = (i = S.current) == null ? void 0 : i.remove) == null || u.call(i), (p = (d = f.current) == null ? void 0 : d.destroy) == null || p.call(d), f.current = null, S.current = null, b.current = !1;
90
119
  }, []), J((i) => {
91
- var t, p;
120
+ var n, s;
92
121
  i.gl.render(i.scene, i.camera);
93
- const o = performance.now(), c = V.current ? Math.min(0.05, (o - V.current) / 1e3) : 0.016;
94
- V.current = o;
95
- const l = i.gl, d = l.backend, A = (d == null ? void 0 : d.context) || ((p = (t = l.domElement) == null ? void 0 : t.getContext) == null ? void 0 : p.call(t, "webgpu"));
96
- !h.current && !D.current && (d != null && d.device) && A && (D.current = !0, Q(
97
- { device: d.device, context: A, canvas: l.domElement },
98
- { getSceneDepth: T ? () => null : Y(l) }
99
- ).then((m) => (h.current = m, q(m))).then((m) => {
100
- R.current = m;
122
+ const u = performance.now(), d = C.current ? Math.min(0.05, (u - C.current) / 1e3) : 0.016;
123
+ C.current = u;
124
+ const p = i.gl, l = p.backend, x = (l == null ? void 0 : l.context) || ((s = (n = p.domElement) == null ? void 0 : n.getContext) == null ? void 0 : s.call(n, "webgpu"));
125
+ !f.current && !b.current && (l != null && l.device) && x && (b.current = !0, Y(
126
+ { device: l.device, context: x, canvas: p.domElement },
127
+ { getSceneDepth: H ? () => null : $(p) }
128
+ ).then((m) => (f.current = m, q(m))).then((m) => {
129
+ S.current = m;
101
130
  }).catch((m) => console.error("[HZFaithfulFX] init failed:", m)));
102
- const E = h.current;
131
+ const E = f.current;
103
132
  if (E) {
104
133
  const m = i.camera;
105
- E.setCamera(m.projectionMatrix.elements, m.matrixWorldInverse.elements, m.position), x && O.current || E.render(c);
134
+ E.setCamera(m.projectionMatrix.elements, m.matrixWorldInverse.elements, m.position), I && W.current || E.render(d);
106
135
  }
107
- }, g), null;
136
+ }, z), null;
108
137
  }
109
138
  const te = (
110
139
  /* glsl */
@@ -125,104 +154,104 @@ void main() {
125
154
  }
126
155
  `
127
156
  );
128
- function se({
157
+ function ce({
129
158
  positionRef: r,
130
- duration: n = 1,
131
- width: S = 0.3,
159
+ duration: t = 1,
160
+ width: v = 0.3,
132
161
  color: e = [1, 1, 1],
133
- maxPoints: a = 256,
134
- minDistance: g = 0.05,
135
- opacity: T = 1,
136
- blending: x = s.AdditiveBlending,
137
- visible: h = !0
162
+ maxPoints: o = 256,
163
+ minDistance: z = 0.05,
164
+ opacity: H = 1,
165
+ blending: I = c.AdditiveBlending,
166
+ visible: f = !0
138
167
  }) {
139
- const { camera: R } = N(), D = I(null), V = I({
140
- positions: new Float32Array(a * 3),
141
- times: new Float32Array(a),
168
+ const { camera: S } = Q(), b = A(null), C = A({
169
+ positions: new Float32Array(o * 3),
170
+ times: new Float32Array(o),
142
171
  head: 0,
143
172
  count: 0,
144
- lastPos: new s.Vector3(1 / 0, 1 / 0, 1 / 0),
173
+ lastPos: new c.Vector3(1 / 0, 1 / 0, 1 / 0),
145
174
  elapsed: 0
146
- }), { geometry: C, posAttr: H, colorAttr: O, indexBuf: U } = b(() => {
147
- const A = a * 2, E = new Float32Array(A * 3), t = new Float32Array(A * 4), p = new s.BufferGeometry(), m = new s.BufferAttribute(E, 3);
148
- m.setUsage(s.DynamicDrawUsage), p.setAttribute("position", m);
149
- const z = new s.BufferAttribute(t, 4);
150
- z.setUsage(s.DynamicDrawUsage), p.setAttribute("aColor", z);
151
- const M = (a - 1) * 6, f = new Uint32Array(M);
152
- for (let y = 0; y < a - 1; y++) {
153
- const u = y * 2, w = y * 6;
154
- f[w] = u, f[w + 1] = u + 1, f[w + 2] = u + 2, f[w + 3] = u + 1, f[w + 4] = u + 3, f[w + 5] = u + 2;
175
+ }), { geometry: F, posAttr: V, colorAttr: W, indexBuf: U } = O(() => {
176
+ const x = o * 2, E = new Float32Array(x * 3), n = new Float32Array(x * 4), s = new c.BufferGeometry(), m = new c.BufferAttribute(E, 3);
177
+ m.setUsage(c.DynamicDrawUsage), s.setAttribute("position", m);
178
+ const M = new c.BufferAttribute(n, 4);
179
+ M.setUsage(c.DynamicDrawUsage), s.setAttribute("aColor", M);
180
+ const w = (o - 1) * 6, h = new Uint32Array(w);
181
+ for (let D = 0; D < o - 1; D++) {
182
+ const a = D * 2, g = D * 6;
183
+ h[g] = a, h[g + 1] = a + 1, h[g + 2] = a + 2, h[g + 3] = a + 1, h[g + 4] = a + 3, h[g + 5] = a + 2;
155
184
  }
156
- const F = new s.BufferAttribute(f, 1);
157
- return p.setIndex(F), p.setDrawRange(0, 0), { geometry: p, posAttr: m, colorAttr: z, indexBuf: F };
158
- }, [a]), q = b(() => new s.ShaderMaterial({
185
+ const T = new c.BufferAttribute(h, 1);
186
+ return s.setIndex(T), s.setDrawRange(0, 0), { geometry: s, posAttr: m, colorAttr: M, indexBuf: T };
187
+ }, [o]), q = O(() => new c.ShaderMaterial({
159
188
  vertexShader: te,
160
189
  fragmentShader: ne,
161
190
  transparent: !0,
162
191
  depthWrite: !1,
163
- side: s.DoubleSide,
164
- blending: x
165
- }), [x]), i = b(() => new s.Vector3(), []), o = b(() => new s.Vector3(), []), c = b(() => new s.Vector3(), []), l = b(() => new s.Vector3(0, 1, 0), []), d = b(() => new s.Vector3(), []);
166
- return J((A, E) => {
167
- if (!D.current) return;
168
- const t = V.current;
169
- if (t.elapsed += E, !h) {
170
- t.count = 0, t.head = 0, t.lastPos.set(1 / 0, 1 / 0, 1 / 0), C.setDrawRange(0, 0);
192
+ side: c.DoubleSide,
193
+ blending: I
194
+ }), [I]), i = O(() => new c.Vector3(), []), u = O(() => new c.Vector3(), []), d = O(() => new c.Vector3(), []), p = O(() => new c.Vector3(0, 1, 0), []), l = O(() => new c.Vector3(), []);
195
+ return J((x, E) => {
196
+ if (!b.current) return;
197
+ const n = C.current;
198
+ if (n.elapsed += E, !f) {
199
+ n.count = 0, n.head = 0, n.lastPos.set(1 / 0, 1 / 0, 1 / 0), F.setDrawRange(0, 0);
171
200
  return;
172
201
  }
173
- const p = r.current;
174
- if (!p) return;
175
- if (t.lastPos.distanceTo(p) >= g) {
176
- const u = (t.head + t.count) % a;
177
- t.positions[u * 3] = p.x, t.positions[u * 3 + 1] = p.y, t.positions[u * 3 + 2] = p.z, t.times[u] = t.elapsed, t.count < a ? t.count++ : t.head = (t.head + 1) % a, t.lastPos.copy(p);
202
+ const s = r.current;
203
+ if (!s) return;
204
+ if (n.lastPos.distanceTo(s) >= z) {
205
+ const a = (n.head + n.count) % o;
206
+ n.positions[a * 3] = s.x, n.positions[a * 3 + 1] = s.y, n.positions[a * 3 + 2] = s.z, n.times[a] = n.elapsed, n.count < o ? n.count++ : n.head = (n.head + 1) % o, n.lastPos.copy(s);
178
207
  }
179
- for (; t.count > 0; ) {
180
- const u = t.head;
181
- if (t.elapsed - t.times[u] > n)
182
- t.head = (t.head + 1) % a, t.count--;
208
+ for (; n.count > 0; ) {
209
+ const a = n.head;
210
+ if (n.elapsed - n.times[a] > t)
211
+ n.head = (n.head + 1) % o, n.count--;
183
212
  else
184
213
  break;
185
214
  }
186
- if (t.count < 2) {
187
- C.setDrawRange(0, 0);
215
+ if (n.count < 2) {
216
+ F.setDrawRange(0, 0);
188
217
  return;
189
218
  }
190
- const z = H.array, M = O.array;
191
- let f = null;
192
- const F = t.count;
193
- for (let u = 0; u < F; u++) {
194
- const w = (t.head + u) % a, P = t.positions[w * 3], W = t.positions[w * 3 + 1], j = t.positions[w * 3 + 2], Z = 1 - (t.elapsed - t.times[w]) / n;
195
- if (u < F - 1) {
196
- const _ = (t.head + u + 1) % a;
219
+ const M = V.array, w = W.array;
220
+ let h = null;
221
+ const T = n.count;
222
+ for (let a = 0; a < T; a++) {
223
+ const g = (n.head + a) % o, j = n.positions[g * 3], k = n.positions[g * 3 + 1], P = n.positions[g * 3 + 2], N = 1 - (n.elapsed - n.times[g]) / t;
224
+ if (a < T - 1) {
225
+ const Z = (n.head + a + 1) % o;
197
226
  i.set(
198
- t.positions[_ * 3] - P,
199
- t.positions[_ * 3 + 1] - W,
200
- t.positions[_ * 3 + 2] - j
227
+ n.positions[Z * 3] - j,
228
+ n.positions[Z * 3 + 1] - k,
229
+ n.positions[Z * 3 + 2] - P
201
230
  );
202
- const k = i.length();
203
- k > 1e-6 ? i.divideScalar(k) : f && i.copy(f);
204
- } else f && i.copy(f);
205
- c.set(
206
- R.position.x - P,
207
- R.position.y - W,
208
- R.position.z - j
209
- ), o.crossVectors(i, c);
210
- let B = o.length();
211
- B < 1e-6 && (d.crossVectors(i, l), o.copy(d), B = o.length(), B < 1e-6 && (o.set(1, 0, 0), B = 1)), o.divideScalar(B);
212
- const L = S * Z, G = T * Z * Z, v = u * 2;
213
- z[v * 3] = P + o.x * L, z[v * 3 + 1] = W + o.y * L, z[v * 3 + 2] = j + o.z * L, z[(v + 1) * 3] = P - o.x * L, z[(v + 1) * 3 + 1] = W - o.y * L, z[(v + 1) * 3 + 2] = j - o.z * L, M[v * 4] = e[0], M[v * 4 + 1] = e[1], M[v * 4 + 2] = e[2], M[v * 4 + 3] = G, M[(v + 1) * 4] = e[0], M[(v + 1) * 4 + 1] = e[1], M[(v + 1) * 4 + 2] = e[2], M[(v + 1) * 4 + 3] = G, f = f || new s.Vector3(), f.copy(i);
231
+ const G = i.length();
232
+ G > 1e-6 ? i.divideScalar(G) : h && i.copy(h);
233
+ } else h && i.copy(h);
234
+ d.set(
235
+ S.position.x - j,
236
+ S.position.y - k,
237
+ S.position.z - P
238
+ ), u.crossVectors(i, d);
239
+ let B = u.length();
240
+ B < 1e-6 && (l.crossVectors(i, p), u.copy(l), B = u.length(), B < 1e-6 && (u.set(1, 0, 0), B = 1)), u.divideScalar(B);
241
+ const L = v * N, X = H * N * N, R = a * 2;
242
+ M[R * 3] = j + u.x * L, M[R * 3 + 1] = k + u.y * L, M[R * 3 + 2] = P + u.z * L, M[(R + 1) * 3] = j - u.x * L, M[(R + 1) * 3 + 1] = k - u.y * L, M[(R + 1) * 3 + 2] = P - u.z * L, w[R * 4] = e[0], w[R * 4 + 1] = e[1], w[R * 4 + 2] = e[2], w[R * 4 + 3] = X, w[(R + 1) * 4] = e[0], w[(R + 1) * 4 + 1] = e[1], w[(R + 1) * 4 + 2] = e[2], w[(R + 1) * 4 + 3] = X, h = h || new c.Vector3(), h.copy(i);
214
243
  }
215
- const y = (F - 1) * 6;
216
- C.setDrawRange(0, y), H.needsUpdate = !0, O.needsUpdate = !0;
217
- }), /* @__PURE__ */ $(
244
+ const D = (T - 1) * 6;
245
+ F.setDrawRange(0, D), V.needsUpdate = !0, W.needsUpdate = !0;
246
+ }), /* @__PURE__ */ y(
218
247
  "mesh",
219
248
  {
220
- ref: D,
221
- geometry: C,
249
+ ref: b,
250
+ geometry: F,
222
251
  material: q,
223
252
  frustumCulled: !1,
224
253
  renderOrder: 101,
225
- visible: h
254
+ visible: f
226
255
  }
227
256
  );
228
257
  }
@@ -230,40 +259,40 @@ function K(r) {
230
259
  return Math.abs(Math.sin(r * 12.9898) * 43758.5453) % 1;
231
260
  }
232
261
  function re(r) {
233
- const n = Math.sin(r * 54321.67) * 43758.5453 % 1;
234
- return n < 0 ? n + 1 : n;
262
+ const t = Math.sin(r * 54321.67) * 43758.5453 % 1;
263
+ return t < 0 ? t + 1 : t;
235
264
  }
236
- function le(r, n, S, e) {
237
- if (S <= 0) return 0;
238
- const a = n / S;
239
- let g = r.particleSize ?? 0.5;
265
+ function pe(r, t, v, e) {
266
+ if (v <= 0) return 0;
267
+ const o = t / v;
268
+ let z = r.particleSize ?? 0.5;
240
269
  if (r.randomSize) {
241
- const x = r.minSize ?? 0.1, h = r.maxSize ?? 0.5;
242
- g = x + (h - x) * re(S);
270
+ const I = r.minSize ?? 0.1, f = r.maxSize ?? 0.5;
271
+ z = I + (f - I) * re(v);
243
272
  }
244
- const T = Math.max(0.01, Math.min(10, r.sizeLifetimeSpeed ?? 1));
245
- if (r.fadeSizeEnabled && (g *= 1 - Math.pow(a, 1 / T)), r.increaseSizeEnabled && (g *= 1 + Math.pow(a, 1 / T)), r.pulseEnabled) {
246
- const x = r.pulseAmplitude ?? 0.5, h = r.pulseFrequency ?? 1, D = (r.pulsePhaseRandom ?? 0) * K(e) * Math.PI * 2;
247
- g *= 1 + x * Math.sin(n * h * Math.PI * 2 + D);
273
+ const H = Math.max(0.01, Math.min(10, r.sizeLifetimeSpeed ?? 1));
274
+ if (r.fadeSizeEnabled && (z *= 1 - Math.pow(o, 1 / H)), r.increaseSizeEnabled && (z *= 1 + Math.pow(o, 1 / H)), r.pulseEnabled) {
275
+ const I = r.pulseAmplitude ?? 0.5, f = r.pulseFrequency ?? 1, b = (r.pulsePhaseRandom ?? 0) * K(e) * Math.PI * 2;
276
+ z *= 1 + I * Math.sin(t * f * Math.PI * 2 + b);
248
277
  }
249
- return Math.max(0, g);
278
+ return Math.max(0, z);
250
279
  }
251
- function pe(r, n, S, e) {
252
- if (S <= 0) return 0;
253
- let a = r.opacity ?? 1;
254
- const g = n / S;
255
- if (r.fadeEnabled && (a *= Math.max(0, 1 - g)), r.pulseEnabled && r.pulseOpacity) {
256
- const T = r.pulseAmplitude ?? 0.5, x = r.pulseFrequency ?? 1, R = (r.pulsePhaseRandom ?? 0) * K(e) * Math.PI * 2;
257
- a *= Math.max(0, 1 + T * Math.sin(n * x * Math.PI * 2 + R));
280
+ function se(r, t, v, e) {
281
+ if (v <= 0) return 0;
282
+ let o = r.opacity ?? 1;
283
+ const z = t / v;
284
+ if (r.fadeEnabled && (o *= Math.max(0, 1 - z)), r.pulseEnabled && r.pulseOpacity) {
285
+ const H = r.pulseAmplitude ?? 0.5, I = r.pulseFrequency ?? 1, S = (r.pulsePhaseRandom ?? 0) * K(e) * Math.PI * 2;
286
+ o *= Math.max(0, 1 + H * Math.sin(t * I * Math.PI * 2 + S));
258
287
  }
259
- return Math.max(0, Math.min(1, a));
288
+ return Math.max(0, Math.min(1, o));
260
289
  }
261
290
  export {
262
- de as HZFaithfulFX,
263
- se as HZTrailRibbon,
264
- pe as computeParticleOpacity,
265
- le as computeParticleSize,
266
- he as fetchPreset,
291
+ le as HZFaithfulFX,
292
+ ce as HZTrailRibbon,
293
+ se as computeParticleOpacity,
294
+ pe as computeParticleSize,
295
+ fe as fetchPreset,
267
296
  K as particleHash,
268
297
  ee as scalePreset
269
298
  };