@eigong/effekseer-webgpu-runtime 0.1.10 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -2
- package/debug.d.ts +3 -1
- package/index.d.ts +223 -1
- package/package.json +1 -1
- package/runtime/effekseer.webgpu.js +1 -1
- package/runtime/effekseer.webgpu.src.js +506 -15
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
`@eigong/effekseer-webgpu-runtime` redistributes the Effekseer WebGPU runtime files needed by browser integrations.
|
|
4
4
|
|
|
5
|
-
The package
|
|
5
|
+
The package separates the bridge into:
|
|
6
6
|
|
|
7
7
|
- client bridge: `effekseer.webgpu.js`
|
|
8
8
|
- debug/source bridge: `effekseer.webgpu.src.js`
|
|
@@ -55,9 +55,42 @@ import { getEffekseerWebGPURuntimeUrls } from '@eigong/effekseer-webgpu-runtime'
|
|
|
55
55
|
const urls = getEffekseerWebGPURuntimeUrls()
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
+
## Registered Effects And Warm-Up
|
|
59
|
+
|
|
60
|
+
```js
|
|
61
|
+
import {
|
|
62
|
+
loadEffekseerWebGPURuntime,
|
|
63
|
+
effekseerWebgpuRuntimeWasmUrl,
|
|
64
|
+
} from '@eigong/effekseer-webgpu-runtime'
|
|
65
|
+
|
|
66
|
+
const effekseer = await loadEffekseerWebGPURuntime()
|
|
67
|
+
effekseer.setWebGPUDevice(device)
|
|
68
|
+
await effekseer.initRuntime(effekseerWebgpuRuntimeWasmUrl)
|
|
69
|
+
|
|
70
|
+
const ctx = effekseer.createContext()
|
|
71
|
+
ctx.initExternal({
|
|
72
|
+
warmupSettings: {
|
|
73
|
+
colorFormat: presentationFormat,
|
|
74
|
+
depthFormat: 'depth24plus',
|
|
75
|
+
sampleCount: 1,
|
|
76
|
+
includeDepthTexture: true,
|
|
77
|
+
},
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
ctx.registerEffects({
|
|
81
|
+
flame: {
|
|
82
|
+
path: '/fx/flame.efkwgpk',
|
|
83
|
+
preload: true,
|
|
84
|
+
warmup: true,
|
|
85
|
+
},
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
await ctx.whenEffectsReady(['flame'])
|
|
89
|
+
```
|
|
90
|
+
|
|
58
91
|
## API Reference
|
|
59
92
|
|
|
60
|
-
La referencia breve de la API
|
|
93
|
+
La referencia breve de la API publica esta en [API.md](./API.md).
|
|
61
94
|
|
|
62
95
|
## License
|
|
63
96
|
|
package/debug.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { EffekseerApi } from "./index.js"
|
|
2
|
+
|
|
1
3
|
export declare const effekseerWebgpuDebugBridgeUrl: string
|
|
2
4
|
|
|
3
5
|
export declare function getEffekseerWebGPUDebugRuntimeUrls(): {
|
|
@@ -7,4 +9,4 @@ export declare function getEffekseerWebGPUDebugRuntimeUrls(): {
|
|
|
7
9
|
effekseerWebgpuBridgeUrl: string
|
|
8
10
|
}
|
|
9
11
|
|
|
10
|
-
export declare function loadEffekseerWebGPUDebugRuntime(): Promise<
|
|
12
|
+
export declare function loadEffekseerWebGPUDebugRuntime(): Promise<EffekseerApi>
|
package/index.d.ts
CHANGED
|
@@ -3,6 +3,228 @@ export declare const effekseerWebgpuRuntimeJsUrl: string
|
|
|
3
3
|
export declare const effekseerWebgpuRuntimeWasmUrl: string
|
|
4
4
|
export declare const effekseerWebgpuBridgeUrl: string
|
|
5
5
|
|
|
6
|
+
export type ManagedEffectInput =
|
|
7
|
+
| string
|
|
8
|
+
| {
|
|
9
|
+
path: string
|
|
10
|
+
scale?: number
|
|
11
|
+
preload?: boolean
|
|
12
|
+
warmup?: boolean
|
|
13
|
+
enabled?: boolean
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type WarmupSettings = {
|
|
17
|
+
colorFormat?: GPUTextureFormat
|
|
18
|
+
depthFormat?: GPUTextureFormat | null
|
|
19
|
+
sampleCount?: number
|
|
20
|
+
width?: number
|
|
21
|
+
height?: number
|
|
22
|
+
frames?: number
|
|
23
|
+
includeDepthTexture?: boolean
|
|
24
|
+
includeBackgroundTexture?: boolean
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type ContextInitSettings = {
|
|
28
|
+
instanceMaxCount?: number
|
|
29
|
+
squareMaxCount?: number
|
|
30
|
+
linearColorSpace?: boolean
|
|
31
|
+
compositeWithBackground?: boolean
|
|
32
|
+
externalRenderPass?: boolean
|
|
33
|
+
effects?: Record<string, ManagedEffectInput>
|
|
34
|
+
warmupSettings?: WarmupSettings
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export type EffekseerRenderPassState = {
|
|
38
|
+
colorFormat: GPUTextureFormat
|
|
39
|
+
depthFormat?: GPUTextureFormat | null
|
|
40
|
+
sampleCount?: number
|
|
41
|
+
backgroundTextureView?: GPUTextureView | null
|
|
42
|
+
depthTextureView?: GPUTextureView | null
|
|
43
|
+
importBackgroundTextureView?: GPUTextureView | null
|
|
44
|
+
importDepthTextureView?: GPUTextureView | null
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface EffekseerEffect {
|
|
48
|
+
nativeptr: number
|
|
49
|
+
readonly isLoaded: boolean
|
|
50
|
+
scale: number
|
|
51
|
+
baseDir?: string
|
|
52
|
+
packageOnly?: boolean
|
|
53
|
+
syncResourceLoad?: boolean
|
|
54
|
+
redirect?: ((path: string) => string) | null
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface EffekseerHandle {
|
|
58
|
+
readonly exists: boolean
|
|
59
|
+
stop(): void
|
|
60
|
+
stopRoot(): void
|
|
61
|
+
setFrame(frame: number): void
|
|
62
|
+
setLocation(x: number, y: number, z: number): void
|
|
63
|
+
setRotation(x: number, y: number, z: number): void
|
|
64
|
+
setScale(x: number, y: number, z: number): void
|
|
65
|
+
setMatrix(matrixArray: ArrayLike<number>): void
|
|
66
|
+
setAllColor(r: number, g: number, b: number, a: number): void
|
|
67
|
+
setTargetLocation(x: number, y: number, z: number): void
|
|
68
|
+
getDynamicInput(index: number): number
|
|
69
|
+
setDynamicInput(index: number, value: number): void
|
|
70
|
+
sendTrigger(index: number): void
|
|
71
|
+
setPaused(paused: boolean): void
|
|
72
|
+
setShown(shown: boolean): void
|
|
73
|
+
setSpeed(speed: number): void
|
|
74
|
+
setRandomSeed(seed: number): void
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export type ManagedEffectState = {
|
|
78
|
+
id: string
|
|
79
|
+
path: string
|
|
80
|
+
scale: number
|
|
81
|
+
preload: boolean
|
|
82
|
+
warmup: boolean
|
|
83
|
+
enabled: boolean
|
|
84
|
+
status: "unloaded" | "loading" | "loaded" | "failed"
|
|
85
|
+
effect: EffekseerEffect | null
|
|
86
|
+
errorMessage: string
|
|
87
|
+
errorPath: string
|
|
88
|
+
warmupStatus: "idle" | "warming" | "warmed" | "failed"
|
|
89
|
+
warmupErrorMessage: string
|
|
90
|
+
warmupSignature: string
|
|
91
|
+
loadPromise: Promise<EffekseerEffect | null> | null
|
|
92
|
+
activeHandles: Set<EffekseerHandle>
|
|
93
|
+
ownedResourceAliases: string[]
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export interface EffekseerContext {
|
|
97
|
+
init(target: string | HTMLCanvasElement, settings?: ContextInitSettings): boolean
|
|
98
|
+
initExternal(settings?: ContextInitSettings): boolean
|
|
99
|
+
registerEffects(effects: Record<string, ManagedEffectInput>): void
|
|
100
|
+
preloadEffects(ids?: string[] | string): Promise<Map<string, EffekseerEffect | null>>
|
|
101
|
+
warmupEffects(ids?: string[] | string, options?: Partial<WarmupSettings>): Promise<Map<string, EffekseerEffect | null>>
|
|
102
|
+
whenEffectsReady(ids?: string[] | string): Promise<Map<string, EffekseerEffect | null>>
|
|
103
|
+
reloadEffects(ids?: string[] | string): Promise<Map<string, EffekseerEffect | null>>
|
|
104
|
+
unloadEffects(ids?: string[] | string): void
|
|
105
|
+
unregisterEffects(ids?: string[] | string): void
|
|
106
|
+
getEffect(id: string): EffekseerEffect | null
|
|
107
|
+
getEffectState(id: string): ManagedEffectState | null
|
|
108
|
+
getEffectStates(): ManagedEffectState[]
|
|
109
|
+
loadEffect(
|
|
110
|
+
data: string | ArrayBuffer | ArrayBufferView,
|
|
111
|
+
scale?: number,
|
|
112
|
+
onload?: () => void,
|
|
113
|
+
onerror?: (message: string, path?: string) => void,
|
|
114
|
+
redirect?: (path: string) => string
|
|
115
|
+
): EffekseerEffect
|
|
116
|
+
loadEffectPackage(
|
|
117
|
+
data: string | ArrayBuffer | ArrayBufferView,
|
|
118
|
+
Unzip: unknown,
|
|
119
|
+
scale?: number,
|
|
120
|
+
onload?: () => void,
|
|
121
|
+
onerror?: (message: string, path?: string) => void
|
|
122
|
+
): EffekseerEffect
|
|
123
|
+
releaseEffect(effect: EffekseerEffect | null): void
|
|
124
|
+
playEffect(id: string, x?: number, y?: number, z?: number): EffekseerHandle | null
|
|
125
|
+
play(effect: EffekseerEffect | null, x?: number, y?: number, z?: number): EffekseerHandle | null
|
|
126
|
+
update(deltaFrames?: number): void
|
|
127
|
+
beginUpdate(): void
|
|
128
|
+
endUpdate(): void
|
|
129
|
+
updateHandle(handle: EffekseerHandle, deltaFrames?: number): void
|
|
130
|
+
draw(): void
|
|
131
|
+
drawExternal(
|
|
132
|
+
renderPassEncoder: GPURenderPassEncoder,
|
|
133
|
+
renderPassState?: EffekseerRenderPassState | null,
|
|
134
|
+
mode?: "all" | "back" | "front"
|
|
135
|
+
): void
|
|
136
|
+
beginDraw(): void
|
|
137
|
+
endDraw(): void
|
|
138
|
+
drawHandle(handle: EffekseerHandle): void
|
|
139
|
+
stopAll(): void
|
|
140
|
+
setCompositeMode(enabled: boolean): void
|
|
141
|
+
setProjectionPerspective(fov: number, aspect: number, near: number, far: number): void
|
|
142
|
+
setProjectionOrthographic(width: number, height: number, near: number, far: number): void
|
|
143
|
+
setCameraLookAt(
|
|
144
|
+
positionX: number,
|
|
145
|
+
positionY: number,
|
|
146
|
+
positionZ: number,
|
|
147
|
+
targetX: number,
|
|
148
|
+
targetY: number,
|
|
149
|
+
targetZ: number,
|
|
150
|
+
upvecX: number,
|
|
151
|
+
upvecY: number,
|
|
152
|
+
upvecZ: number
|
|
153
|
+
): void
|
|
154
|
+
setProjectionMatrix(matrixArray: ArrayLike<number>): void
|
|
155
|
+
setCameraMatrix(matrixArray: ArrayLike<number>): void
|
|
156
|
+
setResourceLoader(loader: (path: string, onload: (data: ArrayBuffer | Uint8Array) => void, onerror: () => void) => void): void
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export interface EffekseerApi {
|
|
160
|
+
setWebGPUDevice(device: GPUDevice | null): void
|
|
161
|
+
getWebGPUDevice(): GPUDevice | null
|
|
162
|
+
initRuntime(path: string, onload?: () => void, onerror?: (error: unknown) => void): Promise<void>
|
|
163
|
+
createContext(): EffekseerContext | null
|
|
164
|
+
releaseContext(context: EffekseerContext | null): void
|
|
165
|
+
setImageCrossOrigin(crossOrigin: string): void
|
|
166
|
+
setLogEnabled(flag: boolean): void
|
|
167
|
+
init(target: string | HTMLCanvasElement, settings?: ContextInitSettings): boolean
|
|
168
|
+
update(deltaFrames?: number): void
|
|
169
|
+
beginUpdate(): void
|
|
170
|
+
endUpdate(): void
|
|
171
|
+
updateHandle(handle: EffekseerHandle, deltaFrames?: number): void
|
|
172
|
+
draw(): void
|
|
173
|
+
drawExternal(
|
|
174
|
+
renderPassEncoder: GPURenderPassEncoder,
|
|
175
|
+
renderPassState?: EffekseerRenderPassState | null,
|
|
176
|
+
mode?: "all" | "back" | "front"
|
|
177
|
+
): void
|
|
178
|
+
beginDraw(): void
|
|
179
|
+
endDraw(): void
|
|
180
|
+
drawHandle(handle: EffekseerHandle): void
|
|
181
|
+
setProjectionMatrix(matrixArray: ArrayLike<number>): void
|
|
182
|
+
setProjectionPerspective(fov: number, aspect: number, near: number, far: number): void
|
|
183
|
+
setProjectionOrthographic(width: number, height: number, near: number, far: number): void
|
|
184
|
+
setCameraMatrix(matrixArray: ArrayLike<number>): void
|
|
185
|
+
setCameraLookAt(
|
|
186
|
+
positionX: number,
|
|
187
|
+
positionY: number,
|
|
188
|
+
positionZ: number,
|
|
189
|
+
targetX: number,
|
|
190
|
+
targetY: number,
|
|
191
|
+
targetZ: number,
|
|
192
|
+
upvecX: number,
|
|
193
|
+
upvecY: number,
|
|
194
|
+
upvecZ: number
|
|
195
|
+
): void
|
|
196
|
+
setCompositeMode(enabled: boolean): void
|
|
197
|
+
loadEffect(
|
|
198
|
+
data: string | ArrayBuffer | ArrayBufferView,
|
|
199
|
+
scale?: number,
|
|
200
|
+
onload?: () => void,
|
|
201
|
+
onerror?: (message: string, path?: string) => void,
|
|
202
|
+
redirect?: (path: string) => string
|
|
203
|
+
): EffekseerEffect
|
|
204
|
+
loadEffectPackage(
|
|
205
|
+
data: string | ArrayBuffer | ArrayBufferView,
|
|
206
|
+
Unzip: unknown,
|
|
207
|
+
scale?: number,
|
|
208
|
+
onload?: () => void,
|
|
209
|
+
onerror?: (message: string, path?: string) => void
|
|
210
|
+
): EffekseerEffect
|
|
211
|
+
registerEffects(effects: Record<string, ManagedEffectInput>): void
|
|
212
|
+
preloadEffects(ids?: string[] | string): Promise<Map<string, EffekseerEffect | null>>
|
|
213
|
+
warmupEffects(ids?: string[] | string, options?: Partial<WarmupSettings>): Promise<Map<string, EffekseerEffect | null>>
|
|
214
|
+
reloadEffects(ids?: string[] | string): Promise<Map<string, EffekseerEffect | null>>
|
|
215
|
+
unloadEffects(ids?: string[] | string): void
|
|
216
|
+
unregisterEffects(ids?: string[] | string): void
|
|
217
|
+
getEffect(id: string): EffekseerEffect | null
|
|
218
|
+
getEffectState(id: string): ManagedEffectState | null
|
|
219
|
+
getEffectStates(): ManagedEffectState[]
|
|
220
|
+
whenEffectsReady(ids?: string[] | string): Promise<Map<string, EffekseerEffect | null>>
|
|
221
|
+
playEffect(id: string, x?: number, y?: number, z?: number): EffekseerHandle | null
|
|
222
|
+
releaseEffect(effect: EffekseerEffect | null): void
|
|
223
|
+
play(effect: EffekseerEffect | null, x?: number, y?: number, z?: number): EffekseerHandle | null
|
|
224
|
+
stopAll(): void
|
|
225
|
+
setResourceLoader(loader: (path: string, onload: (data: ArrayBuffer | Uint8Array) => void, onerror: () => void) => void): void
|
|
226
|
+
}
|
|
227
|
+
|
|
6
228
|
export declare function getEffekseerWebGPURuntimeUrls(): {
|
|
7
229
|
fflateUrl: string
|
|
8
230
|
effekseerWebgpuRuntimeJsUrl: string
|
|
@@ -10,4 +232,4 @@ export declare function getEffekseerWebGPURuntimeUrls(): {
|
|
|
10
232
|
effekseerWebgpuBridgeUrl: string
|
|
11
233
|
}
|
|
12
234
|
|
|
13
|
-
export declare function loadEffekseerWebGPURuntime(): Promise<
|
|
235
|
+
export declare function loadEffekseerWebGPURuntime(): Promise<EffekseerApi>
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=(()=>{let e={},t={},r=null,n=!1,a=!1,s=null,i=null,o="",f=0,c=[],l=!0;const u=()=>{n&&"function"==typeof t.SetLogEnabled&&t.SetLogEnabled(l?1:0)},d=e=>e instanceof ArrayBuffer?e:ArrayBuffer.isView(e)?e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength):null,p=e=>{if("string"!=typeof e||0===e.length)return"";const t=e.replace(/\\/g,"/").split("/"),r=[];for(let e=0;e<t.length;e++){const n=t[e];n&&"."!==n&&(".."!==n?r.push(n):r.length>0&&r.pop())}let n=r.join("/");for(;n.startsWith("/");)n=n.slice(1);return n.replace(/[A-Z]/g,e=>e.toLowerCase())},h="EFWGPKG2",g="__efwgpk__/main_effect_path.txt",m=new Uint8Array([69,102,107,87,103,46,87,101,98,71,80,85,46,67,84,82]);let b=0,w=null;const E=(()=>{const e=new Uint32Array(256);for(let t=0;t<256;t++){let r=t;for(let e=0;e<8;e++)r=1&r?3988292384^r>>>1:r>>>1;e[t]=r>>>0}return e})(),y=e=>{if(!(e instanceof Uint8Array))return 0;let t=4294967295;for(let r=0;r<e.length;r++){const n=255&(t^e[r]);t=t>>>8^E[n]}return~t>>>0},S=async(e,t)=>{const r=await(async()=>{if(w)return w;if(!globalThis.crypto||!globalThis.crypto.subtle||"function"!=typeof globalThis.crypto.subtle.importKey)throw new Error("Web Crypto AES-CTR is required for encrypted efkwgpk payloads");return w=globalThis.crypto.subtle.importKey("raw",m,"AES-CTR",!1,["decrypt"]),w})();return globalThis.crypto.subtle.decrypt({name:"AES-CTR",counter:t,length:128},r,e)},v=e=>String(e||"").replace(/\\/g,"/").split("?")[0].split("#")[0],x=e=>{const t=d(e);if(!t||t.byteLength<8)return"";const r=new Uint8Array(t,0,8);return String.fromCharCode(...r)},_=e=>{const t=new Map,r=e?e.byteLength:0,n=(e=>{const t=e?e.byteLength:0;if(!e||t<64)return null;const r=new DataView(e);if(x(e)!==h)return null;const n=r.getUint32(8,!0),a=r.getUint32(12,!0),s=r.getUint32(16,!0),i=r.getUint32(20,!0),o=r.getUint32(24,!0),f=r.getUint32(28,!0),c=r.getUint32(32,!0),l=r.getUint32(36,!0),u=r.getUint32(40,!0),d=r.getUint32(44,!0),p=r.getUint32(48,!0),g=r.getUint32(52,!0),m=2===s?64:3===s?80:0;if(0===m||n!==m||48!==o)return null;let b=null;if(4&a){if(s<3||t<80)return null;if(b=new Uint8Array(e.slice(56,72)),16!==b.byteLength)return null}return{headerSize:n,globalFlags:a,formatRevision:s,entryCount:i,entryStride:o,entriesOffset:f,stringPoolOffset:c,stringPoolSize:l,payloadOffset:u,payloadSize:d,tocCrc:p,payloadCrc:g,payloadNonce:b,payloadEncrypted:!!(4&a)}})(e);if(!n)return t;const a=new DataView(e),{headerSize:s,entryCount:i,entryStride:o,entriesOffset:f,stringPoolOffset:c,stringPoolSize:l,payloadOffset:u,payloadSize:d,tocCrc:g,payloadCrc:m}=n,b=BigInt(i)*BigInt(o);if(b>BigInt(r))return t;const w=Number(b);if(!U(f,w,r))return t;if(!U(c,l,r))return t;if(!U(u,d,r))return t;const E=c+l,S=u+d,v=new Uint8Array(e,0,s).slice();v.fill(0,48,56);const _=new Uint8Array(s+w+l);if(_.set(v,0),_.set(new Uint8Array(e,f,w),s),_.set(new Uint8Array(e,c,l),s+w),y(_)!==g>>>0)return t;const k=new Uint8Array(e,u,d);if(y(k)!==m>>>0)return t;const C=new TextDecoder("utf-8");for(let n=0;n<i;n++){const s=f+n*o,i=a.getUint32(s+8,!0),l=a.getUint32(s+12,!0),d=a.getUint32(s+16,!0),h=a.getUint32(s+20,!0),g=a.getUint32(s+24,!0),m=a.getUint32(s+28,!0),b=a.getUint32(s+32,!0),w=a.getUint32(s+36,!0);if(!U(i,l,r))continue;if(i<c||i+l>E)continue;if(!U(h,g,r))continue;if(h<u||h+g>S)continue;let y="";try{y=C.decode(new Uint8Array(e,i,l))}catch{continue}const v=p(y);if(!v)continue;const x={index:n,path:y,normalizedPath:v,flags:d,payloadOffset:h,packedSize:g,rawSize:m,packedCrc:b,rawCrc:w},_=t.get(v);_?_.push(x):t.set(v,[x])}return t._efwgpkMeta={payloadOffset:u,payloadSize:d,payloadEncrypted:n.payloadEncrypted,payloadNonce:n.payloadNonce,decryptedPayloadPromise:null},t},k=async e=>{const t=globalThis.fflate;if(t&&"function"==typeof t.unzlibSync){const r=t.unzlibSync(new Uint8Array(e));return d(r)}if("function"!=typeof DecompressionStream)throw new Error("No zlib inflate backend available for efkwgpk payload");const r=new DecompressionStream("deflate"),n=r.writable.getWriter();await n.write(e),await n.close();return await new Response(r.readable).arrayBuffer()},C=async(e,t,r)=>{const n=t&&t._efwgpkMeta?t._efwgpkMeta:null;if(!n||!n.payloadEncrypted)return new Uint8Array(e,r.payloadOffset,r.packedSize);if(!n.decryptedPayloadPromise){const t=new Uint8Array(e,n.payloadOffset,n.payloadSize);n.decryptedPayloadPromise=S(t,n.payloadNonce).then(e=>new Uint8Array(e))}const a=await n.decryptedPayloadPromise,s=r.payloadOffset-n.payloadOffset;return s<0||s+r.packedSize>a.byteLength?null:a.subarray(s,s+r.packedSize)},M=async(e,t,r)=>{const n=p(r);if(!n||!e||!t||0===t.size)return null;const a=t.get(n);if(!a||0===a.length)return null;for(let r=0;r<a.length;r++){const n=a[r];if(!U(n.payloadOffset,n.packedSize,e.byteLength))continue;const s=await C(e,t,n);if(s&&y(s)===n.packedCrc>>>0){if(0===n.flags&&n.packedSize===n.rawSize){const e=s.slice();if(y(e)!==n.rawCrc>>>0)continue;return e.buffer}if(1===n.flags){const e=await k(s);if(!e||e.byteLength!==n.rawSize)continue;if(y(new Uint8Array(e))!==n.rawCrc>>>0)continue;return e}}}return null},P=e=>e&&Number.isFinite(e.payloadOffset)&&Number.isFinite(e.packedSize)&&Number.isFinite(e.rawSize)&&Number.isFinite(e.flags)?`${e.flags}:${e.payloadOffset}:${e.packedSize}:${e.rawSize}`:"",R=(e,t,r)=>{const n=p(r);if(!n||!e||!t||0===t.size)return null;const a=t.get(n);if(!a||0===a.length)return null;for(let t=0;t<a.length;t++){const r=a[t];if(U(r.payloadOffset,r.packedSize,e.byteLength)){if(0===r.flags&&r.packedSize===r.rawSize)return r;if(1===r.flags)return r}}return null},U=(e,t,r)=>!!(Number.isFinite(e)&&Number.isFinite(t)&&Number.isFinite(r))&&(!(e<0||t<0||r<0)&&(!(e>r)&&t<=r-e)),A=(e,t,r)=>{const n=new XMLHttpRequest;n.open("GET",e,!0),n.responseType="arraybuffer",n.onload=()=>{const a=0|n.status;a>=200&&a<300||0===a?t(n.response):r&&r("not found",e)},n.onerror=()=>{r&&r("not found",e)},n.send(null)},L=e=>{try{const t=new XMLHttpRequest;t.open("GET",e,!1),t.responseType="arraybuffer",t.send(null);const r=0|t.status;if(r>=200&&r<300||0===r)return t.response}catch{}return null},D=e=>{"function"==typeof e&&("function"==typeof queueMicrotask?queueMicrotask(e):Promise.resolve().then(e))},I=(e,t)=>{const r=String(e||"").replace(/\\/g,"/");const n=Number(t);return`${r}::${Number.isFinite(n)?n:1}`},F=e=>{e&&e.context&&e._cacheKey&&e.context._effectCache&&e.context._effectCache.get(e._cacheKey)===e&&e.context._effectCache.delete(e._cacheKey)},T=e=>e?{id:e.id,path:e.path,scale:e.scale,enabled:e.enabled,status:e.status,effect:"loaded"===e.status?e.effect:null,errorMessage:e.errorMessage,errorPath:e.errorPath,loadPromise:e.loadPromise,activeHandles:new Set(e.activeHandles),ownedResourceAliases:e.ownedResourceAliases.slice()}:null,O=(e,t,r)=>{if(e&&("function"==typeof t&&(e.isLoaded?D(()=>t()):e._loadFailed||e._onloadListeners.push(t)),"function"==typeof r))if(e._loadFailed){const t=e._loadErrorMessage||"failed to load effect",n=e._loadErrorPath||"";D(()=>r(t,n))}else e.isLoaded||e._onerrorListeners.push(r)},z=(e,t,r="")=>{if(!e||e._loadFailed)return;e._loadFailed=!0,e._loadErrorMessage=String(t||"failed to load effect"),e._loadErrorPath=String(r||""),F(e);const n=e._onerrorListeners.slice();e._onloadListeners.length=0,e._onerrorListeners.length=0;for(let t=0;t<n.length;t++){const r=n[t];D(()=>r(e._loadErrorMessage,e._loadErrorPath))}};let B=(e,t,r)=>{A(e,t,r)};const j={ptr:0,capacity:0},W=(t,r)=>{const n=t instanceof Float32Array?t:new Float32Array(t);if(n.length<=0)return void r(0);const a=((s=n.length)<=j.capacity&&0!==j.ptr||(0!==j.ptr&&(e._free(j.ptr),j.ptr=0,j.capacity=0),j.ptr=e._malloc(4*s),j.capacity=s),j.ptr);var s;e.HEAPF32.set(n,a>>2),r(a)},H=Object.freeze({rgba8unorm:22,"rgba8unorm-srgb":23,bgra8unorm:27,"bgra8unorm-srgb":28,rgba16float:40,depth24plus:46,"depth24plus-stencil8":47,depth32float:48}),V=(Object.freeze(Object.fromEntries(Object.entries(H).map(([e,t])=>[t,e]))),e=>{if("number"==typeof e&&Number.isFinite(e))return 0|e;if("string"!=typeof e)return null;const t=e.trim().toLowerCase();return t&&Object.prototype.hasOwnProperty.call(H,t)?H[t]:null}),G=async i=>{if(n)return;if(a)return void await new Promise((e,t)=>{c.push(r=>r?e():t(new Error("Runtime initialization failed.")))});if(a=!0,"undefined"==typeof effekseer_webgpu_native)throw a=!1,new Error("effekseer_webgpu_native is not loaded.");const o={};"string"==typeof i&&i.length>0&&(o.locateFile=e=>e.endsWith(".wasm")?i:e),s&&(o.preinitializedWebGPUDevice=s);const f=effekseer_webgpu_native(o);e=f instanceof Promise?await f:f,!s&&e?.preinitializedWebGPUDevice&&(s=e.preinitializedWebGPUDevice),s&&(e.preinitializedWebGPUDevice=s),(()=>{t={InitInternal:e.cwrap("EffekseerInitInternal","number",["number","number","string","number","number"]),InitExternal:e.cwrap("EffekseerInitExternal","number",["number","number","number","number"]),Init:e.cwrap("EffekseerInit","number",["number","number","string","number","number","number"]),Terminate:e.cwrap("EffekseerTerminate","void",["number"]),Update:e.cwrap("EffekseerUpdate","void",["number","number"]),BeginUpdate:e.cwrap("EffekseerBeginUpdate","void",["number"]),EndUpdate:e.cwrap("EffekseerEndUpdate","void",["number"]),UpdateHandle:e.cwrap("EffekseerUpdateHandle","void",["number","number","number"]),Draw:e.cwrap("EffekseerDraw","void",["number"]),DrawExternal:e.cwrap("EffekseerDrawExternal","void",["number"]),BeginDraw:e.cwrap("EffekseerBeginDraw","void",["number"]),EndDraw:e.cwrap("EffekseerEndDraw","void",["number"]),DrawHandle:e.cwrap("EffekseerDrawHandle","void",["number","number"]),SetProjectionMatrix:e.cwrap("EffekseerSetProjectionMatrix","void",["number","number"]),SetProjectionPerspective:e.cwrap("EffekseerSetProjectionPerspective","void",["number","number","number","number","number"]),SetProjectionOrthographic:e.cwrap("EffekseerSetProjectionOrthographic","void",["number","number","number","number","number"]),SetCameraMatrix:e.cwrap("EffekseerSetCameraMatrix","void",["number","number"]),SetCameraLookAt:e.cwrap("EffekseerSetCameraLookAt","void",["number","number","number","number","number","number","number","number","number","number"]),LoadEffect:e.cwrap("EffekseerLoadEffect","number",["number","number","number","number"]),ReleaseEffect:e.cwrap("EffekseerReleaseEffect","void",["number","number"]),ReloadResources:e.cwrap("EffekseerReloadResources","void",["number","number","number","number"]),StopAllEffects:e.cwrap("EffekseerStopAllEffects","void",["number"]),PlayEffect:e.cwrap("EffekseerPlayEffect","number",["number","number","number","number","number"]),StopEffect:e.cwrap("EffekseerStopEffect","void",["number","number"]),StopRoot:e.cwrap("EffekseerStopRoot","void",["number","number"]),Exists:e.cwrap("EffekseerExists","number",["number","number"]),SetFrame:e.cwrap("EffekseerSetFrame","void",["number","number","number"]),SetLocation:e.cwrap("EffekseerSetLocation","void",["number","number","number","number","number"]),SetRotation:e.cwrap("EffekseerSetRotation","void",["number","number","number","number","number"]),SetScale:e.cwrap("EffekseerSetScale","void",["number","number","number","number","number"]),SetMatrix:e.cwrap("EffekseerSetMatrix","void",["number","number","number"]),SetAllColor:e.cwrap("EffekseerSetAllColor","void",["number","number","number","number","number","number"]),SetTargetLocation:e.cwrap("EffekseerSetTargetLocation","void",["number","number","number","number","number"]),GetDynamicInput:e.cwrap("EffekseerGetDynamicInput","number",["number","number","number"]),SetDynamicInput:e.cwrap("EffekseerSetDynamicInput","void",["number","number","number","number"]),SendTrigger:e.cwrap("EffekseerSendTrigger","void",["number","number","number"]),SetPaused:e.cwrap("EffekseerSetPaused","void",["number","number","number"]),SetShown:e.cwrap("EffekseerSetShown","void",["number","number","number"]),SetSpeed:e.cwrap("EffekseerSetSpeed","void",["number","number","number"]),SetRandomSeed:e.cwrap("EffekseerSetRandomSeed","void",["number","number","number"]),SetCompositeMode:e.cwrap("EffekseerSetCompositeMode","void",["number","number"]),GetRestInstancesCount:e.cwrap("EffekseerGetRestInstancesCount","number",["number"]),DrawExternalBack:e.cwrap("EffekseerDrawExternalBack","void",["number"]),DrawExternalFront:e.cwrap("EffekseerDrawExternalFront","void",["number"]),IsVertexArrayObjectSupported:e.cwrap("EffekseerIsVertexArrayObjectSupported","number",["number"]),SetRestorationOfStatesFlag:e.cwrap("EffekseerSetRestorationOfStatesFlag","void",["number","number"]),CaptureBackground:e.cwrap("EffekseerCaptureBackground","void",["number","number","number","number","number"]),ResetBackground:e.cwrap("EffekseerResetBackground","void",["number"]),SetLogEnabled:e.cwrap("EffekseerSetLogEnabled","void",["number"]),SetDepthTexture:e.cwrap("EffekseerSetDepthTexture","void",["number","number"]),SetBackgroundTexture:e.cwrap("EffekseerSetBackgroundTexture","void",["number","number"])},e.resourcesMap={},e._loadBinary=(t,n)=>{const a=r;if(!a)return null;let s=a.resources.find(e=>e.path===t);if(s)return s.isLoaded?s.buffer:null;s={path:t,isLoaded:!1,buffer:null,isRequired:!!n},a.resources.push(s);const i=e=>String(e||"").replace(/\\/g,"/"),o=e=>{const t=i(e);let r=t.startsWith("/")||/^[a-zA-Z]+:\/\//.test(t)?t:(a.baseDir||"")+t;return a.redirect&&(r=a.redirect(r)),r},f=(e=>{const t=i(e),r=[],n=new Set,a=e=>{e&&!n.has(e)&&(n.add(e),r.push(e))},s=e=>{if(!e||e.includes("/"))return;const t=e.toLowerCase();(t.endsWith(".png")||t.endsWith(".jpg")||t.endsWith(".jpeg")||t.endsWith(".dds"))&&a(`Texture/${e}`),(t.endsWith(".efkmodel")||t.endsWith(".mqo"))&&a(`Model/${e}`)},o=t.indexOf("/");if(o>0){const e=t.slice(0,o).toLowerCase();(e.endsWith(".efk")||e.endsWith(".efkefc")||e.endsWith(".efkproj"))&&a(t.slice(o+1))}a(t),s(t);let f=t.indexOf("/");for(;f>=0;){const e=t.slice(f+1);a(e),s(e),f=t.indexOf("/",f+1)}return r})(t);if(a.syncResourceLoad){for(let r=0;r<f.length;r++){const n=f[r],a=o(n),i=e.resourcesMap[a]||e.resourcesMap[n]||e.resourcesMap[t];if(null!=i)return s.buffer=i,s.isLoaded=!0,i;const c=L(a);if(null!=c)return s.buffer=c,s.isLoaded=!0,e.resourcesMap[a]=c,e.resourcesMap[n]=c,c}return s.buffer=null,s.isLoaded=!0,null}for(let r=0;r<f.length;r++){const n=f[r],i=o(n),c=e.resourcesMap[i]||e.resourcesMap[n]||e.resourcesMap[t];if(null!=c)return s.buffer=c,s.isLoaded=!0,Promise.resolve().then(()=>a._update()),null}let c=0;const l=()=>{if(c>=f.length)return s.buffer=null,s.isLoaded=!0,void a._update();const e=f[c++],t=o(e);B(t,e=>{if(null!=e)return s.buffer=e,s.isLoaded=!0,void a._update();l()},()=>{l()})};return l(),null},n=!0,a=!1,u();const s=c;c=[],s.forEach(e=>e(!0))})()};class N{constructor(e){this.context=e,this.nativeptr=0,this.baseDir="",this.syncResourceLoad=!1,this.isLoaded=!1,this.scale=1,this.resources=[],this.mainBuffer=null,this.onload=null,this.onerror=null,this._onloadListeners=[],this._onerrorListeners=[],this._loadFailed=!1,this._loadErrorMessage="",this._loadErrorPath="",this._cacheKey="",this.redirect=null,this.packageOnly=!1,this._ownedResourceAliases=[],this._managedRefIds=new Set}_load(n){const a=d(n);if(!a)return void z(this,"invalid data","");r=this,this.mainBuffer=a;const s=e._malloc(a.byteLength);e.HEAPU8.set(new Uint8Array(a),s),this.nativeptr=t.LoadEffect(this.context.nativeptr,s,a.byteLength,this.scale),e._free(s),r=null,this._update()}_reload(){if(!this.mainBuffer||!this.nativeptr)return;r=this;const n=e._malloc(this.mainBuffer.byteLength);e.HEAPU8.set(new Uint8Array(this.mainBuffer),n),t.ReloadResources(this.context.nativeptr,this.nativeptr,n,this.mainBuffer.byteLength),e._free(n),r=null}_update(){let e=!1;const r=[];for(let t=0;t<this.resources.length;t++){const n=this.resources[t];if(!n.isLoaded){e=!0;break}n.isRequired&&null==n.buffer&&r.push(n.path)}if(e)return;const n=0!==this.nativeptr;if(r.length>0){const e=`failed to load effect. missing resources: ${r.join(", ")}`;return n&&(t.ReleaseEffect(this.context.nativeptr,this.nativeptr),this.nativeptr=0),console.error(`[EffekseerWebGPU] ${e}`),void z(this,e,this.baseDir||"")}if(!n){return void z(this,"failed to load effect",this.baseDir||"")}!this.isLoaded&&n&&(this.isLoaded=!0,(e=>{if(!e)return;const t=e._onloadListeners.slice();e._onloadListeners.length=0,e._onerrorListeners.length=0;for(let e=0;e<t.length;e++){const r=t[e];D(()=>r())}})(this))}}const $=(t,r,n,a,s,i,o,f=null)=>{const c=f||new N(t);c.scale=a,c._ownedResourceAliases=[],O(c,s,i);const l=_(r);if(0===l.size)return z(c,"invalid data. expected efkwgpk package",n||""),c;const u=(()=>{if("string"!=typeof n||0===n.length)return"";const e=v(n),t=e.lastIndexOf("/");return t>=0?e.slice(0,t+1):""})(),d=u.toLowerCase(),h=`efwgpk://${++b}/`,m=new Map;return c.baseDir=u,c.syncResourceLoad=!0,c.packageOnly=!0,c.redirect=e=>{const t=v(e),r=[];d&&t.toLowerCase().startsWith(d)&&r.push(t.slice(u.length)),r.push(t);for(let e=0;e<r.length;e++){const t=p(r[e]);if(!t)continue;const n=m.get(t);if(n)return n}return e},(async()=>{try{const t=await(async(e,t)=>{const r=await M(e,t,g);if(r)try{const e=new TextDecoder("utf-8").decode(new Uint8Array(r)).replace(/\0+$/,""),t=p(e);if(t)return t}catch{}for(const[e,r]of t.entries())if(e.endsWith(".efkwg")&&r&&r.length>0)return e;return""})(r,l);if(!t)throw new Error("main effect path not found in efkwgpk package");const a=await M(r,l,t),s=String.fromCharCode(...new Uint8Array(a||new ArrayBuffer(0),0,Math.min(4,a?a.byteLength:0)));if(!a||"EFWG"!==s&&"SKFE"!==s)throw new Error("main effect inside efkwgpk is not a valid .efkwg");const i=new Map,o=new Map;for(const[n]of l.entries()){if(n===t||n===p(g))continue;const a=R(r,l,n);if(!a)continue;const s=P(a);if(!s)continue;let f=i.get(s);if(!f){let t=o.get(s);if(void 0===t&&(t=await M(r,l,n),o.set(s,t||null)),!t)continue;f=`${h}__payload/${i.size}`,e.resourcesMap[f]=t,i.set(s,f)}m.set(n,f)}c._ownedResourceAliases=Array.from(i.values()),c._load(a),c.nativeptr||z(c,"failed to load effect from efkwgpk package",n||t)}catch(e){z(c,e&&e.message?e.message:"failed to load effect from efkwgpk package",n||"")}})(),c};class q{constructor(e,t){this.context=e,this.native=t}stop(){t.StopEffect(this.context.nativeptr,this.native)}stopRoot(){t.StopRoot(this.context.nativeptr,this.native)}get exists(){return!!t.Exists(this.context.nativeptr,this.native)}setFrame(e){t.SetFrame(this.context.nativeptr,this.native,e)}setLocation(e,r,n){t.SetLocation(this.context.nativeptr,this.native,e,r,n)}setRotation(e,r,n){t.SetRotation(this.context.nativeptr,this.native,e,r,n)}setScale(e,r,n){t.SetScale(this.context.nativeptr,this.native,e,r,n)}setAllColor(e,r,n,a){t.SetAllColor(this.context.nativeptr,this.native,e,r,n,a)}setTargetLocation(e,r,n){t.SetTargetLocation(this.context.nativeptr,this.native,e,r,n)}getDynamicInput(e){return t.GetDynamicInput(this.context.nativeptr,this.native,e)}setDynamicInput(e,r){t.SetDynamicInput(this.context.nativeptr,this.native,e,r)}sendTrigger(e){t.SendTrigger(this.context.nativeptr,this.native,e)}setPaused(e){t.SetPaused(this.context.nativeptr,this.native,e?1:0)}setShown(e){t.SetShown(this.context.nativeptr,this.native,e?1:0)}setSpeed(e){t.SetSpeed(this.context.nativeptr,this.native,e)}setRandomSeed(e){t.SetRandomSeed(this.context.nativeptr,this.native,e)}setMatrix(e){W(e,e=>t.SetMatrix(this.context.nativeptr,this.native,e))}}class K{constructor(){this.nativeptr=0,this._effectCache=new Map,this._registeredEffects=new Map,this._registeredEffectStates=new Map,this.fixedUpdateStepFrames=1,this.fixedUpdateMaxSubsteps=4,this.fixedUpdateAccumulator=0,this.externalRenderPassEnabled=!1}_normalizeManagedEffectDescriptor(e,t){const r=String(e||"").trim();if(!r)throw new Error("registerEffects() requires non-empty effect ids.");let n=null;if("string"==typeof t)n={path:t};else{if(!t||"object"!=typeof t||Array.isArray(t))throw new Error(`registerEffects() entry "${r}" must be a string path or config object.`);n=t}const a=String(n.path||"").trim();if(!a)throw new Error(`registerEffects() entry "${r}" requires a non-empty path.`);const s=Number(n.scale);return{id:r,path:a,scale:Number.isFinite(s)?s:1,enabled:!1!==n.enabled}}_createManagedEffectState(e){return{id:e.id,path:e.path,scale:e.scale,enabled:e.enabled,status:"unloaded",effect:null,errorMessage:"",errorPath:"",loadPromise:null,activeHandles:new Set,ownedResourceAliases:[],_generation:0,_loadingEffect:null}}_resolveManagedEffectIds(e,t=!1){if(null==e){const e=[];for(const[r,n]of this._registeredEffectStates.entries())t&&!n.enabled||e.push(r);return e}const r=Array.isArray(e)?e:[e],n=[],a=new Set;for(let e=0;e<r.length;e++){const t=String(r[e]||"").trim();t&&!a.has(t)&&(a.add(t),n.push(t))}return n}_registerManagedEffectReference(e,t){e&&(e._managedRefIds instanceof Set||(e._managedRefIds=new Set),e._managedRefIds.add(t))}_releaseManagedEffectReference(e,t){e&&e._managedRefIds instanceof Set&&e._managedRefIds.delete(t)}_releaseManagedEffectIfUnused(r){if(!r)return;const n=r._managedRefIds instanceof Set?r._managedRefIds:null;n&&n.size>0||(F(r),(t=>{if(t&&e.resourcesMap)for(let r=0;r<t.length;r++){const n=t[r];"string"==typeof n&&0!==n.length&&delete e.resourcesMap[n]}})(r._ownedResourceAliases),r._ownedResourceAliases=[],this.nativeptr&&r.nativeptr&&(t.ReleaseEffect(this.nativeptr,r.nativeptr),r.nativeptr=0))}_stopManagedHandles(e){if(e){for(const t of e.activeHandles)try{t?.stopRoot?.()}catch{}e.activeHandles.clear()}}_cleanupManagedHandles(){for(const e of this._registeredEffectStates.values())if(e&&0!==e.activeHandles.size)for(const t of Array.from(e.activeHandles))t&&!1!==t.exists||e.activeHandles.delete(t)}_resetManagedEffectStateToUnloaded(e){e&&(e.effect=null,e.status="unloaded",e.errorMessage="",e.errorPath="",e.loadPromise=null,e.ownedResourceAliases=[],e._loadingEffect=null)}_loadRegisteredEffectState(e){if(!e||!this.nativeptr)return Promise.resolve(null);const t=this._registeredEffects.get(e.id);if(!t)return Promise.resolve(null);const r=e._generation+1;e._generation=r,e.status="loading",e.errorMessage="",e.errorPath="",e.effect=null,e.ownedResourceAliases=[],e._loadingEffect=null;const n=new Promise(n=>{let a=!1,s=null;const i=s=>{if(a)return;a=!0;return this._registeredEffectStates.get(e.id)!==e||e._generation!==r?(this._releaseManagedEffectIfUnused(s),void n(null)):(e._loadingEffect=null,e.loadPromise=null,s&&s.isLoaded?(e.effect=s,e.status="loaded",e.errorMessage="",e.errorPath="",e.ownedResourceAliases=Array.isArray(s._ownedResourceAliases)?s._ownedResourceAliases.slice():[],void n(s)):(e.status="failed",e.errorMessage="failed to load effect",e.errorPath=t.path,void n(null)))},o=(i,o="")=>{if(a)return;a=!0,s&&this._releaseManagedEffectReference(s,e.id);if(this._registeredEffectStates.get(e.id)!==e||e._generation!==r)return s&&this._releaseManagedEffectIfUnused(s),void n(null);e._loadingEffect=null,e.loadPromise=null,e.effect=null,e.status="failed",e.errorMessage=String(i||"failed to load effect"),e.errorPath=String(o||t.path||""),e.ownedResourceAliases=[],s&&this._releaseManagedEffectIfUnused(s),n(null)};try{s=this.loadEffect(t.path,t.scale,()=>i(s),(e,t)=>o(e,t))}catch(e){return void o(e&&e.message?e.message:"failed to load effect",t.path)}e._loadingEffect=s,s?(this._registerManagedEffectReference(s,e.id),s.isLoaded?i(s):s._loadFailed&&o(s._loadErrorMessage,s._loadErrorPath)):o("failed to create effect",t.path)});return e.loadPromise=n,n}_prepareInitSettings(e={},t=!1){const r=e.instanceMaxCount||4e3,n=e.squareMaxCount||1e4,a=!1!==e.linearColorSpace?1:0,s=e.compositeWithBackground?1:0;return this.externalRenderPassEnabled=t,this.fixedUpdateAccumulator=0,{instanceMaxCount:r,squareMaxCount:n,linearColorSpace:a,compositeWithBackground:s}}_finishContextInit(e={}){return this.nativeptr&&e.effects&&(this.registerEffects(e.effects),this.preloadEffects()),!!this.nativeptr}init(e,r={}){if(!0===r.externalRenderPass)return this.initExternal(r);let n="#canvas";"string"==typeof e?n=e.startsWith("#")?e:`#${e}`:"undefined"!=typeof HTMLCanvasElement&&e instanceof HTMLCanvasElement&&(e.id||(f+=1,e.id=`effekseer_webgpu_canvas_${f}`),n=`#${e.id}`);const a=this._prepareInitSettings(r,!1);return this.nativeptr=t.InitInternal(a.instanceMaxCount,a.squareMaxCount,n,a.linearColorSpace,a.compositeWithBackground),this._finishContextInit(r)}initExternal(e={}){const r=this._prepareInitSettings(e,!0);return this.nativeptr=t.InitExternal(r.instanceMaxCount,r.squareMaxCount,r.linearColorSpace,r.compositeWithBackground),this._finishContextInit(e)}update(e=1){const r=Number(e);if(!Number.isFinite(r)||r<=0)return void this._cleanupManagedHandles();this.fixedUpdateAccumulator+=r;let n=0;for(;this.fixedUpdateAccumulator>=this.fixedUpdateStepFrames&&n<this.fixedUpdateMaxSubsteps;)t.Update(this.nativeptr,this.fixedUpdateStepFrames),this.fixedUpdateAccumulator-=this.fixedUpdateStepFrames,n++;n>=this.fixedUpdateMaxSubsteps&&this.fixedUpdateAccumulator>=this.fixedUpdateStepFrames&&(this.fixedUpdateAccumulator=0),this._cleanupManagedHandles()}beginUpdate(){t.BeginUpdate(this.nativeptr)}endUpdate(){t.EndUpdate(this.nativeptr)}updateHandle(e,r=1){t.UpdateHandle(this.nativeptr,e.native,r)}draw(){this.externalRenderPassEnabled||t.Draw(this.nativeptr)}drawExternal(r,n=null,a="all"){if(!r)return;const s=V(n&&n.colorFormat),i=(()=>{const e=V(n&&n.depthFormat);return null===e?0:e})(),o=(e=>{const t=Number(e);return!Number.isFinite(t)||t<=0?1:Math.max(1,Math.floor(t))})(n&&n.sampleCount),f=(e,t)=>!!e&&Object.prototype.hasOwnProperty.call(e,t),c=f(n,"depthTextureView")||f(n,"importDepthTextureView"),l=f(n,"backgroundTextureView")||f(n,"importBackgroundTextureView"),u=c?f(n,"depthTextureView")?n.depthTextureView:n.importDepthTextureView:null,d=l?f(n,"backgroundTextureView")?n.backgroundTextureView:n.importBackgroundTextureView:null,p=c?e.__effekseerDepthTextureView:null,h=l?e.__effekseerBackgroundTextureView:null;e.__effekseerExternalRenderPass=r,e.__effekseerExternalPassColorFormat=s,e.__effekseerExternalPassDepthFormat=i,e.__effekseerExternalPassSampleCount=o,c&&(e.__effekseerDepthTextureView=u||null),l&&(e.__effekseerBackgroundTextureView=d||null);const g="back"===a?"back":"front"===a?"front":"all";try{"back"===g?t.DrawExternalBack(this.nativeptr):"front"===g?t.DrawExternalFront(this.nativeptr):t.DrawExternal(this.nativeptr)}finally{c&&(e.__effekseerDepthTextureView=p||null),l&&(e.__effekseerBackgroundTextureView=h||null),e.__effekseerExternalRenderPass=null,e.__effekseerExternalPassColorFormat=null,e.__effekseerExternalPassDepthFormat=null,e.__effekseerExternalPassSampleCount=null}}beginDraw(){t.BeginDraw(this.nativeptr)}endDraw(){t.EndDraw(this.nativeptr)}drawHandle(e){t.DrawHandle(this.nativeptr,e.native)}setProjectionMatrix(e){W(e,e=>t.SetProjectionMatrix(this.nativeptr,e))}setProjectionPerspective(e,r,n,a){t.SetProjectionPerspective(this.nativeptr,e,r,n,a)}setProjectionOrthographic(e,r,n,a){t.SetProjectionOrthographic(this.nativeptr,e,r,n,a)}setCameraMatrix(e){W(e,e=>t.SetCameraMatrix(this.nativeptr,e))}setCameraLookAt(e,r,n,a,s,i,o,f,c){t.SetCameraLookAt(this.nativeptr,e,r,n,a,s,i,o,f,c)}setCameraLookAtFromVector(e,t,r={x:0,y:1,z:0}){this.setCameraLookAt(e.x,e.y,e.z,t.x,t.y,t.z,r.x,r.y,r.z)}setCompositeMode(e){t.SetCompositeMode(this.nativeptr,e?1:0)}loadEffect(e,t=1,r,n,a){const s="function"==typeof t?1:t,i="function"==typeof t?t:r,o="function"==typeof t?r:n,f=a;let c=null;if("string"==typeof e&&null==f){c=I(e,s);const t=this._effectCache.get(c);if(t)return O(t,i,o),t}const l=new N(this);l.scale=s,l.redirect=f,l._cacheKey=c||"",O(l,i,o),c&&this._effectCache.set(c,l);const u=(e,t="")=>(z(l,e,t),l);if("string"==typeof e)return"string"==typeof(p=e)&&0!==p.length&&p.replace(/\\/g,"/").split("?")[0].split("#")[0].toLowerCase().endsWith(".efkwg")?(A(e,t=>{const r=d(t);if(!r)return void u("failed to fetch efkwg effect",e);const n=e.replace(/\\/g,"/").split("?")[0].split("#")[0],a=n.lastIndexOf("/");l.baseDir=a>=0?n.slice(0,a+1):"",l.syncResourceLoad=!1,l._load(r),l.nativeptr||u("failed to load efkwg effect",e)},()=>{u("failed to fetch efkwg effect",e)}),l):(e=>"string"==typeof e&&0!==e.length&&v(e).toLowerCase().endsWith(".efkwgpk"))(e)?(A(e,t=>{const r=d(t);r?$(this,r,e,s,null,null,0,l):u("failed to fetch efkwgpk package",e)},()=>{u("failed to fetch efkwgpk package",e)}),l):u("unsupported effect format. expected .efkwg or .efkwgpk",e);var p;const g=d(e);if(!g)return u("invalid data. expected efkwg or efkwgpk bytes","");if(x(g)===h)return $(this,g,"",s,null,null,0,l);const m=String.fromCharCode(...new Uint8Array(g,0,Math.min(4,g.byteLength)));return"EFWG"===m||"SKFE"===m?(l._load(g),l.nativeptr?l:u("failed to load efkwg effect","")):u("invalid data. expected efkwg or efkwgpk bytes","")}loadEffectPackage(e,t,r=1,n,a){let s=r,i=n,o=a;return"function"==typeof r&&(s=1,i=r,o=n),this.loadEffect(e,s,i,o)}registerEffects(e){if(!e||"object"!=typeof e||Array.isArray(e))throw new Error("registerEffects() expects an object map of effect ids to paths/configs.");const t=[];for(const[r,n]of Object.entries(e)){if(this._registeredEffects.has(r))throw new Error(`registerEffects() duplicate id "${r}".`);t.push(this._normalizeManagedEffectDescriptor(r,n))}for(let e=0;e<t.length;e++){const r=t[e];if(this._registeredEffects.has(r.id))throw new Error(`registerEffects() duplicate id "${r.id}".`)}for(let e=0;e<t.length;e++){const r=t[e];this._registeredEffects.set(r.id,r),this._registeredEffectStates.set(r.id,this._createManagedEffectState(r))}if(this.nativeptr)for(let e=0;e<t.length;e++){const r=t[e];r.enabled&&this.preloadEffects([r.id])}}preloadEffects(e){const t=this._resolveManagedEffectIds(e,null==e);return Promise.all(t.map(async e=>{const t=this._registeredEffectStates.get(e);return t?"loaded"===t.status&&t.effect?.isLoaded?[e,t.effect]:"loading"===t.status&&t.loadPromise?[e,await t.loadPromise]:[e,await this._loadRegisteredEffectState(t)]:[e,null]})).then(e=>new Map(e))}reloadEffects(e){const t=this._resolveManagedEffectIds(e,null==e);return this.unloadEffects(t),this.preloadEffects(t)}unloadEffects(e){const t=this._resolveManagedEffectIds(e);for(let e=0;e<t.length;e++){const r=t[e],n=this._registeredEffectStates.get(r);if(!n)continue;n._generation+=1,this._stopManagedHandles(n);const a=n._loadingEffect;a&&(this._releaseManagedEffectReference(a,r),this._releaseManagedEffectIfUnused(a));const s=n.effect;s&&(this._releaseManagedEffectReference(s,r),this._releaseManagedEffectIfUnused(s)),this._resetManagedEffectStateToUnloaded(n)}}unregisterEffects(e){const t=this._resolveManagedEffectIds(e);this.unloadEffects(t);for(let e=0;e<t.length;e++){const r=t[e];this._registeredEffects.delete(r),this._registeredEffectStates.delete(r)}}getEffect(e){const t=this._registeredEffectStates.get(String(e||""));return"loaded"===t?.status&&t.effect?.isLoaded?t.effect:null}getEffectState(e){return T(this._registeredEffectStates.get(String(e||"")))}getEffectStates(){return Array.from(this._registeredEffectStates.values(),e=>T(e))}whenEffectsReady(e){return this.preloadEffects(e)}playEffect(e,t=0,r=0,n=0){const a=this._registeredEffectStates.get(String(e||""));if(!a||"loaded"!==a.status||!a.effect?.isLoaded)return null;const s=this.play(a.effect,t,r,n);return s&&a.activeHandles.add(s),s}releaseEffect(e){e&&e.nativeptr&&(F(e),t.ReleaseEffect(this.nativeptr,e.nativeptr),e.nativeptr=0)}play(e,r=0,n=0,a=0){if(!e||!e.isLoaded)return null;const s=t.PlayEffect(this.nativeptr,e.nativeptr,r,n,a);return s>=0?new q(this,s):null}stopAll(){t.StopAllEffects(this.nativeptr)}setResourceLoader(e){B=e}getRestInstancesCount(){return t.GetRestInstancesCount(this.nativeptr)}isVertexArrayObjectSupported(){return!!t.IsVertexArrayObjectSupported(this.nativeptr)}setRestorationOfStatesFlag(e){t.SetRestorationOfStatesFlag(this.nativeptr,e?1:0)}captureBackground(e,r,n,a){t.CaptureBackground(this.nativeptr,e,r,n,a)}resetBackground(){t.ResetBackground(this.nativeptr)}}return new class{async initRuntime(e,t,r){try{await G(e),t&&t()}catch(e){a=!1,n=!1,c=[],r?r(e):console.error(e)}}createContext(){return n?new K:null}releaseContext(e){e&&e.nativeptr&&(e.unloadEffects?.(),t.Terminate(e.nativeptr),e.nativeptr=0,e._effectCache?.clear?.(),e._registeredEffects?.clear?.(),e._registeredEffectStates?.clear?.())}setLogEnabled(e){l=!!e,u()}setImageCrossOrigin(e){o=e}setWebGPUDevice(e){if(n||a)throw new Error("setWebGPUDevice() must be called before initRuntime().");if(null==e)return i=null,void(s=null);if("object"!=typeof e||"function"!=typeof e.createCommandEncoder||!e.queue)throw new Error("setWebGPUDevice() expects a valid GPUDevice.");i=e,s=e}setRendererWorkingColorSpace(e){return((e=null)=>{const t=e;return!(!t||!t.ColorManagement)&&"workingColorSpace"in t.ColorManagement&&void 0!==t.LinearSRGBColorSpace&&(t.ColorManagement.workingColorSpace=t.LinearSRGBColorSpace,!0)})(e)}getWebGPUDevice(){return s||(e?e.preinitializedWebGPUDevice:null)||null}init(e,t){return this.defaultContext?.nativeptr&&this.releaseContext(this.defaultContext),this.defaultContext=new K,this.defaultContext.init(e,t)}update(e){this.defaultContext.update(e)}beginUpdate(){this.defaultContext.beginUpdate()}endUpdate(){this.defaultContext.endUpdate()}updateHandle(e,t){this.defaultContext.updateHandle(e,t)}draw(){this.defaultContext.draw()}drawExternal(e,t,r="all"){this.defaultContext.drawExternal(e,t,r)}beginDraw(){this.defaultContext.beginDraw()}endDraw(){this.defaultContext.endDraw()}drawHandle(e){this.defaultContext.drawHandle(e)}setProjectionMatrix(e){this.defaultContext.setProjectionMatrix(e)}setProjectionPerspective(e,t,r,n){this.defaultContext.setProjectionPerspective(e,t,r,n)}setProjectionOrthographic(e,t,r,n){this.defaultContext.setProjectionOrthographic(e,t,r,n)}setCameraMatrix(e){this.defaultContext.setCameraMatrix(e)}setCameraLookAt(e,t,r,n,a,s,i,o,f){this.defaultContext.setCameraLookAt(e,t,r,n,a,s,i,o,f)}setCameraLookAtFromVector(e,t,r){this.defaultContext.setCameraLookAtFromVector(e,t,r)}setCompositeMode(e){this.defaultContext.setCompositeMode(e)}loadEffect(e,t,r,n,a){return this.defaultContext.loadEffect(e,t,r,n,a)}loadEffectPackage(e,t,r,n,a){return this.defaultContext.loadEffectPackage(e,t,r,n,a)}registerEffects(e){this.defaultContext.registerEffects(e)}preloadEffects(e){return this.defaultContext.preloadEffects(e)}reloadEffects(e){return this.defaultContext.reloadEffects(e)}unloadEffects(e){this.defaultContext.unloadEffects(e)}unregisterEffects(e){this.defaultContext.unregisterEffects(e)}getEffect(e){return this.defaultContext.getEffect(e)}getEffectState(e){return this.defaultContext.getEffectState(e)}getEffectStates(){return this.defaultContext.getEffectStates()}whenEffectsReady(e){return this.defaultContext.whenEffectsReady(e)}playEffect(e,t,r,n){return this.defaultContext.playEffect(e,t,r,n)}releaseEffect(e){this.defaultContext.releaseEffect(e)}play(e,t,r,n){return this.defaultContext.play(e,t,r,n)}stopAll(){this.defaultContext.stopAll()}setResourceLoader(e){this.defaultContext.setResourceLoader(e)}getRestInstancesCount(){return this.defaultContext.getRestInstancesCount()}isVertexArrayObjectSupported(){return this.defaultContext.isVertexArrayObjectSupported()}}})();"undefined"!=typeof globalThis&&(globalThis.effekseer=e),"undefined"!=typeof exports&&(exports=e);
|
|
1
|
+
const e=(()=>{let e={},t={},r=null,n=!1,a=!1,s=null,i=null,o="",f=0,u=[],l=!0;const c=()=>{n&&"function"==typeof t.SetLogEnabled&&t.SetLogEnabled(l?1:0)},d=e=>e instanceof ArrayBuffer?e:ArrayBuffer.isView(e)?e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength):null,p=e=>{if("string"!=typeof e||0===e.length)return"";const t=e.replace(/\\/g,"/").split("/"),r=[];for(let e=0;e<t.length;e++){const n=t[e];n&&"."!==n&&(".."!==n?r.push(n):r.length>0&&r.pop())}let n=r.join("/");for(;n.startsWith("/");)n=n.slice(1);return n.replace(/[A-Z]/g,e=>e.toLowerCase())},h="EFWGPKG2",g="__efwgpk__/main_effect_path.txt",m=new Uint8Array([69,102,107,87,103,46,87,101,98,71,80,85,46,67,84,82]);let w=0,b=null;const E=(()=>{const e=new Uint32Array(256);for(let t=0;t<256;t++){let r=t;for(let e=0;e<8;e++)r=1&r?3988292384^r>>>1:r>>>1;e[t]=r>>>0}return e})(),S=e=>{if(!(e instanceof Uint8Array))return 0;let t=4294967295;for(let r=0;r<e.length;r++){const n=255&(t^e[r]);t=t>>>8^E[n]}return~t>>>0},y=async(e,t)=>{const r=await(async()=>{if(b)return b;if(!globalThis.crypto||!globalThis.crypto.subtle||"function"!=typeof globalThis.crypto.subtle.importKey)throw new Error("Web Crypto AES-CTR is required for encrypted efkwgpk payloads");return b=globalThis.crypto.subtle.importKey("raw",m,"AES-CTR",!1,["decrypt"]),b})();return globalThis.crypto.subtle.decrypt({name:"AES-CTR",counter:t,length:128},r,e)},_=e=>String(e||"").replace(/\\/g,"/").split("?")[0].split("#")[0],v=e=>{const t=d(e);if(!t||t.byteLength<8)return"";const r=new Uint8Array(t,0,8);return String.fromCharCode(...r)},x=e=>{const t=new Map,r=e?e.byteLength:0,n=(e=>{const t=e?e.byteLength:0;if(!e||t<64)return null;const r=new DataView(e);if(v(e)!==h)return null;const n=r.getUint32(8,!0),a=r.getUint32(12,!0),s=r.getUint32(16,!0),i=r.getUint32(20,!0),o=r.getUint32(24,!0),f=r.getUint32(28,!0),u=r.getUint32(32,!0),l=r.getUint32(36,!0),c=r.getUint32(40,!0),d=r.getUint32(44,!0),p=r.getUint32(48,!0),g=r.getUint32(52,!0),m=2===s?64:3===s?80:0;if(0===m||n!==m||48!==o)return null;let w=null;if(4&a){if(s<3||t<80)return null;if(w=new Uint8Array(e.slice(56,72)),16!==w.byteLength)return null}return{headerSize:n,globalFlags:a,formatRevision:s,entryCount:i,entryStride:o,entriesOffset:f,stringPoolOffset:u,stringPoolSize:l,payloadOffset:c,payloadSize:d,tocCrc:p,payloadCrc:g,payloadNonce:w,payloadEncrypted:!!(4&a)}})(e);if(!n)return t;const a=new DataView(e),{headerSize:s,entryCount:i,entryStride:o,entriesOffset:f,stringPoolOffset:u,stringPoolSize:l,payloadOffset:c,payloadSize:d,tocCrc:g,payloadCrc:m}=n,w=BigInt(i)*BigInt(o);if(w>BigInt(r))return t;const b=Number(w);if(!T(f,b,r))return t;if(!T(u,l,r))return t;if(!T(c,d,r))return t;const E=u+l,y=c+d,_=new Uint8Array(e,0,s).slice();_.fill(0,48,56);const x=new Uint8Array(s+b+l);if(x.set(_,0),x.set(new Uint8Array(e,f,b),s),x.set(new Uint8Array(e,u,l),s+b),S(x)!==g>>>0)return t;const k=new Uint8Array(e,c,d);if(S(k)!==m>>>0)return t;const C=new TextDecoder("utf-8");for(let n=0;n<i;n++){const s=f+n*o,i=a.getUint32(s+8,!0),l=a.getUint32(s+12,!0),d=a.getUint32(s+16,!0),h=a.getUint32(s+20,!0),g=a.getUint32(s+24,!0),m=a.getUint32(s+28,!0),w=a.getUint32(s+32,!0),b=a.getUint32(s+36,!0);if(!T(i,l,r))continue;if(i<u||i+l>E)continue;if(!T(h,g,r))continue;if(h<c||h+g>y)continue;let S="";try{S=C.decode(new Uint8Array(e,i,l))}catch{continue}const _=p(S);if(!_)continue;const v={index:n,path:S,normalizedPath:_,flags:d,payloadOffset:h,packedSize:g,rawSize:m,packedCrc:w,rawCrc:b},x=t.get(_);x?x.push(v):t.set(_,[v])}return t._efwgpkMeta={payloadOffset:c,payloadSize:d,payloadEncrypted:n.payloadEncrypted,payloadNonce:n.payloadNonce,decryptedPayloadPromise:null},t},k=async e=>{const t=globalThis.fflate;if(t&&"function"==typeof t.unzlibSync){const r=t.unzlibSync(new Uint8Array(e));return d(r)}if("function"!=typeof DecompressionStream)throw new Error("No zlib inflate backend available for efkwgpk payload");const r=new DecompressionStream("deflate"),n=r.writable.getWriter();await n.write(e),await n.close();return await new Response(r.readable).arrayBuffer()},C=async(e,t,r)=>{const n=t&&t._efwgpkMeta?t._efwgpkMeta:null;if(!n||!n.payloadEncrypted)return new Uint8Array(e,r.payloadOffset,r.packedSize);if(!n.decryptedPayloadPromise){const t=new Uint8Array(e,n.payloadOffset,n.payloadSize);n.decryptedPayloadPromise=y(t,n.payloadNonce).then(e=>new Uint8Array(e))}const a=await n.decryptedPayloadPromise,s=r.payloadOffset-n.payloadOffset;return s<0||s+r.packedSize>a.byteLength?null:a.subarray(s,s+r.packedSize)},P=async(e,t,r)=>{const n=p(r);if(!n||!e||!t||0===t.size)return null;const a=t.get(n);if(!a||0===a.length)return null;for(let r=0;r<a.length;r++){const n=a[r];if(!T(n.payloadOffset,n.packedSize,e.byteLength))continue;const s=await C(e,t,n);if(s&&S(s)===n.packedCrc>>>0){if(0===n.flags&&n.packedSize===n.rawSize){const e=s.slice();if(S(e)!==n.rawCrc>>>0)continue;return e.buffer}if(1===n.flags){const e=await k(s);if(!e||e.byteLength!==n.rawSize)continue;if(S(new Uint8Array(e))!==n.rawCrc>>>0)continue;return e}}}return null},M=e=>e&&Number.isFinite(e.payloadOffset)&&Number.isFinite(e.packedSize)&&Number.isFinite(e.rawSize)&&Number.isFinite(e.flags)?`${e.flags}:${e.payloadOffset}:${e.packedSize}:${e.rawSize}`:"",R=(e,t,r)=>{const n=p(r);if(!n||!e||!t||0===t.size)return null;const a=t.get(n);if(!a||0===a.length)return null;for(let t=0;t<a.length;t++){const r=a[t];if(T(r.payloadOffset,r.packedSize,e.byteLength)){if(0===r.flags&&r.packedSize===r.rawSize)return r;if(1===r.flags)return r}}return null},T=(e,t,r)=>!!(Number.isFinite(e)&&Number.isFinite(t)&&Number.isFinite(r))&&(!(e<0||t<0||r<0)&&(!(e>r)&&t<=r-e)),U=(e,t,r)=>{const n=new XMLHttpRequest;n.open("GET",e,!0),n.responseType="arraybuffer",n.onload=()=>{const a=0|n.status;a>=200&&a<300||0===a?t(n.response):r&&r("not found",e)},n.onerror=()=>{r&&r("not found",e)},n.send(null)},A=e=>{try{const t=new XMLHttpRequest;t.open("GET",e,!1),t.responseType="arraybuffer",t.send(null);const r=0|t.status;if(r>=200&&r<300||0===r)return t.response}catch{}return null},L=e=>{"function"==typeof e&&("function"==typeof queueMicrotask?queueMicrotask(e):Promise.resolve().then(e))},D=(e,t)=>{const r=String(e||"").replace(/\\/g,"/");const n=Number(t);return`${r}::${Number.isFinite(n)?n:1}`},F=e=>{e&&e.context&&e._cacheKey&&e.context._effectCache&&e.context._effectCache.get(e._cacheKey)===e&&e.context._effectCache.delete(e._cacheKey)},I=e=>e?{id:e.id,path:e.path,scale:e.scale,preload:e.preload,warmup:e.warmup,enabled:e.enabled,status:e.status,effect:"loaded"===e.status?e.effect:null,errorMessage:e.errorMessage,errorPath:e.errorPath,warmupStatus:e.warmupStatus,warmupErrorMessage:e.warmupErrorMessage,warmupSignature:e.warmupSignature,loadPromise:e.loadPromise,activeHandles:new Set(e.activeHandles),ownedResourceAliases:e.ownedResourceAliases.slice()}:null,O=(e,t,r)=>{if(e&&("function"==typeof t&&(e.isLoaded?L(()=>t()):e._loadFailed||e._onloadListeners.push(t)),"function"==typeof r))if(e._loadFailed){const t=e._loadErrorMessage||"failed to load effect",n=e._loadErrorPath||"";L(()=>r(t,n))}else e.isLoaded||e._onerrorListeners.push(r)},W=(e,t,r="")=>{if(!e||e._loadFailed)return;e._loadFailed=!0,e._loadErrorMessage=String(t||"failed to load effect"),e._loadErrorPath=String(r||""),F(e);const n=e._onerrorListeners.slice();e._onloadListeners.length=0,e._onerrorListeners.length=0;for(let t=0;t<n.length;t++){const r=n[t];L(()=>r(e._loadErrorMessage,e._loadErrorPath))}};let z=(e,t,r)=>{U(e,t,r)};const B={ptr:0,capacity:0},j=(t,r)=>{const n=t instanceof Float32Array?t:new Float32Array(t);if(n.length<=0)return void r(0);const a=((s=n.length)<=B.capacity&&0!==B.ptr||(0!==B.ptr&&(e._free(B.ptr),B.ptr=0,B.capacity=0),B.ptr=e._malloc(4*s),B.capacity=s),B.ptr);var s;e.HEAPF32.set(n,a>>2),r(a)},N=Object.freeze({rgba8unorm:22,"rgba8unorm-srgb":23,bgra8unorm:27,"bgra8unorm-srgb":28,rgba16float:40,depth24plus:46,"depth24plus-stencil8":47,depth32float:48}),G=Object.freeze(Object.fromEntries(Object.entries(N).map(([e,t])=>[t,e]))),V=e=>{if("number"==typeof e&&Number.isFinite(e))return 0|e;if("string"!=typeof e)return null;const t=e.trim().toLowerCase();return t&&Object.prototype.hasOwnProperty.call(N,t)?N[t]:null},H=e=>{if("string"==typeof e){const t=e.trim().toLowerCase();return t&&Object.prototype.hasOwnProperty.call(N,t)?t:null}return"number"==typeof e&&Number.isFinite(e)&&G[0|e]||null},$=e=>{const t=Number(e);return!Number.isFinite(t)||t<=0?1:Math.max(1,Math.floor(t))},q="undefined"!=typeof GPUTextureUsage?GPUTextureUsage:{COPY_SRC:1,COPY_DST:2,TEXTURE_BINDING:4,STORAGE_BINDING:8,RENDER_ATTACHMENT:16},K=async i=>{if(n)return;if(a)return void await new Promise((e,t)=>{u.push(r=>r?e():t(new Error("Runtime initialization failed.")))});if(a=!0,"undefined"==typeof effekseer_webgpu_native)throw a=!1,new Error("effekseer_webgpu_native is not loaded.");const o={};"string"==typeof i&&i.length>0&&(o.locateFile=e=>e.endsWith(".wasm")?i:e),s&&(o.preinitializedWebGPUDevice=s);const f=effekseer_webgpu_native(o);e=f instanceof Promise?await f:f,!s&&e?.preinitializedWebGPUDevice&&(s=e.preinitializedWebGPUDevice),s&&(e.preinitializedWebGPUDevice=s),(()=>{t={InitInternal:e.cwrap("EffekseerInitInternal","number",["number","number","string","number","number"]),InitExternal:e.cwrap("EffekseerInitExternal","number",["number","number","number","number"]),Init:e.cwrap("EffekseerInit","number",["number","number","string","number","number","number"]),Terminate:e.cwrap("EffekseerTerminate","void",["number"]),Update:e.cwrap("EffekseerUpdate","void",["number","number"]),BeginUpdate:e.cwrap("EffekseerBeginUpdate","void",["number"]),EndUpdate:e.cwrap("EffekseerEndUpdate","void",["number"]),UpdateHandle:e.cwrap("EffekseerUpdateHandle","void",["number","number","number"]),Draw:e.cwrap("EffekseerDraw","void",["number"]),DrawExternal:e.cwrap("EffekseerDrawExternal","void",["number"]),BeginDraw:e.cwrap("EffekseerBeginDraw","void",["number"]),EndDraw:e.cwrap("EffekseerEndDraw","void",["number"]),DrawHandle:e.cwrap("EffekseerDrawHandle","void",["number","number"]),SetProjectionMatrix:e.cwrap("EffekseerSetProjectionMatrix","void",["number","number"]),SetProjectionPerspective:e.cwrap("EffekseerSetProjectionPerspective","void",["number","number","number","number","number"]),SetProjectionOrthographic:e.cwrap("EffekseerSetProjectionOrthographic","void",["number","number","number","number","number"]),SetCameraMatrix:e.cwrap("EffekseerSetCameraMatrix","void",["number","number"]),SetCameraLookAt:e.cwrap("EffekseerSetCameraLookAt","void",["number","number","number","number","number","number","number","number","number","number"]),LoadEffect:e.cwrap("EffekseerLoadEffect","number",["number","number","number","number"]),ReleaseEffect:e.cwrap("EffekseerReleaseEffect","void",["number","number"]),ReloadResources:e.cwrap("EffekseerReloadResources","void",["number","number","number","number"]),StopAllEffects:e.cwrap("EffekseerStopAllEffects","void",["number"]),PlayEffect:e.cwrap("EffekseerPlayEffect","number",["number","number","number","number","number"]),StopEffect:e.cwrap("EffekseerStopEffect","void",["number","number"]),StopRoot:e.cwrap("EffekseerStopRoot","void",["number","number"]),Exists:e.cwrap("EffekseerExists","number",["number","number"]),SetFrame:e.cwrap("EffekseerSetFrame","void",["number","number","number"]),SetLocation:e.cwrap("EffekseerSetLocation","void",["number","number","number","number","number"]),SetRotation:e.cwrap("EffekseerSetRotation","void",["number","number","number","number","number"]),SetScale:e.cwrap("EffekseerSetScale","void",["number","number","number","number","number"]),SetMatrix:e.cwrap("EffekseerSetMatrix","void",["number","number","number"]),SetAllColor:e.cwrap("EffekseerSetAllColor","void",["number","number","number","number","number","number"]),SetTargetLocation:e.cwrap("EffekseerSetTargetLocation","void",["number","number","number","number","number"]),GetDynamicInput:e.cwrap("EffekseerGetDynamicInput","number",["number","number","number"]),SetDynamicInput:e.cwrap("EffekseerSetDynamicInput","void",["number","number","number","number"]),SendTrigger:e.cwrap("EffekseerSendTrigger","void",["number","number","number"]),SetPaused:e.cwrap("EffekseerSetPaused","void",["number","number","number"]),SetShown:e.cwrap("EffekseerSetShown","void",["number","number","number"]),SetSpeed:e.cwrap("EffekseerSetSpeed","void",["number","number","number"]),SetRandomSeed:e.cwrap("EffekseerSetRandomSeed","void",["number","number","number"]),SetCompositeMode:e.cwrap("EffekseerSetCompositeMode","void",["number","number"]),GetRestInstancesCount:e.cwrap("EffekseerGetRestInstancesCount","number",["number"]),DrawExternalBack:e.cwrap("EffekseerDrawExternalBack","void",["number"]),DrawExternalFront:e.cwrap("EffekseerDrawExternalFront","void",["number"]),IsVertexArrayObjectSupported:e.cwrap("EffekseerIsVertexArrayObjectSupported","number",["number"]),SetRestorationOfStatesFlag:e.cwrap("EffekseerSetRestorationOfStatesFlag","void",["number","number"]),CaptureBackground:e.cwrap("EffekseerCaptureBackground","void",["number","number","number","number","number"]),ResetBackground:e.cwrap("EffekseerResetBackground","void",["number"]),SetLogEnabled:e.cwrap("EffekseerSetLogEnabled","void",["number"]),SetDepthTexture:e.cwrap("EffekseerSetDepthTexture","void",["number","number"]),SetBackgroundTexture:e.cwrap("EffekseerSetBackgroundTexture","void",["number","number"])},e.resourcesMap={},e._loadBinary=(t,n)=>{const a=r;if(!a)return null;let s=a.resources.find(e=>e.path===t);if(s)return s.isLoaded?s.buffer:null;s={path:t,isLoaded:!1,buffer:null,isRequired:!!n},a.resources.push(s);const i=e=>String(e||"").replace(/\\/g,"/"),o=e=>{const t=i(e);let r=t.startsWith("/")||/^[a-zA-Z]+:\/\//.test(t)?t:(a.baseDir||"")+t;return a.redirect&&(r=a.redirect(r)),r},f=(e=>{const t=i(e),r=[],n=new Set,a=e=>{e&&!n.has(e)&&(n.add(e),r.push(e))},s=e=>{if(!e||e.includes("/"))return;const t=e.toLowerCase();(t.endsWith(".png")||t.endsWith(".jpg")||t.endsWith(".jpeg")||t.endsWith(".dds"))&&a(`Texture/${e}`),(t.endsWith(".efkmodel")||t.endsWith(".mqo"))&&a(`Model/${e}`)},o=t.indexOf("/");if(o>0){const e=t.slice(0,o).toLowerCase();(e.endsWith(".efk")||e.endsWith(".efkefc")||e.endsWith(".efkproj"))&&a(t.slice(o+1))}a(t),s(t);let f=t.indexOf("/");for(;f>=0;){const e=t.slice(f+1);a(e),s(e),f=t.indexOf("/",f+1)}return r})(t);if(a.syncResourceLoad){for(let r=0;r<f.length;r++){const n=f[r],a=o(n),i=e.resourcesMap[a]||e.resourcesMap[n]||e.resourcesMap[t];if(null!=i)return s.buffer=i,s.isLoaded=!0,i;const u=A(a);if(null!=u)return s.buffer=u,s.isLoaded=!0,e.resourcesMap[a]=u,e.resourcesMap[n]=u,u}return s.buffer=null,s.isLoaded=!0,null}for(let r=0;r<f.length;r++){const n=f[r],i=o(n),u=e.resourcesMap[i]||e.resourcesMap[n]||e.resourcesMap[t];if(null!=u)return s.buffer=u,s.isLoaded=!0,Promise.resolve().then(()=>a._update()),null}let u=0;const l=()=>{if(u>=f.length)return s.buffer=null,s.isLoaded=!0,void a._update();const e=f[u++],t=o(e);z(t,e=>{if(null!=e)return s.buffer=e,s.isLoaded=!0,void a._update();l()},()=>{l()})};return l(),null},n=!0,a=!1,c();const s=u;u=[],s.forEach(e=>e(!0))})()};class X{constructor(e){this.context=e,this.nativeptr=0,this.baseDir="",this.syncResourceLoad=!1,this.isLoaded=!1,this.scale=1,this.resources=[],this.mainBuffer=null,this.onload=null,this.onerror=null,this._onloadListeners=[],this._onerrorListeners=[],this._loadFailed=!1,this._loadErrorMessage="",this._loadErrorPath="",this._cacheKey="",this.redirect=null,this.packageOnly=!1,this._ownedResourceAliases=[],this._managedRefIds=new Set}_load(n){const a=d(n);if(!a)return void W(this,"invalid data","");r=this,this.mainBuffer=a;const s=e._malloc(a.byteLength);e.HEAPU8.set(new Uint8Array(a),s),this.nativeptr=t.LoadEffect(this.context.nativeptr,s,a.byteLength,this.scale),e._free(s),r=null,this._update()}_reload(){if(!this.mainBuffer||!this.nativeptr)return;r=this;const n=e._malloc(this.mainBuffer.byteLength);e.HEAPU8.set(new Uint8Array(this.mainBuffer),n),t.ReloadResources(this.context.nativeptr,this.nativeptr,n,this.mainBuffer.byteLength),e._free(n),r=null}_update(){let e=!1;const r=[];for(let t=0;t<this.resources.length;t++){const n=this.resources[t];if(!n.isLoaded){e=!0;break}n.isRequired&&null==n.buffer&&r.push(n.path)}if(e)return;const n=0!==this.nativeptr;if(r.length>0){const e=`failed to load effect. missing resources: ${r.join(", ")}`;return n&&(t.ReleaseEffect(this.context.nativeptr,this.nativeptr),this.nativeptr=0),console.error(`[EffekseerWebGPU] ${e}`),void W(this,e,this.baseDir||"")}if(!n){return void W(this,"failed to load effect",this.baseDir||"")}!this.isLoaded&&n&&(this.isLoaded=!0,(e=>{if(!e)return;const t=e._onloadListeners.slice();e._onloadListeners.length=0,e._onerrorListeners.length=0;for(let e=0;e<t.length;e++){const r=t[e];L(()=>r())}})(this))}}const J=(t,r,n,a,s,i,o,f=null)=>{const u=f||new X(t);u.scale=a,u._ownedResourceAliases=[],O(u,s,i);const l=x(r);if(0===l.size)return W(u,"invalid data. expected efkwgpk package",n||""),u;const c=(()=>{if("string"!=typeof n||0===n.length)return"";const e=_(n),t=e.lastIndexOf("/");return t>=0?e.slice(0,t+1):""})(),d=c.toLowerCase(),h=`efwgpk://${++w}/`,m=new Map;return u.baseDir=c,u.syncResourceLoad=!0,u.packageOnly=!0,u.redirect=e=>{const t=_(e),r=[];d&&t.toLowerCase().startsWith(d)&&r.push(t.slice(c.length)),r.push(t);for(let e=0;e<r.length;e++){const t=p(r[e]);if(!t)continue;const n=m.get(t);if(n)return n}return e},(async()=>{try{const t=await(async(e,t)=>{const r=await P(e,t,g);if(r)try{const e=new TextDecoder("utf-8").decode(new Uint8Array(r)).replace(/\0+$/,""),t=p(e);if(t)return t}catch{}for(const[e,r]of t.entries())if(e.endsWith(".efkwg")&&r&&r.length>0)return e;return""})(r,l);if(!t)throw new Error("main effect path not found in efkwgpk package");const a=await P(r,l,t),s=String.fromCharCode(...new Uint8Array(a||new ArrayBuffer(0),0,Math.min(4,a?a.byteLength:0)));if(!a||"EFWG"!==s&&"SKFE"!==s)throw new Error("main effect inside efkwgpk is not a valid .efkwg");const i=new Map,o=new Map;for(const[n]of l.entries()){if(n===t||n===p(g))continue;const a=R(r,l,n);if(!a)continue;const s=M(a);if(!s)continue;let f=i.get(s);if(!f){let t=o.get(s);if(void 0===t&&(t=await P(r,l,n),o.set(s,t||null)),!t)continue;f=`${h}__payload/${i.size}`,e.resourcesMap[f]=t,i.set(s,f)}m.set(n,f)}u._ownedResourceAliases=Array.from(i.values()),u._load(a),u.nativeptr||W(u,"failed to load effect from efkwgpk package",n||t)}catch(e){W(u,e&&e.message?e.message:"failed to load effect from efkwgpk package",n||"")}})(),u};class Y{constructor(e,t){this.context=e,this.native=t}stop(){t.StopEffect(this.context.nativeptr,this.native)}stopRoot(){t.StopRoot(this.context.nativeptr,this.native)}get exists(){return!!t.Exists(this.context.nativeptr,this.native)}setFrame(e){t.SetFrame(this.context.nativeptr,this.native,e)}setLocation(e,r,n){t.SetLocation(this.context.nativeptr,this.native,e,r,n)}setRotation(e,r,n){t.SetRotation(this.context.nativeptr,this.native,e,r,n)}setScale(e,r,n){t.SetScale(this.context.nativeptr,this.native,e,r,n)}setAllColor(e,r,n,a){t.SetAllColor(this.context.nativeptr,this.native,e,r,n,a)}setTargetLocation(e,r,n){t.SetTargetLocation(this.context.nativeptr,this.native,e,r,n)}getDynamicInput(e){return t.GetDynamicInput(this.context.nativeptr,this.native,e)}setDynamicInput(e,r){t.SetDynamicInput(this.context.nativeptr,this.native,e,r)}sendTrigger(e){t.SendTrigger(this.context.nativeptr,this.native,e)}setPaused(e){t.SetPaused(this.context.nativeptr,this.native,e?1:0)}setShown(e){t.SetShown(this.context.nativeptr,this.native,e?1:0)}setSpeed(e){t.SetSpeed(this.context.nativeptr,this.native,e)}setRandomSeed(e){t.SetRandomSeed(this.context.nativeptr,this.native,e)}setMatrix(e){j(e,e=>t.SetMatrix(this.context.nativeptr,this.native,e))}}class Z{constructor(){this.nativeptr=0,this._effectCache=new Map,this._registeredEffects=new Map,this._registeredEffectStates=new Map,this._warmupTargetCache=new Map,this._warmupSettings=this._normalizeWarmupSettings(),this.fixedUpdateStepFrames=1,this.fixedUpdateMaxSubsteps=4,this.fixedUpdateAccumulator=0,this.externalRenderPassEnabled=!1}_normalizeManagedEffectDescriptor(e,t){const r=String(e||"").trim();if(!r)throw new Error("registerEffects() requires non-empty effect ids.");let n=null;if("string"==typeof t)n={path:t};else{if(!t||"object"!=typeof t||Array.isArray(t))throw new Error(`registerEffects() entry "${r}" must be a string path or config object.`);n=t}const a=String(n.path||"").trim();if(!a)throw new Error(`registerEffects() entry "${r}" requires a non-empty path.`);const s=Number(n.scale),i=Object.prototype.hasOwnProperty.call(n,"preload")?!1!==n.preload:!1!==n.enabled;return{id:r,path:a,scale:Number.isFinite(s)?s:1,preload:i,warmup:!0===n.warmup,enabled:i}}_createManagedEffectState(e){return{id:e.id,path:e.path,scale:e.scale,preload:e.preload,warmup:e.warmup,enabled:e.enabled,status:"unloaded",effect:null,errorMessage:"",errorPath:"",warmupStatus:"idle",warmupErrorMessage:"",warmupSignature:"",loadPromise:null,warmupPromise:null,activeHandles:new Set,ownedResourceAliases:[],_generation:0,_loadingEffect:null}}_resolveManagedEffectIds(e,t=null){if(null==e){const e=[];for(const[r,n]of this._registeredEffectStates.entries())("preload"!==t||n.preload)&&("warmup"!==t||n.warmup)&&("preload"!==t&&"warmup"!==t&&null!==t||null!==t&&"preload"!==t&&"warmup"!==t||e.push(r));return e}const r=Array.isArray(e)?e:[e],n=[],a=new Set;for(let e=0;e<r.length;e++){const t=String(r[e]||"").trim();t&&!a.has(t)&&(a.add(t),n.push(t))}return n}_resetManagedEffectWarmupState(e){e&&(e.warmupStatus="idle",e.warmupErrorMessage="",e.warmupSignature="",e.warmupPromise=null)}_toPositiveInteger(e,t){const r=Number(e);return!Number.isFinite(r)||r<=0?t:Math.max(1,Math.floor(r))}_normalizeWarmupSettings(e=null,t=null){const r=e&&"object"==typeof e?e:{},n=t&&"object"==typeof t?t:{},a=H(r.colorFormat??n.colorFormat??(()=>{if("undefined"!=typeof navigator&&navigator.gpu&&"function"==typeof navigator.gpu.getPreferredCanvasFormat){const e=H(navigator.gpu.getPreferredCanvasFormat());if(e)return e}return"bgra8unorm"})());if(!a)throw new Error("warmupSettings.colorFormat must be a supported GPUTextureFormat.");const s=r.depthFormat??n.depthFormat??null,i=null==s?null:H(s);if(null!=s&&!i)throw new Error("warmupSettings.depthFormat must be a supported GPUTextureFormat or null.");return{colorFormat:a,depthFormat:i,sampleCount:$(r.sampleCount??n.sampleCount??1),width:this._toPositiveInteger(r.width??n.width??4,4),height:this._toPositiveInteger(r.height??n.height??4,4),frames:this._toPositiveInteger(r.frames??n.frames??2,2),includeDepthTexture:(r.includeDepthTexture??n.includeDepthTexture??null!=i)&&null!=i,includeBackgroundTexture:!!(r.includeBackgroundTexture??n.includeBackgroundTexture)}}_getWarmupSignature(e){return JSON.stringify({colorFormat:e.colorFormat,depthFormat:e.depthFormat,sampleCount:e.sampleCount,includeDepthTexture:e.includeDepthTexture,includeBackgroundTexture:e.includeBackgroundTexture})}_getWarmupTargetCacheKey(e){return JSON.stringify({colorFormat:e.colorFormat,depthFormat:e.depthFormat,sampleCount:e.sampleCount,width:e.width,height:e.height,includeDepthTexture:e.includeDepthTexture,includeBackgroundTexture:e.includeBackgroundTexture})}_destroyWarmupTarget(e){if(!e)return;const t=e=>{if(e&&"function"==typeof e.destroy)try{e.destroy()}catch{}};t(e.backgroundTexture),t(e.depthTexture),t(e.colorTexture)}_clearWarmupTargetCache(){if(this._warmupTargetCache){for(const e of this._warmupTargetCache.values())this._destroyWarmupTarget(e);this._warmupTargetCache.clear()}}_getRuntimeWebGPUDevice(){return i||s||(e?e.preinitializedWebGPUDevice:null)||null}_getOrCreateWarmupTarget(e){const t=this._getRuntimeWebGPUDevice();if(!t)throw new Error("warmupEffects() requires a GPUDevice. Call setWebGPUDevice() and initRuntime() first.");const r=this._getWarmupTargetCacheKey(e),n=this._warmupTargetCache.get(r);if(n)return n;const a=t.createTexture({size:{width:e.width,height:e.height,depthOrArrayLayers:1},format:e.colorFormat,sampleCount:e.sampleCount,mipLevelCount:1,dimension:"2d",usage:q.RENDER_ATTACHMENT}),s=a.createView();let i=null,o=null;e.depthFormat&&(i=t.createTexture({size:{width:e.width,height:e.height,depthOrArrayLayers:1},format:e.depthFormat,sampleCount:e.sampleCount,mipLevelCount:1,dimension:"2d",usage:q.RENDER_ATTACHMENT|q.TEXTURE_BINDING}),o=i.createView());let f=null,u=null;e.includeBackgroundTexture&&(f=t.createTexture({size:{width:e.width,height:e.height,depthOrArrayLayers:1},format:e.colorFormat,sampleCount:1,mipLevelCount:1,dimension:"2d",usage:q.RENDER_ATTACHMENT|q.TEXTURE_BINDING}),u=f.createView());const l={colorAttachments:[{view:s,clearValue:{r:0,g:0,b:0,a:0},loadOp:"clear",storeOp:"store"}]};o&&(l.depthStencilAttachment={view:o,depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"},"depth24plus-stencil8"===e.depthFormat&&(l.depthStencilAttachment.stencilClearValue=0,l.depthStencilAttachment.stencilLoadOp="clear",l.depthStencilAttachment.stencilStoreOp="discard"));const c={colorFormat:e.colorFormat,depthFormat:e.depthFormat,sampleCount:e.sampleCount};e.includeDepthTexture&&o&&(c.depthTextureView=o),e.includeBackgroundTexture&&u&&(c.backgroundTextureView=u);const d={colorTexture:a,colorView:s,depthTexture:i,depthView:o,backgroundTexture:f,backgroundView:u,renderPassDescriptor:l,renderPassState:c};return this._warmupTargetCache.set(r,d),d}_ensureRegisteredEffectLoaded(e){return e?"loaded"===e.status&&e.effect?.isLoaded?Promise.resolve(e.effect):"loading"===e.status&&e.loadPromise?e.loadPromise:this._loadRegisteredEffectState(e):Promise.resolve(null)}_registerManagedEffectReference(e,t){e&&(e._managedRefIds instanceof Set||(e._managedRefIds=new Set),e._managedRefIds.add(t))}_releaseManagedEffectReference(e,t){e&&e._managedRefIds instanceof Set&&e._managedRefIds.delete(t)}_releaseManagedEffectIfUnused(r){if(!r)return;const n=r._managedRefIds instanceof Set?r._managedRefIds:null;n&&n.size>0||(F(r),(t=>{if(t&&e.resourcesMap)for(let r=0;r<t.length;r++){const n=t[r];"string"==typeof n&&0!==n.length&&delete e.resourcesMap[n]}})(r._ownedResourceAliases),r._ownedResourceAliases=[],this.nativeptr&&r.nativeptr&&(t.ReleaseEffect(this.nativeptr,r.nativeptr),r.nativeptr=0))}_stopManagedHandles(e){if(e){for(const t of e.activeHandles)try{t?.stopRoot?.()}catch{}e.activeHandles.clear()}}_cleanupManagedHandles(){for(const e of this._registeredEffectStates.values())if(e&&0!==e.activeHandles.size)for(const t of Array.from(e.activeHandles))t&&!1!==t.exists||e.activeHandles.delete(t)}_resetManagedEffectStateToUnloaded(e){e&&(e.effect=null,e.status="unloaded",e.errorMessage="",e.errorPath="",e.loadPromise=null,e.ownedResourceAliases=[],e._loadingEffect=null,this._resetManagedEffectWarmupState(e))}_loadRegisteredEffectState(e){if(!e||!this.nativeptr)return Promise.resolve(null);const t=this._registeredEffects.get(e.id);if(!t)return Promise.resolve(null);const r=e._generation+1;e._generation=r,e.status="loading",e.errorMessage="",e.errorPath="",e.effect=null,e.ownedResourceAliases=[],e._loadingEffect=null,this._resetManagedEffectWarmupState(e);const n=new Promise(n=>{let a=!1,s=null;const i=s=>{if(a)return;a=!0;return this._registeredEffectStates.get(e.id)!==e||e._generation!==r?(this._releaseManagedEffectIfUnused(s),void n(null)):(e._loadingEffect=null,e.loadPromise=null,s&&s.isLoaded?(e.effect=s,e.status="loaded",e.errorMessage="",e.errorPath="",e.ownedResourceAliases=Array.isArray(s._ownedResourceAliases)?s._ownedResourceAliases.slice():[],void n(s)):(e.status="failed",e.errorMessage="failed to load effect",e.errorPath=t.path,void n(null)))},o=(i,o="")=>{if(a)return;a=!0,s&&this._releaseManagedEffectReference(s,e.id);if(this._registeredEffectStates.get(e.id)!==e||e._generation!==r)return s&&this._releaseManagedEffectIfUnused(s),void n(null);e._loadingEffect=null,e.loadPromise=null,e.effect=null,e.status="failed",e.errorMessage=String(i||"failed to load effect"),e.errorPath=String(o||t.path||""),e.ownedResourceAliases=[],s&&this._releaseManagedEffectIfUnused(s),n(null)};try{s=this.loadEffect(t.path,t.scale,()=>i(s),(e,t)=>o(e,t))}catch(e){return void o(e&&e.message?e.message:"failed to load effect",t.path)}e._loadingEffect=s,s?(this._registerManagedEffectReference(s,e.id),s.isLoaded?i(s):s._loadFailed&&o(s._loadErrorMessage,s._loadErrorPath)):o("failed to create effect",t.path)});return e.loadPromise=n,n}async _warmupRegisteredEffectStates(e,t=null){const r=this._normalizeWarmupSettings(t,this._warmupSettings),n=this._getWarmupSignature(r),a=new Map,s=[],i=[];for(let t=0;t<e.length;t++){const r=e[t];r&&"loaded"===r.status&&r.effect?.isLoaded?"warmed"!==r.warmupStatus||r.warmupSignature!==n?"warming"===r.warmupStatus&&r.warmupPromise?s.push(r.warmupPromise):i.push(r):a.set(r.id,r.effect):a.set(r?.id??"",null)}if(s.length>0)return await Promise.allSettled(s),this._warmupRegisteredEffectStates(e,r);if(0===i.length){for(let t=0;t<e.length;t++){const r=e[t];r&&!a.has(r.id)&&("warmed"===r.warmupStatus&&r.warmupSignature===n&&r.effect?.isLoaded?a.set(r.id,r.effect):a.set(r.id,null))}return a}const o=(async()=>{const e=new Map,t=[],a=new Map;let s=null;try{const n=this._getRuntimeWebGPUDevice();if(!n)throw new Error("warmupEffects() requires a GPUDevice. Call setWebGPUDevice() and initRuntime() first.");const s=this._getOrCreateWarmupTarget(r);for(let r=0;r<i.length;r++){const n=i[r],s=n._generation;if(a.set(n.id,s),"loaded"!==n.status||!n.effect?.isLoaded){n.warmupStatus="failed",n.warmupErrorMessage="failed to warm up effect because it is not loaded",n.warmupSignature="",e.set(n.id,null);continue}const o=this.play(n.effect,0,0,0);o?t.push({state:n,handle:o,generation:s}):(n.warmupStatus="failed",n.warmupErrorMessage="failed to create a temporary warmup handle",n.warmupSignature="",e.set(n.id,null))}if(t.length>0)for(let e=0;e<r.frames;e++){this.update(1);const e=n.createCommandEncoder(),t=e.beginRenderPass(s.renderPassDescriptor);try{this.drawExternal(t,s.renderPassState,"all")}finally{t.end()}n.queue.submit([e.finish()]),"function"==typeof n.queue.onSubmittedWorkDone&&await n.queue.onSubmittedWorkDone()}}catch(e){s=e}finally{for(let e=0;e<t.length;e++){const r=t[e];try{r.handle.stopRoot?.()}catch{}}t.length>0&&this.update(1)}for(let t=0;t<i.length;t++){const r=i[t];this._registeredEffectStates.get(r.id)===r&&r._generation===a.get(r.id)?s?(r.warmupStatus="failed",r.warmupErrorMessage=s&&s.message?s.message:"failed to warm up effect",r.warmupSignature="",e.set(r.id,null)):e.has(r.id)||(r.warmupStatus="warmed",r.warmupErrorMessage="",r.warmupSignature=n,e.set(r.id,r.effect?.isLoaded?r.effect:null)):e.set(r.id,null)}return e})();for(let e=0;e<i.length;e++){const t=i[e];t.warmupStatus="warming",t.warmupErrorMessage="",t.warmupSignature="",t.warmupPromise=o}const f=await o;for(let e=0;e<i.length;e++){const t=i[e];t.warmupPromise===o&&(t.warmupPromise=null)}for(let t=0;t<e.length;t++){const r=e[t];r&&!a.has(r.id)&&(f.has(r.id)?a.set(r.id,f.get(r.id)):"warmed"===r.warmupStatus&&r.warmupSignature===n&&r.effect?.isLoaded?a.set(r.id,r.effect):a.set(r.id,null))}return a}_prepareInitSettings(e={},t=!1){const r=e.instanceMaxCount||4e3,n=e.squareMaxCount||1e4,a=!1!==e.linearColorSpace?1:0,s=e.compositeWithBackground?1:0;return this.externalRenderPassEnabled=t,this._warmupSettings=this._normalizeWarmupSettings(e.warmupSettings,this._warmupSettings),this.fixedUpdateAccumulator=0,{instanceMaxCount:r,squareMaxCount:n,linearColorSpace:a,compositeWithBackground:s}}_finishContextInit(e={}){return this.nativeptr&&e.effects&&(this.registerEffects(e.effects),this.preloadEffects()),!!this.nativeptr}init(e,r={}){if(!0===r.externalRenderPass)return this.initExternal(r);let n="#canvas";"string"==typeof e?n=e.startsWith("#")?e:`#${e}`:"undefined"!=typeof HTMLCanvasElement&&e instanceof HTMLCanvasElement&&(e.id||(f+=1,e.id=`effekseer_webgpu_canvas_${f}`),n=`#${e.id}`);const a=this._prepareInitSettings(r,!1);return this.nativeptr=t.InitInternal(a.instanceMaxCount,a.squareMaxCount,n,a.linearColorSpace,a.compositeWithBackground),this._finishContextInit(r)}initExternal(e={}){const r=this._prepareInitSettings(e,!0);return this.nativeptr=t.InitExternal(r.instanceMaxCount,r.squareMaxCount,r.linearColorSpace,r.compositeWithBackground),this._finishContextInit(e)}update(e=1){const r=Number(e);if(!Number.isFinite(r)||r<=0)return void this._cleanupManagedHandles();this.fixedUpdateAccumulator+=r;let n=0;for(;this.fixedUpdateAccumulator>=this.fixedUpdateStepFrames&&n<this.fixedUpdateMaxSubsteps;)t.Update(this.nativeptr,this.fixedUpdateStepFrames),this.fixedUpdateAccumulator-=this.fixedUpdateStepFrames,n++;n>=this.fixedUpdateMaxSubsteps&&this.fixedUpdateAccumulator>=this.fixedUpdateStepFrames&&(this.fixedUpdateAccumulator=0),this._cleanupManagedHandles()}beginUpdate(){t.BeginUpdate(this.nativeptr)}endUpdate(){t.EndUpdate(this.nativeptr)}updateHandle(e,r=1){t.UpdateHandle(this.nativeptr,e.native,r)}draw(){this.externalRenderPassEnabled||t.Draw(this.nativeptr)}drawExternal(r,n=null,a="all"){if(!r)return;const s=V(n&&n.colorFormat),i=(()=>{const e=V(n&&n.depthFormat);return null===e?0:e})(),o=$(n&&n.sampleCount),f=(e,t)=>!!e&&Object.prototype.hasOwnProperty.call(e,t),u=f(n,"depthTextureView")||f(n,"importDepthTextureView"),l=f(n,"backgroundTextureView")||f(n,"importBackgroundTextureView"),c=u?f(n,"depthTextureView")?n.depthTextureView:n.importDepthTextureView:null,d=l?f(n,"backgroundTextureView")?n.backgroundTextureView:n.importBackgroundTextureView:null,p=u?e.__effekseerDepthTextureView:null,h=l?e.__effekseerBackgroundTextureView:null;e.__effekseerExternalRenderPass=r,e.__effekseerExternalPassColorFormat=s,e.__effekseerExternalPassDepthFormat=i,e.__effekseerExternalPassSampleCount=o,u&&(e.__effekseerDepthTextureView=c||null),l&&(e.__effekseerBackgroundTextureView=d||null);const g="back"===a?"back":"front"===a?"front":"all";try{"back"===g?t.DrawExternalBack(this.nativeptr):"front"===g?t.DrawExternalFront(this.nativeptr):t.DrawExternal(this.nativeptr)}finally{u&&(e.__effekseerDepthTextureView=p||null),l&&(e.__effekseerBackgroundTextureView=h||null),e.__effekseerExternalRenderPass=null,e.__effekseerExternalPassColorFormat=null,e.__effekseerExternalPassDepthFormat=null,e.__effekseerExternalPassSampleCount=null}}beginDraw(){t.BeginDraw(this.nativeptr)}endDraw(){t.EndDraw(this.nativeptr)}drawHandle(e){t.DrawHandle(this.nativeptr,e.native)}setProjectionMatrix(e){j(e,e=>t.SetProjectionMatrix(this.nativeptr,e))}setProjectionPerspective(e,r,n,a){t.SetProjectionPerspective(this.nativeptr,e,r,n,a)}setProjectionOrthographic(e,r,n,a){t.SetProjectionOrthographic(this.nativeptr,e,r,n,a)}setCameraMatrix(e){j(e,e=>t.SetCameraMatrix(this.nativeptr,e))}setCameraLookAt(e,r,n,a,s,i,o,f,u){t.SetCameraLookAt(this.nativeptr,e,r,n,a,s,i,o,f,u)}setCameraLookAtFromVector(e,t,r={x:0,y:1,z:0}){this.setCameraLookAt(e.x,e.y,e.z,t.x,t.y,t.z,r.x,r.y,r.z)}setCompositeMode(e){t.SetCompositeMode(this.nativeptr,e?1:0)}loadEffect(e,t=1,r,n,a){const s="function"==typeof t?1:t,i="function"==typeof t?t:r,o="function"==typeof t?r:n,f=a;let u=null;if("string"==typeof e&&null==f){u=D(e,s);const t=this._effectCache.get(u);if(t)return O(t,i,o),t}const l=new X(this);l.scale=s,l.redirect=f,l._cacheKey=u||"",O(l,i,o),u&&this._effectCache.set(u,l);const c=(e,t="")=>(W(l,e,t),l);if("string"==typeof e)return"string"==typeof(p=e)&&0!==p.length&&p.replace(/\\/g,"/").split("?")[0].split("#")[0].toLowerCase().endsWith(".efkwg")?(U(e,t=>{const r=d(t);if(!r)return void c("failed to fetch efkwg effect",e);const n=e.replace(/\\/g,"/").split("?")[0].split("#")[0],a=n.lastIndexOf("/");l.baseDir=a>=0?n.slice(0,a+1):"",l.syncResourceLoad=!1,l._load(r),l.nativeptr||c("failed to load efkwg effect",e)},()=>{c("failed to fetch efkwg effect",e)}),l):(e=>"string"==typeof e&&0!==e.length&&_(e).toLowerCase().endsWith(".efkwgpk"))(e)?(U(e,t=>{const r=d(t);r?J(this,r,e,s,null,null,0,l):c("failed to fetch efkwgpk package",e)},()=>{c("failed to fetch efkwgpk package",e)}),l):c("unsupported effect format. expected .efkwg or .efkwgpk",e);var p;const g=d(e);if(!g)return c("invalid data. expected efkwg or efkwgpk bytes","");if(v(g)===h)return J(this,g,"",s,null,null,0,l);const m=String.fromCharCode(...new Uint8Array(g,0,Math.min(4,g.byteLength)));return"EFWG"===m||"SKFE"===m?(l._load(g),l.nativeptr?l:c("failed to load efkwg effect","")):c("invalid data. expected efkwg or efkwgpk bytes","")}loadEffectPackage(e,t,r=1,n,a){let s=r,i=n,o=a;return"function"==typeof r&&(s=1,i=r,o=n),this.loadEffect(e,s,i,o)}registerEffects(e){if(!e||"object"!=typeof e||Array.isArray(e))throw new Error("registerEffects() expects an object map of effect ids to paths/configs.");const t=[];for(const[r,n]of Object.entries(e)){if(this._registeredEffects.has(r))throw new Error(`registerEffects() duplicate id "${r}".`);t.push(this._normalizeManagedEffectDescriptor(r,n))}for(let e=0;e<t.length;e++){const r=t[e];if(this._registeredEffects.has(r.id))throw new Error(`registerEffects() duplicate id "${r.id}".`)}for(let e=0;e<t.length;e++){const r=t[e];this._registeredEffects.set(r.id,r),this._registeredEffectStates.set(r.id,this._createManagedEffectState(r))}if(this.nativeptr)for(let e=0;e<t.length;e++){const r=t[e];r.preload&&this.preloadEffects([r.id])}}async preloadEffects(e){const t=this._resolveManagedEffectIds(e,null==e?"preload":null),r=new Map,n=[];for(let e=0;e<t.length;e++){const a=t[e],s=this._registeredEffectStates.get(a);if(!s){r.set(a,null);continue}const i=await this._ensureRegisteredEffectLoaded(s);r.set(a,i),i&&s.warmup&&n.push(s)}if(n.length>0){const e=await this._warmupRegisteredEffectStates(n);for(const[t,n]of e.entries())r.set(t,n)}return r}reloadEffects(e){const t=this._resolveManagedEffectIds(e,null==e?"preload":null);return this.unloadEffects(t),this.preloadEffects(t)}unloadEffects(e){const t=this._resolveManagedEffectIds(e);for(let e=0;e<t.length;e++){const r=t[e],n=this._registeredEffectStates.get(r);if(!n)continue;n._generation+=1,this._stopManagedHandles(n);const a=n._loadingEffect;a&&(this._releaseManagedEffectReference(a,r),this._releaseManagedEffectIfUnused(a));const s=n.effect;s&&(this._releaseManagedEffectReference(s,r),this._releaseManagedEffectIfUnused(s)),this._resetManagedEffectStateToUnloaded(n)}}unregisterEffects(e){const t=this._resolveManagedEffectIds(e);this.unloadEffects(t);for(let e=0;e<t.length;e++){const r=t[e];this._registeredEffects.delete(r),this._registeredEffectStates.delete(r)}}getEffect(e){const t=this._registeredEffectStates.get(String(e||""));return"loaded"===t?.status&&t.effect?.isLoaded?t.effect:null}getEffectState(e){return I(this._registeredEffectStates.get(String(e||"")))}getEffectStates(){return Array.from(this._registeredEffectStates.values(),e=>I(e))}async warmupEffects(e,t){const r=this._resolveManagedEffectIds(e,null==e?"warmup":null),n=new Map,a=[];for(let e=0;e<r.length;e++){const t=r[e],s=this._registeredEffectStates.get(t);if(!s){n.set(t,null);continue}await this._ensureRegisteredEffectLoaded(s)?a.push(s):n.set(t,null)}if(0===a.length)return n;const s=await this._warmupRegisteredEffectStates(a,t);for(const[e,t]of s.entries())n.set(e,t);return n}whenEffectsReady(e){return this.preloadEffects(e)}playEffect(e,t=0,r=0,n=0){const a=this._registeredEffectStates.get(String(e||""));if(!a||"loaded"!==a.status||!a.effect?.isLoaded)return null;const s=this.play(a.effect,t,r,n);return s&&a.activeHandles.add(s),s}releaseEffect(e){e&&e.nativeptr&&(F(e),t.ReleaseEffect(this.nativeptr,e.nativeptr),e.nativeptr=0)}play(e,r=0,n=0,a=0){if(!e||!e.isLoaded)return null;const s=t.PlayEffect(this.nativeptr,e.nativeptr,r,n,a);return s>=0?new Y(this,s):null}stopAll(){t.StopAllEffects(this.nativeptr)}setResourceLoader(e){z=e}getRestInstancesCount(){return t.GetRestInstancesCount(this.nativeptr)}isVertexArrayObjectSupported(){return!!t.IsVertexArrayObjectSupported(this.nativeptr)}setRestorationOfStatesFlag(e){t.SetRestorationOfStatesFlag(this.nativeptr,e?1:0)}captureBackground(e,r,n,a){t.CaptureBackground(this.nativeptr,e,r,n,a)}resetBackground(){t.ResetBackground(this.nativeptr)}}return new class{async initRuntime(e,t,r){try{await K(e),t&&t()}catch(e){a=!1,n=!1,u=[],r?r(e):console.error(e)}}createContext(){return n?new Z:null}releaseContext(e){e&&e.nativeptr&&(e.unloadEffects?.(),e._clearWarmupTargetCache?.(),t.Terminate(e.nativeptr),e.nativeptr=0,e._effectCache?.clear?.(),e._registeredEffects?.clear?.(),e._registeredEffectStates?.clear?.())}setLogEnabled(e){l=!!e,c()}setImageCrossOrigin(e){o=e}setWebGPUDevice(e){if(n||a)throw new Error("setWebGPUDevice() must be called before initRuntime().");if(null==e)return i=null,void(s=null);if("object"!=typeof e||"function"!=typeof e.createCommandEncoder||!e.queue)throw new Error("setWebGPUDevice() expects a valid GPUDevice.");i=e,s=e}setRendererWorkingColorSpace(e){return((e=null)=>{const t=e;return!(!t||!t.ColorManagement)&&"workingColorSpace"in t.ColorManagement&&void 0!==t.LinearSRGBColorSpace&&(t.ColorManagement.workingColorSpace=t.LinearSRGBColorSpace,!0)})(e)}getWebGPUDevice(){return s||(e?e.preinitializedWebGPUDevice:null)||null}init(e,t){return this.defaultContext?.nativeptr&&this.releaseContext(this.defaultContext),this.defaultContext=new Z,this.defaultContext.init(e,t)}update(e){this.defaultContext.update(e)}beginUpdate(){this.defaultContext.beginUpdate()}endUpdate(){this.defaultContext.endUpdate()}updateHandle(e,t){this.defaultContext.updateHandle(e,t)}draw(){this.defaultContext.draw()}drawExternal(e,t,r="all"){this.defaultContext.drawExternal(e,t,r)}beginDraw(){this.defaultContext.beginDraw()}endDraw(){this.defaultContext.endDraw()}drawHandle(e){this.defaultContext.drawHandle(e)}setProjectionMatrix(e){this.defaultContext.setProjectionMatrix(e)}setProjectionPerspective(e,t,r,n){this.defaultContext.setProjectionPerspective(e,t,r,n)}setProjectionOrthographic(e,t,r,n){this.defaultContext.setProjectionOrthographic(e,t,r,n)}setCameraMatrix(e){this.defaultContext.setCameraMatrix(e)}setCameraLookAt(e,t,r,n,a,s,i,o,f){this.defaultContext.setCameraLookAt(e,t,r,n,a,s,i,o,f)}setCameraLookAtFromVector(e,t,r){this.defaultContext.setCameraLookAtFromVector(e,t,r)}setCompositeMode(e){this.defaultContext.setCompositeMode(e)}loadEffect(e,t,r,n,a){return this.defaultContext.loadEffect(e,t,r,n,a)}loadEffectPackage(e,t,r,n,a){return this.defaultContext.loadEffectPackage(e,t,r,n,a)}registerEffects(e){this.defaultContext.registerEffects(e)}preloadEffects(e){return this.defaultContext.preloadEffects(e)}warmupEffects(e,t){return this.defaultContext.warmupEffects(e,t)}reloadEffects(e){return this.defaultContext.reloadEffects(e)}unloadEffects(e){this.defaultContext.unloadEffects(e)}unregisterEffects(e){this.defaultContext.unregisterEffects(e)}getEffect(e){return this.defaultContext.getEffect(e)}getEffectState(e){return this.defaultContext.getEffectState(e)}getEffectStates(){return this.defaultContext.getEffectStates()}whenEffectsReady(e){return this.defaultContext.whenEffectsReady(e)}playEffect(e,t,r,n){return this.defaultContext.playEffect(e,t,r,n)}releaseEffect(e){this.defaultContext.releaseEffect(e)}play(e,t,r,n){return this.defaultContext.play(e,t,r,n)}stopAll(){this.defaultContext.stopAll()}setResourceLoader(e){this.defaultContext.setResourceLoader(e)}getRestInstancesCount(){return this.defaultContext.getRestInstancesCount()}isVertexArrayObjectSupported(){return this.defaultContext.isVertexArrayObjectSupported()}}})();"undefined"!=typeof globalThis&&(globalThis.effekseer=e),"undefined"!=typeof exports&&(exports=e);
|
|
@@ -586,11 +586,16 @@ const effekseer = (() => {
|
|
|
586
586
|
id: state.id,
|
|
587
587
|
path: state.path,
|
|
588
588
|
scale: state.scale,
|
|
589
|
+
preload: state.preload,
|
|
590
|
+
warmup: state.warmup,
|
|
589
591
|
enabled: state.enabled,
|
|
590
592
|
status: state.status,
|
|
591
593
|
effect: state.status === "loaded" ? state.effect : null,
|
|
592
594
|
errorMessage: state.errorMessage,
|
|
593
595
|
errorPath: state.errorPath,
|
|
596
|
+
warmupStatus: state.warmupStatus,
|
|
597
|
+
warmupErrorMessage: state.warmupErrorMessage,
|
|
598
|
+
warmupSignature: state.warmupSignature,
|
|
594
599
|
loadPromise: state.loadPromise,
|
|
595
600
|
activeHandles: new Set(state.activeHandles),
|
|
596
601
|
ownedResourceAliases: state.ownedResourceAliases.slice(),
|
|
@@ -745,6 +750,29 @@ const effekseer = (() => {
|
|
|
745
750
|
return Math.max(1, Math.floor(n));
|
|
746
751
|
};
|
|
747
752
|
|
|
753
|
+
const GPUTextureUsageFlags = (() => {
|
|
754
|
+
if (typeof GPUTextureUsage !== "undefined") {
|
|
755
|
+
return GPUTextureUsage;
|
|
756
|
+
}
|
|
757
|
+
return {
|
|
758
|
+
COPY_SRC: 0x01,
|
|
759
|
+
COPY_DST: 0x02,
|
|
760
|
+
TEXTURE_BINDING: 0x04,
|
|
761
|
+
STORAGE_BINDING: 0x08,
|
|
762
|
+
RENDER_ATTACHMENT: 0x10,
|
|
763
|
+
};
|
|
764
|
+
})();
|
|
765
|
+
|
|
766
|
+
const getDefaultWarmupColorFormat = () => {
|
|
767
|
+
if (typeof navigator !== "undefined" && navigator.gpu && typeof navigator.gpu.getPreferredCanvasFormat === "function") {
|
|
768
|
+
const preferred = toTextureFormatName(navigator.gpu.getPreferredCanvasFormat());
|
|
769
|
+
if (preferred) {
|
|
770
|
+
return preferred;
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
return "bgra8unorm";
|
|
774
|
+
};
|
|
775
|
+
|
|
748
776
|
const setRendererLinearWorkingColorSpace = (colorSpaceApiLike = null) => {
|
|
749
777
|
const colorSpaceApi = colorSpaceApiLike;
|
|
750
778
|
if (!colorSpaceApi || !colorSpaceApi.ColorManagement) {
|
|
@@ -1314,6 +1342,8 @@ const effekseer = (() => {
|
|
|
1314
1342
|
this._effectCache = new Map();
|
|
1315
1343
|
this._registeredEffects = new Map();
|
|
1316
1344
|
this._registeredEffectStates = new Map();
|
|
1345
|
+
this._warmupTargetCache = new Map();
|
|
1346
|
+
this._warmupSettings = this._normalizeWarmupSettings();
|
|
1317
1347
|
this.fixedUpdateStepFrames = 1.0;
|
|
1318
1348
|
this.fixedUpdateMaxSubsteps = 4;
|
|
1319
1349
|
this.fixedUpdateAccumulator = 0.0;
|
|
@@ -1341,11 +1371,16 @@ const effekseer = (() => {
|
|
|
1341
1371
|
}
|
|
1342
1372
|
|
|
1343
1373
|
const numericScale = Number(descriptor.scale);
|
|
1374
|
+
const preload = Object.prototype.hasOwnProperty.call(descriptor, "preload")
|
|
1375
|
+
? descriptor.preload !== false
|
|
1376
|
+
: descriptor.enabled !== false;
|
|
1344
1377
|
return {
|
|
1345
1378
|
id: effectId,
|
|
1346
1379
|
path,
|
|
1347
1380
|
scale: Number.isFinite(numericScale) ? numericScale : 1.0,
|
|
1348
|
-
|
|
1381
|
+
preload,
|
|
1382
|
+
warmup: descriptor.warmup === true,
|
|
1383
|
+
enabled: preload,
|
|
1349
1384
|
};
|
|
1350
1385
|
}
|
|
1351
1386
|
|
|
@@ -1354,12 +1389,18 @@ const effekseer = (() => {
|
|
|
1354
1389
|
id: descriptor.id,
|
|
1355
1390
|
path: descriptor.path,
|
|
1356
1391
|
scale: descriptor.scale,
|
|
1392
|
+
preload: descriptor.preload,
|
|
1393
|
+
warmup: descriptor.warmup,
|
|
1357
1394
|
enabled: descriptor.enabled,
|
|
1358
1395
|
status: "unloaded",
|
|
1359
1396
|
effect: null,
|
|
1360
1397
|
errorMessage: "",
|
|
1361
1398
|
errorPath: "",
|
|
1399
|
+
warmupStatus: "idle",
|
|
1400
|
+
warmupErrorMessage: "",
|
|
1401
|
+
warmupSignature: "",
|
|
1362
1402
|
loadPromise: null,
|
|
1403
|
+
warmupPromise: null,
|
|
1363
1404
|
activeHandles: new Set(),
|
|
1364
1405
|
ownedResourceAliases: [],
|
|
1365
1406
|
_generation: 0,
|
|
@@ -1367,11 +1408,20 @@ const effekseer = (() => {
|
|
|
1367
1408
|
};
|
|
1368
1409
|
}
|
|
1369
1410
|
|
|
1370
|
-
_resolveManagedEffectIds(ids,
|
|
1411
|
+
_resolveManagedEffectIds(ids, filter = null) {
|
|
1371
1412
|
if (ids == null) {
|
|
1372
1413
|
const resolvedIds = [];
|
|
1373
1414
|
for (const [id, state] of this._registeredEffectStates.entries()) {
|
|
1374
|
-
if (
|
|
1415
|
+
if (filter === "preload" && !state.preload) {
|
|
1416
|
+
continue;
|
|
1417
|
+
}
|
|
1418
|
+
if (filter === "warmup" && !state.warmup) {
|
|
1419
|
+
continue;
|
|
1420
|
+
}
|
|
1421
|
+
if (filter !== "preload" && filter !== "warmup" && filter !== null) {
|
|
1422
|
+
continue;
|
|
1423
|
+
}
|
|
1424
|
+
if (filter === null || filter === "preload" || filter === "warmup") {
|
|
1375
1425
|
resolvedIds.push(id);
|
|
1376
1426
|
}
|
|
1377
1427
|
}
|
|
@@ -1392,6 +1442,224 @@ const effekseer = (() => {
|
|
|
1392
1442
|
return uniqueIds;
|
|
1393
1443
|
}
|
|
1394
1444
|
|
|
1445
|
+
_resetManagedEffectWarmupState(state) {
|
|
1446
|
+
if (!state) {
|
|
1447
|
+
return;
|
|
1448
|
+
}
|
|
1449
|
+
state.warmupStatus = "idle";
|
|
1450
|
+
state.warmupErrorMessage = "";
|
|
1451
|
+
state.warmupSignature = "";
|
|
1452
|
+
state.warmupPromise = null;
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
_toPositiveInteger(value, defaultValue) {
|
|
1456
|
+
const numericValue = Number(value);
|
|
1457
|
+
if (!Number.isFinite(numericValue) || numericValue <= 0) {
|
|
1458
|
+
return defaultValue;
|
|
1459
|
+
}
|
|
1460
|
+
return Math.max(1, Math.floor(numericValue));
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1463
|
+
_normalizeWarmupSettings(settings = null, baseSettings = null) {
|
|
1464
|
+
const nextSettings = settings && typeof settings === "object" ? settings : {};
|
|
1465
|
+
const base = baseSettings && typeof baseSettings === "object" ? baseSettings : {};
|
|
1466
|
+
const colorFormat = toTextureFormatName(nextSettings.colorFormat ?? base.colorFormat ?? getDefaultWarmupColorFormat());
|
|
1467
|
+
if (!colorFormat) {
|
|
1468
|
+
throw new Error("warmupSettings.colorFormat must be a supported GPUTextureFormat.");
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
const rawDepthFormat = nextSettings.depthFormat ?? base.depthFormat ?? null;
|
|
1472
|
+
const depthFormat = rawDepthFormat == null ? null : toTextureFormatName(rawDepthFormat);
|
|
1473
|
+
if (rawDepthFormat != null && !depthFormat) {
|
|
1474
|
+
throw new Error("warmupSettings.depthFormat must be a supported GPUTextureFormat or null.");
|
|
1475
|
+
}
|
|
1476
|
+
|
|
1477
|
+
const sampleCount = toSampleCountValue(nextSettings.sampleCount ?? base.sampleCount ?? 1);
|
|
1478
|
+
const width = this._toPositiveInteger(nextSettings.width ?? base.width ?? 4, 4);
|
|
1479
|
+
const height = this._toPositiveInteger(nextSettings.height ?? base.height ?? 4, 4);
|
|
1480
|
+
const frames = this._toPositiveInteger(nextSettings.frames ?? base.frames ?? 2, 2);
|
|
1481
|
+
const includeDepthTexture = (nextSettings.includeDepthTexture ?? base.includeDepthTexture ?? (depthFormat != null)) && depthFormat != null;
|
|
1482
|
+
const includeBackgroundTexture = !!(nextSettings.includeBackgroundTexture ?? base.includeBackgroundTexture ?? false);
|
|
1483
|
+
|
|
1484
|
+
return {
|
|
1485
|
+
colorFormat,
|
|
1486
|
+
depthFormat,
|
|
1487
|
+
sampleCount,
|
|
1488
|
+
width,
|
|
1489
|
+
height,
|
|
1490
|
+
frames,
|
|
1491
|
+
includeDepthTexture,
|
|
1492
|
+
includeBackgroundTexture,
|
|
1493
|
+
};
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1496
|
+
_getWarmupSignature(settings) {
|
|
1497
|
+
return JSON.stringify({
|
|
1498
|
+
colorFormat: settings.colorFormat,
|
|
1499
|
+
depthFormat: settings.depthFormat,
|
|
1500
|
+
sampleCount: settings.sampleCount,
|
|
1501
|
+
includeDepthTexture: settings.includeDepthTexture,
|
|
1502
|
+
includeBackgroundTexture: settings.includeBackgroundTexture,
|
|
1503
|
+
});
|
|
1504
|
+
}
|
|
1505
|
+
|
|
1506
|
+
_getWarmupTargetCacheKey(settings) {
|
|
1507
|
+
return JSON.stringify({
|
|
1508
|
+
colorFormat: settings.colorFormat,
|
|
1509
|
+
depthFormat: settings.depthFormat,
|
|
1510
|
+
sampleCount: settings.sampleCount,
|
|
1511
|
+
width: settings.width,
|
|
1512
|
+
height: settings.height,
|
|
1513
|
+
includeDepthTexture: settings.includeDepthTexture,
|
|
1514
|
+
includeBackgroundTexture: settings.includeBackgroundTexture,
|
|
1515
|
+
});
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1518
|
+
_destroyWarmupTarget(target) {
|
|
1519
|
+
if (!target) {
|
|
1520
|
+
return;
|
|
1521
|
+
}
|
|
1522
|
+
const destroyTexture = (texture) => {
|
|
1523
|
+
if (texture && typeof texture.destroy === "function") {
|
|
1524
|
+
try {
|
|
1525
|
+
texture.destroy();
|
|
1526
|
+
} catch {
|
|
1527
|
+
// Ignore texture destruction errors during teardown.
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
};
|
|
1531
|
+
destroyTexture(target.backgroundTexture);
|
|
1532
|
+
destroyTexture(target.depthTexture);
|
|
1533
|
+
destroyTexture(target.colorTexture);
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1536
|
+
_clearWarmupTargetCache() {
|
|
1537
|
+
if (!this._warmupTargetCache) {
|
|
1538
|
+
return;
|
|
1539
|
+
}
|
|
1540
|
+
for (const target of this._warmupTargetCache.values()) {
|
|
1541
|
+
this._destroyWarmupTarget(target);
|
|
1542
|
+
}
|
|
1543
|
+
this._warmupTargetCache.clear();
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1546
|
+
_getRuntimeWebGPUDevice() {
|
|
1547
|
+
return externalWebGPUDevice || preinitializedDevice || (Module ? Module.preinitializedWebGPUDevice : null) || null;
|
|
1548
|
+
}
|
|
1549
|
+
|
|
1550
|
+
_getOrCreateWarmupTarget(settings) {
|
|
1551
|
+
const device = this._getRuntimeWebGPUDevice();
|
|
1552
|
+
if (!device) {
|
|
1553
|
+
throw new Error("warmupEffects() requires a GPUDevice. Call setWebGPUDevice() and initRuntime() first.");
|
|
1554
|
+
}
|
|
1555
|
+
|
|
1556
|
+
const cacheKey = this._getWarmupTargetCacheKey(settings);
|
|
1557
|
+
const cachedTarget = this._warmupTargetCache.get(cacheKey);
|
|
1558
|
+
if (cachedTarget) {
|
|
1559
|
+
return cachedTarget;
|
|
1560
|
+
}
|
|
1561
|
+
|
|
1562
|
+
const colorTexture = device.createTexture({
|
|
1563
|
+
size: { width: settings.width, height: settings.height, depthOrArrayLayers: 1 },
|
|
1564
|
+
format: settings.colorFormat,
|
|
1565
|
+
sampleCount: settings.sampleCount,
|
|
1566
|
+
mipLevelCount: 1,
|
|
1567
|
+
dimension: "2d",
|
|
1568
|
+
usage: GPUTextureUsageFlags.RENDER_ATTACHMENT,
|
|
1569
|
+
});
|
|
1570
|
+
const colorView = colorTexture.createView();
|
|
1571
|
+
|
|
1572
|
+
let depthTexture = null;
|
|
1573
|
+
let depthView = null;
|
|
1574
|
+
if (settings.depthFormat) {
|
|
1575
|
+
depthTexture = device.createTexture({
|
|
1576
|
+
size: { width: settings.width, height: settings.height, depthOrArrayLayers: 1 },
|
|
1577
|
+
format: settings.depthFormat,
|
|
1578
|
+
sampleCount: settings.sampleCount,
|
|
1579
|
+
mipLevelCount: 1,
|
|
1580
|
+
dimension: "2d",
|
|
1581
|
+
usage: GPUTextureUsageFlags.RENDER_ATTACHMENT | GPUTextureUsageFlags.TEXTURE_BINDING,
|
|
1582
|
+
});
|
|
1583
|
+
depthView = depthTexture.createView();
|
|
1584
|
+
}
|
|
1585
|
+
|
|
1586
|
+
let backgroundTexture = null;
|
|
1587
|
+
let backgroundView = null;
|
|
1588
|
+
if (settings.includeBackgroundTexture) {
|
|
1589
|
+
backgroundTexture = device.createTexture({
|
|
1590
|
+
size: { width: settings.width, height: settings.height, depthOrArrayLayers: 1 },
|
|
1591
|
+
format: settings.colorFormat,
|
|
1592
|
+
sampleCount: 1,
|
|
1593
|
+
mipLevelCount: 1,
|
|
1594
|
+
dimension: "2d",
|
|
1595
|
+
usage: GPUTextureUsageFlags.RENDER_ATTACHMENT | GPUTextureUsageFlags.TEXTURE_BINDING,
|
|
1596
|
+
});
|
|
1597
|
+
backgroundView = backgroundTexture.createView();
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1600
|
+
const renderPassDescriptor = {
|
|
1601
|
+
colorAttachments: [{
|
|
1602
|
+
view: colorView,
|
|
1603
|
+
clearValue: { r: 0, g: 0, b: 0, a: 0 },
|
|
1604
|
+
loadOp: "clear",
|
|
1605
|
+
storeOp: "store",
|
|
1606
|
+
}],
|
|
1607
|
+
};
|
|
1608
|
+
|
|
1609
|
+
if (depthView) {
|
|
1610
|
+
renderPassDescriptor.depthStencilAttachment = {
|
|
1611
|
+
view: depthView,
|
|
1612
|
+
depthClearValue: 1.0,
|
|
1613
|
+
depthLoadOp: "clear",
|
|
1614
|
+
depthStoreOp: "store",
|
|
1615
|
+
};
|
|
1616
|
+
if (settings.depthFormat === "depth24plus-stencil8") {
|
|
1617
|
+
renderPassDescriptor.depthStencilAttachment.stencilClearValue = 0;
|
|
1618
|
+
renderPassDescriptor.depthStencilAttachment.stencilLoadOp = "clear";
|
|
1619
|
+
renderPassDescriptor.depthStencilAttachment.stencilStoreOp = "discard";
|
|
1620
|
+
}
|
|
1621
|
+
}
|
|
1622
|
+
|
|
1623
|
+
const renderPassState = {
|
|
1624
|
+
colorFormat: settings.colorFormat,
|
|
1625
|
+
depthFormat: settings.depthFormat,
|
|
1626
|
+
sampleCount: settings.sampleCount,
|
|
1627
|
+
};
|
|
1628
|
+
if (settings.includeDepthTexture && depthView) {
|
|
1629
|
+
renderPassState.depthTextureView = depthView;
|
|
1630
|
+
}
|
|
1631
|
+
if (settings.includeBackgroundTexture && backgroundView) {
|
|
1632
|
+
renderPassState.backgroundTextureView = backgroundView;
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1635
|
+
const target = {
|
|
1636
|
+
colorTexture,
|
|
1637
|
+
colorView,
|
|
1638
|
+
depthTexture,
|
|
1639
|
+
depthView,
|
|
1640
|
+
backgroundTexture,
|
|
1641
|
+
backgroundView,
|
|
1642
|
+
renderPassDescriptor,
|
|
1643
|
+
renderPassState,
|
|
1644
|
+
};
|
|
1645
|
+
|
|
1646
|
+
this._warmupTargetCache.set(cacheKey, target);
|
|
1647
|
+
return target;
|
|
1648
|
+
}
|
|
1649
|
+
|
|
1650
|
+
_ensureRegisteredEffectLoaded(state) {
|
|
1651
|
+
if (!state) {
|
|
1652
|
+
return Promise.resolve(null);
|
|
1653
|
+
}
|
|
1654
|
+
if (state.status === "loaded" && state.effect?.isLoaded) {
|
|
1655
|
+
return Promise.resolve(state.effect);
|
|
1656
|
+
}
|
|
1657
|
+
if (state.status === "loading" && state.loadPromise) {
|
|
1658
|
+
return state.loadPromise;
|
|
1659
|
+
}
|
|
1660
|
+
return this._loadRegisteredEffectState(state);
|
|
1661
|
+
}
|
|
1662
|
+
|
|
1395
1663
|
_registerManagedEffectReference(effect, id) {
|
|
1396
1664
|
if (!effect) {
|
|
1397
1665
|
return;
|
|
@@ -1466,6 +1734,7 @@ const effekseer = (() => {
|
|
|
1466
1734
|
state.loadPromise = null;
|
|
1467
1735
|
state.ownedResourceAliases = [];
|
|
1468
1736
|
state._loadingEffect = null;
|
|
1737
|
+
this._resetManagedEffectWarmupState(state);
|
|
1469
1738
|
}
|
|
1470
1739
|
|
|
1471
1740
|
_loadRegisteredEffectState(state) {
|
|
@@ -1486,6 +1755,7 @@ const effekseer = (() => {
|
|
|
1486
1755
|
state.effect = null;
|
|
1487
1756
|
state.ownedResourceAliases = [];
|
|
1488
1757
|
state._loadingEffect = null;
|
|
1758
|
+
this._resetManagedEffectWarmupState(state);
|
|
1489
1759
|
|
|
1490
1760
|
const loadPromise = new Promise((resolve) => {
|
|
1491
1761
|
let settled = false;
|
|
@@ -1591,12 +1861,186 @@ const effekseer = (() => {
|
|
|
1591
1861
|
return loadPromise;
|
|
1592
1862
|
}
|
|
1593
1863
|
|
|
1864
|
+
async _warmupRegisteredEffectStates(states, options = null) {
|
|
1865
|
+
const normalizedSettings = this._normalizeWarmupSettings(options, this._warmupSettings);
|
|
1866
|
+
const signature = this._getWarmupSignature(normalizedSettings);
|
|
1867
|
+
const result = new Map();
|
|
1868
|
+
const pendingWarmups = [];
|
|
1869
|
+
const statesToWarm = [];
|
|
1870
|
+
|
|
1871
|
+
for (let i = 0; i < states.length; i++) {
|
|
1872
|
+
const state = states[i];
|
|
1873
|
+
if (!state || state.status !== "loaded" || !state.effect?.isLoaded) {
|
|
1874
|
+
result.set(state?.id ?? "", null);
|
|
1875
|
+
continue;
|
|
1876
|
+
}
|
|
1877
|
+
if (state.warmupStatus === "warmed" && state.warmupSignature === signature) {
|
|
1878
|
+
result.set(state.id, state.effect);
|
|
1879
|
+
continue;
|
|
1880
|
+
}
|
|
1881
|
+
if (state.warmupStatus === "warming" && state.warmupPromise) {
|
|
1882
|
+
pendingWarmups.push(state.warmupPromise);
|
|
1883
|
+
continue;
|
|
1884
|
+
}
|
|
1885
|
+
statesToWarm.push(state);
|
|
1886
|
+
}
|
|
1887
|
+
|
|
1888
|
+
if (pendingWarmups.length > 0) {
|
|
1889
|
+
await Promise.allSettled(pendingWarmups);
|
|
1890
|
+
return this._warmupRegisteredEffectStates(states, normalizedSettings);
|
|
1891
|
+
}
|
|
1892
|
+
|
|
1893
|
+
if (statesToWarm.length === 0) {
|
|
1894
|
+
for (let i = 0; i < states.length; i++) {
|
|
1895
|
+
const state = states[i];
|
|
1896
|
+
if (!state || result.has(state.id)) {
|
|
1897
|
+
continue;
|
|
1898
|
+
}
|
|
1899
|
+
if (state.warmupStatus === "warmed" && state.warmupSignature === signature && state.effect?.isLoaded) {
|
|
1900
|
+
result.set(state.id, state.effect);
|
|
1901
|
+
} else {
|
|
1902
|
+
result.set(state.id, null);
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1905
|
+
return result;
|
|
1906
|
+
}
|
|
1907
|
+
|
|
1908
|
+
const batchPromise = (async () => {
|
|
1909
|
+
const batchResult = new Map();
|
|
1910
|
+
const handles = [];
|
|
1911
|
+
const stateGenerationMap = new Map();
|
|
1912
|
+
let batchError = null;
|
|
1913
|
+
|
|
1914
|
+
try {
|
|
1915
|
+
const device = this._getRuntimeWebGPUDevice();
|
|
1916
|
+
if (!device) {
|
|
1917
|
+
throw new Error("warmupEffects() requires a GPUDevice. Call setWebGPUDevice() and initRuntime() first.");
|
|
1918
|
+
}
|
|
1919
|
+
|
|
1920
|
+
const target = this._getOrCreateWarmupTarget(normalizedSettings);
|
|
1921
|
+
|
|
1922
|
+
for (let i = 0; i < statesToWarm.length; i++) {
|
|
1923
|
+
const state = statesToWarm[i];
|
|
1924
|
+
const generation = state._generation;
|
|
1925
|
+
stateGenerationMap.set(state.id, generation);
|
|
1926
|
+
if (state.status !== "loaded" || !state.effect?.isLoaded) {
|
|
1927
|
+
state.warmupStatus = "failed";
|
|
1928
|
+
state.warmupErrorMessage = "failed to warm up effect because it is not loaded";
|
|
1929
|
+
state.warmupSignature = "";
|
|
1930
|
+
batchResult.set(state.id, null);
|
|
1931
|
+
continue;
|
|
1932
|
+
}
|
|
1933
|
+
|
|
1934
|
+
const handle = this.play(state.effect, 0, 0, 0);
|
|
1935
|
+
if (!handle) {
|
|
1936
|
+
state.warmupStatus = "failed";
|
|
1937
|
+
state.warmupErrorMessage = "failed to create a temporary warmup handle";
|
|
1938
|
+
state.warmupSignature = "";
|
|
1939
|
+
batchResult.set(state.id, null);
|
|
1940
|
+
continue;
|
|
1941
|
+
}
|
|
1942
|
+
handles.push({ state, handle, generation });
|
|
1943
|
+
}
|
|
1944
|
+
|
|
1945
|
+
if (handles.length > 0) {
|
|
1946
|
+
for (let frameIndex = 0; frameIndex < normalizedSettings.frames; frameIndex++) {
|
|
1947
|
+
this.update(1.0);
|
|
1948
|
+
const encoder = device.createCommandEncoder();
|
|
1949
|
+
const pass = encoder.beginRenderPass(target.renderPassDescriptor);
|
|
1950
|
+
try {
|
|
1951
|
+
this.drawExternal(pass, target.renderPassState, "all");
|
|
1952
|
+
} finally {
|
|
1953
|
+
pass.end();
|
|
1954
|
+
}
|
|
1955
|
+
device.queue.submit([encoder.finish()]);
|
|
1956
|
+
if (typeof device.queue.onSubmittedWorkDone === "function") {
|
|
1957
|
+
await device.queue.onSubmittedWorkDone();
|
|
1958
|
+
}
|
|
1959
|
+
}
|
|
1960
|
+
}
|
|
1961
|
+
} catch (error) {
|
|
1962
|
+
batchError = error;
|
|
1963
|
+
} finally {
|
|
1964
|
+
for (let i = 0; i < handles.length; i++) {
|
|
1965
|
+
const entry = handles[i];
|
|
1966
|
+
try {
|
|
1967
|
+
entry.handle.stopRoot?.();
|
|
1968
|
+
} catch {
|
|
1969
|
+
// Ignore stale-handle errors during warmup cleanup.
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
if (handles.length > 0) {
|
|
1973
|
+
this.update(1.0);
|
|
1974
|
+
}
|
|
1975
|
+
}
|
|
1976
|
+
|
|
1977
|
+
for (let i = 0; i < statesToWarm.length; i++) {
|
|
1978
|
+
const state = statesToWarm[i];
|
|
1979
|
+
const currentState = this._registeredEffectStates.get(state.id);
|
|
1980
|
+
if (currentState !== state || state._generation !== stateGenerationMap.get(state.id)) {
|
|
1981
|
+
batchResult.set(state.id, null);
|
|
1982
|
+
continue;
|
|
1983
|
+
}
|
|
1984
|
+
|
|
1985
|
+
if (batchError) {
|
|
1986
|
+
state.warmupStatus = "failed";
|
|
1987
|
+
state.warmupErrorMessage = batchError && batchError.message ? batchError.message : "failed to warm up effect";
|
|
1988
|
+
state.warmupSignature = "";
|
|
1989
|
+
batchResult.set(state.id, null);
|
|
1990
|
+
continue;
|
|
1991
|
+
}
|
|
1992
|
+
|
|
1993
|
+
if (!batchResult.has(state.id)) {
|
|
1994
|
+
state.warmupStatus = "warmed";
|
|
1995
|
+
state.warmupErrorMessage = "";
|
|
1996
|
+
state.warmupSignature = signature;
|
|
1997
|
+
batchResult.set(state.id, state.effect?.isLoaded ? state.effect : null);
|
|
1998
|
+
}
|
|
1999
|
+
}
|
|
2000
|
+
|
|
2001
|
+
return batchResult;
|
|
2002
|
+
})();
|
|
2003
|
+
|
|
2004
|
+
for (let i = 0; i < statesToWarm.length; i++) {
|
|
2005
|
+
const state = statesToWarm[i];
|
|
2006
|
+
state.warmupStatus = "warming";
|
|
2007
|
+
state.warmupErrorMessage = "";
|
|
2008
|
+
state.warmupSignature = "";
|
|
2009
|
+
state.warmupPromise = batchPromise;
|
|
2010
|
+
}
|
|
2011
|
+
|
|
2012
|
+
const batchResult = await batchPromise;
|
|
2013
|
+
for (let i = 0; i < statesToWarm.length; i++) {
|
|
2014
|
+
const state = statesToWarm[i];
|
|
2015
|
+
if (state.warmupPromise === batchPromise) {
|
|
2016
|
+
state.warmupPromise = null;
|
|
2017
|
+
}
|
|
2018
|
+
}
|
|
2019
|
+
|
|
2020
|
+
for (let i = 0; i < states.length; i++) {
|
|
2021
|
+
const state = states[i];
|
|
2022
|
+
if (!state || result.has(state.id)) {
|
|
2023
|
+
continue;
|
|
2024
|
+
}
|
|
2025
|
+
if (batchResult.has(state.id)) {
|
|
2026
|
+
result.set(state.id, batchResult.get(state.id));
|
|
2027
|
+
} else if (state.warmupStatus === "warmed" && state.warmupSignature === signature && state.effect?.isLoaded) {
|
|
2028
|
+
result.set(state.id, state.effect);
|
|
2029
|
+
} else {
|
|
2030
|
+
result.set(state.id, null);
|
|
2031
|
+
}
|
|
2032
|
+
}
|
|
2033
|
+
|
|
2034
|
+
return result;
|
|
2035
|
+
}
|
|
2036
|
+
|
|
1594
2037
|
_prepareInitSettings(settings = {}, externalRenderPassEnabled = false) {
|
|
1595
2038
|
const instanceMaxCount = settings.instanceMaxCount || 4000;
|
|
1596
2039
|
const squareMaxCount = settings.squareMaxCount || 10000;
|
|
1597
2040
|
const linearColorSpace = settings.linearColorSpace !== false ? 1 : 0;
|
|
1598
2041
|
const compositeWithBackground = settings.compositeWithBackground ? 1 : 0;
|
|
1599
2042
|
this.externalRenderPassEnabled = externalRenderPassEnabled;
|
|
2043
|
+
this._warmupSettings = this._normalizeWarmupSettings(settings.warmupSettings, this._warmupSettings);
|
|
1600
2044
|
|
|
1601
2045
|
// Always use stable fixed-step simulation.
|
|
1602
2046
|
this.fixedUpdateAccumulator = 0.0;
|
|
@@ -1917,31 +2361,43 @@ const effekseer = (() => {
|
|
|
1917
2361
|
|
|
1918
2362
|
for (let i = 0; i < nextDescriptors.length; i++) {
|
|
1919
2363
|
const descriptor = nextDescriptors[i];
|
|
1920
|
-
if (descriptor.
|
|
2364
|
+
if (descriptor.preload) {
|
|
1921
2365
|
void this.preloadEffects([descriptor.id]);
|
|
1922
2366
|
}
|
|
1923
2367
|
}
|
|
1924
2368
|
}
|
|
1925
2369
|
|
|
1926
|
-
preloadEffects(ids) {
|
|
1927
|
-
const targetIds = this._resolveManagedEffectIds(ids, ids == null);
|
|
1928
|
-
|
|
2370
|
+
async preloadEffects(ids) {
|
|
2371
|
+
const targetIds = this._resolveManagedEffectIds(ids, ids == null ? "preload" : null);
|
|
2372
|
+
const result = new Map();
|
|
2373
|
+
const statesToWarm = [];
|
|
2374
|
+
|
|
2375
|
+
for (let i = 0; i < targetIds.length; i++) {
|
|
2376
|
+
const id = targetIds[i];
|
|
1929
2377
|
const state = this._registeredEffectStates.get(id);
|
|
1930
2378
|
if (!state) {
|
|
1931
|
-
|
|
2379
|
+
result.set(id, null);
|
|
2380
|
+
continue;
|
|
1932
2381
|
}
|
|
1933
|
-
|
|
1934
|
-
|
|
2382
|
+
const effect = await this._ensureRegisteredEffectLoaded(state);
|
|
2383
|
+
result.set(id, effect);
|
|
2384
|
+
if (effect && state.warmup) {
|
|
2385
|
+
statesToWarm.push(state);
|
|
1935
2386
|
}
|
|
1936
|
-
|
|
1937
|
-
|
|
2387
|
+
}
|
|
2388
|
+
|
|
2389
|
+
if (statesToWarm.length > 0) {
|
|
2390
|
+
const warmupResults = await this._warmupRegisteredEffectStates(statesToWarm);
|
|
2391
|
+
for (const [id, effect] of warmupResults.entries()) {
|
|
2392
|
+
result.set(id, effect);
|
|
1938
2393
|
}
|
|
1939
|
-
|
|
1940
|
-
|
|
2394
|
+
}
|
|
2395
|
+
|
|
2396
|
+
return result;
|
|
1941
2397
|
}
|
|
1942
2398
|
|
|
1943
2399
|
reloadEffects(ids) {
|
|
1944
|
-
const targetIds = this._resolveManagedEffectIds(ids, ids == null);
|
|
2400
|
+
const targetIds = this._resolveManagedEffectIds(ids, ids == null ? "preload" : null);
|
|
1945
2401
|
this.unloadEffects(targetIds);
|
|
1946
2402
|
return this.preloadEffects(targetIds);
|
|
1947
2403
|
}
|
|
@@ -1997,6 +2453,39 @@ const effekseer = (() => {
|
|
|
1997
2453
|
return Array.from(this._registeredEffectStates.values(), (state) => createManagedEffectSnapshot(state));
|
|
1998
2454
|
}
|
|
1999
2455
|
|
|
2456
|
+
async warmupEffects(ids, options) {
|
|
2457
|
+
const targetIds = this._resolveManagedEffectIds(ids, ids == null ? "warmup" : null);
|
|
2458
|
+
const result = new Map();
|
|
2459
|
+
const statesToWarm = [];
|
|
2460
|
+
|
|
2461
|
+
for (let i = 0; i < targetIds.length; i++) {
|
|
2462
|
+
const id = targetIds[i];
|
|
2463
|
+
const state = this._registeredEffectStates.get(id);
|
|
2464
|
+
if (!state) {
|
|
2465
|
+
result.set(id, null);
|
|
2466
|
+
continue;
|
|
2467
|
+
}
|
|
2468
|
+
|
|
2469
|
+
const effect = await this._ensureRegisteredEffectLoaded(state);
|
|
2470
|
+
if (!effect) {
|
|
2471
|
+
result.set(id, null);
|
|
2472
|
+
continue;
|
|
2473
|
+
}
|
|
2474
|
+
|
|
2475
|
+
statesToWarm.push(state);
|
|
2476
|
+
}
|
|
2477
|
+
|
|
2478
|
+
if (statesToWarm.length === 0) {
|
|
2479
|
+
return result;
|
|
2480
|
+
}
|
|
2481
|
+
|
|
2482
|
+
const warmupResults = await this._warmupRegisteredEffectStates(statesToWarm, options);
|
|
2483
|
+
for (const [id, effect] of warmupResults.entries()) {
|
|
2484
|
+
result.set(id, effect);
|
|
2485
|
+
}
|
|
2486
|
+
return result;
|
|
2487
|
+
}
|
|
2488
|
+
|
|
2000
2489
|
whenEffectsReady(ids) {
|
|
2001
2490
|
return this.preloadEffects(ids);
|
|
2002
2491
|
}
|
|
@@ -2121,6 +2610,7 @@ const effekseer = (() => {
|
|
|
2121
2610
|
return;
|
|
2122
2611
|
}
|
|
2123
2612
|
context.unloadEffects?.();
|
|
2613
|
+
context._clearWarmupTargetCache?.();
|
|
2124
2614
|
Core.Terminate(context.nativeptr);
|
|
2125
2615
|
context.nativeptr = 0;
|
|
2126
2616
|
context._effectCache?.clear?.();
|
|
@@ -2196,6 +2686,7 @@ const effekseer = (() => {
|
|
|
2196
2686
|
loadEffectPackage(pathOrBuffer, Unzip, scale, onload, onerror) { return this.defaultContext.loadEffectPackage(pathOrBuffer, Unzip, scale, onload, onerror); }
|
|
2197
2687
|
registerEffects(effects) { this.defaultContext.registerEffects(effects); }
|
|
2198
2688
|
preloadEffects(ids) { return this.defaultContext.preloadEffects(ids); }
|
|
2689
|
+
warmupEffects(ids, options) { return this.defaultContext.warmupEffects(ids, options); }
|
|
2199
2690
|
reloadEffects(ids) { return this.defaultContext.reloadEffects(ids); }
|
|
2200
2691
|
unloadEffects(ids) { this.defaultContext.unloadEffects(ids); }
|
|
2201
2692
|
unregisterEffects(ids) { this.defaultContext.unregisterEffects(ids); }
|