@eigong/effekseer-webgpu-runtime 0.1.9 → 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_Runtime.wasm +0 -0
- package/runtime/effekseer.webgpu.js +1 -1
- package/runtime/effekseer.webgpu.src.js +506 -21
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
|
Binary file
|
|
@@ -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,this._didFinalResourceReload=!1}_load(n){const a=d(n);if(!a)return void z(this,"invalid data","");r=this,this.mainBuffer=a,this._didFinalResourceReload=!1;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(n&&this.resources.length>0&&!this._didFinalResourceReload&&(this._didFinalResourceReload=!0,this._reload()),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) {
|
|
@@ -1093,7 +1121,6 @@ const effekseer = (() => {
|
|
|
1093
1121
|
this.packageOnly = false;
|
|
1094
1122
|
this._ownedResourceAliases = [];
|
|
1095
1123
|
this._managedRefIds = new Set();
|
|
1096
|
-
this._didFinalResourceReload = false;
|
|
1097
1124
|
}
|
|
1098
1125
|
|
|
1099
1126
|
_load(buffer) {
|
|
@@ -1105,7 +1132,6 @@ const effekseer = (() => {
|
|
|
1105
1132
|
|
|
1106
1133
|
loadingEffect = this;
|
|
1107
1134
|
this.mainBuffer = ab;
|
|
1108
|
-
this._didFinalResourceReload = false;
|
|
1109
1135
|
const memptr = Module._malloc(ab.byteLength);
|
|
1110
1136
|
Module.HEAPU8.set(new Uint8Array(ab), memptr);
|
|
1111
1137
|
this.nativeptr = Core.LoadEffect(this.context.nativeptr, memptr, ab.byteLength, this.scale);
|
|
@@ -1147,10 +1173,6 @@ const effekseer = (() => {
|
|
|
1147
1173
|
}
|
|
1148
1174
|
|
|
1149
1175
|
const loaded = this.nativeptr !== 0;
|
|
1150
|
-
if (loaded && this.resources.length > 0 && !this._didFinalResourceReload) {
|
|
1151
|
-
this._didFinalResourceReload = true;
|
|
1152
|
-
this._reload();
|
|
1153
|
-
}
|
|
1154
1176
|
|
|
1155
1177
|
if (missingRequiredResources.length > 0) {
|
|
1156
1178
|
const detail = `failed to load effect. missing resources: ${missingRequiredResources.join(", ")}`;
|
|
@@ -1320,6 +1342,8 @@ const effekseer = (() => {
|
|
|
1320
1342
|
this._effectCache = new Map();
|
|
1321
1343
|
this._registeredEffects = new Map();
|
|
1322
1344
|
this._registeredEffectStates = new Map();
|
|
1345
|
+
this._warmupTargetCache = new Map();
|
|
1346
|
+
this._warmupSettings = this._normalizeWarmupSettings();
|
|
1323
1347
|
this.fixedUpdateStepFrames = 1.0;
|
|
1324
1348
|
this.fixedUpdateMaxSubsteps = 4;
|
|
1325
1349
|
this.fixedUpdateAccumulator = 0.0;
|
|
@@ -1347,11 +1371,16 @@ const effekseer = (() => {
|
|
|
1347
1371
|
}
|
|
1348
1372
|
|
|
1349
1373
|
const numericScale = Number(descriptor.scale);
|
|
1374
|
+
const preload = Object.prototype.hasOwnProperty.call(descriptor, "preload")
|
|
1375
|
+
? descriptor.preload !== false
|
|
1376
|
+
: descriptor.enabled !== false;
|
|
1350
1377
|
return {
|
|
1351
1378
|
id: effectId,
|
|
1352
1379
|
path,
|
|
1353
1380
|
scale: Number.isFinite(numericScale) ? numericScale : 1.0,
|
|
1354
|
-
|
|
1381
|
+
preload,
|
|
1382
|
+
warmup: descriptor.warmup === true,
|
|
1383
|
+
enabled: preload,
|
|
1355
1384
|
};
|
|
1356
1385
|
}
|
|
1357
1386
|
|
|
@@ -1360,12 +1389,18 @@ const effekseer = (() => {
|
|
|
1360
1389
|
id: descriptor.id,
|
|
1361
1390
|
path: descriptor.path,
|
|
1362
1391
|
scale: descriptor.scale,
|
|
1392
|
+
preload: descriptor.preload,
|
|
1393
|
+
warmup: descriptor.warmup,
|
|
1363
1394
|
enabled: descriptor.enabled,
|
|
1364
1395
|
status: "unloaded",
|
|
1365
1396
|
effect: null,
|
|
1366
1397
|
errorMessage: "",
|
|
1367
1398
|
errorPath: "",
|
|
1399
|
+
warmupStatus: "idle",
|
|
1400
|
+
warmupErrorMessage: "",
|
|
1401
|
+
warmupSignature: "",
|
|
1368
1402
|
loadPromise: null,
|
|
1403
|
+
warmupPromise: null,
|
|
1369
1404
|
activeHandles: new Set(),
|
|
1370
1405
|
ownedResourceAliases: [],
|
|
1371
1406
|
_generation: 0,
|
|
@@ -1373,11 +1408,20 @@ const effekseer = (() => {
|
|
|
1373
1408
|
};
|
|
1374
1409
|
}
|
|
1375
1410
|
|
|
1376
|
-
_resolveManagedEffectIds(ids,
|
|
1411
|
+
_resolveManagedEffectIds(ids, filter = null) {
|
|
1377
1412
|
if (ids == null) {
|
|
1378
1413
|
const resolvedIds = [];
|
|
1379
1414
|
for (const [id, state] of this._registeredEffectStates.entries()) {
|
|
1380
|
-
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") {
|
|
1381
1425
|
resolvedIds.push(id);
|
|
1382
1426
|
}
|
|
1383
1427
|
}
|
|
@@ -1398,6 +1442,224 @@ const effekseer = (() => {
|
|
|
1398
1442
|
return uniqueIds;
|
|
1399
1443
|
}
|
|
1400
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
|
+
|
|
1401
1663
|
_registerManagedEffectReference(effect, id) {
|
|
1402
1664
|
if (!effect) {
|
|
1403
1665
|
return;
|
|
@@ -1472,6 +1734,7 @@ const effekseer = (() => {
|
|
|
1472
1734
|
state.loadPromise = null;
|
|
1473
1735
|
state.ownedResourceAliases = [];
|
|
1474
1736
|
state._loadingEffect = null;
|
|
1737
|
+
this._resetManagedEffectWarmupState(state);
|
|
1475
1738
|
}
|
|
1476
1739
|
|
|
1477
1740
|
_loadRegisteredEffectState(state) {
|
|
@@ -1492,6 +1755,7 @@ const effekseer = (() => {
|
|
|
1492
1755
|
state.effect = null;
|
|
1493
1756
|
state.ownedResourceAliases = [];
|
|
1494
1757
|
state._loadingEffect = null;
|
|
1758
|
+
this._resetManagedEffectWarmupState(state);
|
|
1495
1759
|
|
|
1496
1760
|
const loadPromise = new Promise((resolve) => {
|
|
1497
1761
|
let settled = false;
|
|
@@ -1597,12 +1861,186 @@ const effekseer = (() => {
|
|
|
1597
1861
|
return loadPromise;
|
|
1598
1862
|
}
|
|
1599
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
|
+
|
|
1600
2037
|
_prepareInitSettings(settings = {}, externalRenderPassEnabled = false) {
|
|
1601
2038
|
const instanceMaxCount = settings.instanceMaxCount || 4000;
|
|
1602
2039
|
const squareMaxCount = settings.squareMaxCount || 10000;
|
|
1603
2040
|
const linearColorSpace = settings.linearColorSpace !== false ? 1 : 0;
|
|
1604
2041
|
const compositeWithBackground = settings.compositeWithBackground ? 1 : 0;
|
|
1605
2042
|
this.externalRenderPassEnabled = externalRenderPassEnabled;
|
|
2043
|
+
this._warmupSettings = this._normalizeWarmupSettings(settings.warmupSettings, this._warmupSettings);
|
|
1606
2044
|
|
|
1607
2045
|
// Always use stable fixed-step simulation.
|
|
1608
2046
|
this.fixedUpdateAccumulator = 0.0;
|
|
@@ -1923,31 +2361,43 @@ const effekseer = (() => {
|
|
|
1923
2361
|
|
|
1924
2362
|
for (let i = 0; i < nextDescriptors.length; i++) {
|
|
1925
2363
|
const descriptor = nextDescriptors[i];
|
|
1926
|
-
if (descriptor.
|
|
2364
|
+
if (descriptor.preload) {
|
|
1927
2365
|
void this.preloadEffects([descriptor.id]);
|
|
1928
2366
|
}
|
|
1929
2367
|
}
|
|
1930
2368
|
}
|
|
1931
2369
|
|
|
1932
|
-
preloadEffects(ids) {
|
|
1933
|
-
const targetIds = this._resolveManagedEffectIds(ids, ids == null);
|
|
1934
|
-
|
|
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];
|
|
1935
2377
|
const state = this._registeredEffectStates.get(id);
|
|
1936
2378
|
if (!state) {
|
|
1937
|
-
|
|
2379
|
+
result.set(id, null);
|
|
2380
|
+
continue;
|
|
1938
2381
|
}
|
|
1939
|
-
|
|
1940
|
-
|
|
2382
|
+
const effect = await this._ensureRegisteredEffectLoaded(state);
|
|
2383
|
+
result.set(id, effect);
|
|
2384
|
+
if (effect && state.warmup) {
|
|
2385
|
+
statesToWarm.push(state);
|
|
1941
2386
|
}
|
|
1942
|
-
|
|
1943
|
-
|
|
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);
|
|
1944
2393
|
}
|
|
1945
|
-
|
|
1946
|
-
|
|
2394
|
+
}
|
|
2395
|
+
|
|
2396
|
+
return result;
|
|
1947
2397
|
}
|
|
1948
2398
|
|
|
1949
2399
|
reloadEffects(ids) {
|
|
1950
|
-
const targetIds = this._resolveManagedEffectIds(ids, ids == null);
|
|
2400
|
+
const targetIds = this._resolveManagedEffectIds(ids, ids == null ? "preload" : null);
|
|
1951
2401
|
this.unloadEffects(targetIds);
|
|
1952
2402
|
return this.preloadEffects(targetIds);
|
|
1953
2403
|
}
|
|
@@ -2003,6 +2453,39 @@ const effekseer = (() => {
|
|
|
2003
2453
|
return Array.from(this._registeredEffectStates.values(), (state) => createManagedEffectSnapshot(state));
|
|
2004
2454
|
}
|
|
2005
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
|
+
|
|
2006
2489
|
whenEffectsReady(ids) {
|
|
2007
2490
|
return this.preloadEffects(ids);
|
|
2008
2491
|
}
|
|
@@ -2127,6 +2610,7 @@ const effekseer = (() => {
|
|
|
2127
2610
|
return;
|
|
2128
2611
|
}
|
|
2129
2612
|
context.unloadEffects?.();
|
|
2613
|
+
context._clearWarmupTargetCache?.();
|
|
2130
2614
|
Core.Terminate(context.nativeptr);
|
|
2131
2615
|
context.nativeptr = 0;
|
|
2132
2616
|
context._effectCache?.clear?.();
|
|
@@ -2202,6 +2686,7 @@ const effekseer = (() => {
|
|
|
2202
2686
|
loadEffectPackage(pathOrBuffer, Unzip, scale, onload, onerror) { return this.defaultContext.loadEffectPackage(pathOrBuffer, Unzip, scale, onload, onerror); }
|
|
2203
2687
|
registerEffects(effects) { this.defaultContext.registerEffects(effects); }
|
|
2204
2688
|
preloadEffects(ids) { return this.defaultContext.preloadEffects(ids); }
|
|
2689
|
+
warmupEffects(ids, options) { return this.defaultContext.warmupEffects(ids, options); }
|
|
2205
2690
|
reloadEffects(ids) { return this.defaultContext.reloadEffects(ids); }
|
|
2206
2691
|
unloadEffects(ids) { this.defaultContext.unloadEffects(ids); }
|
|
2207
2692
|
unregisterEffects(ids) { this.defaultContext.unregisterEffects(ids); }
|