@hology/core 0.0.180 → 0.0.182

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.
@@ -80,4 +80,16 @@ export declare class MoveOverLife extends Behaviour {
80
80
  initialize(particle: Particle): void;
81
81
  mutate(target: Particle | Emitter, time: number, index: number): void;
82
82
  }
83
+ export declare class AnimationBehavior extends Behaviour {
84
+ private clip;
85
+ private timeScale;
86
+ private weight;
87
+ private loop;
88
+ private clampWhenFinished;
89
+ private mixer;
90
+ private action;
91
+ constructor(clip: THREE.AnimationClip, timeScale?: number, weight?: number, loop?: THREE.AnimationActionLoopStyles, clampWhenFinished?: boolean, easing?: EasingFunction);
92
+ initialize(particle: Particle): void;
93
+ mutate(target: Particle | Emitter, time: number, index: number): void;
94
+ }
83
95
  //# sourceMappingURL=behaviours.d.ts.map
@@ -1,4 +1,4 @@
1
- import{Vector3 as t}from"three";import{Behaviour as i,Vector3D as s,ease as e,MathUtils as o}from"@hology/nebula";import*as n from"three";export class RotatePosition extends i{constructor(t,i){super(),this.axis=t,this.angle=i,this.axis3D=new s(this.axis.x,this.axis.y,this.axis.z)}mutate(t,i,s){this.energize(t,i),null!=t.old&&0!=t.old.position.lengthSq()&&(a.copy(t.old.position),a.sub(t.parent.position),a.applyAxisAngle(this.axis3D,this.angle*i),a.add(t.parent.position),a.sub(t.old.position).divideScalar(i),t.velocity.sub(a)),a.copy(t.position),a.sub(t.parent.position),a.applyAxisAngle(this.axis3D,this.angle*i),a.add(t.parent.position),a.sub(t.position).divideScalar(i),t.velocity.add(a)}}const a=new t;export var AxisDirection;!function(t){t[t.x=0]="x",t[t.y=1]="y",t[t.z=2]="z",t[t.mx=3]="mx",t[t.my=4]="my",t[t.mz=5]="mz"}(AxisDirection||(AxisDirection={}));export class OrientAlongVelocity extends i{constructor(t){super(),this.axisDirection=t}initialize(t){t.transform.orientAlongVelocity=!0}mutate(t,i,s){t.target,n.Object3D}}export class FollowParent extends i{constructor(t){super(),this.speed=t}initialize(t){}mutate(t,i,s){const e=t.parent.parentParticle??t.parent;if(0===this.speed)return t.position.copy(e.old.position),t.acceleration.copy(e.acceleration),void t.velocity.copy(e.velocity);const o=r.copy(e.position).sub(t.position),n=(o.length(),o.normalize());l.copy(n).multiplyScalar(this.speed),t.velocity.copy(l)}}export class Scale extends i{constructor(t,i,s){super(void 0,s),this.scaleA=t,this.scaleB=i}initialize(t){t.transform.scaleA=t.scale*this.scaleA,t.transform.scaleB=t.scale*this.scaleB,t.transform.oldRadius=t.radius}mutate(t,i,s){this.energize(t,i),t.scale=o.lerp(t.transform.scaleA,t.transform.scaleB,this.energy),t.scale<5e-4&&(t.scale=0),t.radius=t.transform.oldRadius*t.scale}}export class ScaleComponents extends i{constructor(t,i,s){super(void 0,s),this.scaleA=t,this.scaleB=i}initialize(i){let s=i.transform.initialScale;s?(s=s.clone(),i.transform.initialScale=s):(s=new t(1,1,1),i.transform.initialScale=s),i.transform.scaleComponentsA=s.clone().multiply(this.scaleA),i.transform.scaleComponentsB=s.clone().multiply(this.scaleB)}mutate(t,i,s){this.energize(t,i);const e=t.transform.scaleComponentsA,o=t.transform.scaleComponentsB;t.transform.initialScale.lerpVectors(o,e,this.energy)}}export class LinearDamping extends i{constructor(t){super(),this.factor=t}mutate(t,i,s){this.energize(t,i);const e=r.copy(t.velocity).multiplyScalar(-this.factor*i);t.velocity.add(e)}}const r=new s,l=new s;export var AxisPlane;!function(t){t[t.xy=0]="xy",t[t.xz=1]="xz",t[t.yz=2]="yz",t[t.xyz=3]="xyz"}(AxisPlane||(AxisPlane={}));export class Disperse extends i{constructor(t,i,s=e.easeLinear){super(void 0,s,void 0,!0),this.distance=t,this.plane=i}initialize(t){t.transform.initialPos=t.position.clone();const i=c.copy(t.transform.initialPos).sub(t.parent.position).normalize();switch(this.plane){case AxisPlane.xy:i.setComponent(2,0);break;case AxisPlane.xz:i.setComponent(1,0);break;case AxisPlane.yz:i.setComponent(0,0)}t.transform.displacement=i.clone().multiplyScalar(this.distance),t.transform.prevEnergy=1}mutate(t,i,s){this.energize(t,i);t.transform.initialPos;const e=t.transform.displacement,o=t.transform.prevEnergy-this.energy;t.transform.prevEnergy=this.energy;t.position.x+=e.x*o,t.position.y+=e.y*o,t.position.z+=e.z*o}}export class MoveOverLife extends i{constructor(t,i,s,o=e.easeLinear){super(void 0,o,void 0,!0),this.x=t,this.y=i,this.z=s}initialize(t){t.transform.initialPos=t.position.clone()}mutate(t,i,s){this.energize(t,i);const e=t.transform.initialPos,o=1-this.energy;t.position.x=e.x+this.x*o,t.position.y=e.y+this.y*o,t.position.z=e.z+this.z*o}}const c=new s;/*
1
+ import{Vector3 as i}from"three";import{Behaviour as t,Vector3D as e,ease as s,MathUtils as o}from"@hology/nebula";import*as n from"three";export class RotatePosition extends t{constructor(i,t){super(),this.axis=i,this.angle=t,this.axis3D=new e(this.axis.x,this.axis.y,this.axis.z)}mutate(i,t,e){this.energize(i,t),null!=i.old&&0!=i.old.position.lengthSq()&&(a.copy(i.old.position),a.sub(i.parent.position),a.applyAxisAngle(this.axis3D,this.angle*t),a.add(i.parent.position),a.sub(i.old.position).divideScalar(t),i.velocity.sub(a)),a.copy(i.position),a.sub(i.parent.position),a.applyAxisAngle(this.axis3D,this.angle*t),a.add(i.parent.position),a.sub(i.position).divideScalar(t),i.velocity.add(a)}}const a=new i;export var AxisDirection;!function(i){i[i.x=0]="x",i[i.y=1]="y",i[i.z=2]="z",i[i.mx=3]="mx",i[i.my=4]="my",i[i.mz=5]="mz"}(AxisDirection||(AxisDirection={}));export class OrientAlongVelocity extends t{constructor(i){super(),this.axisDirection=i}initialize(i){i.transform.orientAlongVelocity=!0}mutate(i,t,e){i.target,n.Object3D}}export class FollowParent extends t{constructor(i){super(),this.speed=i}initialize(i){}mutate(i,t,e){const s=i.parent.parentParticle??i.parent;if(0===this.speed)return i.position.copy(s.old.position),i.acceleration.copy(s.acceleration),void i.velocity.copy(s.velocity);const o=r.copy(s.position).sub(i.position),n=(o.length(),o.normalize());l.copy(n).multiplyScalar(this.speed),i.velocity.copy(l)}}export class Scale extends t{constructor(i,t,e){super(void 0,e),this.scaleA=i,this.scaleB=t}initialize(i){i.transform.scaleA=i.scale*this.scaleA,i.transform.scaleB=i.scale*this.scaleB,i.transform.oldRadius=i.radius}mutate(i,t,e){this.energize(i,t),i.scale=o.lerp(i.transform.scaleA,i.transform.scaleB,this.energy),i.scale<5e-4&&(i.scale=0),i.radius=i.transform.oldRadius*i.scale}}export class ScaleComponents extends t{constructor(i,t,e){super(void 0,e),this.scaleA=i,this.scaleB=t}initialize(t){let e=t.transform.initialScale;e?(e=e.clone(),t.transform.initialScale=e):(e=new i(1,1,1),t.transform.initialScale=e),t.transform.scaleComponentsA=e.clone().multiply(this.scaleA),t.transform.scaleComponentsB=e.clone().multiply(this.scaleB)}mutate(i,t,e){this.energize(i,t);const s=i.transform.scaleComponentsA,o=i.transform.scaleComponentsB;i.transform.initialScale.lerpVectors(o,s,this.energy)}}export class LinearDamping extends t{constructor(i){super(),this.factor=i}mutate(i,t,e){this.energize(i,t);const s=r.copy(i.velocity).multiplyScalar(-this.factor*t);i.velocity.add(s)}}const r=new e,l=new e;export var AxisPlane;!function(i){i[i.xy=0]="xy",i[i.xz=1]="xz",i[i.yz=2]="yz",i[i.xyz=3]="xyz"}(AxisPlane||(AxisPlane={}));export class Disperse extends t{constructor(i,t,e=s.easeLinear){super(void 0,e,void 0,!0),this.distance=i,this.plane=t}initialize(i){i.transform.initialPos=i.position.clone();const t=c.copy(i.transform.initialPos).sub(i.parent.position).normalize();switch(this.plane){case AxisPlane.xy:t.setComponent(2,0);break;case AxisPlane.xz:t.setComponent(1,0);break;case AxisPlane.yz:t.setComponent(0,0)}i.transform.displacement=t.clone().multiplyScalar(this.distance),i.transform.prevEnergy=1}mutate(i,t,e){this.energize(i,t);i.transform.initialPos;const s=i.transform.displacement,o=i.transform.prevEnergy-this.energy;i.transform.prevEnergy=this.energy;i.position.x+=s.x*o,i.position.y+=s.y*o,i.position.z+=s.z*o}}export class MoveOverLife extends t{constructor(i,t,e,o=s.easeLinear){super(void 0,o,void 0,!0),this.x=i,this.y=t,this.z=e}initialize(i){i.transform.initialPos=i.position.clone()}mutate(i,t,e){this.energize(i,t);const s=i.transform.initialPos,o=1-this.energy;i.position.x=s.x+this.x*o,i.position.y=s.y+this.y*o,i.position.z=s.z+this.z*o}}const c=new e,p=new WeakMap;export class AnimationBehavior extends t{constructor(i,t=1,e=1,o=n.LoopOnce,a=!0,r=s.easeLinear){super(void 0,r,void 0,!0),this.clip=i,this.timeScale=t,this.weight=e,this.loop=o,this.clampWhenFinished=a}initialize(i){this.mixer?.stopAllAction(),this.mixer=null,this.action=null}mutate(i,t,e){if(this.energize(i,t),null==this.mixer){const t=i.target;if(t instanceof n.Object3D){let i=p.get(t);i?this.mixer=i:(this.mixer=new n.AnimationMixer(t.children[0]),p.set(t,this.mixer)),this.action=this.mixer.clipAction(this.clip),this.action.timeScale=this.timeScale,this.action.weight=this.weight,this.action.loop=this.loop,this.action.clampWhenFinished=this.clampWhenFinished,this.action.play()}}this.mixer&&this.mixer.update(t)}}/*
2
2
  * Copyright (©) 2025 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -10,6 +10,8 @@ export declare class VfxActor extends BaseActor {
10
10
  private disposeSystem;
11
11
  private sourceAsset;
12
12
  private assetLoader;
13
+ private assetManagerService;
14
+ private assetService;
13
15
  private world;
14
16
  private view;
15
17
  private particleSystemContainer;
@@ -1,4 +1,4 @@
1
- import{__decorate as t}from"tslib";import*as s from"three";import{Rate as e}from"@hology/nebula";import{Actor as i,BaseActor as r}from"../../gameplay/actors/actor.js";import{inject as o}from"../../gameplay/inject.js";import{AssetLoader as a}from"../../gameplay/services/asset-loader.js";import{ViewController as h}from"../../gameplay/services/render.js";import{World as m}from"../../gameplay/services/world.js";import{DelayRate as l}from"./rates.js";import{materializeVfx as d}from"./vfx-materializer.js";import{PhysicsSystem as p}from"../../gameplay/services/physics/physics-system.js";import{ShaderProvider as n}from"../../gameplay/services/shader-provider.js";let c=class extends r{constructor(){super(...arguments),this.timescale=1,this.paused=!0,this.assetLoader=o(a),this.world=o(m),this.view=o(h),this.physics=o(p),this.shaderProvider=o(n),this._worldPos=new s.Vector3,this._worldRot=new s.Quaternion,this._worldEul=new s.Euler,this.max=0}async fromAsset(t){if("vfx"!==t.type)throw"Asset must be a VFX asset but is "+t.type;null!=this.system&&(this.system.destroy(),this.system.emitters.forEach(t=>t.reset())),this.sourceAsset=t,this.disposeSystem&&this.disposeSystem(),this.world.scene.add(this.object);const{system:s,dispose:e,container:i}=await d(this.sourceAsset,this.object,{getAsset:t=>this.assetLoader.getAsset(t),getMaterial:t=>this.assetLoader.getMaterialByAssetId(t),getTexture:t=>this.assetLoader.getTextureByAssetId(t),getMesh:t=>this.assetLoader.getModelByAssetId(t).then(t=>t.scene)},this.view,this.physics,this.shaderProvider);this.system=s,this.disposeSystem=e,this.particleSystemContainer=i,this.object.visible=!1,this.object.matrixAutoUpdate=!1,this.object.matrixWorldAutoUpdate=!1,this.particleSystemContainer.matrixAutoUpdate=!1,this.particleSystemContainer.matrixWorldAutoUpdate=!1}play(){null==this.particleSystemContainer.parent&&this.world.scene.add(this.particleSystemContainer),this.object.matrixAutoUpdate=!0,this.object.matrixWorldAutoUpdate=!0,this.particleSystemContainer.matrixAutoUpdate=!0,this.particleSystemContainer.matrixWorldAutoUpdate=!0,this.object.visible=!0,this.paused=!1;this.system.emitters.every(t=>t.dead)&&this.restart()}pause(){this.paused=!0}stop(){this.system.emitters.forEach(t=>{const s=t.rate;s instanceof e&&(s.nextTime=1/0)})}restart(){if(null!=this.system&&null!=this.system.emitters)for(const t of this.system.emitters){const s=t.rate;s instanceof l?s.restart():s.nextTime=0,t.removeAllParticles()}}onUpdate(t){this.paused||(this.object.getWorldPosition(this._worldPos),this.object.getWorldQuaternion(this._worldRot),this._worldEul.setFromQuaternion(this._worldRot),this.system?.emitters.forEach(t=>{"world"===t._space&&(t.setPosition(this._worldPos),t.setRotation(this._worldEul))}),this.system?.update(t*this.timescale))}getParticleCount(){return this.system?.getCount()??0}onEndPlay(){this.stop(),null!=this.disposeSystem&&this.disposeSystem()}};c=t([i()],c);export{c as VfxActor};/*
1
+ import{__decorate as t}from"tslib";import*as s from"three";import{Rate as e}from"@hology/nebula";import{Actor as i,BaseActor as r}from"../../gameplay/actors/actor.js";import{inject as o}from"../../gameplay/inject.js";import{AssetLoader as a}from"../../gameplay/services/asset-loader.js";import{ViewController as h}from"../../gameplay/services/render.js";import{World as m}from"../../gameplay/services/world.js";import{DelayRate as l}from"./rates.js";import{materializeVfx as d}from"./vfx-materializer.js";import{PhysicsSystem as n}from"../../gameplay/services/physics/physics-system.js";import{ShaderProvider as p}from"../../gameplay/services/shader-provider.js";import{AssetResourceLoader as c}from"../../scene/asset-resource-loader.js";import{AssetsProvider as y}from"../../scene/assets-provider.js";let u=class extends r{constructor(){super(...arguments),this.timescale=1,this.paused=!0,this.assetLoader=o(a),this.assetManagerService=o(c),this.assetService=o(y),this.world=o(m),this.view=o(h),this.physics=o(n),this.shaderProvider=o(p),this._worldPos=new s.Vector3,this._worldRot=new s.Quaternion,this._worldEul=new s.Euler,this.max=0}async fromAsset(t){if("vfx"!==t.type)throw"Asset must be a VFX asset but is "+t.type;null!=this.system&&(this.system.destroy(),this.system.emitters.forEach(t=>t.reset())),this.sourceAsset=t,this.disposeSystem&&this.disposeSystem(),this.world.scene.add(this.object);const{system:s,dispose:e,container:i}=await d(this.sourceAsset,this.object,{getAsset:t=>this.assetLoader.getAsset(t),getMaterial:t=>this.assetLoader.getMaterialByAssetId(t),getTexture:t=>this.assetLoader.getTextureByAssetId(t),getMesh:t=>this.assetLoader.getModelByAssetId(t).then(t=>t.scene)},this.view,this.physics,this.shaderProvider,this.assetService,this.assetManagerService);this.system=s,this.disposeSystem=e,this.particleSystemContainer=i,this.object.visible=!1,this.object.matrixAutoUpdate=!1,this.object.matrixWorldAutoUpdate=!1,this.particleSystemContainer.matrixAutoUpdate=!1,this.particleSystemContainer.matrixWorldAutoUpdate=!1}play(){null==this.particleSystemContainer.parent&&this.world.scene.add(this.particleSystemContainer),this.object.matrixAutoUpdate=!0,this.object.matrixWorldAutoUpdate=!0,this.particleSystemContainer.matrixAutoUpdate=!0,this.particleSystemContainer.matrixWorldAutoUpdate=!0,this.object.visible=!0,this.paused=!1;this.system.emitters.every(t=>t.dead)&&this.restart()}pause(){this.paused=!0}stop(){this.system.emitters.forEach(t=>{const s=t.rate;s instanceof e&&(s.nextTime=1/0)})}restart(){if(null!=this.system&&null!=this.system.emitters)for(const t of this.system.emitters){const s=t.rate;s instanceof l?s.restart():s.nextTime=0,t.removeAllParticles()}}onUpdate(t){this.paused||(this.object.getWorldPosition(this._worldPos),this.object.getWorldQuaternion(this._worldRot),this._worldEul.setFromQuaternion(this._worldRot),this.system?.emitters.forEach(t=>{"world"===t._space&&(t.setPosition(this._worldPos),t.setRotation(this._worldEul))}),this.system?.update(t*this.timescale))}getParticleCount(){return this.system?.getCount()??0}onEndPlay(){this.stop(),null!=this.disposeSystem&&this.disposeSystem()}};u=t([i()],u);export{u as VfxActor};/*
2
2
  * Copyright (©) 2025 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,10 +1,11 @@
1
- import { Vector2, Vector3 } from "three";
1
+ import { AnimationClip, Vector2, Vector3 } from "three";
2
2
  import { Behaviour, Initializer } from "@hology/nebula";
3
3
  import { Curve2 } from "../../utils/curve.js";
4
4
  type HexColor = `#${string}`;
5
- export type ShapeParameterDef<T = boolean | number | string | Vector3 | Vector2 | HexColor | Curve2> = {
6
- type: T extends number ? 'number' : T extends HexColor ? 'color' : T extends string ? 'string' | 'select' : T extends Vector2 ? 'vec2' : T extends Vector3 ? 'vec3' : T extends Curve2 ? 'curve' : T extends boolean ? 'boolean' : never;
5
+ export type ShapeParameterDef<T = boolean | number | string | Vector3 | Vector2 | HexColor | Curve2 | AnimationClip> = {
6
+ type: T extends number ? 'number' : T extends HexColor ? 'color' : T extends string ? 'string' | 'select' : T extends Vector2 ? 'vec2' : T extends Vector3 ? 'vec3' : T extends Curve2 ? 'curve' : T extends AnimationClip ? 'animationclip' : T extends boolean ? 'boolean' : never;
7
7
  default: T;
8
+ requires?: Record<string, unknown>;
8
9
  };
9
10
  type FloatParameterDef = ShapeParameterDef<number> & {
10
11
  float: boolean;
@@ -279,6 +280,22 @@ declare class WorldCollisionDef extends BaseBevDef<WorldCollisionDef> {
279
280
  };
280
281
  make(params?: ParamsType<this>): Behaviour;
281
282
  }
283
+ declare class AnimationBehaviorDef extends BaseBevDef<AnimationBehaviorDef> {
284
+ parameters: {
285
+ clip: ShapeParameterDef<AnimationClip>;
286
+ timeScale: FloatParameterDef;
287
+ weight: FloatParameterDef;
288
+ loop: SelectParameterDef<string>;
289
+ clampWhenFinished: {
290
+ requires: {
291
+ loop: string;
292
+ };
293
+ type: "boolean";
294
+ default: boolean;
295
+ };
296
+ };
297
+ make(params?: ParamsType<this>): Behaviour;
298
+ }
282
299
  declare const vfxInitializsers: {
283
300
  lifetime: LifetimeDef;
284
301
  randomLifetime: RandomLifetimeDef;
@@ -316,6 +333,7 @@ declare const vfxBehaviours: {
316
333
  linearDamping: LinearDampingDef;
317
334
  followParent: FollowParentDef;
318
335
  worldCollision: WorldCollisionDef;
336
+ animation: AnimationBehaviorDef;
319
337
  };
320
338
  export type LibraryVfxInitalizerType = keyof typeof vfxInitializsers;
321
339
  export declare const VfxInitializserLibrary: Record<LibraryVfxInitalizerType, InitializerDefinition>;
@@ -1,4 +1,4 @@
1
- import{MathUtils as e,Vector2 as r,Vector3 as t}from"three";import{Alpha as s,Attraction as n,BoxZone as a,CircleZone as o,Color as i,ease as c,Force as u,Gravity as d,Life as m,LineZone as p,Mass as l,Position as w,RadialVelocity as x,RandomDrift as f,Repulsion as h,Rotate as y,Vector3D as g}from"@hology/nebula";import{AxisDirection as k,AxisPlane as b,Disperse as v,FollowParent as z,LinearDamping as R,MoveOverLife as T,OrientAlongVelocity as L,RotatePosition as V,Scale as j,ScaleComponents as D}from"./behaviours.js";import{AdditiveVelocity as C,InitialScale as B,InitialScaleComponents as I,RandomDirection as O,RandomRotation as A,randomRotationAxis as K,RandomScale as P,Rotation as S}from"./initializsers.js";import{PointZone as Y,SphereZone as M}from"./zones.js";import{WorldCollisionBehaviour as X}from"./vfx-collision-behaviour.js";import{Curve2 as Z}from"../../utils/curve.js";class q{build(e={}){const r=Q(e,this.parameters);return this.make(r)}}class E{build(e={}){const r=Q(e,this.parameters);return this.make(r)}}function F(e,r,t){return{type:"number",default:e,float:!0,min:r,max:t}}function G(e){return{type:"vec3",default:(new t).fromArray(e)}}function H(e){return{type:"color",default:e}}function J(e,r){return{type:"select",opts:e,default:r}}function N(){return{type:"curve",default:Z.linear()}}function Q(e,r){const t={};for(let s in r)null==e[s]?t[s]=r[s].default:t[s]=e[s];return t}function U(e){return r=>e.getY(r)}const W={lifetime:new class extends E{constructor(){super(...arguments),this.parameters={duration:F(1,0,1e5)}}make(e={}){return new m(e.duration)}},randomLifetime:new class extends E{constructor(){super(...arguments),this.parameters={minDuration:F(1,0,1e5),maxDuration:F(2,0,1e5)}}make(e={}){return new m(e.minDuration,e.maxDuration)}},positionPoint:new class extends E{constructor(){super(...arguments),this.parameters={position:G([0,0,0])}}make(e={}){const{x:r,y:t,z:s}=e.position;return new w(new Y(r,t,s))}},positionBox:new class extends E{constructor(){super(...arguments),this.parameters={position:G([0,0,0]),dimensions:G([0,0,0])}}make(e={}){const{x:r,y:t,z:s}=e.position,{x:n,y:o,z:i}=e.dimensions;return new w(new a(r,t,s,n,o,i))}},positionSphere:new class extends E{constructor(){super(...arguments),this.parameters={position:G([0,0,0]),radius:F(1)}}make(e={}){const{x:r,y:t,z:s}=e.position;return new w(new M(r,t,s,e.radius))}},positionLine:new class extends E{constructor(){super(...arguments),this.parameters={a:G([0,0,0]),b:G([0,0,1])}}make(e={}){const{x:r,y:t,z:s}=e.a,{x:n,y:a,z:o}=e.b;return new w(new p(r,t,s,n,a,o))}},positionCircle:new class extends E{constructor(){super(...arguments),this.parameters={position:G([0,0,0]),rotation:G([0,0,0]),radius:F(1,0,1e4)}}make(r={}){const{x:t,y:s,z:n}=r.position,{x:a,y:i,z:c}=r.rotation;return new w(new o(t,s,n,r.radius,0,e.degToRad(a),e.degToRad(i),e.degToRad(c)))}},positionRing:new class extends E{constructor(){super(...arguments),this.parameters={position:G([0,0,0]),rotation:G([0,0,0]),radius:F(1,0,1e4),thickness:F(.2,0,1e4)}}make(r={}){const{x:t,y:s,z:n}=r.position,{x:a,y:i,z:c}=r.rotation;return new w(new o(t,s,n,r.radius,Math.max(r.thickness,1e-4),e.degToRad(a),e.degToRad(i),e.degToRad(c)))}},rotation:new class extends E{constructor(){super(...arguments),this.parameters={rotation:G([0,0,0])}}make(r={}){const{x:s,y:n,z:a}=r.rotation;return new S(new t(e.degToRad(s),e.degToRad(n),e.degToRad(a)))}},randomRotation:new class extends E{constructor(){super(...arguments),this.parameters={axis:J(K,"XYZ")}}make(e={}){return new A(e.axis)}},scale:new class extends E{constructor(){super(...arguments),this.parameters={scale:F(1)}}make(e={}){return new B(e.scale)}},scaleComponents:new class extends E{constructor(){super(...arguments),this.parameters={scale:G([1,1,1])}}make(e={}){return new I(e.scale)}},randomScale:new class extends E{constructor(){super(...arguments),this.parameters={min:F(1),max:F(1)}}make(e={}){return new P(e.min,e.max)}},mass:new class extends E{constructor(){super(...arguments),this.parameters={min:F(1)}}make(e={}){return new l(e.min)}},velocity:new class extends E{constructor(){super(...arguments),this.parameters={velocity:G([0,0,0])}}make(e={}){const{x:r,y:s,z:n}=e.velocity;return new C(new t(r,s,n))}},randomVelocity:new class extends E{constructor(){super(...arguments),this.parameters={min:G([0,0,0]),max:G([0,0,0])}}make(e={}){return new C(e.min,e.max)}},radialVelocity:new class extends E{constructor(){super(...arguments),this.parameters={speed:F(1),direction:G([0,1,0]),spread:F(0)}}make(e={}){return new x(e.speed,new g(e.direction.x,e.direction.y,e.direction.z),e.spread)}},randomDirection:new class extends E{constructor(){super(...arguments),this.parameters={speed:F(1)}}make(e={}){return new O(e.speed)}}},$={force:new class extends q{constructor(){super(...arguments),this.parameters={force:G([0,0,0]),ease:N()}}make(e={}){return new u(e.force.x,e.force.y,e.force.z,void 0,U(e.ease))}},gravity:new class extends q{constructor(){super(...arguments),this.parameters={gravity:F(8),easing:N()}}make(e={}){return new d(e.gravity,void 0,U(e.easing))}},repulsion:new class extends q{constructor(){super(...arguments),this.parameters={target:G([0,0,0]),force:F(1),radius:F(1),easing:N()}}make(e={}){const r=new g(e.target.x,e.target.y,e.target.z);return new h(r,e.force,e.radius,void 0,U(e.easing))}},attraction:new class extends q{constructor(){super(...arguments),this.parameters={target:G([0,0,0]),force:F(1),radius:F(1),easing:N()}}make(e={}){const r=new g(e.target.x,e.target.y,e.target.z);return new n(r,e.force,e.radius,void 0,U(e.easing))}},scale:new class extends q{constructor(){super(...arguments),this.parameters={a:F(1),b:F(1),ease:N()}}make(e={}){return new j(e.a,e.b,U(e.ease))}},scaleComponents:new class extends q{constructor(){super(...arguments),this.parameters={a:G([1,1,1]),b:G([1,1,1]),ease:N()}}make(e={}){return new D(e.a,e.b,U(e.ease))}},randomDrift:new class extends q{constructor(){super(...arguments),this.parameters={drift:G([1,1,1]),delay:F(0),ease:N()}}make(e={}){return new f(e.drift.x,e.drift.y,e.drift.z,e.delay,void 0,U(e.ease))}},rotate:new class extends q{constructor(){super(...arguments),this.parameters={rotation:G([0,0,0]),ease:N()}}make(r={}){const{x:t,y:s,z:n}=r.rotation;return new y(e.degToRad(t),e.degToRad(s),e.degToRad(n),void 0,U(r.ease))}},rotateAdd:new class extends q{constructor(){super(...arguments),this.parameters={rotation:G([0,0,0])}}make(r={}){const{x:t,y:s,z:n}=r.rotation,a=new y(e.degToRad(t),e.degToRad(s),e.degToRad(n),void 0);return a.rotationType="add",a}},changeColor:new class extends q{constructor(){super(...arguments),this.parameters={a:H("#ffffff"),b:H("#ffffff"),ease:N()}}make(e={}){return new i(e.a,e.b,void 0,U(e.ease))}},changeOpacity:new class extends q{constructor(){super(...arguments),this.parameters={a:F(1,0,1),b:F(0,0,1),ease:N()}}make(e={}){return new s(e.a,e.b,void 0,U(e.ease))}},vortex:new class extends q{constructor(){super(...arguments),this.parameters={axis:G([0,1,0]),amount:F(1)}}make(e={}){return new V(e.axis,e.amount)}},moveTo:new class extends q{constructor(){super(...arguments),this.parameters={target:G([0,1,0]),ease:N()}}make(e={}){return new T(e.target.x,e.target.y,e.target.z,U(e.ease))}},linearDamping:new class extends q{constructor(){super(...arguments),this.parameters={factor:F(.1,0,1e3)}}make(e={}){return new R(e.factor)}},followParent:new class extends q{constructor(){super(...arguments),this.parameters={speed:F(0)}}make(e={}){return new z(e.speed)}},worldCollision:new class extends q{constructor(){super(...arguments),this.parameters={friction:F(1,0,1),bounce:F(1,0,1),lifeLoss:F(0,0)}}make(e={}){return new X(null,e.bounce,e.friction,e.lifeLoss)}}};export const VfxInitializserLibrary=W;export const VfxInitializserLibraryKeys=Object.keys(VfxInitializserLibrary);export const VfxBehaviourLibrary=$;export const VfxBehaviourLibraryKeys=Object.keys(VfxBehaviourLibrary);/*
1
+ import{LoopOnce as e,LoopPingPong as t,LoopRepeat as r,MathUtils as s,Vector2 as n,Vector3 as a}from"three";import{Alpha as o,Attraction as i,BoxZone as c,CircleZone as u,Color as p,ease as d,Force as m,Gravity as l,Life as w,LineZone as x,Mass as f,Position as h,RadialVelocity as y,RandomDrift as g,Repulsion as k,Rotate as b,Vector3D as v}from"@hology/nebula";import{AnimationBehavior as z,AxisDirection as R,AxisPlane as T,Disperse as L,FollowParent as V,LinearDamping as j,MoveOverLife as D,OrientAlongVelocity as C,RotatePosition as O,Scale as P,ScaleComponents as B}from"./behaviours.js";import{AdditiveVelocity as S,InitialScale as I,InitialScaleComponents as A,RandomDirection as F,RandomRotation as K,randomRotationAxis as W,RandomScale as Y,Rotation as q}from"./initializsers.js";import{PointZone as M,SphereZone as X}from"./zones.js";import{WorldCollisionBehaviour as Z}from"./vfx-collision-behaviour.js";import{Curve2 as E}from"../../utils/curve.js";class G{build(e={}){const t=_(e,this.parameters);return this.make(t)}}class H{build(e={}){const t=_(e,this.parameters);return this.make(t)}}function J(e,t,r){return{type:"number",default:e,float:!0,min:t,max:r}}function N(e){return{type:"vec3",default:(new a).fromArray(e)}}function Q(e){return{type:"color",default:e}}function U(e,t){return{type:"select",opts:e,default:t}}function $(){return{type:"curve",default:E.linear()}}function _(e,t){const r={};for(let s in t)null==e[s]?r[s]=t[s].default:r[s]=e[s];return r}function ee(e){return t=>e.getY(t)}const te={lifetime:new class extends H{constructor(){super(...arguments),this.parameters={duration:J(1,0,1e5)}}make(e={}){return new w(e.duration)}},randomLifetime:new class extends H{constructor(){super(...arguments),this.parameters={minDuration:J(1,0,1e5),maxDuration:J(2,0,1e5)}}make(e={}){return new w(e.minDuration,e.maxDuration)}},positionPoint:new class extends H{constructor(){super(...arguments),this.parameters={position:N([0,0,0])}}make(e={}){const{x:t,y:r,z:s}=e.position;return new h(new M(t,r,s))}},positionBox:new class extends H{constructor(){super(...arguments),this.parameters={position:N([0,0,0]),dimensions:N([0,0,0])}}make(e={}){const{x:t,y:r,z:s}=e.position,{x:n,y:a,z:o}=e.dimensions;return new h(new c(t,r,s,n,a,o))}},positionSphere:new class extends H{constructor(){super(...arguments),this.parameters={position:N([0,0,0]),radius:J(1)}}make(e={}){const{x:t,y:r,z:s}=e.position;return new h(new X(t,r,s,e.radius))}},positionLine:new class extends H{constructor(){super(...arguments),this.parameters={a:N([0,0,0]),b:N([0,0,1])}}make(e={}){const{x:t,y:r,z:s}=e.a,{x:n,y:a,z:o}=e.b;return new h(new x(t,r,s,n,a,o))}},positionCircle:new class extends H{constructor(){super(...arguments),this.parameters={position:N([0,0,0]),rotation:N([0,0,0]),radius:J(1,0,1e4)}}make(e={}){const{x:t,y:r,z:n}=e.position,{x:a,y:o,z:i}=e.rotation;return new h(new u(t,r,n,e.radius,0,s.degToRad(a),s.degToRad(o),s.degToRad(i)))}},positionRing:new class extends H{constructor(){super(...arguments),this.parameters={position:N([0,0,0]),rotation:N([0,0,0]),radius:J(1,0,1e4),thickness:J(.2,0,1e4)}}make(e={}){const{x:t,y:r,z:n}=e.position,{x:a,y:o,z:i}=e.rotation;return new h(new u(t,r,n,e.radius,Math.max(e.thickness,1e-4),s.degToRad(a),s.degToRad(o),s.degToRad(i)))}},rotation:new class extends H{constructor(){super(...arguments),this.parameters={rotation:N([0,0,0])}}make(e={}){const{x:t,y:r,z:n}=e.rotation;return new q(new a(s.degToRad(t),s.degToRad(r),s.degToRad(n)))}},randomRotation:new class extends H{constructor(){super(...arguments),this.parameters={axis:U(W,"XYZ")}}make(e={}){return new K(e.axis)}},scale:new class extends H{constructor(){super(...arguments),this.parameters={scale:J(1)}}make(e={}){return new I(e.scale)}},scaleComponents:new class extends H{constructor(){super(...arguments),this.parameters={scale:N([1,1,1])}}make(e={}){return new A(e.scale)}},randomScale:new class extends H{constructor(){super(...arguments),this.parameters={min:J(1),max:J(1)}}make(e={}){return new Y(e.min,e.max)}},mass:new class extends H{constructor(){super(...arguments),this.parameters={min:J(1)}}make(e={}){return new f(e.min)}},velocity:new class extends H{constructor(){super(...arguments),this.parameters={velocity:N([0,0,0])}}make(e={}){const{x:t,y:r,z:s}=e.velocity;return new S(new a(t,r,s))}},randomVelocity:new class extends H{constructor(){super(...arguments),this.parameters={min:N([0,0,0]),max:N([0,0,0])}}make(e={}){return new S(e.min,e.max)}},radialVelocity:new class extends H{constructor(){super(...arguments),this.parameters={speed:J(1),direction:N([0,1,0]),spread:J(0)}}make(e={}){return new y(e.speed,new v(e.direction.x,e.direction.y,e.direction.z),e.spread)}},randomDirection:new class extends H{constructor(){super(...arguments),this.parameters={speed:J(1)}}make(e={}){return new F(e.speed)}}},re={force:new class extends G{constructor(){super(...arguments),this.parameters={force:N([0,0,0]),ease:$()}}make(e={}){return new m(e.force.x,e.force.y,e.force.z,void 0,ee(e.ease))}},gravity:new class extends G{constructor(){super(...arguments),this.parameters={gravity:J(8),easing:$()}}make(e={}){return new l(e.gravity,void 0,ee(e.easing))}},repulsion:new class extends G{constructor(){super(...arguments),this.parameters={target:N([0,0,0]),force:J(1),radius:J(1),easing:$()}}make(e={}){const t=new v(e.target.x,e.target.y,e.target.z);return new k(t,e.force,e.radius,void 0,ee(e.easing))}},attraction:new class extends G{constructor(){super(...arguments),this.parameters={target:N([0,0,0]),force:J(1),radius:J(1),easing:$()}}make(e={}){const t=new v(e.target.x,e.target.y,e.target.z);return new i(t,e.force,e.radius,void 0,ee(e.easing))}},scale:new class extends G{constructor(){super(...arguments),this.parameters={a:J(1),b:J(1),ease:$()}}make(e={}){return new P(e.a,e.b,ee(e.ease))}},scaleComponents:new class extends G{constructor(){super(...arguments),this.parameters={a:N([1,1,1]),b:N([1,1,1]),ease:$()}}make(e={}){return new B(e.a,e.b,ee(e.ease))}},randomDrift:new class extends G{constructor(){super(...arguments),this.parameters={drift:N([1,1,1]),delay:J(0),ease:$()}}make(e={}){return new g(e.drift.x,e.drift.y,e.drift.z,e.delay,void 0,ee(e.ease))}},rotate:new class extends G{constructor(){super(...arguments),this.parameters={rotation:N([0,0,0]),ease:$()}}make(e={}){const{x:t,y:r,z:n}=e.rotation;return new b(s.degToRad(t),s.degToRad(r),s.degToRad(n),void 0,ee(e.ease))}},rotateAdd:new class extends G{constructor(){super(...arguments),this.parameters={rotation:N([0,0,0])}}make(e={}){const{x:t,y:r,z:n}=e.rotation,a=new b(s.degToRad(t),s.degToRad(r),s.degToRad(n),void 0);return a.rotationType="add",a}},changeColor:new class extends G{constructor(){super(...arguments),this.parameters={a:Q("#ffffff"),b:Q("#ffffff"),ease:$()}}make(e={}){return new p(e.a,e.b,void 0,ee(e.ease))}},changeOpacity:new class extends G{constructor(){super(...arguments),this.parameters={a:J(1,0,1),b:J(0,0,1),ease:$()}}make(e={}){return new o(e.a,e.b,void 0,ee(e.ease))}},vortex:new class extends G{constructor(){super(...arguments),this.parameters={axis:N([0,1,0]),amount:J(1)}}make(e={}){return new O(e.axis,e.amount)}},moveTo:new class extends G{constructor(){super(...arguments),this.parameters={target:N([0,1,0]),ease:$()}}make(e={}){return new D(e.target.x,e.target.y,e.target.z,ee(e.ease))}},linearDamping:new class extends G{constructor(){super(...arguments),this.parameters={factor:J(.1,0,1e3)}}make(e={}){return new j(e.factor)}},followParent:new class extends G{constructor(){super(...arguments),this.parameters={speed:J(0)}}make(e={}){return new V(e.speed)}},worldCollision:new class extends G{constructor(){super(...arguments),this.parameters={friction:J(1,0,1),bounce:J(1,0,1),lifeLoss:J(0,0)}}make(e={}){return new Z(null,e.bounce,e.friction,e.lifeLoss)}},animation:new class extends G{constructor(){var e;super(...arguments),this.parameters={clip:{type:"animationclip",default:null},timeScale:J(1,0,10),weight:J(1,0,1),loop:U(["Once","Repeat","PingPong"],"Once"),clampWhenFinished:{...(e=!0,{type:"boolean",default:e}),requires:{loop:"Once"}}}}make(s={}){let n=e;return"Repeat"===s.loop?n=r:"PingPong"===s.loop&&(n=t),new z(s.clip,s.timeScale,s.weight,n,s.clampWhenFinished,d.easeLinear)}}};export const VfxInitializserLibrary=te;export const VfxInitializserLibraryKeys=Object.keys(VfxInitializserLibrary);export const VfxBehaviourLibrary=re;export const VfxBehaviourLibraryKeys=Object.keys(VfxBehaviourLibrary);/*
2
2
  * Copyright (©) 2025 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -5,13 +5,15 @@ import { PhysicsSystem } from '../../gameplay/services/physics/physics-system.js
5
5
  import { ViewController } from '../../gameplay/services/render.js';
6
6
  import { Asset, VfxAsset } from '../../scene/model.js';
7
7
  import { ShaderProvider } from "../../gameplay/services/shader-provider.js";
8
+ import { AssetResourceLoader } from "../../scene/asset-resource-loader.js";
9
+ import { AssetsProvider } from "../../scene/assets-provider.js";
8
10
  export type VfxAssetProvider = {
9
11
  getAsset(assetId: string): Promise<Asset>;
10
12
  getTexture(assetId: string): Promise<THREE.Texture>;
11
13
  getMesh(assetId: string): Promise<THREE.Object3D>;
12
14
  getMaterial(assetId: string): Promise<THREE.Material>;
13
15
  };
14
- export declare function materializeVfx(asset: VfxAsset, target: Object3D, assetProvider: VfxAssetProvider, view: ViewController, physics: PhysicsSystem, shaderProvider: ShaderProvider): Promise<{
16
+ export declare function materializeVfx(asset: VfxAsset, target: Object3D, assetProvider: VfxAssetProvider, view: ViewController, physics: PhysicsSystem, shaderProvider: ShaderProvider, assetsService: AssetsProvider, assetManagerService: AssetResourceLoader): Promise<{
15
17
  container: THREE.Object3D<THREE.Object3DEventMap>;
16
18
  system: System;
17
19
  dispose: () => void;
@@ -1,4 +1,4 @@
1
- import e,{Behaviour as t,Body as a,Emitter as s,Rate as n}from"@hology/nebula";import*as i from"three";import{Object3D as r}from"three";import{AttributeVec3Node as o,AttributeVec4Node as l,NodeShaderMaterial as c,RgbNode as u,UniformFloatNode as p,UniformVec3Node as m,Vec3ExpressionNode as h,Vec4Node as d,attributeFloat as f,attributeVec3 as y,attributeVec4 as w,attributes as g,clamp as b,float as v,glslFunction as A,lambertMaterial as E,log as M,pow as x,rgb as I,rgba as T,smoothstep as P,standardMaterial as S,textureSampler2d as B,uniformFloat as C,uniforms as R,varying as k,varyingAttributes as j,varyingVec3 as D,varyingVec4 as z}from"three-shader-graph";import{prepareClassParameters as V,prepareShapeParameters as F}from"../../scene/materializer.js";import{SerializedParamType as L}from"../../scene/model.js";import{ShapeLibrary as O}from"../../scene/objects/shapes.js";import{fragmentLinearEyeDepth as Q,linearEyeDepth as W}from"../../shader-nodes/depth.js";import{particleEnergyUniformName as H,particleTimeUniformName as U,particleUniforms as q,particleVelcoityUniformName as G}from"../../shader-nodes/particle.js";import{sampleFlipbook as J}from"../../shader-nodes/texture-sequence.js";import{DefaultInitializer as N}from"./initializsers.js";import{DelayRate as K,OnceRate as Y}from"./rates.js";import{StretchedSprite as X}from"./stretched-sprite.js";import{ThreeBlendingMode as Z}from"./vfx-asset.js";import{VfxBehaviourLibrary as _,VfxInitializserLibrary as $}from"./vfx-defs.js";import{MultiRenderer as ee}from"./vfx-renderers.js";import{WorldCollisionBehaviour as te}from"./vfx-collision-behaviour.js";import{getSpritePosition as ae,SpriteNodeShaderMaterial as se}from"../../shader/sprite-shader.js";import{DecalUnlitShader as ne}from"../../shader/builtin/decal-unlit-shader.js";import{DecalStandardShader as ie}from"../../shader/builtin/decal-standard-shader.js";export async function materializeVfx(t,a,s,n,o,l){let c=a;for(;null!=c.parent;)c=c.parent;const u=new r;u.name="particle system local",a.add(u);const p=new r;p.name="particle system world";const m=new ee(p,u,i,n),h=new e;return(await Promise.all(t.vfx.emitters.slice().sort((e,t)=>(t.output.renderOrder??0)-(e.output.renderOrder??0)).map(async e=>{const t=await re(e,s,h,o,l);return t.setParentRecursive(h),t.emit()}))).forEach(e=>h.addEmitter(e)),h.addRenderer(m).emit({onEnd:()=>{}}),{container:p,system:h,dispose:()=>{p.removeFromParent(),u.removeFromParent(),m.dispose()}}}async function re(e,t,s,u,v){const x=function(e){let t;switch(e.rate.type){case"continuous":t=new K(e.rate.delay??0,e.rate.count,e.rate.time,e.rate.duration);break;case"once":t=new Y(e.rate.delay??0,e.rate.count);break;default:console.warn(`Failed to configure rate for emitter: ${JSON.stringify(e)}`),t=new n(0,1/0)}return t}(e);let I;switch(e.output.type){case"decal":I=new a(await async function(e,t){const a=!1!==e.unlit?new ne:new ie;a.color=new i.Color(e.color),a instanceof ne?a.intensity=e.intensity??1:a.emissiveIntensity=e.intensity??1;if(e.colorMap){const s=await t.getTexture(e.colorMap);a.colorMap=s}if(e.alphaMap){const s=await t.getTexture(e.alphaMap);a.alphaMap=s}const s=a.build();s.blending=Z[e.blendingMode]??i.NormalBlending,s.transparent=!0,s.side=i.BackSide,s.depthTest=!1,null!=s&&!0===e.bloom&&(s.userData.hasBloom=!0);s.defines.IS_PARTICLE="";const n=new i.BoxGeometry(1,1,1),r=new i.Mesh(n,s);null!=e.renderOrder&&(r.renderOrder=e.renderOrder);return r}(e.output,t));break;case"sprite":I=new a(await async function(e,t,a){let s=null;s=null!=e.shader?await le(e,t,a):await async function(e,t){const a=null!=e.texture?await t.getTexture(e.texture):oe,s=B(a);let n=s.sample(j.uv);e.flipbook?.enabled&&(n=J(s,g.uv,e.flipbook.columns,e.flipbook.rows,q.time,e.flipbook.fps,e.flipbook.mode));const r=new p("rotation",0),o=new m("color").rgb,l=C("opacity",1),c=W.subtract(Q).divide(W);let u=l;switch(e.opacityChannel??"red"){case"none":break;case"red":u=u.multiply(n.r);break;case"alpha":u=u.multiply(n.a)}if("number"==typeof e.softness&&e.softness>0){const t=b(c,0,1e3);u=u.multiply(P(0,.2*e.softness,t))}const h=ae(r),d=T(o.multiply(n.rgb).multiplyScalar(e.intensity??1),u);var f=new se({color:d,emissive:d.rgb.multiplyScalar(u),transparent:!0,position:h,alphaTest:1e-4,uniforms:{color:{value:new i.Color(e.color)}}});f.alphaHash=!0,null!=f&&!0===e.bloom&&(f.userData.hasBloom=!0);return f.blending=Z[e.blendingMode]??i.NormalBlending,f}(e,t);s instanceof i.ShaderMaterial&&!0===e.lockY&&(s.defines.LOCK_Y_AXIS="");const n=new i.Mesh(new i.PlaneGeometry(1,1),s);return n.name="sprite",n}(e.output,t,v));break;case"stretchedSprite":I=new a(await async function(e,t){const a=null!=e.texture?await t.getTexture(e.texture):oe,s=B(a).sample(j.uv),n=z(new l("color")),r=n.rgb.multiply(s.rgb);let o=n.w;switch(e.opacityChannel??"red"){case"none":break;case"red":o=o.multiply(s.r);break;case"alpha":o=o.multiply(s.a)}if("number"==typeof e.softness&&e.softness>0){const t=W.subtract(Q).divide(M(W)),a=b(t,0,1e3);o=o.multiply(P(0,.2*e.softness,a))}const c=A(d,{position:g.position,offset:y("offset"),modelViewMatrix:R.modelViewMatrix,velocity:w("velocity"),size:y("size"),rotation:f("rotation")},"\n float lengthFactor = velocity.w;\n float avgSize = (size.x + size.y) * 0.5;\n\n vec4 mvPosition = modelViewMatrix * vec4( offset , 1.0 );\n vec3 viewVelocity = normalMatrix * velocity.xyz;\n float vlength = length(viewVelocity); \n mvPosition.xyz += position.y * normalize(cross(mvPosition.xyz, viewVelocity)) * avgSize; \n mvPosition.xyz -= (position.x + 0.5) * viewVelocity * (1.0 + lengthFactor / vlength) * avgSize;\n return projectionMatrix * mvPosition;\n ");var u=new se({color:T(r.multiplyScalar(e.intensity??1),o),alphaTest:.1,transparent:!0,position:c,uniforms:{color:{value:new i.Color(e.color)}}});null!=u&&!0===e.bloom&&(u.userData.hasBloom=!0);u.blending=Z[e.blendingMode]??i.NormalBlending;const p=new X(new i.PlaneGeometry(1,1),u);return p.scaleFactor=e.scale,p}(e.output,t));break;case"shape":I=new a(await async function(e,t,a){if(null==e.shape)return console.log("Shape is null"),new r;const s=O[e.shape];if(null==s)return console.error(`No shape with type ${e.shape}`),new r;const n=F(e.params??{}),l=s.geometry(n);let u=null;u=null!=e.shader?await le(e,t,a):null!=e.material?ce(await t.getMaterial(e.material)):function(){const e=k(new h("instanceColor")).rgb,t=k(new o("particleData")).x;return new c({color:E({color:e}).rgb.rgba(t),opacity:t,transparent:!0})}();null!=u&&!0===e.bloom&&(u.userData.hasBloom=!0);return new i.Mesh(l,u)}(e.output,t,v));break;case"mesh":I=new a(await async function(e,t,a){if(null==e.assetId)return console.warn("Can't use mesh as particle without asset id"),new r;const s=await t.getMesh(e.assetId),n=await t.getAsset(e.assetId);if(null!=e.shader||null!=e.material){let n;n=null!=e.shader?await le(e,t,a):ce(await t.getMaterial(e.material)),null!=n&&!0===e.bloom&&(n.userData.hasBloom=!0),null!=n&&!0===e.bloom&&(n.userData.hasBloom=!0),s.traverse(e=>{e instanceof i.Mesh&&(e.material=n)})}else{const e=[];if(null!=n.materialAssignments)for(const a of n.materialAssignments)s.traverse(s=>{s instanceof i.Mesh&&s.material instanceof i.Material&&s.material.color instanceof i.Color&&(s.material.name!=a.name&&null!=a.name||"#"+s.material.color.getHexString()!==a.color||e.push(t.getMaterial(a.materialId).then(e=>s.material=e)))});await Promise.all(e)}const o=[];if(s.traverse(e=>{e instanceof i.Mesh&&o.push(e)}),1===o.length){const e=o[0];return e.updateWorldMatrix(!0,!0),e.updateMatrixWorld(),e.matrix.copy(e.matrixWorld),e.matrixWorld.decompose(e.position,e.quaternion,e.scale),e.removeFromParent(),e}return s}(e.output,t,v));break;case"trail":I=new a({type:"trail",taper:e.output.taper,headGeometry:null,dragTexture:!1,texture:null!=e.output.texture?await t.getTexture(e.output.texture):null,opacityChannel:e.output.opacityChannel,color:e.output.color,colorEnd:e.output.colorEnd,intensity:e.output.intensity??1,intensityEnd:e.output.intensityEnd??1,length:e.output.length,opacityStart:e.output.opacityStart,opacityEnd:e.output.opacityEnd,bloom:e.output.bloom,scrollSpeed:e.output.scrollSpeed,width:e.output.width,billboard:e.output.billboard??!1});break;default:console.error("Failed to create particly system body: "+JSON.stringify(e))}const S=new pe;S.parent=s,S.setRate(x),S._space=e.output.space;const D=await Promise.all(e.initializers.filter(e=>!1!==e.enabled).filter(e=>null!=$[e.type]).map(async e=>{const t=$[e.type],a=await F(e.params??{});return t.build(a)}));D.push(I,new N),S.addInitializers(D);const V=await Promise.all(e.behaviours.filter(e=>!1!==e.enabled).filter(e=>null!=_[e.type]).map(async e=>{const t=_[e.type];for(const[a,s]of Object.entries(e.params))t.parameters&&null!=t.parameters[a]&&"curve"===t.parameters[a].type&&s.type!==L.Curve&&(s.type=L.Curve);const a=await F(e.params??{});return t.build(a)}).sort((e,t)=>e instanceof te?1:0));V.push(new ue);for(const e of V)e instanceof te&&(e.physics=u);S.addBehaviours(V);for(const a of e.children){const e=await re(a,t,s,u,v),n=new EmitterPool(()=>{const t=e.clone();return t.onExpired=()=>{const e=S.childEmitters.findIndex(e=>e.id===t.id);-1!=e&&S.childEmitters.splice(e,1),n.release(t)},t}),i=S.eventDispatcher,r=new Map;S.bindEmitterEvent=!0,i.addEventListener("PARTICLE_DEAD",e=>{const t=r.get(e.id);if(null!=t){const e=S.childEmitters.findIndex(e=>e.id===t.id);null!=e&&(t.stopEmit(),S.childEmitters.splice(e,1))}});let o="PARTICLE_CREATED";if("spawnEvent"in a)switch(a.spawnEvent){case"collision":o="PARTICLE_COLLISION";break;case"start":o="PARTICLE_CREATED"}i.addEventListener(o,e=>{const t=n.get();t.age=0,t.totalEmitTimes=-1,t.particles.length=0,t.currentEmitTime=0,t.cID=0,t.eventDispatcher.removeAllEventListeners(),S.childEmitters.push(t),r.set(e.id,t),t.parentParticle=e,t.system=S.system,t.emit()})}return S}const oe=(new i.TextureLoader).load("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJkSURBVHjaxJeJbusgEEW94S1L//83X18M2MSuLd2pbqc4wZGqRLrKBsyZhQHny7Jk73xVL8xpVhWrcmiB5lX+6GJ5YgQ2owbAm8oIwH1VgKZUmGcRqKGGPgtEQQAzGR8hQ59fAmhJHSAagigJ4E7GPWRXOYC6owAd1JM6wDQPADyMWUqZRMqmAojHp1Vn6EQQEgUNMJLnUjMyJsM49wygBkAPw9dVFwXRkncCIIW3GRgoTQUZn6HxCMAFEFd8TwEQ78X4rHbILoAUmeT+RFG4UhQ6MiIAE4W/UsYFjuVjAIa2nIY4q1R0GFtQWG3E84lqw2GO2QOoCKBVu0BAPgDSU0eUDjjQenNkV/AW/pWChhpMTelo1a64AOKM30vk18GzTHXCNtI/Knz3DFBgsUqBGIjTInXRY1yA9xkVoqW5tVq3pDR9A0hfF5BSARmVnh7RMDCaIdcNgbPBkgzn1Bu+SfIEFSpSBmkxyrMicb0fAEuCZrWnN89veA/4XcakrPcjBWzkTuLjlbfTQPOlBhz+HwkqqPXmPQDdrQItxE1moGof1S74j/8txk8EHhTQrAE8qlwfqS5yukm1x/rAJ9Jiaa6nyATqD78aUVBhFo8b1V4DdTXdCW+IxA1zB4JhiOhZMEWO1HqnvdoHZ4FAMIhV9REF8FiUm0jsYPEJx/Fm/N8OhH90HI9YRHesWbXXZwAShU8qThe7H8YAuJmw5yOd989uRINKRTJAhoF8jbqrHKfeCYdIISZfSq26bk/K+yO3YvfKrVgiwQBHnwt8ynPB25+M8hceTt/ybPhnryJ78+tLgAEAuCFyiQgQB30AAAAASUVORK5CYII=");async function le(e,t,a){const s=a.get(e.shader);if(null==s)return console.error("No shader exists with name "+e.shader),new i.Material;const n=new s.type,r=await V(e.shaderParams,s.type,t,{getTexture:e=>t.getTexture(e.id),getMaterial:e=>t.getMaterial(e.id),getMesh:e=>t.getMesh(e.id)},void 0,void 0,void 0,void 0);return Object.assign(n,r),n.build()}function ce(e){const t=k(new h("instanceColor")).rgb;let a,s=k(new o("particleData")).x;if(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshBasicMaterial){let n=t.multiply(I(e.color));null!=e.map&&(n=n.multiply(B(e.map).sample(j.uv).rgb)),null!=e.alphaMap&&(s=s.multiply(B(e.alphaMap).sample(j.uv).r)),e instanceof i.MeshStandardMaterial?a=new c({color:S({color:n,emissive:I(e.emissive),emissiveIntensity:v(e.emissiveIntensity),roughness:e.roughness,metalness:e.metalness}).rgb.rgba(s),emissive:I(e.emissive).multiplyScalar(e.emissiveIntensity),transparent:e.transparent,opacity:s,alphaTest:e.alphaTest}):e instanceof i.MeshLambertMaterial?a=new c({color:E({color:n}).rgb.rgba(s),emissive:I(e.emissive).multiplyScalar(e.emissiveIntensity),transparent:e.transparent,opacity:s,alphaTest:e.alphaTest}):e instanceof i.MeshBasicMaterial&&(a=new c({color:n.rgb.rgba(s),emissive:n.rgb,transparent:e.transparent,opacity:s,alphaTest:e.alphaTest}))}else e instanceof c&&(a=e.clone(),a.defines.IS_PARTICLE="");return null!=a&&(!0===e.userData?.hasBloom&&null!=a&&(a.userData.hasBloom=!0),a.side=e.side,a.transparent=e.transparent),a??e}class ue extends t{initialize(e){e.body instanceof i.Object3D&&e.body.traverse(e=>{if(e instanceof i.Mesh){const t=e.material;t instanceof c&&(null!=t.uniforms[H]||null!=t.uniforms[U]||t.uniforms[G])}})}mutate(e,t,a){this.energize(e,t),e.target instanceof r&&e.target.traverse(t=>{if(t instanceof i.Mesh){const a=t.material;a instanceof c&&(null!=a.uniforms[H]&&(a.uniforms[H].value=this.energy),null!=a.uniforms[U]&&(a.uniforms[U].value=e.age),null!=a.uniforms[G]&&(a.uniforms[G].value=e.velocity))}})}}class pe extends s{constructor(){super(...arguments),this.childEmitters=[],this.bindEmitterEvent=!1,this.onExpired=()=>{}}update(e){if(!this.isEmitting&&0===this.particles.length)return;this.age+=e,(this.dead||this.age>=this.life)&&this.destroy(),this.generate(e),this.integrate(e);let t=this.particles.length;for(;t--;){const e=this.particles[t];e.dead&&(this.system&&this.system.dispatch("PARTICLE_DEAD",e),this.bindEmitterEvent&&this.dispatch("PARTICLE_DEAD",e),this.system.pool.expire(e.reset()),this.particles.splice(t,1))}this.updateEmitterBehaviours(e),this.updateChildren(e),this.isEmitting||0!==this.particles.length||this.onExpired()}updateChildren(e){for(const t of this.childEmitters)null!=t.parentParticle?t.position.copy(t.parentParticle.position):t.setPosition(this.position),t.update(e)}clone(){const e=new pe;return e.setRate(this.rate.clone()),e.behaviours=this.behaviours,e.initializers=this.initializers,e._space=this._space,e.body=this.body,e.parent=this.parent,e.system=this.system,e}setParentRecursive(e){this.system=e,this.childEmitters.forEach(t=>t.setParentRecursive(e))}}export class EmitterPool{constructor(e){this.creator=e,this.instances=[]}get(){0==this.instances.length&&this.instances.push(this.creator());return this.instances.pop()}release(e){this.instances.push(e)}dispose(){this.instances.length=0}}/*
1
+ import e,{Behaviour as t,Body as a,Emitter as s,Rate as n}from"@hology/nebula";import*as i from"three";import{Object3D as r}from"three";import{AttributeVec3Node as o,AttributeVec4Node as l,NodeShaderMaterial as c,RgbNode as u,UniformFloatNode as p,UniformVec3Node as m,Vec3ExpressionNode as h,Vec4Node as d,attributeFloat as f,attributeVec3 as y,attributeVec4 as w,attributes as g,clamp as b,float as v,glslFunction as A,lambertMaterial as E,log as M,pow as x,rgb as I,rgba as T,smoothstep as P,standardMaterial as S,textureSampler2d as B,uniformFloat as C,uniforms as R,varying as k,varyingAttributes as j,varyingVec3 as D,varyingVec4 as z}from"three-shader-graph";import{prepareClassParameters as V,prepareShapeParameters as F}from"../../scene/materializer.js";import{SerializedParamType as L}from"../../scene/model.js";import{ShapeLibrary as O}from"../../scene/objects/shapes.js";import{fragmentLinearEyeDepth as Q,linearEyeDepth as W}from"../../shader-nodes/depth.js";import{particleEnergyUniformName as H,particleTimeUniformName as U,particleUniforms as q,particleVelcoityUniformName as G}from"../../shader-nodes/particle.js";import{sampleFlipbook as J}from"../../shader-nodes/texture-sequence.js";import{DefaultInitializer as N}from"./initializsers.js";import{DelayRate as K,OnceRate as Y}from"./rates.js";import{StretchedSprite as X}from"./stretched-sprite.js";import{ThreeBlendingMode as Z}from"./vfx-asset.js";import{VfxBehaviourLibrary as _,VfxInitializserLibrary as $}from"./vfx-defs.js";import{MultiRenderer as ee}from"./vfx-renderers.js";import{WorldCollisionBehaviour as te}from"./vfx-collision-behaviour.js";import{getSpritePosition as ae,SpriteNodeShaderMaterial as se}from"../../shader/sprite-shader.js";import{DecalUnlitShader as ne}from"../../shader/builtin/decal-unlit-shader.js";import{DecalStandardShader as ie}from"../../shader/builtin/decal-standard-shader.js";export async function materializeVfx(t,a,s,n,o,l,c,u){let p=a;for(;null!=p.parent;)p=p.parent;const m=new r;m.name="particle system local",a.add(m);const h=new r;h.name="particle system world";const d=new ee(h,m,i,n),f=new e;return(await Promise.all(t.vfx.emitters.slice().sort((e,t)=>(t.output.renderOrder??0)-(e.output.renderOrder??0)).map(async e=>{const t=await re(e,s,c,u,f,o,l);return t.setParentRecursive(f),t.emit()}))).forEach(e=>f.addEmitter(e)),f.addRenderer(d).emit({onEnd:()=>{}}),{container:h,system:f,dispose:()=>{h.removeFromParent(),m.removeFromParent(),d.dispose()}}}async function re(e,t,s,u,v,x,I){const S=function(e){let t;switch(e.rate.type){case"continuous":t=new K(e.rate.delay??0,e.rate.count,e.rate.time,e.rate.duration);break;case"once":t=new Y(e.rate.delay??0,e.rate.count);break;default:console.warn(`Failed to configure rate for emitter: ${JSON.stringify(e)}`),t=new n(0,1/0)}return t}(e);let D;switch(e.output.type){case"decal":D=new a(await async function(e,t){const a=!1!==e.unlit?new ne:new ie;a.color=new i.Color(e.color),a instanceof ne?a.intensity=e.intensity??1:a.emissiveIntensity=e.intensity??1;if(e.colorMap){const s=await t.getTexture(e.colorMap);a.colorMap=s}if(e.alphaMap){const s=await t.getTexture(e.alphaMap);a.alphaMap=s}const s=a.build();s.blending=Z[e.blendingMode]??i.NormalBlending,s.transparent=!0,s.side=i.BackSide,s.depthTest=!1,null!=s&&!0===e.bloom&&(s.userData.hasBloom=!0);s.defines.IS_PARTICLE="";const n=new i.BoxGeometry(1,1,1),r=new i.Mesh(n,s);null!=e.renderOrder&&(r.renderOrder=e.renderOrder);return r}(e.output,t));break;case"sprite":D=new a(await async function(e,t,a){let s=null;s=null!=e.shader?await le(e,t,a):await async function(e,t){const a=null!=e.texture?await t.getTexture(e.texture):oe,s=B(a);let n=s.sample(j.uv);e.flipbook?.enabled&&(n=J(s,g.uv,e.flipbook.columns,e.flipbook.rows,q.time,e.flipbook.fps,e.flipbook.mode));const r=new p("rotation",0),o=new m("color").rgb,l=C("opacity",1),c=W.subtract(Q).divide(W);let u=l;switch(e.opacityChannel??"red"){case"none":break;case"red":u=u.multiply(n.r);break;case"alpha":u=u.multiply(n.a)}if("number"==typeof e.softness&&e.softness>0){const t=b(c,0,1e3);u=u.multiply(P(0,.2*e.softness,t))}const h=ae(r),d=T(o.multiply(n.rgb).multiplyScalar(e.intensity??1),u);var f=new se({color:d,emissive:d.rgb.multiplyScalar(u),transparent:!0,position:h,alphaTest:1e-4,uniforms:{color:{value:new i.Color(e.color)}}});f.alphaHash=!0,null!=f&&!0===e.bloom&&(f.userData.hasBloom=!0);return f.blending=Z[e.blendingMode]??i.NormalBlending,f}(e,t);s instanceof i.ShaderMaterial&&!0===e.lockY&&(s.defines.LOCK_Y_AXIS="");const n=new i.Mesh(new i.PlaneGeometry(1,1),s);return n.name="sprite",n}(e.output,t,I));break;case"stretchedSprite":D=new a(await async function(e,t){const a=null!=e.texture?await t.getTexture(e.texture):oe,s=B(a).sample(j.uv),n=z(new l("color")),r=n.rgb.multiply(s.rgb);let o=n.w;switch(e.opacityChannel??"red"){case"none":break;case"red":o=o.multiply(s.r);break;case"alpha":o=o.multiply(s.a)}if("number"==typeof e.softness&&e.softness>0){const t=W.subtract(Q).divide(M(W)),a=b(t,0,1e3);o=o.multiply(P(0,.2*e.softness,a))}const c=A(d,{position:g.position,offset:y("offset"),modelViewMatrix:R.modelViewMatrix,velocity:w("velocity"),size:y("size"),rotation:f("rotation")},"\n float lengthFactor = velocity.w;\n float avgSize = (size.x + size.y) * 0.5;\n\n vec4 mvPosition = modelViewMatrix * vec4( offset , 1.0 );\n vec3 viewVelocity = normalMatrix * velocity.xyz;\n float vlength = length(viewVelocity); \n mvPosition.xyz += position.y * normalize(cross(mvPosition.xyz, viewVelocity)) * avgSize; \n mvPosition.xyz -= (position.x + 0.5) * viewVelocity * (1.0 + lengthFactor / vlength) * avgSize;\n return projectionMatrix * mvPosition;\n ");var u=new se({color:T(r.multiplyScalar(e.intensity??1),o),alphaTest:.1,transparent:!0,position:c,uniforms:{color:{value:new i.Color(e.color)}}});null!=u&&!0===e.bloom&&(u.userData.hasBloom=!0);u.blending=Z[e.blendingMode]??i.NormalBlending;const p=new X(new i.PlaneGeometry(1,1),u);return p.scaleFactor=e.scale,p}(e.output,t));break;case"shape":D=new a(await async function(e,t,a){if(null==e.shape)return console.log("Shape is null"),new r;const s=O[e.shape];if(null==s)return console.error(`No shape with type ${e.shape}`),new r;const n=F(e.params??{}),l=s.geometry(n);let u=null;u=null!=e.shader?await le(e,t,a):null!=e.material?ce(await t.getMaterial(e.material)):function(){const e=k(new h("instanceColor")).rgb,t=k(new o("particleData")).x;return new c({color:E({color:e}).rgb.rgba(t),opacity:t,transparent:!0})}();null!=u&&!0===e.bloom&&(u.userData.hasBloom=!0);return new i.Mesh(l,u)}(e.output,t,I));break;case"mesh":D=new a(await async function(e,t,a){if(null==e.assetId)return console.warn("Can't use mesh as particle without asset id"),new r;const s=await t.getMesh(e.assetId),n=await t.getAsset(e.assetId);if(null!=e.shader||null!=e.material){let n;n=null!=e.shader?await le(e,t,a):ce(await t.getMaterial(e.material)),null!=n&&!0===e.bloom&&(n.userData.hasBloom=!0),null!=n&&!0===e.bloom&&(n.userData.hasBloom=!0),s.traverse(e=>{e instanceof i.Mesh&&(e.material=n)})}else{const e=[];if(null!=n.materialAssignments)for(const a of n.materialAssignments)s.traverse(s=>{s instanceof i.Mesh&&s.material instanceof i.Material&&s.material.color instanceof i.Color&&(s.material.name!=a.name&&null!=a.name||"#"+s.material.color.getHexString()!==a.color||e.push(t.getMaterial(a.materialId).then(e=>s.material=e)))});await Promise.all(e)}const o=[];if(s.traverse(e=>{e instanceof i.Mesh&&o.push(e)}),1===o.length){const e=o[0];return e.updateWorldMatrix(!0,!0),e.updateMatrixWorld(),e.matrix.copy(e.matrixWorld),e.matrixWorld.decompose(e.position,e.quaternion,e.scale),e.removeFromParent(),e}return s}(e.output,t,I));break;case"trail":D=new a({type:"trail",taper:e.output.taper,headGeometry:null,dragTexture:!1,texture:null!=e.output.texture?await t.getTexture(e.output.texture):null,opacityChannel:e.output.opacityChannel,color:e.output.color,colorEnd:e.output.colorEnd,intensity:e.output.intensity??1,intensityEnd:e.output.intensityEnd??1,length:e.output.length,opacityStart:e.output.opacityStart,opacityEnd:e.output.opacityEnd,bloom:e.output.bloom,scrollSpeed:e.output.scrollSpeed,width:e.output.width,billboard:e.output.billboard??!1});break;default:console.error("Failed to create particly system body: "+JSON.stringify(e))}const V=new pe;V.parent=v,V.setRate(S),V._space=e.output.space;const H=await Promise.all(e.initializers.filter(e=>!1!==e.enabled).filter(e=>null!=$[e.type]).map(async e=>{const t=$[e.type],a=await F(e.params??{});return t.build(a)}));H.push(D,new N),V.addInitializers(H);const U=await Promise.all(e.behaviours.filter(e=>!1!==e.enabled).filter(e=>null!=_[e.type]).map(async e=>{const t=_[e.type];for(const[a,s]of Object.entries(e.params))t.parameters&&null!=t.parameters[a]&&"curve"===t.parameters[a].type&&s.type!==L.Curve&&(s.type=L.Curve);const a=await F(e.params??{},s,u);return t.build(a)}).sort((e,t)=>e instanceof te?1:0));U.push(new ue);for(const e of U)e instanceof te&&(e.physics=x);V.addBehaviours(U);for(const a of e.children){const e=await re(a,t,s,u,v,x,I),n=new EmitterPool(()=>{const t=e.clone();return t.onExpired=()=>{const e=V.childEmitters.findIndex(e=>e.id===t.id);-1!=e&&V.childEmitters.splice(e,1),n.release(t)},t}),i=V.eventDispatcher,r=new Map;V.bindEmitterEvent=!0,i.addEventListener("PARTICLE_DEAD",e=>{const t=r.get(e.id);if(null!=t){const e=V.childEmitters.findIndex(e=>e.id===t.id);null!=e&&(t.stopEmit(),V.childEmitters.splice(e,1))}});let o="PARTICLE_CREATED";if("spawnEvent"in a)switch(a.spawnEvent){case"collision":o="PARTICLE_COLLISION";break;case"start":o="PARTICLE_CREATED"}i.addEventListener(o,e=>{const t=n.get();t.age=0,t.totalEmitTimes=-1,t.particles.length=0,t.currentEmitTime=0,t.cID=0,t.eventDispatcher.removeAllEventListeners(),V.childEmitters.push(t),r.set(e.id,t),t.parentParticle=e,t.system=V.system,t.emit()})}return V}const oe=(new i.TextureLoader).load("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJkSURBVHjaxJeJbusgEEW94S1L//83X18M2MSuLd2pbqc4wZGqRLrKBsyZhQHny7Jk73xVL8xpVhWrcmiB5lX+6GJ5YgQ2owbAm8oIwH1VgKZUmGcRqKGGPgtEQQAzGR8hQ59fAmhJHSAagigJ4E7GPWRXOYC6owAd1JM6wDQPADyMWUqZRMqmAojHp1Vn6EQQEgUNMJLnUjMyJsM49wygBkAPw9dVFwXRkncCIIW3GRgoTQUZn6HxCMAFEFd8TwEQ78X4rHbILoAUmeT+RFG4UhQ6MiIAE4W/UsYFjuVjAIa2nIY4q1R0GFtQWG3E84lqw2GO2QOoCKBVu0BAPgDSU0eUDjjQenNkV/AW/pWChhpMTelo1a64AOKM30vk18GzTHXCNtI/Knz3DFBgsUqBGIjTInXRY1yA9xkVoqW5tVq3pDR9A0hfF5BSARmVnh7RMDCaIdcNgbPBkgzn1Bu+SfIEFSpSBmkxyrMicb0fAEuCZrWnN89veA/4XcakrPcjBWzkTuLjlbfTQPOlBhz+HwkqqPXmPQDdrQItxE1moGof1S74j/8txk8EHhTQrAE8qlwfqS5yukm1x/rAJ9Jiaa6nyATqD78aUVBhFo8b1V4DdTXdCW+IxA1zB4JhiOhZMEWO1HqnvdoHZ4FAMIhV9REF8FiUm0jsYPEJx/Fm/N8OhH90HI9YRHesWbXXZwAShU8qThe7H8YAuJmw5yOd989uRINKRTJAhoF8jbqrHKfeCYdIISZfSq26bk/K+yO3YvfKrVgiwQBHnwt8ynPB25+M8hceTt/ybPhnryJ78+tLgAEAuCFyiQgQB30AAAAASUVORK5CYII=");async function le(e,t,a){const s=a.get(e.shader);if(null==s)return console.error("No shader exists with name "+e.shader),new i.Material;const n=new s.type,r=await V(e.shaderParams,s.type,t,{getTexture:e=>t.getTexture(e.id),getMaterial:e=>t.getMaterial(e.id),getMesh:e=>t.getMesh(e.id)},void 0,void 0,void 0,void 0);return Object.assign(n,r),n.build()}function ce(e){const t=k(new h("instanceColor")).rgb;let a,s=k(new o("particleData")).x;if(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshBasicMaterial){let n=t.multiply(I(e.color));null!=e.map&&(n=n.multiply(B(e.map).sample(j.uv).rgb)),null!=e.alphaMap&&(s=s.multiply(B(e.alphaMap).sample(j.uv).r)),e instanceof i.MeshStandardMaterial?a=new c({color:S({color:n,emissive:I(e.emissive),emissiveIntensity:v(e.emissiveIntensity),roughness:e.roughness,metalness:e.metalness}).rgb.rgba(s),emissive:I(e.emissive).multiplyScalar(e.emissiveIntensity),transparent:e.transparent,opacity:s,alphaTest:e.alphaTest}):e instanceof i.MeshLambertMaterial?a=new c({color:E({color:n}).rgb.rgba(s),emissive:I(e.emissive).multiplyScalar(e.emissiveIntensity),transparent:e.transparent,opacity:s,alphaTest:e.alphaTest}):e instanceof i.MeshBasicMaterial&&(a=new c({color:n.rgb.rgba(s),emissive:n.rgb,transparent:e.transparent,opacity:s,alphaTest:e.alphaTest}))}else e instanceof c&&(a=e.clone(),a.defines.IS_PARTICLE="");return null!=a&&(!0===e.userData?.hasBloom&&null!=a&&(a.userData.hasBloom=!0),a.side=e.side,a.transparent=e.transparent),a??e}class ue extends t{initialize(e){e.body instanceof i.Object3D&&e.body.traverse(e=>{if(e instanceof i.Mesh){const t=e.material;t instanceof c&&(null!=t.uniforms[H]||null!=t.uniforms[U]||t.uniforms[G])}})}mutate(e,t,a){this.energize(e,t),e.target instanceof r&&e.target.traverse(t=>{if(t instanceof i.Mesh){const a=t.material;a instanceof c&&(null!=a.uniforms[H]&&(a.uniforms[H].value=this.energy),null!=a.uniforms[U]&&(a.uniforms[U].value=e.age),null!=a.uniforms[G]&&(a.uniforms[G].value=e.velocity))}})}}class pe extends s{constructor(){super(...arguments),this.childEmitters=[],this.bindEmitterEvent=!1,this.onExpired=()=>{}}update(e){if(!this.isEmitting&&0===this.particles.length)return;this.age+=e,(this.dead||this.age>=this.life)&&this.destroy(),this.generate(e),this.integrate(e);let t=this.particles.length;for(;t--;){const e=this.particles[t];e.dead&&(this.system&&this.system.dispatch("PARTICLE_DEAD",e),this.bindEmitterEvent&&this.dispatch("PARTICLE_DEAD",e),this.system.pool.expire(e.reset()),this.particles.splice(t,1))}this.updateEmitterBehaviours(e),this.updateChildren(e),this.isEmitting||0!==this.particles.length||this.onExpired()}updateChildren(e){for(const t of this.childEmitters)null!=t.parentParticle?t.position.copy(t.parentParticle.position):t.setPosition(this.position),t.update(e)}clone(){const e=new pe;return e.setRate(this.rate.clone()),e.behaviours=this.behaviours,e.initializers=this.initializers,e._space=this._space,e.body=this.body,e.parent=this.parent,e.system=this.system,e}setParentRecursive(e){this.system=e,this.childEmitters.forEach(t=>t.setParentRecursive(e))}}export class EmitterPool{constructor(e){this.creator=e,this.instances=[]}get(){0==this.instances.length&&this.instances.push(this.creator());return this.instances.pop()}release(e){this.instances.push(e)}dispose(){this.instances.length=0}}/*
2
2
  * Copyright (©) 2025 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,4 +1,4 @@
1
- import e from"typedi";import{loadScene as t}from"../scene/bootstrap.js";import{ActorFactory as n}from"./actors/factory.js";import{World as s}from"./services/world.js";import{SceneMaterializer as o}from"../scene/materializer.js";import{ViewController as r}from"./services/render.js";import{RenderingView as i}from"../rendering.js";import{PhysicsSystem as a}from"./services/physics/physics-system.js";import{MeshComponent as c}from"./actors/builtin/components/mesh-component.js";import{builtInComponents as m}from"./actors/builtin/components/index.js";import{activeContainerInstance as d}from"./actors/internal/container-map.js";import{InputService as l}from"./input/index.js";import{RuntimeAssetsService as p}from"../scene/runtime-asset-service.js";import{AssetResourceLoader as h}from"../scene/asset-resource-loader.js";import{AssetLoader as f}from"./services/asset-loader.js";import{polyfillClient as u}from"./polyfill.js";import{Subject as g}from"rxjs";import{PointerEvents as w}from"./services/pointer-events.js";import{RuntimeBundledBackendService as j}from"../scene/runtime-bundled-backend-service.js";import{Scene as b}from"three";import{ShaderProvider as v}from"./services/shader-provider.js";import{SceneDataService as S}from"../scene/scene-data-service.js";export function initiateGame(l,g){if(u(),0!=g.element.childNodes.length)return console.error("Can not initialize the game with a non-empty html element"),null;e.has(r);const y=e.of("default"),I=new HologyRuntime(y),x=new n(y,{inEditor:!1});var D;e.set(n,x),D=g.element,Object.assign(D.style,{position:"absolute",top:"0",left:"0",width:"100%",height:"100%",overflow:"hidden"});const R=new i(g.element,{enableXR:!0===g.xr?.enabled,maxPixelRatio:g.rendering?.maxPixelRatio,resolutionScale:g.rendering?.resolutionScale,bloom:{enabled:!1!==g?.rendering?.bloom?.enabled},reflection:{enabled:!1!==g?.rendering?.reflection?.enabled},shadows:{cascadeUpdateIntervals:[22,135,250,500]}});R.renderer.shadowMap.enabled=g.rendering?.shadows?.enabled??!0,R.renderer.shadowMap.autoUpdate=g.rendering?.shadows?.autoUpdate??!0,R.renderer.debug.checkShaderErrors=!1,e.set(i,R);const A=new r(R);e.set(r,A);const G=new j,O=new p(G),P=new h;P.setDataDir(g.dataDir),P.initKtx2(R.renderer);const z=Object.entries(g.shaders).map(([e,t])=>({name:e,type:t})),E=Object.entries(g.actors).map(([e,t])=>({name:e,type:t})),H={...m,...g.components??{}},M=Object.entries(H).map(([e,t])=>({name:e,type:t})),U=new v(z);e.set(v,U);const W=new f(P,O,z);e.set(f,W);const k=new b,F=new o(k,new S,O,P,R,z,E,x,M);e.set(o,F);const N=e.get(s);return e.set(s,N),N.materializer=F,(async()=>{const n=e.get(a);if(await n.start(),I.isShutdown)return;if(await G.preloadData(),I.isShutdown)return;N.scene=k;const{scene:s,actors:o}=await t(R,g.sceneName,g.dataDir,g.shaders,g.actors,H,x,G,O,P,{detailTier:g.detailTier});N.scene=s,n.scene=N.scene;for(const e of k.children)N.scene.add(e);if(I.isShutdown)return void R.stop();e.import([c]);for(const e of o)N.addActor(e);n.addFromScene(s),console.log("Start compile shaders"),console.time("compile shaders"),await R.compileAsync(),console.timeEnd("compile shaders"),console.log("Finished compile shaders. Programs: ",R.renderer.info.programs?.length??0),R.loop(e=>{}),I.status=5,I.shutdownStarted.subscribe(()=>{P.disposeAll()}),d.value=y,y.remove(l),y.set({id:l,type:l});const r=y.get(l);d.value=null,I.gameInstance=r,y.get(w).start(),r instanceof GameInstance&&await r.onStart(),I._resolver(!0)})(),I}export class GameInstance{onStart(){}onShutdown(){}}export function createHologyScene(){}export class HologyRuntime{constructor(e){this.containerInstance=e,this.status=0,this.isShutdown=!1,this.shutdownStarted=new g,this.ready=new Promise(e=>{this._resolver=e})}getWorld(){return this.containerInstance.get(s)}getService(e){return this.containerInstance.get(e)}shutdown(){this.isShutdown=!0;const e=this.shutdownStarted;e.next(),e.complete(),this.gameInstance instanceof GameInstance&&this.gameInstance.onShutdown(),this.containerInstance.get(l).stop();const t=this.containerInstance.get(i);t?.stop();const n=this.containerInstance.get(r);n.setMuted(!0),n.dispose();for(const e of this.getWorld().actors)this.getWorld().removeActor(e);this.containerInstance.get(a).stop(),this.containerInstance.get(o).dispose(),this.containerInstance.get(w).stop(),this.containerInstance.reset()}}/*
1
+ import e from"typedi";import{loadScene as t}from"../scene/bootstrap.js";import{ActorFactory as s}from"./actors/factory.js";import{World as n}from"./services/world.js";import{SceneMaterializer as r}from"../scene/materializer.js";import{ViewController as o}from"./services/render.js";import{RenderingView as i}from"../rendering.js";import{PhysicsSystem as a}from"./services/physics/physics-system.js";import{MeshComponent as c}from"./actors/builtin/components/mesh-component.js";import{builtInComponents as m}from"./actors/builtin/components/index.js";import{activeContainerInstance as d}from"./actors/internal/container-map.js";import{InputService as l}from"./input/index.js";import{RuntimeAssetsService as p}from"../scene/runtime-asset-service.js";import{AssetResourceLoader as h}from"../scene/asset-resource-loader.js";import{AssetLoader as f}from"./services/asset-loader.js";import{polyfillClient as u}from"./polyfill.js";import{Subject as g}from"rxjs";import{PointerEvents as w}from"./services/pointer-events.js";import{RuntimeBundledBackendService as j}from"../scene/runtime-bundled-backend-service.js";import{Scene as v}from"three";import{ShaderProvider as b}from"./services/shader-provider.js";import{SceneDataService as S}from"../scene/scene-data-service.js";import{AssetsProvider as y}from"../scene/assets-provider.js";export function initiateGame(l,g){if(u(),0!=g.element.childNodes.length)return console.error("Can not initialize the game with a non-empty html element"),null;e.has(o);const I=e.of("default"),x=new HologyRuntime(I),D=new s(I,{inEditor:!1});var R;e.set(s,D),R=g.element,Object.assign(R.style,{position:"absolute",top:"0",left:"0",width:"100%",height:"100%",overflow:"hidden"});const A=new i(g.element,{enableXR:!0===g.xr?.enabled,maxPixelRatio:g.rendering?.maxPixelRatio,resolutionScale:g.rendering?.resolutionScale,bloom:{enabled:!1!==g?.rendering?.bloom?.enabled},reflection:{enabled:!1!==g?.rendering?.reflection?.enabled},shadows:{cascadeUpdateIntervals:[22,135,250,500]}});A.renderer.shadowMap.enabled=g.rendering?.shadows?.enabled??!0,A.renderer.shadowMap.autoUpdate=g.rendering?.shadows?.autoUpdate??!0,A.renderer.debug.checkShaderErrors=!1,e.set(i,A);const G=new o(A);e.set(o,G);const M=new j,O=new p(M),P=new h;P.setDataDir(g.dataDir),P.initKtx2(A.renderer);const z=Object.entries(g.shaders).map(([e,t])=>({name:e,type:t})),E=Object.entries(g.actors).map(([e,t])=>({name:e,type:t})),H={...m,...g.components??{}},U=Object.entries(H).map(([e,t])=>({name:e,type:t})),W=new b(z);e.set(b,W);const k=new f(P,O,z);e.set(y,this.assetsService),e.set(h,this.assetManagerService),e.set(f,k);const F=new v,N=new r(F,new S,O,P,A,z,E,D,U);e.set(r,N);const T=e.get(n);return e.set(n,T),T.materializer=N,(async()=>{const s=e.get(a);if(await s.start(),x.isShutdown)return;if(await M.preloadData(),x.isShutdown)return;T.scene=F;const{scene:n,actors:r}=await t(A,g.sceneName,g.dataDir,g.shaders,g.actors,H,D,M,O,P,{detailTier:g.detailTier});T.scene=n,s.scene=T.scene;for(const e of F.children)T.scene.add(e);if(x.isShutdown)return void A.stop();e.import([c]);for(const e of r)T.addActor(e);s.addFromScene(n),console.log("Start compile shaders"),console.time("compile shaders"),await A.compileAsync(),console.timeEnd("compile shaders"),console.log("Finished compile shaders. Programs: ",A.renderer.info.programs?.length??0),A.loop(e=>{}),x.status=5,x.shutdownStarted.subscribe(()=>{P.disposeAll()}),d.value=I,I.remove(l),I.set({id:l,type:l});const o=I.get(l);d.value=null,x.gameInstance=o,I.get(w).start(),o instanceof GameInstance&&await o.onStart(),x._resolver(!0)})(),x}export class GameInstance{onStart(){}onShutdown(){}}export function createHologyScene(){}export class HologyRuntime{constructor(e){this.containerInstance=e,this.status=0,this.isShutdown=!1,this.shutdownStarted=new g,this.ready=new Promise(e=>{this._resolver=e})}getWorld(){return this.containerInstance.get(n)}getService(e){return this.containerInstance.get(e)}shutdown(){this.isShutdown=!0;const e=this.shutdownStarted;e.next(),e.complete(),this.gameInstance instanceof GameInstance&&this.gameInstance.onShutdown(),this.containerInstance.get(l).stop();const t=this.containerInstance.get(i);t?.stop();const s=this.containerInstance.get(o);s.setMuted(!0),s.dispose();for(const e of this.getWorld().actors)this.getWorld().removeActor(e);this.containerInstance.get(a).stop(),this.containerInstance.get(r).dispose(),this.containerInstance.get(w).stop(),this.containerInstance.reset()}}/*
2
2
  * Copyright (©) 2025 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,4 +1,4 @@
1
- import{__decorate as e,__metadata as t}from"tslib";import{AudioLoader as s,LoadingManager as a,TextureLoader as r}from"three";import{FBXLoader as i,GLTFLoader as o,MTLLoader as n,OBJLoader as h,TGALoader as d}from"three-stdlib";import{KTX2Loader as l}from"three/examples/jsm/Addons.js";import{Service as c}from"typedi";import{AssetResourceLoader as u}from"../../scene/asset-resource-loader.js";import{applyMaterial as g}from"../../scene/materializer";import{materialFromAsset as w}from"../../scene/materializer.js";import{Prefab as f}from"../../scene/objects/prefab.js";import{pathJoin as m}from"../../utils/files.js";let y=class{constructor(e,t,c){this.assetResourceLoader=e,this.assetService=t,this.shaders=c,this.baseUrl="",this.urlSuffix="",this.loadingManager=new a,this.glbLoader=new o(this.loadingManager),this.fbxLoader=new i(this.loadingManager),this.objLoader=new h(this.loadingManager),this.mtlLoader=new n(this.loadingManager),this.tgaLoader=new d(this.loadingManager),this.ktx2Loader=new l(this.loadingManager),this.textureLoader=new r(this.loadingManager),this.audioLoader=new s(this.loadingManager)}resolvePath(e){return m(this.baseUrl,e)+this.urlSuffix}getAudioAtPath(e){const t=this.resolvePath(e);return this.audioLoader.loadAsync(t)}async getAudioByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No audio could be found with asset id ${e}`);return this.assetResourceLoader.getAudio(t)}async getAudioByAssetName(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No audio could be found with asset name ${e}`);return this.assetResourceLoader.getAudio(t)}async getModelAtPath(e){const t=this.resolvePath(e);switch(e.split(".").pop().toLowerCase()){case"glb":case"gltf":return(await this.glbLoader.loadAsync(t)).scene;case"fbx":return this.fbxLoader.loadAsync(t);case"obj":return this.objLoader.loadAsync(t);default:throw new Error(`File suffix is not supperted in file ${e}`)}}async getGltfAtPath(e){const t=this.resolvePath(e);return this.glbLoader.loadAsync(t)}async getModelByAssetName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if(null==t)throw new Error(`No model could be found with asset name ${e}`);const s=await this.assetResourceLoader.getMesh(t);return this.applyMaterials(t,s.scene),s}async getModelByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No model could be found with asset id ${e}`);const s=await this.assetResourceLoader.getMesh(t);return this.applyMaterials(t,s.scene),s}async applyMaterials(e,t){for(const s of e.materialAssignments??[])await g(t,s,async e=>this.getMaterialByAssetId(e))}async getTextureByAssetName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if(null==t)throw new Error(`No texture could be found with asset name ${e}`);return this.assetResourceLoader.getTexture(t)}async getTextureByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No texture could be found with asset id ${e}`);return this.assetResourceLoader.getTexture(t)}async getMaterialByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No material could be found with asset id ${e}`);return w(t,null,this.assetService,this.assetResourceLoader,this.shaders,!1)}async getAsset(e){return this.assetService.getAsset(e)}async getPrefabByName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if("prefab"!==t.type)throw`Asset with name ${e} is not a prefab`;return new f(t)}async getPrefabById(e){const t=await this.getAsset(e);if("prefab"!==t.type)throw`Asset with name ${name} is not a prefab`;return new f(t)}};y=e([c(),t("design:paramtypes",[u,Object,Array])],y);export{y as AssetLoader};/*
1
+ import{__decorate as e,__metadata as t}from"tslib";import{AudioLoader as s,LoadingManager as a,TextureLoader as r}from"three";import{FBXLoader as i,GLTFLoader as o,MTLLoader as n,OBJLoader as h,TGALoader as d}from"three-stdlib";import{KTX2Loader as l}from"three/examples/jsm/Addons.js";import{Service as c}from"typedi";import{AssetResourceLoader as u}from"../../scene/asset-resource-loader.js";import{applyMaterial as g}from"../../scene/materializer";import{materialFromAsset as w}from"../../scene/materializer.js";import{Prefab as f}from"../../scene/objects/prefab.js";import{pathJoin as m}from"../../utils/files.js";let y=class{constructor(e,t,c){this.assetResourceLoader=e,this.assetService=t,this.shaders=c,this.baseUrl="",this.urlSuffix="",this.loadingManager=new a,this.glbLoader=new o(this.loadingManager),this.fbxLoader=new i(this.loadingManager),this.objLoader=new h(this.loadingManager),this.mtlLoader=new n(this.loadingManager),this.tgaLoader=new d(this.loadingManager),this.ktx2Loader=new l(this.loadingManager),this.textureLoader=new r(this.loadingManager),this.audioLoader=new s(this.loadingManager)}resolvePath(e){return m(this.baseUrl,e)+this.urlSuffix}getAudioAtPath(e){const t=this.resolvePath(e);return this.audioLoader.loadAsync(t)}async getAudioByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No audio could be found with asset id ${e}`);return this.assetResourceLoader.getAudio(t)}async getAudioByAssetName(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No audio could be found with asset name ${e}`);return this.assetResourceLoader.getAudio(t)}async getModelAtPath(e){const t=this.resolvePath(e);switch(e.split(".").pop().toLowerCase()){case"glb":case"gltf":return(await this.glbLoader.loadAsync(t)).scene;case"fbx":return this.fbxLoader.loadAsync(t);case"obj":return this.objLoader.loadAsync(t);default:throw new Error(`File suffix is not supperted in file ${e}`)}}async getGltfAtPath(e){const t=this.resolvePath(e);return this.glbLoader.loadAsync(t)}async getModelByAssetName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if(null==t)throw new Error(`No model could be found with asset name ${e}`);const s=await this.assetResourceLoader.getMesh(t);return this.applyMaterials(t,s.scene),s}async getModelByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No model could be found with asset id ${e}`);const s=await this.assetResourceLoader.getMesh(t);return this.applyMaterials(t,s.scene),s}async applyMaterials(e,t){for(const s of e.materialAssignments??[])await g(t,s,async e=>this.getMaterialByAssetId(e))}async getTextureByAssetName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if(null==t)throw new Error(`No texture could be found with asset name ${e}`);return this.assetResourceLoader.getTexture(t)}async getTextureByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No texture could be found with asset id ${e}`);return this.assetResourceLoader.getTexture(t)}async getMaterialByAssetId(e){const t=await this.assetService.getAsset(e);if(null==t)throw new Error(`No material could be found with asset id ${e}`);return w(t,null,this.assetService,this.assetResourceLoader,this.shaders,!1)}async getAsset(e){return this.assetService.getAsset(e)}async getPrefabByName(e){const t=(await this.assetService.getAssets()).find(t=>t.name===e);if("prefab"!==t.type)throw`Asset with name ${e} is not a prefab`;return new f(t)}async getPrefabById(e){const t=await this.getAsset(e);if("prefab"!==t.type)throw`Asset with name ${name} is not a prefab`;return new f(t)}};y=e([c(),t("design:paramtypes",[u,Function,Array])],y);export{y as AssetLoader};/*
2
2
  * Copyright (©) 2025 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -34,6 +34,8 @@ export declare class AssetResourceLoader {
34
34
  setDataDir(path: string): void;
35
35
  private getUri;
36
36
  private _texturePromises;
37
+ private _animationPromises;
38
+ private _animationCache;
37
39
  /**
38
40
  * Loads a texture for the given asset, handling concurrent calls by caching the promise
39
41
  * based on asset.id. If a request for the same id is already in progress,
@@ -47,6 +49,11 @@ export declare class AssetResourceLoader {
47
49
  getMesh(asset: Asset, options?: GetMeshOptions): Promise<LoadedMesh>;
48
50
  private asyncAudioResults;
49
51
  getAudio(asset: Asset): Promise<AudioBuffer>;
52
+ /**
53
+ * Loads an animation clip for the given asset. The asset should refer to
54
+ * a model file (glb/gltf/fbx) that contains animation clips.
55
+ */
56
+ getAnimationClip(asset: Asset): Promise<THREE.AnimationClip | null>;
50
57
  private collisionShapeCache;
51
58
  private computeCollisionShapes;
52
59
  private loadMesh;
@@ -65,6 +72,10 @@ export declare class AssetResourceLoader {
65
72
  * into separate meshes per material.
66
73
  */
67
74
  private extractGeometryGroups;
75
+ /**
76
+ * Load a mesh by asset using fileKey and fileFormat
77
+ * Used both for meshes and animations
78
+ */
68
79
  private loadByAsset;
69
80
  /**
70
81
  * Dispose all resource loaded.
@@ -1,4 +1,4 @@
1
- import{AudioLoader as e,BufferGeometry as t,Group as s,LoadingManager as r,Mesh as i,Object3D as a,TextureLoader as n}from"three";import{GLTFLoader as o,MTLLoader as h,OBJLoader as l,DRACOLoader as c,LUTCubeLoader as u}from"three-stdlib";import{FBXLoader as d}from"three-stdlib";import{cloneMesh as m}from"../utils/mesh.js";import{pathJoin as f}from"../utils/files.js";import{Subject as p,firstValueFrom as g}from"rxjs";import{importCollisionShapes as w,isCollisionMesh as y}from"./collision/collision-shape-import.js";import*as x from"three";import{iterateMaterials as M}from"../utils/materials.js";import{BufferGeometryUtils as L,EXRLoader as b,KTX2Loader as A,TGALoader as v,UltraHDRLoader as S}from"three/examples/jsm/Addons.js";import{disposeScene as R}from"../utils/three/cleanup.js";const C=new c;C.setDecoderConfig({type:"js"}),C.setDecoderPath("/assets/draco/");const T=["glb","gltf","fbx","obj"];export class AssetResourceLoader{onError(e){console.error(e)}constructor(){this.cache=new Map,this.textureCache=new Map,this.loadingManager=new r,this.glbLoader=new o(this.loadingManager).setDRACOLoader(C),this.fbxLoader=new d(this.loadingManager),this.objLoader=new l(this.loadingManager),this.textureLoader=new n(this.loadingManager),this.tgaLoader=new v(this.loadingManager),this.exrLoader=new b(this.loadingManager),this.cubeLoader=new u(this.loadingManager),this.hdrLoader=new S(this.loadingManager),this.ktx2Loader=new A(this.loadingManager),this._textureLoader=new x.ImageBitmapLoader(this.loadingManager),this.audioLoader=new e(this.loadingManager),this.initialisedKtx2=!1,this._retrievedMeshes=[],this._retrievedTextures=[],this.makeReady=new p,this.ready=g(this.makeReady),this._texturePromises=new Map,this.asyncMeshResults=new Map,this.asyncAudioResults=new Map,this.collisionShapeCache=new Map,this.optimizedMeshes=new Set}initKtx2(e){this.initialisedKtx2=!0;null!=getElectronArg("windowId")||import.meta.url.includes(".vite")||import.meta.url.includes("hology/packages/core")?this.ktx2Loader.setTranscoderPath("/assets/basis/"):this.ktx2Loader.setTranscoderPath(new URL("../assets/basis/",import.meta.url).href),this.ktx2Loader.detectSupport(e)}setDataDir(e){this.basePath=f(e,"asset-resources"),this.makeReady.next(!0)}getUri(e){const t=getElectronArg("windowId");return null!=t||import.meta.url.includes(".vite")||import.meta.url.includes("hology/packages/core")?f(this.basePath,e)+(null!=t?`?windowId=${t}`:""):new URL(f("..",this.basePath,e),import.meta.url).href}async getTexture(e){if(!e||!e.fileKey)return null;if(this._texturePromises.has(e.id))return this._texturePromises.get(e.id);const t=this._getTexture(e).finally(()=>{this._texturePromises.delete(e.id)});return this._texturePromises.set(e.id,t),t}async _getTexture(e){if(null==e||null==e.fileKey)return null;if(await this.ready,this.textureCache.has(e.id)){const t=this.textureCache.get(e.id);t.dispose(),null!=e.texture&&(t.flipY!==e.texture?.flipY?(t.needsUpdate=!0,t.flipY=e.texture?.flipY??!0):t.wrapS!==j(e.texture?.wrapS)?(t.needsUpdate=!0,t.wrapS=j(e.texture?.wrapS)):t.wrapT!==j(e.texture?.wrapT)&&(t.wrapT=j(e.texture?.wrapT),t.needsUpdate=!0))}else try{await this._getTextureLoader(e.fileKey).loadAsync(this.getUri(e.fileKey)).then(t=>(t.texture3D?t=t.texture3D:(t.wrapS=j(e.texture?.wrapS),t.wrapT=j(e.texture?.wrapT),t.flipY=e.texture?.flipY??!0),this.textureCache.set(e.id,t),this._retrievedTextures.push(t),t))}catch(t){return console.warn("Failed to load texture "+e.name,t),null}return this.textureCache.get(e.id)}_getTextureLoader(e){return e?.toLowerCase().endsWith(".tga")?this.tgaLoader:e?.toLowerCase().endsWith(".ktx2")?this.ktx2Loader:e?.toLowerCase().endsWith(".exr")?this.exrLoader:e?.toLowerCase().endsWith(".cube")?this.cubeLoader:this.textureLoader}clearCache(e){"mesh"===e.type&&Array.from(this.cache.keys()).forEach(t=>{t.startsWith(e.fileKey)&&this.cache.delete(t)})}async getMesh(e,t){if(await this.ready,null==e)return console.error("No asset was provided"),{scene:new s,animations:[]};if(!T.includes(e.fileFormat?.toLowerCase()))return console.error("Unsupported mesh file format "+e.fileFormat,e),{scene:new s,animations:[]};const r=e.fileKey+(!0===t?.mergeGeomtries?"1":"0");if(!this.cache.has(r))try{this.asyncMeshResults.has(r)||this.asyncMeshResults.set(r,this.loadMesh(e).finally(()=>this.asyncMeshResults.delete(r))),this.cache.set(r,await this.asyncMeshResults.get(r))}catch(e){return this.onError(e),{scene:new s,animations:[]}}const a=this.cache.get(r).scene,n=this.computeCollisionShapes(e,a);!0===t?.mergeGeomtries&&this.optimizeDrawGroups(a);const o=m(a),h=this.cache.get(r).animations;o.traverse(e=>{e instanceof i&&e.material instanceof Array&&(e.material=e.material.slice())});const l=new AssetMeshInstance;l.add(o),l.collisionShapes=n,l.animations=h;const c=e.receiveShadow??!0,u=e.castShadow??!1;return o.traverse(e=>{e.castShadow=u,e.receiveShadow=c}),{scene:l,animations:h}}async getAudio(e){await this.ready;const t=e.fileKey;if(this.asyncAudioResults.has(t))return await this.asyncAudioResults.get(t);const s=this.audioLoader.loadAsync(this.getUri(e.fileKey)).finally(()=>{setTimeout(()=>{this.asyncAudioResults.delete(t)},1e3)});return this.asyncAudioResults.set(t,s),s}computeCollisionShapes(e,t){const s=e.id+e.mesh?.collisions?.shapeType;return this.collisionShapeCache.has(s)||this.collisionShapeCache.set(s,w(t,e)),this.collisionShapeCache.get(s)}async loadMesh(e){return await this.ready,await this.loadByAsset(e).then(e=>(e.scene.traverse(e=>{e instanceof i&&e.material,y(e)?e.visible=!1:e instanceof i&&e.geometry instanceof t&&(e.geometry.hasAttribute("normal")||e.geometry.computeVertexNormals())}),this._retrievedMeshes.push(e.scene),e.scene=function(e,t){let s=!1;if(t.traverseVisible(e=>{k.test(e.name)&&(s=!0)}),!s)return t;const r=new x.LOD,i=[t];for(;i.length>0;){const e=i.shift(),t=e.name.match(k);if(null!=t){const s=parseInt(t[1]);0===s?r.addLevel(e,0):console.warn(`Skipping LOD level ${s} for now as LOD is not fully supported`)}else i.push(...e.children)}return r}(0,e.scene),e))}optimizeDrawGroups(e){if(this.optimizedMeshes.has(e.uuid))return;this.optimizedMeshes.add(e.uuid);let s=!0,r=0,a=0;if(e.traverse(e=>{if(e instanceof i&&e.geometry instanceof t&&!y(e)){r++;const t=Object.keys(e.geometry.attributes).length;t!==a&&0!==a&&(s=!1),a=t}else(e instanceof x.SkinnedMesh||e instanceof x.Bone)&&(s=!1)}),r>1&&s){const s=new Map;e.updateWorldMatrix(!0,!0),e.traverse(e=>{if(e instanceof i&&e.geometry instanceof t&&!y(e)){if(Array.isArray(e.material))return;e.updateWorldMatrix(!0,!0);const t=e.material?.uuid||"default";s.has(t)||s.set(t,{material:e.material,geometries:[],objects:[]});const r=s.get(t);r.geometries.push(e.geometry.clone().applyMatrix4(e.matrixWorld)),r.objects.push(e)}});for(const e of s.values())for(const t of e.objects)t.removeFromParent();for(const t of s.values()){let s;s=1===t.geometries.length?t.geometries[0]:L.mergeGeometries(t.geometries,!0),s.groups.length>1&&L.mergeGroups(s),e.add(new i(s,t.material))}}const n=[];e.traverse(e=>{e instanceof i&&e.geometry instanceof t&&Array.isArray(e.material)&&!y(e)&&n.push({mesh:e,geometry:e.geometry,materialArray:e.material,parent:e.parent})});for(const{mesh:t,geometry:s,materialArray:r,parent:a}of n){t.removeFromParent();for(let t=0;t<r.length;t++){const n=r[t],o=s.groups.filter(e=>e.materialIndex===t);if(0===o.length)continue;const h=this.extractGeometryGroups(s,o);h.groups.length>1&&L.mergeGroups(h);const l=new i(h,n);a?a.add(l):e.add(l)}s.dispose()}e.traverse(e=>{if(e instanceof i&&e.geometry instanceof t&&!y(e)){const t=e.geometry;!Array.isArray(e.material)&&t.groups.length>1&&L.mergeGroups(t)}})}extractGeometryGroups(e,s){const r=e.index;if(!r){const r=new t;let i=0;for(const e of s)i+=e.count;if(0===i)return r;for(const t in e.attributes){const a=e.attributes[t],n=a.itemSize,o=a.array,h=new(0,o.constructor)(i*n);let l=0;for(const e of s){const t=e.start*n,s=e.count*n;for(let e=0;e<s;e++)h[l+e]=o[t+e];l+=s}const c=new x.BufferAttribute(h,n,a.normalized);r.setAttribute(t,c)}return r.groups=[{start:0,count:i,materialIndex:0}],r}const i=[];for(const e of s)for(let t=0;t<e.count;t++){const s=r.getX(e.start+t);i.push(s)}if(0===i.length)return new t;const a=new Map,n=[];let o=0;for(const e of i)a.has(e)||(a.set(e,o),o++),n.push(a.get(e));if(0===n.length||0===a.size)return new t;const h=new t;for(const t in e.attributes){const s=e.attributes[t],r=s.itemSize,i=s.array,n=new(0,i.constructor)(a.size*r);for(const[e,t]of a)for(let s=0;s<r;s++)n[t*r+s]=i[e*r+s];const o=new x.BufferAttribute(n,r,s.normalized);h.setAttribute(t,o)}const l=new((n.length>0?Math.max(...n):0)>65535?Uint32Array:Uint16Array)(n.length);for(let e=0;e<n.length;e++)l[e]=n[e];return h.setIndex(new x.BufferAttribute(l,1)),h.groups=[{start:0,count:n.length,materialIndex:0}],h}async loadByAsset(e){this.fbxLoader;const t=this.getUri(e.fileKey);switch(e.fileFormat){case"glb":case"gltf":return this.glbLoader.loadAsync(t).then(e=>({scene:e.scene,animations:e.animations}));case"fbx":return this.fbxLoader.loadAsync(t).then(e=>({scene:e,animations:e.animations}));case"obj":if(null!=e.materialLib){const t=new h;t.materialOptions={normalizeRGB:!1};const s=await t.loadAsync(this.getUri(e.materialLib));this.objLoader.setMaterials(s)}return this.objLoader.loadAsync(t).then(e=>(_(e),e)).then(e=>({scene:e,animations:e.animations}))}}disposeAll(){this.cache.clear(),this._retrievedMeshes.forEach(e=>R(e)),this._retrievedTextures.forEach(e=>e.dispose()),this._retrievedMeshes.length=0,this._retrievedTextures.length=0}}function _(e){if(e instanceof i)for(const t of M(e.material))t instanceof x.MeshPhongMaterial&&!t.color.isLinear&&(t.color.isLinear=!0);e.children?.forEach(_)}export class AssetMeshInstance extends a{}export function getElectronArg(e){const t=`--${e}=`,s=window.process?.argv.find(e=>e.startsWith(t));return s?.substring(t.length)}function j(e){switch(e){case"clamp":return x.ClampToEdgeWrapping;case"repeat":return x.RepeatWrapping;case"mirror":return x.MirroredRepeatWrapping}return x.RepeatWrapping}new x.Matrix4;const k=/_LOD(\d+)$/;/*
1
+ import{AudioLoader as e,BufferGeometry as t,Group as s,LoadingManager as r,Mesh as i,Object3D as a,TextureLoader as n}from"three";import{GLTFLoader as o,MTLLoader as h,OBJLoader as l,DRACOLoader as c,LUTCubeLoader as u}from"three-stdlib";import{FBXLoader as d}from"three-stdlib";import{cloneMesh as m}from"../utils/mesh.js";import{pathJoin as f}from"../utils/files.js";import{Subject as p,firstValueFrom as g}from"rxjs";import{importCollisionShapes as w,isCollisionMesh as y}from"./collision/collision-shape-import.js";import*as x from"three";import{iterateMaterials as M}from"../utils/materials.js";import{BufferGeometryUtils as L,EXRLoader as b,KTX2Loader as A,TGALoader as v,UltraHDRLoader as _}from"three/examples/jsm/Addons.js";import{disposeScene as C}from"../utils/three/cleanup.js";const S=new c;S.setDecoderConfig({type:"js"}),S.setDecoderPath("/assets/draco/");const R=["glb","gltf","fbx","obj"];export class AssetResourceLoader{onError(e){console.error(e)}constructor(){this.cache=new Map,this.textureCache=new Map,this.loadingManager=new r,this.glbLoader=new o(this.loadingManager).setDRACOLoader(S),this.fbxLoader=new d(this.loadingManager),this.objLoader=new l(this.loadingManager),this.textureLoader=new n(this.loadingManager),this.tgaLoader=new v(this.loadingManager),this.exrLoader=new b(this.loadingManager),this.cubeLoader=new u(this.loadingManager),this.hdrLoader=new _(this.loadingManager),this.ktx2Loader=new A(this.loadingManager),this._textureLoader=new x.ImageBitmapLoader(this.loadingManager),this.audioLoader=new e(this.loadingManager),this.initialisedKtx2=!1,this._retrievedMeshes=[],this._retrievedTextures=[],this.makeReady=new p,this.ready=g(this.makeReady),this._texturePromises=new Map,this._animationPromises=new Map,this._animationCache=new Map,this.asyncMeshResults=new Map,this.asyncAudioResults=new Map,this.collisionShapeCache=new Map,this.optimizedMeshes=new Set}initKtx2(e){this.initialisedKtx2=!0;null!=getElectronArg("windowId")||import.meta.url.includes(".vite")||import.meta.url.includes("hology/packages/core")?this.ktx2Loader.setTranscoderPath("/assets/basis/"):this.ktx2Loader.setTranscoderPath(new URL("../assets/basis/",import.meta.url).href),this.ktx2Loader.detectSupport(e)}setDataDir(e){this.basePath=f(e,"asset-resources"),this.makeReady.next(!0)}getUri(e){const t=getElectronArg("windowId");return null!=t||import.meta.url.includes(".vite")||import.meta.url.includes("hology/packages/core")?f(this.basePath,e)+(null!=t?`?windowId=${t}`:""):new URL(f("..",this.basePath,e),import.meta.url).href}async getTexture(e){if(!e||!e.fileKey)return null;if(this._texturePromises.has(e.id))return this._texturePromises.get(e.id);const t=this._getTexture(e).finally(()=>{this._texturePromises.delete(e.id)});return this._texturePromises.set(e.id,t),t}async _getTexture(e){if(null==e||null==e.fileKey)return null;if(await this.ready,this.textureCache.has(e.id)){const t=this.textureCache.get(e.id);t.dispose(),null!=e.texture&&(t.flipY!==e.texture?.flipY?(t.needsUpdate=!0,t.flipY=e.texture?.flipY??!0):t.wrapS!==P(e.texture?.wrapS)?(t.needsUpdate=!0,t.wrapS=P(e.texture?.wrapS)):t.wrapT!==P(e.texture?.wrapT)&&(t.wrapT=P(e.texture?.wrapT),t.needsUpdate=!0))}else try{await this._getTextureLoader(e.fileKey).loadAsync(this.getUri(e.fileKey)).then(t=>(t.texture3D?t=t.texture3D:(t.wrapS=P(e.texture?.wrapS),t.wrapT=P(e.texture?.wrapT),t.flipY=e.texture?.flipY??!0),this.textureCache.set(e.id,t),this._retrievedTextures.push(t),t))}catch(t){return console.warn("Failed to load texture "+e.name,t),null}return this.textureCache.get(e.id)}_getTextureLoader(e){return e?.toLowerCase().endsWith(".tga")?this.tgaLoader:e?.toLowerCase().endsWith(".ktx2")?this.ktx2Loader:e?.toLowerCase().endsWith(".exr")?this.exrLoader:e?.toLowerCase().endsWith(".cube")?this.cubeLoader:this.textureLoader}clearCache(e){"mesh"===e.type&&Array.from(this.cache.keys()).forEach(t=>{t.startsWith(e.fileKey)&&this.cache.delete(t)})}async getMesh(e,t){if(await this.ready,null==e)return console.error("No asset was provided"),{scene:new s,animations:[]};if(!R.includes(e.fileFormat?.toLowerCase()))return console.error("Unsupported mesh file format "+e.fileFormat,e),{scene:new s,animations:[]};const r=e.fileKey+(!0===t?.mergeGeomtries?"1":"0");if(!this.cache.has(r))try{this.asyncMeshResults.has(r)||this.asyncMeshResults.set(r,this.loadMesh(e).finally(()=>this.asyncMeshResults.delete(r))),this.cache.set(r,await this.asyncMeshResults.get(r))}catch(e){return this.onError(e),{scene:new s,animations:[]}}const a=this.cache.get(r).scene,n=this.computeCollisionShapes(e,a);!0===t?.mergeGeomtries&&this.optimizeDrawGroups(a);const o=m(a),h=this.cache.get(r).animations;o.traverse(e=>{e instanceof i&&e.material instanceof Array&&(e.material=e.material.slice())});const l=new AssetMeshInstance;l.add(o),l.collisionShapes=n,l.animations=h;const c=e.receiveShadow??!0,u=e.castShadow??!1;return o.traverse(e=>{e.castShadow=u,e.receiveShadow=c}),{scene:l,animations:h}}async getAudio(e){await this.ready;const t=e.fileKey;if(this.asyncAudioResults.has(t))return await this.asyncAudioResults.get(t);const s=this.audioLoader.loadAsync(this.getUri(e.fileKey)).finally(()=>{setTimeout(()=>{this.asyncAudioResults.delete(t)},1e3)});return this.asyncAudioResults.set(t,s),s}async getAnimationClip(e){if(null==e||null==e.fileKey||null==!e.anim?.clip)return console.warn("Asset or animation clip name is not defined",e),null;const t=e.anim.clip,s=e.fileKey+"|"+t;if(this._animationCache.has(s))return this._animationCache.get(s);if(this._animationPromises.has(s))return this._animationPromises.get(s);const r=(async()=>{try{const r=await this.getMesh(e),i=r.animations.find(e=>e.name===t);return null!=i&&this._animationCache.set(s,i),i}catch(e){return this.onError(e),null}finally{setTimeout(()=>this._animationPromises.delete(s),1e3)}})();return this._animationPromises.set(s,r),r}computeCollisionShapes(e,t){const s=e.id+e.mesh?.collisions?.shapeType;return this.collisionShapeCache.has(s)||this.collisionShapeCache.set(s,w(t,e)),this.collisionShapeCache.get(s)}async loadMesh(e){return await this.ready,await this.loadByAsset(e).then(e=>(e.scene.traverse(e=>{e instanceof i&&e.material,y(e)?e.visible=!1:e instanceof i&&e.geometry instanceof t&&(e.geometry.hasAttribute("normal")||e.geometry.computeVertexNormals())}),this._retrievedMeshes.push(e.scene),e.scene=function(e,t){let s=!1;if(t.traverseVisible(e=>{j.test(e.name)&&(s=!0)}),!s)return t;const r=new x.LOD,i=[t];for(;i.length>0;){const e=i.shift(),t=e.name.match(j);if(null!=t){const s=parseInt(t[1]);0===s?r.addLevel(e,0):console.warn(`Skipping LOD level ${s} for now as LOD is not fully supported`)}else i.push(...e.children)}return r}(0,e.scene),e))}optimizeDrawGroups(e){if(this.optimizedMeshes.has(e.uuid))return;this.optimizedMeshes.add(e.uuid);let s=!0,r=0,a=0;if(e.traverse(e=>{if(e instanceof i&&e.geometry instanceof t&&!y(e)){r++;const t=Object.keys(e.geometry.attributes).length;t!==a&&0!==a&&(s=!1),a=t}else(e instanceof x.SkinnedMesh||e instanceof x.Bone)&&(s=!1)}),r>1&&s){const s=new Map;e.updateWorldMatrix(!0,!0),e.traverse(e=>{if(e instanceof i&&e.geometry instanceof t&&!y(e)){if(Array.isArray(e.material))return;e.updateWorldMatrix(!0,!0);const t=e.material?.uuid||"default";s.has(t)||s.set(t,{material:e.material,geometries:[],objects:[]});const r=s.get(t);r.geometries.push(e.geometry.clone().applyMatrix4(e.matrixWorld)),r.objects.push(e)}});for(const e of s.values())for(const t of e.objects)t.removeFromParent();for(const t of s.values()){let s;s=1===t.geometries.length?t.geometries[0]:L.mergeGeometries(t.geometries,!0),s.groups.length>1&&L.mergeGroups(s),e.add(new i(s,t.material))}}const n=[];e.traverse(e=>{e instanceof i&&e.geometry instanceof t&&Array.isArray(e.material)&&!y(e)&&n.push({mesh:e,geometry:e.geometry,materialArray:e.material,parent:e.parent})});for(const{mesh:t,geometry:s,materialArray:r,parent:a}of n){t.removeFromParent();for(let t=0;t<r.length;t++){const n=r[t],o=s.groups.filter(e=>e.materialIndex===t);if(0===o.length)continue;const h=this.extractGeometryGroups(s,o);h.groups.length>1&&L.mergeGroups(h);const l=new i(h,n);a?a.add(l):e.add(l)}s.dispose()}e.traverse(e=>{if(e instanceof i&&e.geometry instanceof t&&!y(e)){const t=e.geometry;!Array.isArray(e.material)&&t.groups.length>1&&L.mergeGroups(t)}})}extractGeometryGroups(e,s){const r=e.index;if(!r){const r=new t;let i=0;for(const e of s)i+=e.count;if(0===i)return r;for(const t in e.attributes){const a=e.attributes[t],n=a.itemSize,o=a.array,h=new(0,o.constructor)(i*n);let l=0;for(const e of s){const t=e.start*n,s=e.count*n;for(let e=0;e<s;e++)h[l+e]=o[t+e];l+=s}const c=new x.BufferAttribute(h,n,a.normalized);r.setAttribute(t,c)}return r.groups=[{start:0,count:i,materialIndex:0}],r}const i=[];for(const e of s)for(let t=0;t<e.count;t++){const s=r.getX(e.start+t);i.push(s)}if(0===i.length)return new t;const a=new Map,n=[];let o=0;for(const e of i)a.has(e)||(a.set(e,o),o++),n.push(a.get(e));if(0===n.length||0===a.size)return new t;const h=new t;for(const t in e.attributes){const s=e.attributes[t],r=s.itemSize,i=s.array,n=new(0,i.constructor)(a.size*r);for(const[e,t]of a)for(let s=0;s<r;s++)n[t*r+s]=i[e*r+s];const o=new x.BufferAttribute(n,r,s.normalized);h.setAttribute(t,o)}const l=new((n.length>0?Math.max(...n):0)>65535?Uint32Array:Uint16Array)(n.length);for(let e=0;e<n.length;e++)l[e]=n[e];return h.setIndex(new x.BufferAttribute(l,1)),h.groups=[{start:0,count:n.length,materialIndex:0}],h}async loadByAsset(e){this.fbxLoader;const t=this.getUri(e.fileKey);switch(e.fileFormat){case"glb":case"gltf":return this.glbLoader.loadAsync(t).then(e=>({scene:e.scene,animations:e.animations}));case"fbx":return this.fbxLoader.loadAsync(t).then(e=>({scene:e,animations:e.animations}));case"obj":if(null!=e.materialLib){const t=new h;t.materialOptions={normalizeRGB:!1};const s=await t.loadAsync(this.getUri(e.materialLib));this.objLoader.setMaterials(s)}return this.objLoader.loadAsync(t).then(e=>(T(e),e)).then(e=>({scene:e,animations:e.animations}))}}disposeAll(){this.cache.clear(),this._retrievedMeshes.forEach(e=>C(e)),this._retrievedTextures.forEach(e=>e.dispose()),this._retrievedMeshes.length=0,this._retrievedTextures.length=0}}function T(e){if(e instanceof i)for(const t of M(e.material))t instanceof x.MeshPhongMaterial&&!t.color.isLinear&&(t.color.isLinear=!0);e.children?.forEach(T)}export class AssetMeshInstance extends a{}export function getElectronArg(e){const t=`--${e}=`,s=window.process?.argv.find(e=>e.startsWith(t));return s?.substring(t.length)}function P(e){switch(e){case"clamp":return x.ClampToEdgeWrapping;case"repeat":return x.RepeatWrapping;case"mirror":return x.MirroredRepeatWrapping}return x.RepeatWrapping}new x.Matrix4;const j=/_LOD(\d+)$/;/*
2
2
  * Copyright (©) 2025 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,10 +1,10 @@
1
1
  import { Subject } from "rxjs";
2
2
  import { Asset, AssetId } from './model.js';
3
- export interface AssetsProvider {
3
+ export declare abstract class AssetsProvider {
4
4
  onCreate: Subject<Asset>;
5
5
  onDelete: Subject<Asset>;
6
6
  onUpdate: Subject<Asset>;
7
- getAsset(assetId: AssetId): Promise<Asset>;
8
- getAssets(): Promise<Asset[]>;
7
+ abstract getAsset(assetId: AssetId): Promise<Asset>;
8
+ abstract getAssets(): Promise<Asset[]>;
9
9
  }
10
10
  //# sourceMappingURL=assets-provider.d.ts.map
@@ -1,4 +1,4 @@
1
- export{};/*
1
+ export class AssetsProvider{}/*
2
2
  * Copyright (©) 2025 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -442,7 +442,7 @@ prefabResolver?: (prefabInstanceId: string) => string | null): Promise<{
442
442
  }>;
443
443
  export declare function prepareShapeParameters(paramsSource: {
444
444
  [key: string]: CustomParamValue;
445
- }): Promise<{
445
+ }, assetProvider?: AssetsProvider, assetManagerService?: AssetResourceLoader): Promise<{
446
446
  [key: string]: unknown;
447
447
  }>;
448
448
  export declare function toSerializedParamType(type: Type<any>): SerializedParamType;