bloody-engine 1.0.3 → 1.0.5
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/dist/node/index.js +400 -0
- package/dist/web/core/buffer.d.ts +58 -0
- package/dist/web/core/buffer.d.ts.map +1 -0
- package/dist/web/core/grahpic-device.d.ts +66 -0
- package/dist/web/core/grahpic-device.d.ts.map +1 -0
- package/dist/web/core/index.d.ts +8 -0
- package/dist/web/core/index.d.ts.map +1 -0
- package/dist/web/core/resource-loader-factory.d.ts +90 -0
- package/dist/web/core/resource-loader-factory.d.ts.map +1 -0
- package/dist/web/core/resource-loader.d.ts +71 -0
- package/dist/web/core/resource-loader.d.ts.map +1 -0
- package/dist/web/core/resource-pipeline.d.ts +139 -0
- package/dist/web/core/resource-pipeline.d.ts.map +1 -0
- package/dist/web/core/shader.d.ts +62 -0
- package/dist/web/core/shader.d.ts.map +1 -0
- package/dist/web/core/texture.d.ts +69 -0
- package/dist/web/core/texture.d.ts.map +1 -0
- package/dist/web/demo-node.d.ts +2 -0
- package/dist/web/demo-node.d.ts.map +1 -0
- package/dist/web/examples/batch-renderer-demo.d.ts +10 -0
- package/dist/web/examples/batch-renderer-demo.d.ts.map +1 -0
- package/dist/web/examples/projection-examples.d.ts +87 -0
- package/dist/web/examples/projection-examples.d.ts.map +1 -0
- package/dist/web/examples/resource-loader-demo.d.ts +14 -0
- package/dist/web/examples/resource-loader-demo.d.ts.map +1 -0
- package/dist/web/examples/shader-examples.d.ts +92 -0
- package/dist/web/examples/shader-examples.d.ts.map +1 -0
- package/dist/web/examples/sprite-batch-renderer-demo.d.ts +12 -0
- package/dist/web/examples/sprite-batch-renderer-demo.d.ts.map +1 -0
- package/dist/web/index.d.ts +7 -0
- package/dist/web/index.d.ts.map +1 -0
- package/dist/web/index.js +760 -474
- package/dist/web/index.umd.js +23 -23
- package/dist/web/platforms/browser/browser-context.d.ts +31 -0
- package/dist/web/platforms/browser/browser-context.d.ts.map +1 -0
- package/dist/web/platforms/browser/browser-resource-loader.d.ts +67 -0
- package/dist/web/platforms/browser/browser-resource-loader.d.ts.map +1 -0
- package/dist/web/platforms/node/node-context.d.ts +31 -0
- package/dist/web/platforms/node/node-context.d.ts.map +1 -0
- package/dist/web/platforms/node/node-resource-loader.d.ts +73 -0
- package/dist/web/platforms/node/node-resource-loader.d.ts.map +1 -0
- package/dist/web/platforms/node/sdl-window.d.ts +41 -0
- package/dist/web/platforms/node/sdl-window.d.ts.map +1 -0
- package/dist/web/projection.test.d.ts +5 -0
- package/dist/web/projection.test.d.ts.map +1 -0
- package/dist/web/public-api.d.ts +25 -0
- package/dist/web/public-api.d.ts.map +1 -0
- package/dist/web/rendering/batch-renderer.d.ts +273 -0
- package/dist/web/rendering/batch-renderer.d.ts.map +1 -0
- package/dist/web/rendering/camera.d.ts +153 -0
- package/dist/web/rendering/camera.d.ts.map +1 -0
- package/dist/web/rendering/projection.d.ts +108 -0
- package/dist/web/rendering/projection.d.ts.map +1 -0
- package/dist/web/rendering/rendering-context-factory.d.ts +24 -0
- package/dist/web/rendering/rendering-context-factory.d.ts.map +1 -0
- package/dist/web/rendering/rendering-context.d.ts +77 -0
- package/dist/web/rendering/rendering-context.d.ts.map +1 -0
- package/dist/web/rendering/vertex.d.ts +98 -0
- package/dist/web/rendering/vertex.d.ts.map +1 -0
- package/dist/web/scene/scene.d.ts +139 -0
- package/dist/web/scene/scene.d.ts.map +1 -0
- package/package.json +5 -4
package/dist/web/index.js
CHANGED
|
@@ -1,25 +1,26 @@
|
|
|
1
|
-
import
|
|
1
|
+
import Q from "gl";
|
|
2
|
+
import W from "@kmamal/sdl";
|
|
2
3
|
import * as p from "fs/promises";
|
|
3
|
-
import * as
|
|
4
|
-
class
|
|
5
|
-
constructor(
|
|
6
|
-
this.isBrowser = !0,
|
|
7
|
-
const
|
|
4
|
+
import * as C from "path";
|
|
5
|
+
class O {
|
|
6
|
+
constructor(t) {
|
|
7
|
+
this.isBrowser = !0, t.canvas ? this.canvas = t.canvas : (this.canvas = document.createElement("canvas"), document.body.appendChild(this.canvas)), this.width = t.width, this.height = t.height, this.canvas.width = this.width, this.canvas.height = this.height;
|
|
8
|
+
const e = {
|
|
8
9
|
alpha: !1,
|
|
9
|
-
...
|
|
10
|
-
}, r = this.canvas.getContext("webgl",
|
|
10
|
+
...t.contextAttributes
|
|
11
|
+
}, r = this.canvas.getContext("webgl", e);
|
|
11
12
|
if (!r)
|
|
12
13
|
throw new Error("Failed to initialize WebGL context in browser");
|
|
13
14
|
this.glContext = r;
|
|
14
15
|
}
|
|
15
|
-
resize(
|
|
16
|
-
this.width =
|
|
16
|
+
resize(t, e) {
|
|
17
|
+
this.width = t, this.height = e, this.canvas.width = t, this.canvas.height = e, this.glContext.viewport(0, 0, t, e);
|
|
17
18
|
}
|
|
18
19
|
getViewport() {
|
|
19
20
|
return { width: this.width, height: this.height };
|
|
20
21
|
}
|
|
21
|
-
clear(
|
|
22
|
-
|
|
22
|
+
clear(t) {
|
|
23
|
+
t && this.glContext.clearColor(t.r, t.g, t.b, t.a), this.glContext.clear(
|
|
23
24
|
this.glContext.COLOR_BUFFER_BIT | this.glContext.DEPTH_BUFFER_BIT
|
|
24
25
|
);
|
|
25
26
|
}
|
|
@@ -35,27 +36,27 @@ class Y {
|
|
|
35
36
|
return this.canvas;
|
|
36
37
|
}
|
|
37
38
|
}
|
|
38
|
-
class
|
|
39
|
-
constructor(
|
|
40
|
-
this.isBrowser = !1, this.width =
|
|
41
|
-
const
|
|
42
|
-
preserveDrawingBuffer:
|
|
43
|
-
...
|
|
39
|
+
class q {
|
|
40
|
+
constructor(t) {
|
|
41
|
+
this.isBrowser = !1, this.width = t.width, this.height = t.height;
|
|
42
|
+
const e = Q(this.width, this.height, {
|
|
43
|
+
preserveDrawingBuffer: t.preserveDrawingBuffer ?? !0,
|
|
44
|
+
...t.contextAttributes
|
|
44
45
|
});
|
|
45
|
-
if (!
|
|
46
|
+
if (!e)
|
|
46
47
|
throw new Error("Failed to initialize WebGL context in Node.js");
|
|
47
|
-
this.glContext =
|
|
48
|
+
this.glContext = e;
|
|
48
49
|
}
|
|
49
|
-
resize(
|
|
50
|
-
this.width =
|
|
50
|
+
resize(t, e) {
|
|
51
|
+
this.width = t, this.height = e, console.warn(
|
|
51
52
|
"NodeRenderingContext: Resize requested but not supported. Consider recreating context."
|
|
52
53
|
);
|
|
53
54
|
}
|
|
54
55
|
getViewport() {
|
|
55
56
|
return { width: this.width, height: this.height };
|
|
56
57
|
}
|
|
57
|
-
clear(
|
|
58
|
-
|
|
58
|
+
clear(t) {
|
|
59
|
+
t && this.glContext.clearColor(t.r, t.g, t.b, t.a), this.glContext.clear(
|
|
59
60
|
this.glContext.COLOR_BUFFER_BIT | this.glContext.DEPTH_BUFFER_BIT
|
|
60
61
|
);
|
|
61
62
|
}
|
|
@@ -70,7 +71,7 @@ class G {
|
|
|
70
71
|
* Used for capturing frames for display or saving
|
|
71
72
|
*/
|
|
72
73
|
readPixels() {
|
|
73
|
-
const
|
|
74
|
+
const t = new Uint8Array(this.width * this.height * 4);
|
|
74
75
|
return this.glContext.readPixels(
|
|
75
76
|
0,
|
|
76
77
|
0,
|
|
@@ -78,11 +79,11 @@ class G {
|
|
|
78
79
|
this.height,
|
|
79
80
|
this.glContext.RGBA,
|
|
80
81
|
this.glContext.UNSIGNED_BYTE,
|
|
81
|
-
|
|
82
|
-
),
|
|
82
|
+
t
|
|
83
|
+
), t;
|
|
83
84
|
}
|
|
84
85
|
}
|
|
85
|
-
class
|
|
86
|
+
class X {
|
|
86
87
|
/**
|
|
87
88
|
* Detect if running in a browser environment
|
|
88
89
|
*/
|
|
@@ -92,20 +93,20 @@ class k {
|
|
|
92
93
|
/**
|
|
93
94
|
* Create a rendering context appropriate for the current environment
|
|
94
95
|
*/
|
|
95
|
-
static createContext(
|
|
96
|
-
return this.isBrowserEnvironment() ? new
|
|
96
|
+
static createContext(t) {
|
|
97
|
+
return this.isBrowserEnvironment() ? new O(t) : new q(t);
|
|
97
98
|
}
|
|
98
99
|
/**
|
|
99
100
|
* Create a browser-specific rendering context
|
|
100
101
|
*/
|
|
101
|
-
static createBrowserContext(
|
|
102
|
-
return new
|
|
102
|
+
static createBrowserContext(t) {
|
|
103
|
+
return new O(t);
|
|
103
104
|
}
|
|
104
105
|
/**
|
|
105
106
|
* Create a Node.js-specific rendering context
|
|
106
107
|
*/
|
|
107
|
-
static createNodeContext(
|
|
108
|
-
return new
|
|
108
|
+
static createNodeContext(t) {
|
|
109
|
+
return new q(t);
|
|
109
110
|
}
|
|
110
111
|
}
|
|
111
112
|
class H {
|
|
@@ -116,21 +117,21 @@ class H {
|
|
|
116
117
|
* @param fragmentSource Raw fragment shader source code
|
|
117
118
|
* @param isBrowser Whether running in browser environment (affects precision header)
|
|
118
119
|
*/
|
|
119
|
-
constructor(
|
|
120
|
-
this.gl =
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
120
|
+
constructor(t, e, r, i) {
|
|
121
|
+
this.gl = t;
|
|
122
|
+
const s = this.injectPrecisionHeader(
|
|
123
|
+
e,
|
|
124
|
+
i
|
|
124
125
|
), o = this.injectPrecisionHeader(
|
|
125
126
|
r,
|
|
126
|
-
|
|
127
|
+
i
|
|
127
128
|
);
|
|
128
129
|
this.vertexShader = this.compileShader(
|
|
129
|
-
|
|
130
|
-
|
|
130
|
+
s,
|
|
131
|
+
t.VERTEX_SHADER
|
|
131
132
|
), this.fragmentShader = this.compileShader(
|
|
132
133
|
o,
|
|
133
|
-
|
|
134
|
+
t.FRAGMENT_SHADER
|
|
134
135
|
), this.program = this.linkProgram(this.vertexShader, this.fragmentShader);
|
|
135
136
|
}
|
|
136
137
|
/**
|
|
@@ -139,11 +140,11 @@ class H {
|
|
|
139
140
|
* @param isBrowser Whether in browser (WebGL ES) or Node (desktop OpenGL)
|
|
140
141
|
* @returns Processed shader source with precision header
|
|
141
142
|
*/
|
|
142
|
-
injectPrecisionHeader(
|
|
143
|
-
return
|
|
143
|
+
injectPrecisionHeader(t, e) {
|
|
144
|
+
return t.includes("#ifdef GL_ES") || t.includes("precision") ? t : `#ifdef GL_ES
|
|
144
145
|
precision highp float;
|
|
145
146
|
#endif
|
|
146
|
-
` +
|
|
147
|
+
` + t;
|
|
147
148
|
}
|
|
148
149
|
/**
|
|
149
150
|
* Compile a single shader (vertex or fragment)
|
|
@@ -151,18 +152,18 @@ precision highp float;
|
|
|
151
152
|
* @param type gl.VERTEX_SHADER or gl.FRAGMENT_SHADER
|
|
152
153
|
* @returns Compiled shader
|
|
153
154
|
*/
|
|
154
|
-
compileShader(
|
|
155
|
-
const r = this.gl.createShader(
|
|
155
|
+
compileShader(t, e) {
|
|
156
|
+
const r = this.gl.createShader(e);
|
|
156
157
|
if (!r)
|
|
157
|
-
throw new Error(`Failed to create shader of type ${
|
|
158
|
-
if (this.gl.shaderSource(r,
|
|
159
|
-
const
|
|
158
|
+
throw new Error(`Failed to create shader of type ${e}`);
|
|
159
|
+
if (this.gl.shaderSource(r, t), this.gl.compileShader(r), !this.gl.getShaderParameter(r, this.gl.COMPILE_STATUS)) {
|
|
160
|
+
const s = this.gl.getShaderInfoLog(r), o = e === this.gl.VERTEX_SHADER ? "vertex" : "fragment";
|
|
160
161
|
throw this.gl.deleteShader(r), new Error(
|
|
161
162
|
`Failed to compile ${o} shader:
|
|
162
|
-
${
|
|
163
|
+
${s}
|
|
163
164
|
|
|
164
165
|
Source:
|
|
165
|
-
${
|
|
166
|
+
${t}`
|
|
166
167
|
);
|
|
167
168
|
}
|
|
168
169
|
return r;
|
|
@@ -173,14 +174,14 @@ ${e}`
|
|
|
173
174
|
* @param fragmentShader Compiled fragment shader
|
|
174
175
|
* @returns Linked shader program
|
|
175
176
|
*/
|
|
176
|
-
linkProgram(
|
|
177
|
+
linkProgram(t, e) {
|
|
177
178
|
const r = this.gl.createProgram();
|
|
178
179
|
if (!r)
|
|
179
180
|
throw new Error("Failed to create shader program");
|
|
180
|
-
if (this.gl.attachShader(r,
|
|
181
|
-
const
|
|
182
|
-
throw this.gl.deleteProgram(r), this.gl.deleteShader(
|
|
183
|
-
${
|
|
181
|
+
if (this.gl.attachShader(r, t), this.gl.attachShader(r, e), this.gl.linkProgram(r), !this.gl.getProgramParameter(r, this.gl.LINK_STATUS)) {
|
|
182
|
+
const s = this.gl.getProgramInfoLog(r);
|
|
183
|
+
throw this.gl.deleteProgram(r), this.gl.deleteShader(t), this.gl.deleteShader(e), new Error(`Failed to link shader program:
|
|
184
|
+
${s}`);
|
|
184
185
|
}
|
|
185
186
|
return r;
|
|
186
187
|
}
|
|
@@ -194,15 +195,15 @@ ${i}`);
|
|
|
194
195
|
* Get uniform location by name
|
|
195
196
|
* @param name Uniform variable name
|
|
196
197
|
*/
|
|
197
|
-
getUniformLocation(
|
|
198
|
-
return this.gl.getUniformLocation(this.program,
|
|
198
|
+
getUniformLocation(t) {
|
|
199
|
+
return this.gl.getUniformLocation(this.program, t);
|
|
199
200
|
}
|
|
200
201
|
/**
|
|
201
202
|
* Get attribute location by name
|
|
202
203
|
* @param name Attribute variable name
|
|
203
204
|
*/
|
|
204
|
-
getAttributeLocation(
|
|
205
|
-
return this.gl.getAttribLocation(this.program,
|
|
205
|
+
getAttributeLocation(t) {
|
|
206
|
+
return this.gl.getAttribLocation(this.program, t);
|
|
206
207
|
}
|
|
207
208
|
/**
|
|
208
209
|
* Use this shader program
|
|
@@ -217,11 +218,11 @@ ${i}`);
|
|
|
217
218
|
this.gl.deleteProgram(this.program), this.gl.deleteShader(this.vertexShader), this.gl.deleteShader(this.fragmentShader);
|
|
218
219
|
}
|
|
219
220
|
}
|
|
220
|
-
class
|
|
221
|
-
constructor(
|
|
222
|
-
this.context =
|
|
223
|
-
width:
|
|
224
|
-
height:
|
|
221
|
+
class k {
|
|
222
|
+
constructor(t, e) {
|
|
223
|
+
this.context = X.createContext({
|
|
224
|
+
width: t,
|
|
225
|
+
height: e,
|
|
225
226
|
preserveDrawingBuffer: !0
|
|
226
227
|
});
|
|
227
228
|
}
|
|
@@ -264,14 +265,14 @@ class W {
|
|
|
264
265
|
/**
|
|
265
266
|
* Resize the graphics device
|
|
266
267
|
*/
|
|
267
|
-
resize(
|
|
268
|
-
this.context.resize(
|
|
268
|
+
resize(t, e) {
|
|
269
|
+
this.context.resize(t, e);
|
|
269
270
|
}
|
|
270
271
|
/**
|
|
271
272
|
* Clear the rendering surface
|
|
272
273
|
*/
|
|
273
|
-
clear(
|
|
274
|
-
this.context.clear(
|
|
274
|
+
clear(t) {
|
|
275
|
+
this.context.clear(t);
|
|
275
276
|
}
|
|
276
277
|
/**
|
|
277
278
|
* Present the rendered frame
|
|
@@ -291,16 +292,96 @@ class W {
|
|
|
291
292
|
* @param fragmentSource Fragment shader source code
|
|
292
293
|
* @returns Compiled and linked shader program
|
|
293
294
|
*/
|
|
294
|
-
createShader(
|
|
295
|
+
createShader(t, e) {
|
|
295
296
|
return new H(
|
|
296
297
|
this.context.glContext,
|
|
297
|
-
e,
|
|
298
298
|
t,
|
|
299
|
+
e,
|
|
299
300
|
this.context.isBrowser
|
|
300
301
|
);
|
|
301
302
|
}
|
|
302
303
|
}
|
|
303
|
-
class
|
|
304
|
+
class ft {
|
|
305
|
+
constructor(t, e, r = "Bloody Engine") {
|
|
306
|
+
this.closed = !1, this.width = t, this.height = e, this.title = r;
|
|
307
|
+
try {
|
|
308
|
+
if (this.window = W.video.createWindow({
|
|
309
|
+
width: this.width,
|
|
310
|
+
height: this.height,
|
|
311
|
+
title: this.title
|
|
312
|
+
}), !this.window)
|
|
313
|
+
throw new Error("Failed to create SDL window");
|
|
314
|
+
this.window.on("close", () => {
|
|
315
|
+
this.closed = !0;
|
|
316
|
+
}), console.log(`✓ SDL Window created (${t}x${e}): "${r}"`);
|
|
317
|
+
} catch (i) {
|
|
318
|
+
throw this.cleanup(), new Error(`Window creation failed: ${i}`);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Get window dimensions
|
|
323
|
+
*/
|
|
324
|
+
getDimensions() {
|
|
325
|
+
return { width: this.width, height: this.height };
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Display pixel data in the window
|
|
329
|
+
* @param pixels Uint8Array of RGBA pixel data
|
|
330
|
+
*/
|
|
331
|
+
updatePixels(t) {
|
|
332
|
+
if (!(!this.window || this.closed))
|
|
333
|
+
try {
|
|
334
|
+
const e = Buffer.from(t), r = this.width * 4;
|
|
335
|
+
this.window.render(this.width, this.height, r, "rgba32", e);
|
|
336
|
+
} catch (e) {
|
|
337
|
+
console.error("Failed to update pixels:", e);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Register an event handler
|
|
342
|
+
*/
|
|
343
|
+
on(t, e) {
|
|
344
|
+
if (!(!this.window || this.closed))
|
|
345
|
+
try {
|
|
346
|
+
this.window.on(t, (r) => {
|
|
347
|
+
try {
|
|
348
|
+
e(r);
|
|
349
|
+
} catch (i) {
|
|
350
|
+
console.error(`Error in ${t} handler:`, i);
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
} catch (r) {
|
|
354
|
+
console.error(`Error registering ${t} handler:`, r);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Check if window is still open
|
|
359
|
+
*/
|
|
360
|
+
isOpen() {
|
|
361
|
+
return this.window !== null && !this.closed;
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Cleanup and close window
|
|
365
|
+
*/
|
|
366
|
+
cleanup() {
|
|
367
|
+
if (this.window && !this.closed) {
|
|
368
|
+
try {
|
|
369
|
+
this.window.destroy();
|
|
370
|
+
} catch (t) {
|
|
371
|
+
console.warn("Error destroying window:", t);
|
|
372
|
+
}
|
|
373
|
+
this.window = null, this.closed = !0;
|
|
374
|
+
}
|
|
375
|
+
console.log("✓ SDL Window cleaned up");
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Destroy the window (alias for cleanup)
|
|
379
|
+
*/
|
|
380
|
+
destroy() {
|
|
381
|
+
this.cleanup();
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
class _ {
|
|
304
385
|
/**
|
|
305
386
|
* Create a texture from pixel data
|
|
306
387
|
* @param gl WebGL context
|
|
@@ -308,32 +389,32 @@ class B {
|
|
|
308
389
|
* @param height Texture height
|
|
309
390
|
* @param data Pixel data (Uint8Array RGBA)
|
|
310
391
|
*/
|
|
311
|
-
constructor(
|
|
312
|
-
this.gl =
|
|
313
|
-
const
|
|
314
|
-
if (!
|
|
392
|
+
constructor(t, e, r, i) {
|
|
393
|
+
this.gl = t, this.width = e, this.height = r;
|
|
394
|
+
const s = t.createTexture();
|
|
395
|
+
if (!s)
|
|
315
396
|
throw new Error("Failed to create texture");
|
|
316
|
-
this.texture =
|
|
317
|
-
|
|
397
|
+
this.texture = s, t.bindTexture(t.TEXTURE_2D, this.texture), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_WRAP_S, t.CLAMP_TO_EDGE), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_WRAP_T, t.CLAMP_TO_EDGE), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_MIN_FILTER, t.LINEAR), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_MAG_FILTER, t.LINEAR), i ? t.texImage2D(
|
|
398
|
+
t.TEXTURE_2D,
|
|
318
399
|
0,
|
|
319
|
-
|
|
320
|
-
|
|
400
|
+
t.RGBA,
|
|
401
|
+
e,
|
|
321
402
|
r,
|
|
322
403
|
0,
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
) :
|
|
327
|
-
|
|
404
|
+
t.RGBA,
|
|
405
|
+
t.UNSIGNED_BYTE,
|
|
406
|
+
i
|
|
407
|
+
) : t.texImage2D(
|
|
408
|
+
t.TEXTURE_2D,
|
|
328
409
|
0,
|
|
329
|
-
|
|
330
|
-
|
|
410
|
+
t.RGBA,
|
|
411
|
+
e,
|
|
331
412
|
r,
|
|
332
413
|
0,
|
|
333
|
-
|
|
334
|
-
|
|
414
|
+
t.RGBA,
|
|
415
|
+
t.UNSIGNED_BYTE,
|
|
335
416
|
null
|
|
336
|
-
),
|
|
417
|
+
), t.bindTexture(t.TEXTURE_2D, null);
|
|
337
418
|
}
|
|
338
419
|
/**
|
|
339
420
|
* Create a solid color texture
|
|
@@ -345,13 +426,13 @@ class B {
|
|
|
345
426
|
* @param b Blue (0-255)
|
|
346
427
|
* @param a Alpha (0-255)
|
|
347
428
|
*/
|
|
348
|
-
static createSolid(
|
|
349
|
-
const a =
|
|
350
|
-
for (let
|
|
351
|
-
const l =
|
|
352
|
-
h[l] =
|
|
429
|
+
static createSolid(t, e, r, i, s, o, n = 255) {
|
|
430
|
+
const a = e * r, h = new Uint8Array(a * 4);
|
|
431
|
+
for (let g = 0; g < a; g++) {
|
|
432
|
+
const l = g * 4;
|
|
433
|
+
h[l] = i, h[l + 1] = s, h[l + 2] = o, h[l + 3] = n;
|
|
353
434
|
}
|
|
354
|
-
return new
|
|
435
|
+
return new _(t, e, r, h);
|
|
355
436
|
}
|
|
356
437
|
/**
|
|
357
438
|
* Create a checkerboard texture
|
|
@@ -360,14 +441,14 @@ class B {
|
|
|
360
441
|
* @param height Texture height
|
|
361
442
|
* @param squareSize Size of each square
|
|
362
443
|
*/
|
|
363
|
-
static createCheckerboard(
|
|
364
|
-
const
|
|
444
|
+
static createCheckerboard(t, e, r, i = 32) {
|
|
445
|
+
const s = new Uint8Array(e * r * 4);
|
|
365
446
|
for (let o = 0; o < r; o++)
|
|
366
|
-
for (let n = 0; n <
|
|
367
|
-
const a = Math.floor(n /
|
|
368
|
-
|
|
447
|
+
for (let n = 0; n < e; n++) {
|
|
448
|
+
const a = Math.floor(n / i), h = Math.floor(o / i), g = (a + h) % 2 === 0, l = (o * e + n) * 4, f = g ? 255 : 0;
|
|
449
|
+
s[l] = f, s[l + 1] = f, s[l + 2] = f, s[l + 3] = 255;
|
|
369
450
|
}
|
|
370
|
-
return new
|
|
451
|
+
return new _(t, e, r, s);
|
|
371
452
|
}
|
|
372
453
|
/**
|
|
373
454
|
* Create a gradient texture
|
|
@@ -375,21 +456,21 @@ class B {
|
|
|
375
456
|
* @param width Texture width
|
|
376
457
|
* @param height Texture height
|
|
377
458
|
*/
|
|
378
|
-
static createGradient(
|
|
379
|
-
const
|
|
380
|
-
for (let
|
|
381
|
-
for (let o = 0; o <
|
|
382
|
-
const n = (
|
|
383
|
-
|
|
459
|
+
static createGradient(t, e, r) {
|
|
460
|
+
const i = new Uint8Array(e * r * 4);
|
|
461
|
+
for (let s = 0; s < r; s++)
|
|
462
|
+
for (let o = 0; o < e; o++) {
|
|
463
|
+
const n = (s * e + o) * 4;
|
|
464
|
+
i[n] = Math.floor(o / e * 255), i[n + 1] = Math.floor(s / r * 255), i[n + 2] = 128, i[n + 3] = 255;
|
|
384
465
|
}
|
|
385
|
-
return new
|
|
466
|
+
return new _(t, e, r, i);
|
|
386
467
|
}
|
|
387
468
|
/**
|
|
388
469
|
* Bind this texture to a texture unit
|
|
389
470
|
* @param unit Texture unit (0-7 typically)
|
|
390
471
|
*/
|
|
391
|
-
bind(
|
|
392
|
-
this.gl.activeTexture(this.gl.TEXTURE0 +
|
|
472
|
+
bind(t = 0) {
|
|
473
|
+
this.gl.activeTexture(this.gl.TEXTURE0 + t), this.gl.bindTexture(this.gl.TEXTURE_2D, this.texture);
|
|
393
474
|
}
|
|
394
475
|
/**
|
|
395
476
|
* Unbind texture
|
|
@@ -416,15 +497,15 @@ class B {
|
|
|
416
497
|
this.gl.deleteTexture(this.texture);
|
|
417
498
|
}
|
|
418
499
|
}
|
|
419
|
-
class
|
|
420
|
-
constructor(
|
|
421
|
-
this.gl =
|
|
422
|
-
const
|
|
423
|
-
this.vertexCount =
|
|
424
|
-
const
|
|
425
|
-
if (!
|
|
500
|
+
class j {
|
|
501
|
+
constructor(t, e, r = 0) {
|
|
502
|
+
this.gl = t, this.stride = r;
|
|
503
|
+
const i = r > 0 ? r / 4 : 3;
|
|
504
|
+
this.vertexCount = e.length / i;
|
|
505
|
+
const s = t.createBuffer();
|
|
506
|
+
if (!s)
|
|
426
507
|
throw new Error("Failed to create vertex buffer");
|
|
427
|
-
this.buffer =
|
|
508
|
+
this.buffer = s, t.bindBuffer(t.ARRAY_BUFFER, this.buffer), t.bufferData(t.ARRAY_BUFFER, e, t.STATIC_DRAW), t.bindBuffer(t.ARRAY_BUFFER, null);
|
|
428
509
|
}
|
|
429
510
|
/**
|
|
430
511
|
* Bind buffer for rendering
|
|
@@ -457,13 +538,13 @@ class Q {
|
|
|
457
538
|
this.gl.deleteBuffer(this.buffer);
|
|
458
539
|
}
|
|
459
540
|
}
|
|
460
|
-
class
|
|
461
|
-
constructor(
|
|
462
|
-
this.gl =
|
|
463
|
-
const r =
|
|
541
|
+
class K {
|
|
542
|
+
constructor(t, e) {
|
|
543
|
+
this.gl = t, this.indexCount = e.length;
|
|
544
|
+
const r = t.createBuffer();
|
|
464
545
|
if (!r)
|
|
465
546
|
throw new Error("Failed to create index buffer");
|
|
466
|
-
this.buffer = r,
|
|
547
|
+
this.buffer = r, t.bindBuffer(t.ELEMENT_ARRAY_BUFFER, this.buffer), t.bufferData(t.ELEMENT_ARRAY_BUFFER, e, t.STATIC_DRAW), t.bindBuffer(t.ELEMENT_ARRAY_BUFFER, null);
|
|
467
548
|
}
|
|
468
549
|
/**
|
|
469
550
|
* Bind buffer for rendering
|
|
@@ -490,44 +571,44 @@ class j {
|
|
|
490
571
|
this.gl.deleteBuffer(this.buffer);
|
|
491
572
|
}
|
|
492
573
|
}
|
|
493
|
-
const
|
|
574
|
+
const Z = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
494
575
|
__proto__: null,
|
|
495
|
-
IndexBuffer:
|
|
496
|
-
VertexBuffer:
|
|
576
|
+
IndexBuffer: K,
|
|
577
|
+
VertexBuffer: j
|
|
497
578
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
498
|
-
class
|
|
579
|
+
class gt {
|
|
499
580
|
/**
|
|
500
581
|
* Create a new batch renderer (V1)
|
|
501
582
|
* @param gl WebGL rendering context
|
|
502
583
|
* @param shader Shader program to use
|
|
503
584
|
* @param maxQuads Maximum number of quads to batch (default 1000)
|
|
504
585
|
*/
|
|
505
|
-
constructor(
|
|
506
|
-
this.vertexBuffer = null, this.quads = [], this.isDirty = !1, this.verticesPerQuad = 6, this.floatsPerVertex = 5, this.texture = null, this.gl =
|
|
507
|
-
const
|
|
508
|
-
this.vertexData = new Float32Array(
|
|
509
|
-
const
|
|
510
|
-
if (!
|
|
586
|
+
constructor(t, e, r = 1e3) {
|
|
587
|
+
this.vertexBuffer = null, this.quads = [], this.isDirty = !1, this.verticesPerQuad = 6, this.floatsPerVertex = 5, this.texture = null, this.gl = t, this.shader = e, this.maxQuads = r;
|
|
588
|
+
const i = r * this.verticesPerQuad * this.floatsPerVertex;
|
|
589
|
+
this.vertexData = new Float32Array(i);
|
|
590
|
+
const s = t.createBuffer();
|
|
591
|
+
if (!s)
|
|
511
592
|
throw new Error("Failed to create vertex buffer");
|
|
512
|
-
this.vertexBuffer =
|
|
593
|
+
this.vertexBuffer = s, t.bindBuffer(t.ARRAY_BUFFER, this.vertexBuffer), t.bufferData(t.ARRAY_BUFFER, this.vertexData.byteLength, t.DYNAMIC_DRAW), t.bindBuffer(t.ARRAY_BUFFER, null);
|
|
513
594
|
}
|
|
514
595
|
/**
|
|
515
596
|
* Set the texture for batch rendering
|
|
516
597
|
* @param texture The texture to use when rendering
|
|
517
598
|
*/
|
|
518
|
-
setTexture(
|
|
519
|
-
this.texture =
|
|
599
|
+
setTexture(t) {
|
|
600
|
+
this.texture = t;
|
|
520
601
|
}
|
|
521
602
|
/**
|
|
522
603
|
* Add a quad to the batch
|
|
523
604
|
* @param quad Quad instance to add
|
|
524
605
|
*/
|
|
525
|
-
addQuad(
|
|
606
|
+
addQuad(t) {
|
|
526
607
|
if (this.quads.length >= this.maxQuads) {
|
|
527
608
|
console.warn(`Batch renderer at max capacity (${this.maxQuads})`);
|
|
528
609
|
return;
|
|
529
610
|
}
|
|
530
|
-
this.quads.push(
|
|
611
|
+
this.quads.push(t), this.isDirty = !0;
|
|
531
612
|
}
|
|
532
613
|
/**
|
|
533
614
|
* Clear all quads from the batch
|
|
@@ -547,28 +628,28 @@ class ue {
|
|
|
547
628
|
update() {
|
|
548
629
|
if (!this.isDirty || this.quads.length === 0)
|
|
549
630
|
return;
|
|
550
|
-
let
|
|
551
|
-
for (const
|
|
552
|
-
const r = this.generateQuadVertices(
|
|
553
|
-
for (const
|
|
554
|
-
this.vertexData[
|
|
631
|
+
let t = 0;
|
|
632
|
+
for (const e of this.quads) {
|
|
633
|
+
const r = this.generateQuadVertices(e);
|
|
634
|
+
for (const i of r)
|
|
635
|
+
this.vertexData[t++] = i[0], this.vertexData[t++] = i[1], this.vertexData[t++] = i[2], this.vertexData[t++] = i[3], this.vertexData[t++] = i[4];
|
|
555
636
|
}
|
|
556
637
|
this.vertexBuffer && (this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexBuffer), this.gl.bufferSubData(
|
|
557
638
|
this.gl.ARRAY_BUFFER,
|
|
558
639
|
0,
|
|
559
|
-
this.vertexData.subarray(0,
|
|
640
|
+
this.vertexData.subarray(0, t)
|
|
560
641
|
), this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null)), this.isDirty = !1;
|
|
561
642
|
}
|
|
562
643
|
/**
|
|
563
644
|
* Render the batch
|
|
564
645
|
* @param camera Optional camera for view transform (defaults to identity matrix)
|
|
565
646
|
*/
|
|
566
|
-
render(
|
|
647
|
+
render(t) {
|
|
567
648
|
if (this.quads.length !== 0 && (this.update(), this.shader.use(), this.vertexBuffer)) {
|
|
568
649
|
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexBuffer);
|
|
569
|
-
const
|
|
570
|
-
if (
|
|
571
|
-
|
|
650
|
+
const e = this.shader.getAttributeLocation("aPosition"), r = this.shader.getAttributeLocation("aTexCoord");
|
|
651
|
+
if (e !== -1 && (this.gl.enableVertexAttribArray(e), this.gl.vertexAttribPointer(
|
|
652
|
+
e,
|
|
572
653
|
3,
|
|
573
654
|
// 3 floats (x, y, z)
|
|
574
655
|
this.gl.FLOAT,
|
|
@@ -592,9 +673,9 @@ class ue {
|
|
|
592
673
|
const o = this.shader.getUniformLocation("uTexture");
|
|
593
674
|
o !== null && this.gl.uniform1i(o, 0);
|
|
594
675
|
}
|
|
595
|
-
const
|
|
596
|
-
if (
|
|
597
|
-
const o =
|
|
676
|
+
const i = this.shader.getUniformLocation("uMatrix");
|
|
677
|
+
if (i !== null) {
|
|
678
|
+
const o = t ? t.getViewMatrix() : new Float32Array([
|
|
598
679
|
1,
|
|
599
680
|
0,
|
|
600
681
|
0,
|
|
@@ -612,10 +693,10 @@ class ue {
|
|
|
612
693
|
0,
|
|
613
694
|
1
|
|
614
695
|
]);
|
|
615
|
-
this.gl.uniformMatrix4fv(
|
|
696
|
+
this.gl.uniformMatrix4fv(i, !1, o);
|
|
616
697
|
}
|
|
617
|
-
const
|
|
618
|
-
this.gl.drawArrays(this.gl.TRIANGLES, 0,
|
|
698
|
+
const s = this.quads.length * this.verticesPerQuad;
|
|
699
|
+
this.gl.drawArrays(this.gl.TRIANGLES, 0, s), this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null);
|
|
619
700
|
}
|
|
620
701
|
}
|
|
621
702
|
/**
|
|
@@ -623,8 +704,8 @@ class ue {
|
|
|
623
704
|
* Returns 6 vertices (2 triangles)
|
|
624
705
|
* @private
|
|
625
706
|
*/
|
|
626
|
-
generateQuadVertices(
|
|
627
|
-
const { x:
|
|
707
|
+
generateQuadVertices(t) {
|
|
708
|
+
const { x: e, y: r, width: i, height: s, rotation: o } = t, n = i / 2, a = s / 2, h = Math.cos(o), g = Math.sin(o), l = (x, w) => [x * h - w * g, x * g + w * h], f = [
|
|
628
709
|
[-n, -a],
|
|
629
710
|
// bottom-left
|
|
630
711
|
[n, -a],
|
|
@@ -637,7 +718,7 @@ class ue {
|
|
|
637
718
|
// top-left
|
|
638
719
|
[-n, -a]
|
|
639
720
|
// bottom-left (duplicate)
|
|
640
|
-
],
|
|
721
|
+
], d = [
|
|
641
722
|
[0, 0],
|
|
642
723
|
// bottom-left
|
|
643
724
|
[1, 0],
|
|
@@ -650,12 +731,12 @@ class ue {
|
|
|
650
731
|
// top-left
|
|
651
732
|
[0, 0]
|
|
652
733
|
// bottom-left
|
|
653
|
-
],
|
|
654
|
-
for (let
|
|
655
|
-
const [w,
|
|
656
|
-
|
|
734
|
+
], A = [];
|
|
735
|
+
for (let x = 0; x < f.length; x++) {
|
|
736
|
+
const [w, y] = f[x], [E, u] = l(w, y), [m, b] = d[x];
|
|
737
|
+
A.push([e + E, r + u, 0, m, b]);
|
|
657
738
|
}
|
|
658
|
-
return
|
|
739
|
+
return A;
|
|
659
740
|
}
|
|
660
741
|
/**
|
|
661
742
|
* Dispose resources
|
|
@@ -664,39 +745,39 @@ class ue {
|
|
|
664
745
|
this.vertexBuffer && (this.gl.deleteBuffer(this.vertexBuffer), this.vertexBuffer = null);
|
|
665
746
|
}
|
|
666
747
|
}
|
|
667
|
-
class
|
|
748
|
+
class xt {
|
|
668
749
|
/**
|
|
669
750
|
* Create a new sprite batch renderer (V2)
|
|
670
751
|
* @param gl WebGL rendering context
|
|
671
752
|
* @param shader Shader program to use (should be SHADERS_V2)
|
|
672
753
|
* @param maxQuads Maximum number of quads to batch (default 1000)
|
|
673
754
|
*/
|
|
674
|
-
constructor(
|
|
675
|
-
this.vertexBuffer = null, this.quads = [], this.isDirty = !1, this.verticesPerQuad = 6, this.floatsPerVertex = 10, this.texture = null, this.depthTestEnabled = !0, this.gl =
|
|
676
|
-
const
|
|
677
|
-
this.vertexData = new Float32Array(
|
|
678
|
-
const
|
|
679
|
-
if (!
|
|
755
|
+
constructor(t, e, r = 1e3) {
|
|
756
|
+
this.vertexBuffer = null, this.quads = [], this.isDirty = !1, this.verticesPerQuad = 6, this.floatsPerVertex = 10, this.texture = null, this.depthTestEnabled = !0, this.gl = t, this.shader = e, this.maxQuads = r;
|
|
757
|
+
const i = r * this.verticesPerQuad * this.floatsPerVertex;
|
|
758
|
+
this.vertexData = new Float32Array(i);
|
|
759
|
+
const s = t.createBuffer();
|
|
760
|
+
if (!s)
|
|
680
761
|
throw new Error("Failed to create vertex buffer");
|
|
681
|
-
this.vertexBuffer =
|
|
762
|
+
this.vertexBuffer = s, t.bindBuffer(t.ARRAY_BUFFER, this.vertexBuffer), t.bufferData(t.ARRAY_BUFFER, this.vertexData.byteLength, t.DYNAMIC_DRAW), t.bindBuffer(t.ARRAY_BUFFER, null);
|
|
682
763
|
}
|
|
683
764
|
/**
|
|
684
765
|
* Set the texture for batch rendering
|
|
685
766
|
* @param texture The texture to use when rendering
|
|
686
767
|
*/
|
|
687
|
-
setTexture(
|
|
688
|
-
this.texture =
|
|
768
|
+
setTexture(t) {
|
|
769
|
+
this.texture = t;
|
|
689
770
|
}
|
|
690
771
|
/**
|
|
691
772
|
* Add a sprite quad to the batch
|
|
692
773
|
* @param quad Sprite quad instance to add
|
|
693
774
|
*/
|
|
694
|
-
addQuad(
|
|
775
|
+
addQuad(t) {
|
|
695
776
|
if (this.quads.length >= this.maxQuads) {
|
|
696
777
|
console.warn(`Sprite batch renderer at max capacity (${this.maxQuads})`);
|
|
697
778
|
return;
|
|
698
779
|
}
|
|
699
|
-
this.quads.push(
|
|
780
|
+
this.quads.push(t), this.isDirty = !0;
|
|
700
781
|
}
|
|
701
782
|
/**
|
|
702
783
|
* Clear all quads from the batch
|
|
@@ -716,36 +797,36 @@ class de {
|
|
|
716
797
|
update() {
|
|
717
798
|
if (!this.isDirty || this.quads.length === 0)
|
|
718
799
|
return;
|
|
719
|
-
let
|
|
720
|
-
for (const
|
|
800
|
+
let t = 0;
|
|
801
|
+
for (const e of this.quads) {
|
|
721
802
|
const {
|
|
722
803
|
x: r,
|
|
723
|
-
y:
|
|
724
|
-
z:
|
|
804
|
+
y: i,
|
|
805
|
+
z: s = 0,
|
|
725
806
|
width: o,
|
|
726
807
|
height: n,
|
|
727
808
|
rotation: a,
|
|
728
809
|
color: h = { r: 1, g: 1, b: 1, a: 1 },
|
|
729
|
-
uvRect:
|
|
810
|
+
uvRect: g = { uMin: 0, vMin: 0, uMax: 1, vMax: 1 },
|
|
730
811
|
texIndex: l = 0
|
|
731
|
-
} =
|
|
812
|
+
} = e, f = this.generateQuadVertices({
|
|
732
813
|
x: r,
|
|
733
|
-
y:
|
|
734
|
-
z:
|
|
814
|
+
y: i,
|
|
815
|
+
z: s,
|
|
735
816
|
width: o,
|
|
736
817
|
height: n,
|
|
737
818
|
rotation: a,
|
|
738
819
|
color: h,
|
|
739
|
-
uvRect:
|
|
820
|
+
uvRect: g,
|
|
740
821
|
texIndex: l
|
|
741
822
|
});
|
|
742
|
-
for (const
|
|
743
|
-
this.vertexData[
|
|
823
|
+
for (const d of f)
|
|
824
|
+
this.vertexData[t++] = d.x, this.vertexData[t++] = d.y, this.vertexData[t++] = d.z, this.vertexData[t++] = d.u, this.vertexData[t++] = d.v, this.vertexData[t++] = d.r, this.vertexData[t++] = d.g, this.vertexData[t++] = d.b, this.vertexData[t++] = d.a, this.vertexData[t++] = d.texIndex;
|
|
744
825
|
}
|
|
745
826
|
this.vertexBuffer && (this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexBuffer), this.gl.bufferSubData(
|
|
746
827
|
this.gl.ARRAY_BUFFER,
|
|
747
828
|
0,
|
|
748
|
-
this.vertexData.subarray(0,
|
|
829
|
+
this.vertexData.subarray(0, t)
|
|
749
830
|
), this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null)), this.isDirty = !1;
|
|
750
831
|
}
|
|
751
832
|
/**
|
|
@@ -753,19 +834,19 @@ class de {
|
|
|
753
834
|
* When enabled, sprites with lower Z values appear behind sprites with higher Z values
|
|
754
835
|
* @param enabled Whether to enable depth testing (default true)
|
|
755
836
|
*/
|
|
756
|
-
setDepthTestEnabled(
|
|
757
|
-
this.depthTestEnabled =
|
|
837
|
+
setDepthTestEnabled(t) {
|
|
838
|
+
this.depthTestEnabled = t;
|
|
758
839
|
}
|
|
759
840
|
/**
|
|
760
841
|
* Render the batch
|
|
761
842
|
* @param camera Optional camera for view transform (defaults to identity matrix)
|
|
762
843
|
*/
|
|
763
|
-
render(
|
|
844
|
+
render(t) {
|
|
764
845
|
if (this.quads.length !== 0 && (this.update(), this.shader.use(), this.depthTestEnabled ? (this.gl.enable(this.gl.DEPTH_TEST), this.gl.depthFunc(this.gl.LEQUAL)) : this.gl.disable(this.gl.DEPTH_TEST), this.vertexBuffer)) {
|
|
765
846
|
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexBuffer);
|
|
766
|
-
const
|
|
767
|
-
if (
|
|
768
|
-
|
|
847
|
+
const e = this.shader.getAttributeLocation("aPosition"), r = this.shader.getAttributeLocation("aTexCoord"), i = this.shader.getAttributeLocation("aColor"), s = this.shader.getAttributeLocation("aTexIndex"), o = this.floatsPerVertex * 4;
|
|
848
|
+
if (e !== -1 && (this.gl.enableVertexAttribArray(e), this.gl.vertexAttribPointer(
|
|
849
|
+
e,
|
|
769
850
|
3,
|
|
770
851
|
// 3 floats (x, y, z)
|
|
771
852
|
this.gl.FLOAT,
|
|
@@ -782,8 +863,8 @@ class de {
|
|
|
782
863
|
o,
|
|
783
864
|
12
|
|
784
865
|
// offset after position
|
|
785
|
-
)),
|
|
786
|
-
|
|
866
|
+
)), i !== -1 && (this.gl.enableVertexAttribArray(i), this.gl.vertexAttribPointer(
|
|
867
|
+
i,
|
|
787
868
|
4,
|
|
788
869
|
// 4 floats (r, g, b, a)
|
|
789
870
|
this.gl.FLOAT,
|
|
@@ -791,8 +872,8 @@ class de {
|
|
|
791
872
|
o,
|
|
792
873
|
20
|
|
793
874
|
// offset after texCoord
|
|
794
|
-
)),
|
|
795
|
-
|
|
875
|
+
)), s !== -1 && (this.gl.enableVertexAttribArray(s), this.gl.vertexAttribPointer(
|
|
876
|
+
s,
|
|
796
877
|
1,
|
|
797
878
|
// 1 float (texIndex)
|
|
798
879
|
this.gl.FLOAT,
|
|
@@ -807,7 +888,7 @@ class de {
|
|
|
807
888
|
}
|
|
808
889
|
const n = this.shader.getUniformLocation("uMatrix");
|
|
809
890
|
if (n !== null) {
|
|
810
|
-
const h =
|
|
891
|
+
const h = t ? t.getViewMatrix() : new Float32Array([
|
|
811
892
|
1,
|
|
812
893
|
0,
|
|
813
894
|
0,
|
|
@@ -836,21 +917,21 @@ class de {
|
|
|
836
917
|
* Returns 6 vertices (2 triangles)
|
|
837
918
|
* @private
|
|
838
919
|
*/
|
|
839
|
-
generateQuadVertices(
|
|
840
|
-
const { x:
|
|
841
|
-
[-l, -
|
|
920
|
+
generateQuadVertices(t) {
|
|
921
|
+
const { x: e, y: r, z: i, width: s, height: o, rotation: n, color: a, uvRect: h, texIndex: g } = t, l = s / 2, f = o / 2, d = Math.cos(n), A = Math.sin(n), x = (u, m) => [u * d - m * A, u * A + m * d], w = [
|
|
922
|
+
[-l, -f],
|
|
842
923
|
// bottom-left
|
|
843
|
-
[l, -
|
|
924
|
+
[l, -f],
|
|
844
925
|
// bottom-right
|
|
845
|
-
[l,
|
|
926
|
+
[l, f],
|
|
846
927
|
// top-right
|
|
847
|
-
[l,
|
|
928
|
+
[l, f],
|
|
848
929
|
// top-right (duplicate)
|
|
849
|
-
[-l,
|
|
930
|
+
[-l, f],
|
|
850
931
|
// top-left
|
|
851
|
-
[-l, -
|
|
932
|
+
[-l, -f]
|
|
852
933
|
// bottom-left (duplicate)
|
|
853
|
-
],
|
|
934
|
+
], y = [
|
|
854
935
|
[h.uMin, h.vMin],
|
|
855
936
|
// bottom-left
|
|
856
937
|
[h.uMax, h.vMin],
|
|
@@ -863,23 +944,23 @@ class de {
|
|
|
863
944
|
// top-left
|
|
864
945
|
[h.uMin, h.vMin]
|
|
865
946
|
// bottom-left
|
|
866
|
-
],
|
|
947
|
+
], E = [];
|
|
867
948
|
for (let u = 0; u < w.length; u++) {
|
|
868
|
-
const [
|
|
869
|
-
|
|
870
|
-
x:
|
|
871
|
-
y: r +
|
|
872
|
-
z:
|
|
873
|
-
u:
|
|
874
|
-
v
|
|
949
|
+
const [m, b] = w[u], [R, B] = x(m, b), [L, v] = y[u];
|
|
950
|
+
E.push({
|
|
951
|
+
x: e + R,
|
|
952
|
+
y: r + B,
|
|
953
|
+
z: i,
|
|
954
|
+
u: L,
|
|
955
|
+
v,
|
|
875
956
|
r: a.r,
|
|
876
957
|
g: a.g,
|
|
877
958
|
b: a.b,
|
|
878
959
|
a: a.a,
|
|
879
|
-
texIndex:
|
|
960
|
+
texIndex: g
|
|
880
961
|
});
|
|
881
962
|
}
|
|
882
|
-
return
|
|
963
|
+
return E;
|
|
883
964
|
}
|
|
884
965
|
/**
|
|
885
966
|
* Dispose resources
|
|
@@ -888,7 +969,203 @@ class de {
|
|
|
888
969
|
this.vertexBuffer && (this.gl.deleteBuffer(this.vertexBuffer), this.vertexBuffer = null);
|
|
889
970
|
}
|
|
890
971
|
}
|
|
891
|
-
class
|
|
972
|
+
class wt {
|
|
973
|
+
/**
|
|
974
|
+
* Create a new GPU-based sprite batch renderer (V3)
|
|
975
|
+
* @param gl WebGL rendering context
|
|
976
|
+
* @param shader Shader program to use (should be SHADERS_V3)
|
|
977
|
+
* @param maxQuads Maximum number of quads to batch (default 1000)
|
|
978
|
+
* @param tileSize Tile size for isometric projection (default {width: 64, height: 32})
|
|
979
|
+
* @param zScale Scale factor for Z height (default 1.0)
|
|
980
|
+
*/
|
|
981
|
+
constructor(t, e, r = 1e3, i = { width: 64, height: 32 }, s = 1) {
|
|
982
|
+
this.vertexBuffer = null, this.quads = [], this.isDirty = !1, this.verticesPerQuad = 6, this.floatsPerVertex = 12, this.texture = null, this.depthTestEnabled = !0, this.gl = t, this.shader = e, this.maxQuads = r, this.tileSize = i, this.zScale = s, this.resolution = { width: t.canvas.width, height: t.canvas.height };
|
|
983
|
+
const o = r * this.verticesPerQuad * this.floatsPerVertex;
|
|
984
|
+
this.vertexData = new Float32Array(o);
|
|
985
|
+
const n = t.createBuffer();
|
|
986
|
+
if (!n)
|
|
987
|
+
throw new Error("Failed to create vertex buffer");
|
|
988
|
+
this.vertexBuffer = n, t.bindBuffer(t.ARRAY_BUFFER, this.vertexBuffer), t.bufferData(t.ARRAY_BUFFER, this.vertexData.byteLength, t.DYNAMIC_DRAW), t.bindBuffer(t.ARRAY_BUFFER, null);
|
|
989
|
+
}
|
|
990
|
+
/**
|
|
991
|
+
* Set the texture for batch rendering
|
|
992
|
+
* @param texture The texture to use when rendering
|
|
993
|
+
*/
|
|
994
|
+
setTexture(t) {
|
|
995
|
+
this.texture = t;
|
|
996
|
+
}
|
|
997
|
+
/**
|
|
998
|
+
* Add a sprite quad to the batch
|
|
999
|
+
* If gridX and gridY are provided, uses GPU transformation.
|
|
1000
|
+
* Otherwise, converts x, y to grid coordinates.
|
|
1001
|
+
* @param quad Sprite quad instance to add
|
|
1002
|
+
*/
|
|
1003
|
+
addQuad(t) {
|
|
1004
|
+
if (this.quads.length >= this.maxQuads) {
|
|
1005
|
+
console.warn(`Sprite batch renderer at max capacity (${this.maxQuads})`);
|
|
1006
|
+
return;
|
|
1007
|
+
}
|
|
1008
|
+
this.quads.push(t), this.isDirty = !0;
|
|
1009
|
+
}
|
|
1010
|
+
/**
|
|
1011
|
+
* Clear all quads from the batch
|
|
1012
|
+
*/
|
|
1013
|
+
clear() {
|
|
1014
|
+
this.quads = [], this.isDirty = !0;
|
|
1015
|
+
}
|
|
1016
|
+
/**
|
|
1017
|
+
* Get number of quads currently in batch
|
|
1018
|
+
*/
|
|
1019
|
+
getQuadCount() {
|
|
1020
|
+
return this.quads.length;
|
|
1021
|
+
}
|
|
1022
|
+
/**
|
|
1023
|
+
* Update the batch - rebuilds vertex buffer if quads changed
|
|
1024
|
+
*/
|
|
1025
|
+
update() {
|
|
1026
|
+
if (!this.isDirty || this.quads.length === 0)
|
|
1027
|
+
return;
|
|
1028
|
+
let t = 0;
|
|
1029
|
+
for (const e of this.quads) {
|
|
1030
|
+
const {
|
|
1031
|
+
x: r,
|
|
1032
|
+
y: i,
|
|
1033
|
+
z: s = 0,
|
|
1034
|
+
width: o,
|
|
1035
|
+
height: n,
|
|
1036
|
+
color: a = { r: 1, g: 1, b: 1, a: 1 },
|
|
1037
|
+
uvRect: h = { uMin: 0, vMin: 0, uMax: 1, vMax: 1 },
|
|
1038
|
+
texIndex: g = 0,
|
|
1039
|
+
gridX: l,
|
|
1040
|
+
gridY: f
|
|
1041
|
+
} = e;
|
|
1042
|
+
let d, A;
|
|
1043
|
+
l !== void 0 && f !== void 0 ? (d = l, A = f) : (d = (r / (this.tileSize.width * 0.5) + i / (this.tileSize.height * 0.5)) * 0.5, A = (i / (this.tileSize.height * 0.5) - r / (this.tileSize.width * 0.5)) * 0.5);
|
|
1044
|
+
const x = o / 2, w = n / 2, y = [
|
|
1045
|
+
[-x, -w],
|
|
1046
|
+
// bottom-left
|
|
1047
|
+
[x, -w],
|
|
1048
|
+
// bottom-right
|
|
1049
|
+
[x, w],
|
|
1050
|
+
// top-right
|
|
1051
|
+
[x, w],
|
|
1052
|
+
// top-right (duplicate)
|
|
1053
|
+
[-w, w],
|
|
1054
|
+
// top-left
|
|
1055
|
+
[-x, -w]
|
|
1056
|
+
// bottom-left (duplicate)
|
|
1057
|
+
], E = [
|
|
1058
|
+
[h.uMin, h.vMin],
|
|
1059
|
+
[h.uMax, h.vMin],
|
|
1060
|
+
[h.uMax, h.vMax],
|
|
1061
|
+
[h.uMax, h.vMax],
|
|
1062
|
+
[h.uMin, h.vMax],
|
|
1063
|
+
[h.uMin, h.vMin]
|
|
1064
|
+
];
|
|
1065
|
+
for (let u = 0; u < y.length; u++) {
|
|
1066
|
+
const [m, b] = y[u], [R, B] = E[u];
|
|
1067
|
+
this.vertexData[t++] = d, this.vertexData[t++] = A, this.vertexData[t++] = s, this.vertexData[t++] = m, this.vertexData[t++] = b, this.vertexData[t++] = R, this.vertexData[t++] = B, this.vertexData[t++] = a.r, this.vertexData[t++] = a.g, this.vertexData[t++] = a.b, this.vertexData[t++] = a.a, this.vertexData[t++] = g;
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
this.vertexBuffer && (this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexBuffer), this.gl.bufferSubData(
|
|
1071
|
+
this.gl.ARRAY_BUFFER,
|
|
1072
|
+
0,
|
|
1073
|
+
this.vertexData.subarray(0, t)
|
|
1074
|
+
), this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null)), this.isDirty = !1;
|
|
1075
|
+
}
|
|
1076
|
+
/**
|
|
1077
|
+
* Set whether depth testing is enabled
|
|
1078
|
+
* @param enabled Whether to enable depth testing (default true)
|
|
1079
|
+
*/
|
|
1080
|
+
setDepthTestEnabled(t) {
|
|
1081
|
+
this.depthTestEnabled = t;
|
|
1082
|
+
}
|
|
1083
|
+
/**
|
|
1084
|
+
* Render the batch with GPU-based transformation
|
|
1085
|
+
* @param camera Camera for view transform
|
|
1086
|
+
*/
|
|
1087
|
+
render(t) {
|
|
1088
|
+
if (this.quads.length !== 0 && (this.update(), this.shader.use(), this.depthTestEnabled ? (this.gl.enable(this.gl.DEPTH_TEST), this.gl.depthFunc(this.gl.LEQUAL)) : this.gl.disable(this.gl.DEPTH_TEST), this.vertexBuffer)) {
|
|
1089
|
+
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexBuffer);
|
|
1090
|
+
const e = this.floatsPerVertex * 4, r = {
|
|
1091
|
+
gridPosition: this.shader.getAttributeLocation("aGridPosition"),
|
|
1092
|
+
zPosition: this.shader.getAttributeLocation("aZPosition"),
|
|
1093
|
+
localOffset: this.shader.getAttributeLocation("aLocalOffset"),
|
|
1094
|
+
texCoord: this.shader.getAttributeLocation("aTexCoord"),
|
|
1095
|
+
color: this.shader.getAttributeLocation("aColor"),
|
|
1096
|
+
texIndex: this.shader.getAttributeLocation("aTexIndex")
|
|
1097
|
+
};
|
|
1098
|
+
if (r.gridPosition !== -1 && (this.gl.enableVertexAttribArray(r.gridPosition), this.gl.vertexAttribPointer(
|
|
1099
|
+
r.gridPosition,
|
|
1100
|
+
2,
|
|
1101
|
+
this.gl.FLOAT,
|
|
1102
|
+
!1,
|
|
1103
|
+
e,
|
|
1104
|
+
0
|
|
1105
|
+
)), r.zPosition !== -1 && (this.gl.enableVertexAttribArray(r.zPosition), this.gl.vertexAttribPointer(
|
|
1106
|
+
r.zPosition,
|
|
1107
|
+
1,
|
|
1108
|
+
this.gl.FLOAT,
|
|
1109
|
+
!1,
|
|
1110
|
+
e,
|
|
1111
|
+
8
|
|
1112
|
+
)), r.localOffset !== -1 && (this.gl.enableVertexAttribArray(r.localOffset), this.gl.vertexAttribPointer(
|
|
1113
|
+
r.localOffset,
|
|
1114
|
+
2,
|
|
1115
|
+
this.gl.FLOAT,
|
|
1116
|
+
!1,
|
|
1117
|
+
e,
|
|
1118
|
+
12
|
|
1119
|
+
)), r.texCoord !== -1 && (this.gl.enableVertexAttribArray(r.texCoord), this.gl.vertexAttribPointer(
|
|
1120
|
+
r.texCoord,
|
|
1121
|
+
2,
|
|
1122
|
+
this.gl.FLOAT,
|
|
1123
|
+
!1,
|
|
1124
|
+
e,
|
|
1125
|
+
20
|
|
1126
|
+
)), r.color !== -1 && (this.gl.enableVertexAttribArray(r.color), this.gl.vertexAttribPointer(
|
|
1127
|
+
r.color,
|
|
1128
|
+
4,
|
|
1129
|
+
this.gl.FLOAT,
|
|
1130
|
+
!1,
|
|
1131
|
+
e,
|
|
1132
|
+
28
|
|
1133
|
+
)), r.texIndex !== -1 && (this.gl.enableVertexAttribArray(r.texIndex), this.gl.vertexAttribPointer(
|
|
1134
|
+
r.texIndex,
|
|
1135
|
+
1,
|
|
1136
|
+
this.gl.FLOAT,
|
|
1137
|
+
!1,
|
|
1138
|
+
e,
|
|
1139
|
+
44
|
|
1140
|
+
)), this.texture) {
|
|
1141
|
+
this.texture.bind(0);
|
|
1142
|
+
const l = this.shader.getUniformLocation("uTexture");
|
|
1143
|
+
l !== null && this.gl.uniform1i(l, 0);
|
|
1144
|
+
}
|
|
1145
|
+
const i = this.shader.getUniformLocation("uTileSize");
|
|
1146
|
+
i !== null && this.gl.uniform2f(i, this.tileSize.width, this.tileSize.height);
|
|
1147
|
+
const s = this.shader.getUniformLocation("uCamera");
|
|
1148
|
+
s !== null && this.gl.uniform3f(s, t.x, t.y, t.zoom);
|
|
1149
|
+
const o = this.shader.getUniformLocation("uZScale");
|
|
1150
|
+
o !== null && this.gl.uniform1f(o, this.zScale);
|
|
1151
|
+
const n = this.shader.getUniformLocation("uResolution");
|
|
1152
|
+
n !== null && this.gl.uniform2f(n, this.resolution.width, this.resolution.height);
|
|
1153
|
+
const a = this.shader.getUniformLocation("uRotation");
|
|
1154
|
+
a !== null && this.gl.uniform1f(a, 0);
|
|
1155
|
+
const h = this.shader.getUniformLocation("uQuadSize");
|
|
1156
|
+
h !== null && this.gl.uniform2f(h, 1, 1);
|
|
1157
|
+
const g = this.quads.length * this.verticesPerQuad;
|
|
1158
|
+
this.gl.drawArrays(this.gl.TRIANGLES, 0, g), this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null);
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
/**
|
|
1162
|
+
* Clean up GPU resources
|
|
1163
|
+
*/
|
|
1164
|
+
dispose() {
|
|
1165
|
+
this.vertexBuffer && (this.gl.deleteBuffer(this.vertexBuffer), this.vertexBuffer = null);
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
class D {
|
|
892
1169
|
/**
|
|
893
1170
|
* Create an identity matrix
|
|
894
1171
|
* @returns 4x4 identity matrix in column-major order
|
|
@@ -924,7 +1201,7 @@ class F {
|
|
|
924
1201
|
* @param z Translation along Z axis (default 0)
|
|
925
1202
|
* @returns 4x4 translation matrix in column-major order
|
|
926
1203
|
*/
|
|
927
|
-
static translation(
|
|
1204
|
+
static translation(t, e, r = 0) {
|
|
928
1205
|
return new Float32Array([
|
|
929
1206
|
1,
|
|
930
1207
|
0,
|
|
@@ -941,8 +1218,8 @@ class F {
|
|
|
941
1218
|
1,
|
|
942
1219
|
0,
|
|
943
1220
|
// column 2
|
|
944
|
-
e,
|
|
945
1221
|
t,
|
|
1222
|
+
e,
|
|
946
1223
|
r,
|
|
947
1224
|
1
|
|
948
1225
|
// column 3
|
|
@@ -955,15 +1232,15 @@ class F {
|
|
|
955
1232
|
* @param z Scale factor along Z axis (default 1)
|
|
956
1233
|
* @returns 4x4 scale matrix in column-major order
|
|
957
1234
|
*/
|
|
958
|
-
static scale(
|
|
1235
|
+
static scale(t, e, r = 1) {
|
|
959
1236
|
return new Float32Array([
|
|
960
|
-
|
|
1237
|
+
t,
|
|
961
1238
|
0,
|
|
962
1239
|
0,
|
|
963
1240
|
0,
|
|
964
1241
|
// column 0
|
|
965
1242
|
0,
|
|
966
|
-
|
|
1243
|
+
e,
|
|
967
1244
|
0,
|
|
968
1245
|
0,
|
|
969
1246
|
// column 1
|
|
@@ -985,14 +1262,14 @@ class F {
|
|
|
985
1262
|
* @param b Second matrix (right operand)
|
|
986
1263
|
* @returns Result of matrix multiplication in column-major order
|
|
987
1264
|
*/
|
|
988
|
-
static multiply(
|
|
1265
|
+
static multiply(t, e) {
|
|
989
1266
|
const r = new Float32Array(16);
|
|
990
|
-
for (let
|
|
991
|
-
for (let
|
|
1267
|
+
for (let i = 0; i < 4; i++)
|
|
1268
|
+
for (let s = 0; s < 4; s++) {
|
|
992
1269
|
let o = 0;
|
|
993
1270
|
for (let n = 0; n < 4; n++)
|
|
994
|
-
o +=
|
|
995
|
-
r[
|
|
1271
|
+
o += t[n * 4 + s] * e[i * 4 + n];
|
|
1272
|
+
r[i * 4 + s] = o;
|
|
996
1273
|
}
|
|
997
1274
|
return r;
|
|
998
1275
|
}
|
|
@@ -1007,20 +1284,20 @@ class F {
|
|
|
1007
1284
|
* @param zoom Camera zoom level (1.0 = no zoom, >1 = zoom in, <1 = zoom out)
|
|
1008
1285
|
* @returns 4x4 view matrix in column-major order
|
|
1009
1286
|
*/
|
|
1010
|
-
static createViewMatrix(
|
|
1011
|
-
const
|
|
1012
|
-
return
|
|
1287
|
+
static createViewMatrix(t, e, r) {
|
|
1288
|
+
const i = D.translation(-t, -e, 0), s = D.scale(r, r, 1);
|
|
1289
|
+
return D.multiply(i, s);
|
|
1013
1290
|
}
|
|
1014
1291
|
}
|
|
1015
|
-
class
|
|
1292
|
+
class vt {
|
|
1016
1293
|
/**
|
|
1017
1294
|
* Create a new camera
|
|
1018
1295
|
* @param x Initial X position (default 0)
|
|
1019
1296
|
* @param y Initial Y position (default 0)
|
|
1020
1297
|
* @param zoom Initial zoom level (default 1.0)
|
|
1021
1298
|
*/
|
|
1022
|
-
constructor(
|
|
1023
|
-
this._viewMatrix = null, this._viewMatrixDirty = !0, this._x =
|
|
1299
|
+
constructor(t = 0, e = 0, r = 1) {
|
|
1300
|
+
this._viewMatrix = null, this._viewMatrixDirty = !0, this._x = t, this._y = e, this._zoom = r;
|
|
1024
1301
|
}
|
|
1025
1302
|
/**
|
|
1026
1303
|
* Get the camera X position
|
|
@@ -1031,8 +1308,8 @@ class fe {
|
|
|
1031
1308
|
/**
|
|
1032
1309
|
* Set the camera X position
|
|
1033
1310
|
*/
|
|
1034
|
-
set x(
|
|
1035
|
-
this._x =
|
|
1311
|
+
set x(t) {
|
|
1312
|
+
this._x = t, this._viewMatrixDirty = !0;
|
|
1036
1313
|
}
|
|
1037
1314
|
/**
|
|
1038
1315
|
* Get the camera Y position
|
|
@@ -1043,8 +1320,8 @@ class fe {
|
|
|
1043
1320
|
/**
|
|
1044
1321
|
* Set the camera Y position
|
|
1045
1322
|
*/
|
|
1046
|
-
set y(
|
|
1047
|
-
this._y =
|
|
1323
|
+
set y(t) {
|
|
1324
|
+
this._y = t, this._viewMatrixDirty = !0;
|
|
1048
1325
|
}
|
|
1049
1326
|
/**
|
|
1050
1327
|
* Get the camera zoom level
|
|
@@ -1056,31 +1333,31 @@ class fe {
|
|
|
1056
1333
|
* Set the camera zoom level
|
|
1057
1334
|
* Values: 1.0 = no zoom, >1 = zoom in, <1 = zoom out
|
|
1058
1335
|
*/
|
|
1059
|
-
set zoom(
|
|
1060
|
-
this._zoom = Math.max(1e-3,
|
|
1336
|
+
set zoom(t) {
|
|
1337
|
+
this._zoom = Math.max(1e-3, t), this._viewMatrixDirty = !0;
|
|
1061
1338
|
}
|
|
1062
1339
|
/**
|
|
1063
1340
|
* Set both X and Y position at once
|
|
1064
1341
|
* @param x New X position
|
|
1065
1342
|
* @param y New Y position
|
|
1066
1343
|
*/
|
|
1067
|
-
setPosition(
|
|
1068
|
-
this._x =
|
|
1344
|
+
setPosition(t, e) {
|
|
1345
|
+
this._x = t, this._y = e, this._viewMatrixDirty = !0;
|
|
1069
1346
|
}
|
|
1070
1347
|
/**
|
|
1071
1348
|
* Move the camera by a relative offset
|
|
1072
1349
|
* @param dx X offset to add to current position
|
|
1073
1350
|
* @param dy Y offset to add to current position
|
|
1074
1351
|
*/
|
|
1075
|
-
move(
|
|
1076
|
-
this._x +=
|
|
1352
|
+
move(t, e) {
|
|
1353
|
+
this._x += t, this._y += e, this._viewMatrixDirty = !0;
|
|
1077
1354
|
}
|
|
1078
1355
|
/**
|
|
1079
1356
|
* Scale the zoom by a factor
|
|
1080
1357
|
* @param factor Multiplier for current zoom (e.g., 1.1 to zoom in 10%)
|
|
1081
1358
|
*/
|
|
1082
|
-
zoomBy(
|
|
1083
|
-
this._zoom = Math.max(1e-3, this._zoom *
|
|
1359
|
+
zoomBy(t) {
|
|
1360
|
+
this._zoom = Math.max(1e-3, this._zoom * t), this._viewMatrixDirty = !0;
|
|
1084
1361
|
}
|
|
1085
1362
|
/**
|
|
1086
1363
|
* Reset camera to default position and zoom
|
|
@@ -1096,7 +1373,7 @@ class fe {
|
|
|
1096
1373
|
* @returns 4x4 view matrix in column-major order
|
|
1097
1374
|
*/
|
|
1098
1375
|
getViewMatrix() {
|
|
1099
|
-
return (this._viewMatrixDirty || this._viewMatrix === null) && (this._viewMatrix =
|
|
1376
|
+
return (this._viewMatrixDirty || this._viewMatrix === null) && (this._viewMatrix = D.createViewMatrix(this._x, this._y, this._zoom), this._viewMatrixDirty = !1), this._viewMatrix;
|
|
1100
1377
|
}
|
|
1101
1378
|
/**
|
|
1102
1379
|
* Convert screen coordinates to world coordinates
|
|
@@ -1108,8 +1385,8 @@ class fe {
|
|
|
1108
1385
|
* @param viewportHeight Viewport height in pixels
|
|
1109
1386
|
* @returns World coordinates {x, y}
|
|
1110
1387
|
*/
|
|
1111
|
-
screenToWorld(
|
|
1112
|
-
const
|
|
1388
|
+
screenToWorld(t, e, r, i) {
|
|
1389
|
+
const s = t - r / 2, o = e - i / 2, n = s / this._zoom + this._x, a = o / this._zoom + this._y;
|
|
1113
1390
|
return { x: n, y: a };
|
|
1114
1391
|
}
|
|
1115
1392
|
/**
|
|
@@ -1122,19 +1399,25 @@ class fe {
|
|
|
1122
1399
|
* @param viewportHeight Viewport height in pixels
|
|
1123
1400
|
* @returns Screen coordinates {x, y} in pixels
|
|
1124
1401
|
*/
|
|
1125
|
-
worldToScreen(
|
|
1126
|
-
const
|
|
1402
|
+
worldToScreen(t, e, r, i) {
|
|
1403
|
+
const s = (t - this._x) * this._zoom, o = (e - this._y) * this._zoom, n = s + r / 2, a = o + i / 2;
|
|
1127
1404
|
return { x: n, y: a };
|
|
1128
1405
|
}
|
|
1129
1406
|
}
|
|
1407
|
+
class mt {
|
|
1408
|
+
// Scale factor for height (vertical exaggeration)
|
|
1409
|
+
constructor(t = 64, e = 32, r = 1) {
|
|
1410
|
+
this.tileWidth = t, this.tileHeight = e, this.zScale = r;
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1130
1413
|
class J {
|
|
1131
1414
|
/**
|
|
1132
1415
|
* Create a new browser resource loader
|
|
1133
1416
|
* @param baseUrl Optional base URL for resolving relative paths (defaults to current origin)
|
|
1134
1417
|
* @param timeout Default timeout for requests in milliseconds (default: 10000)
|
|
1135
1418
|
*/
|
|
1136
|
-
constructor(
|
|
1137
|
-
this.baseUrl =
|
|
1419
|
+
constructor(t = "", e = 1e4) {
|
|
1420
|
+
this.baseUrl = t || this.getCurrentOrigin(), this.defaultTimeout = e;
|
|
1138
1421
|
}
|
|
1139
1422
|
/**
|
|
1140
1423
|
* Get the current origin (protocol + host + port)
|
|
@@ -1147,11 +1430,11 @@ class J {
|
|
|
1147
1430
|
* @param path Relative or absolute path
|
|
1148
1431
|
* @returns Resolved absolute URL
|
|
1149
1432
|
*/
|
|
1150
|
-
resolvePath(
|
|
1433
|
+
resolvePath(t) {
|
|
1151
1434
|
try {
|
|
1152
|
-
return
|
|
1435
|
+
return t.startsWith("http://") || t.startsWith("https://") ? t : t.startsWith("//") ? window.location.protocol + t : t.startsWith("/") ? this.baseUrl + t : `${this.baseUrl}/${t}`;
|
|
1153
1436
|
} catch {
|
|
1154
|
-
return
|
|
1437
|
+
return t;
|
|
1155
1438
|
}
|
|
1156
1439
|
}
|
|
1157
1440
|
/**
|
|
@@ -1160,25 +1443,25 @@ class J {
|
|
|
1160
1443
|
* @param options Optional loading configuration
|
|
1161
1444
|
* @returns Promise resolving to the resource content
|
|
1162
1445
|
*/
|
|
1163
|
-
async load(
|
|
1164
|
-
const r = this.resolvePath(
|
|
1446
|
+
async load(t, e) {
|
|
1447
|
+
const r = this.resolvePath(t);
|
|
1165
1448
|
try {
|
|
1166
|
-
const
|
|
1167
|
-
credentials:
|
|
1449
|
+
const i = {
|
|
1450
|
+
credentials: e?.credentials || "same-origin"
|
|
1168
1451
|
};
|
|
1169
|
-
|
|
1170
|
-
const
|
|
1171
|
-
|
|
1172
|
-
const n = await fetch(r,
|
|
1452
|
+
e?.headers && (i.headers = e.headers);
|
|
1453
|
+
const s = new AbortController(), o = setTimeout(() => s.abort(), this.defaultTimeout);
|
|
1454
|
+
i.signal = s.signal;
|
|
1455
|
+
const n = await fetch(r, i);
|
|
1173
1456
|
if (clearTimeout(o), !n.ok)
|
|
1174
1457
|
throw new Error(
|
|
1175
1458
|
`HTTP ${n.status}: ${n.statusText} for URL: ${r}`
|
|
1176
1459
|
);
|
|
1177
1460
|
return await n.text();
|
|
1178
|
-
} catch (
|
|
1179
|
-
throw
|
|
1461
|
+
} catch (i) {
|
|
1462
|
+
throw i instanceof Error ? i.name === "AbortError" ? new Error(
|
|
1180
1463
|
`Request timeout after ${this.defaultTimeout}ms for URL: ${r}`
|
|
1181
|
-
) : new Error(`Failed to load resource from ${r}: ${
|
|
1464
|
+
) : new Error(`Failed to load resource from ${r}: ${i.message}`) : new Error(`Failed to load resource from ${r}: Unknown error`);
|
|
1182
1465
|
}
|
|
1183
1466
|
}
|
|
1184
1467
|
/**
|
|
@@ -1187,20 +1470,20 @@ class J {
|
|
|
1187
1470
|
* @param options Optional loading configuration
|
|
1188
1471
|
* @returns Promise resolving to array of load results
|
|
1189
1472
|
*/
|
|
1190
|
-
async loadMultiple(
|
|
1191
|
-
const r =
|
|
1473
|
+
async loadMultiple(t, e) {
|
|
1474
|
+
const r = t.map(async (i) => {
|
|
1192
1475
|
try {
|
|
1193
1476
|
return {
|
|
1194
|
-
data: await this.load(
|
|
1195
|
-
path:
|
|
1477
|
+
data: await this.load(i, e),
|
|
1478
|
+
path: i,
|
|
1196
1479
|
success: !0
|
|
1197
1480
|
};
|
|
1198
|
-
} catch (
|
|
1481
|
+
} catch (s) {
|
|
1199
1482
|
return {
|
|
1200
1483
|
data: "",
|
|
1201
|
-
path:
|
|
1484
|
+
path: i,
|
|
1202
1485
|
success: !1,
|
|
1203
|
-
error:
|
|
1486
|
+
error: s instanceof Error ? s.message : String(s)
|
|
1204
1487
|
};
|
|
1205
1488
|
}
|
|
1206
1489
|
});
|
|
@@ -1211,8 +1494,8 @@ class J {
|
|
|
1211
1494
|
* @param path URL or path to check
|
|
1212
1495
|
* @returns true if the path can be loaded
|
|
1213
1496
|
*/
|
|
1214
|
-
canLoad(
|
|
1215
|
-
const
|
|
1497
|
+
canLoad(t) {
|
|
1498
|
+
const e = [
|
|
1216
1499
|
/^https?:\/\//i,
|
|
1217
1500
|
// Absolute HTTP(S) URLs
|
|
1218
1501
|
/^\/\//,
|
|
@@ -1221,15 +1504,15 @@ class J {
|
|
|
1221
1504
|
// Absolute paths
|
|
1222
1505
|
/^\.\.?\//
|
|
1223
1506
|
// Relative paths starting with ./ or ../
|
|
1224
|
-
], r = /\.[a-z0-9]+$/i.test(
|
|
1225
|
-
return
|
|
1507
|
+
], r = /\.[a-z0-9]+$/i.test(t);
|
|
1508
|
+
return e.some((i) => i.test(t)) || r;
|
|
1226
1509
|
}
|
|
1227
1510
|
/**
|
|
1228
1511
|
* Set a new base URL for resolving relative paths
|
|
1229
1512
|
* @param baseUrl New base URL
|
|
1230
1513
|
*/
|
|
1231
|
-
setBaseUrl(
|
|
1232
|
-
this.baseUrl =
|
|
1514
|
+
setBaseUrl(t) {
|
|
1515
|
+
this.baseUrl = t;
|
|
1233
1516
|
}
|
|
1234
1517
|
/**
|
|
1235
1518
|
* Get the current base URL
|
|
@@ -1242,29 +1525,29 @@ class J {
|
|
|
1242
1525
|
* Set the default request timeout
|
|
1243
1526
|
* @param timeout Timeout in milliseconds
|
|
1244
1527
|
*/
|
|
1245
|
-
setTimeout(
|
|
1246
|
-
this.defaultTimeout =
|
|
1528
|
+
setTimeout(t) {
|
|
1529
|
+
this.defaultTimeout = t;
|
|
1247
1530
|
}
|
|
1248
1531
|
}
|
|
1249
|
-
const
|
|
1532
|
+
const tt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1250
1533
|
__proto__: null,
|
|
1251
1534
|
BrowserResourceLoader: J
|
|
1252
1535
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1253
|
-
class
|
|
1536
|
+
class et {
|
|
1254
1537
|
/**
|
|
1255
1538
|
* Create a new Node.js resource loader
|
|
1256
1539
|
* @param baseDir Optional base directory for resolving relative paths (defaults to current working directory)
|
|
1257
1540
|
*/
|
|
1258
|
-
constructor(
|
|
1259
|
-
this.baseDir =
|
|
1541
|
+
constructor(t = process.cwd()) {
|
|
1542
|
+
this.baseDir = t;
|
|
1260
1543
|
}
|
|
1261
1544
|
/**
|
|
1262
1545
|
* Resolve a relative path against the base directory
|
|
1263
1546
|
* @param filePath Relative or absolute file path
|
|
1264
1547
|
* @returns Resolved absolute file path
|
|
1265
1548
|
*/
|
|
1266
|
-
resolvePath(
|
|
1267
|
-
return
|
|
1549
|
+
resolvePath(t) {
|
|
1550
|
+
return C.isAbsolute(t) ? C.normalize(t) : C.normalize(C.join(this.baseDir, t));
|
|
1268
1551
|
}
|
|
1269
1552
|
/**
|
|
1270
1553
|
* Load a single resource from a file
|
|
@@ -1272,21 +1555,21 @@ class ee {
|
|
|
1272
1555
|
* @param options Optional loading configuration
|
|
1273
1556
|
* @returns Promise resolving to the file content
|
|
1274
1557
|
*/
|
|
1275
|
-
async load(
|
|
1276
|
-
const r = this.resolvePath(
|
|
1558
|
+
async load(t, e) {
|
|
1559
|
+
const r = this.resolvePath(t), i = e?.encoding || "utf-8";
|
|
1277
1560
|
try {
|
|
1278
|
-
return await p.readFile(r,
|
|
1279
|
-
} catch (
|
|
1280
|
-
if (
|
|
1281
|
-
const o =
|
|
1561
|
+
return await p.readFile(r, i);
|
|
1562
|
+
} catch (s) {
|
|
1563
|
+
if (s instanceof Error) {
|
|
1564
|
+
const o = s.code;
|
|
1282
1565
|
throw o === "ENOENT" ? new Error(
|
|
1283
|
-
`File not found: ${r} (resolved from: ${
|
|
1566
|
+
`File not found: ${r} (resolved from: ${t})`
|
|
1284
1567
|
) : o === "EACCES" ? new Error(
|
|
1285
1568
|
`Permission denied reading file: ${r}`
|
|
1286
1569
|
) : o === "EISDIR" ? new Error(
|
|
1287
1570
|
`Path is a directory, not a file: ${r}`
|
|
1288
1571
|
) : new Error(
|
|
1289
|
-
`Failed to load resource from ${r}: ${
|
|
1572
|
+
`Failed to load resource from ${r}: ${s.message}`
|
|
1290
1573
|
);
|
|
1291
1574
|
}
|
|
1292
1575
|
throw new Error(
|
|
@@ -1300,20 +1583,20 @@ class ee {
|
|
|
1300
1583
|
* @param options Optional loading configuration
|
|
1301
1584
|
* @returns Promise resolving to array of load results
|
|
1302
1585
|
*/
|
|
1303
|
-
async loadMultiple(
|
|
1304
|
-
const r =
|
|
1586
|
+
async loadMultiple(t, e) {
|
|
1587
|
+
const r = t.map(async (i) => {
|
|
1305
1588
|
try {
|
|
1306
1589
|
return {
|
|
1307
|
-
data: await this.load(
|
|
1308
|
-
path:
|
|
1590
|
+
data: await this.load(i, e),
|
|
1591
|
+
path: i,
|
|
1309
1592
|
success: !0
|
|
1310
1593
|
};
|
|
1311
|
-
} catch (
|
|
1594
|
+
} catch (s) {
|
|
1312
1595
|
return {
|
|
1313
1596
|
data: "",
|
|
1314
|
-
path:
|
|
1597
|
+
path: i,
|
|
1315
1598
|
success: !1,
|
|
1316
|
-
error:
|
|
1599
|
+
error: s instanceof Error ? s.message : String(s)
|
|
1317
1600
|
};
|
|
1318
1601
|
}
|
|
1319
1602
|
});
|
|
@@ -1324,7 +1607,7 @@ class ee {
|
|
|
1324
1607
|
* @param filePath File path to check
|
|
1325
1608
|
* @returns true if the path can be loaded
|
|
1326
1609
|
*/
|
|
1327
|
-
canLoad(
|
|
1610
|
+
canLoad(t) {
|
|
1328
1611
|
return [
|
|
1329
1612
|
/^\//,
|
|
1330
1613
|
// Unix absolute paths
|
|
@@ -1334,17 +1617,17 @@ class ee {
|
|
|
1334
1617
|
// Relative paths starting with ./ or ../
|
|
1335
1618
|
/^[^/\\]+\//
|
|
1336
1619
|
// Relative paths without explicit prefix (e.g., "shaders/")
|
|
1337
|
-
].some((r) => r.test(
|
|
1620
|
+
].some((r) => r.test(t));
|
|
1338
1621
|
}
|
|
1339
1622
|
/**
|
|
1340
1623
|
* Check if a file exists without loading it
|
|
1341
1624
|
* @param filePath File path to check
|
|
1342
1625
|
* @returns Promise resolving to true if file exists
|
|
1343
1626
|
*/
|
|
1344
|
-
async exists(
|
|
1345
|
-
const
|
|
1627
|
+
async exists(t) {
|
|
1628
|
+
const e = this.resolvePath(t);
|
|
1346
1629
|
try {
|
|
1347
|
-
return await p.access(
|
|
1630
|
+
return await p.access(e, p.constants.F_OK), !0;
|
|
1348
1631
|
} catch {
|
|
1349
1632
|
return !1;
|
|
1350
1633
|
}
|
|
@@ -1354,16 +1637,16 @@ class ee {
|
|
|
1354
1637
|
* @param filePath File path to check
|
|
1355
1638
|
* @returns Promise resolving to file stats
|
|
1356
1639
|
*/
|
|
1357
|
-
async getStats(
|
|
1358
|
-
const
|
|
1359
|
-
return p.stat(
|
|
1640
|
+
async getStats(t) {
|
|
1641
|
+
const e = this.resolvePath(t);
|
|
1642
|
+
return p.stat(e);
|
|
1360
1643
|
}
|
|
1361
1644
|
/**
|
|
1362
1645
|
* Set a new base directory for resolving relative paths
|
|
1363
1646
|
* @param baseDir New base directory
|
|
1364
1647
|
*/
|
|
1365
|
-
setBaseDir(
|
|
1366
|
-
this.baseDir =
|
|
1648
|
+
setBaseDir(t) {
|
|
1649
|
+
this.baseDir = t;
|
|
1367
1650
|
}
|
|
1368
1651
|
/**
|
|
1369
1652
|
* Get the current base directory
|
|
@@ -1378,24 +1661,24 @@ class ee {
|
|
|
1378
1661
|
* @param recursive Whether to recursively list subdirectories (default: false)
|
|
1379
1662
|
* @returns Promise resolving to array of file paths
|
|
1380
1663
|
*/
|
|
1381
|
-
async listDirectory(
|
|
1382
|
-
const r = this.resolvePath(
|
|
1383
|
-
for (const o of
|
|
1384
|
-
const n =
|
|
1385
|
-
if (o.isDirectory() &&
|
|
1664
|
+
async listDirectory(t, e = !1) {
|
|
1665
|
+
const r = this.resolvePath(t), i = await p.readdir(r, { withFileTypes: !0 }), s = [];
|
|
1666
|
+
for (const o of i) {
|
|
1667
|
+
const n = C.join(r, o.name);
|
|
1668
|
+
if (o.isDirectory() && e) {
|
|
1386
1669
|
const a = await this.listDirectory(n, !0);
|
|
1387
|
-
|
|
1388
|
-
} else o.isFile() &&
|
|
1670
|
+
s.push(...a);
|
|
1671
|
+
} else o.isFile() && s.push(n);
|
|
1389
1672
|
}
|
|
1390
|
-
return
|
|
1673
|
+
return s;
|
|
1391
1674
|
}
|
|
1392
1675
|
}
|
|
1393
|
-
const
|
|
1676
|
+
const rt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1394
1677
|
__proto__: null,
|
|
1395
|
-
NodeResourceLoader:
|
|
1678
|
+
NodeResourceLoader: et
|
|
1396
1679
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1397
1680
|
var I = /* @__PURE__ */ ((c) => (c.BROWSER = "browser", c.NODE = "node", c.UNKNOWN = "unknown", c))(I || {});
|
|
1398
|
-
class
|
|
1681
|
+
class Y {
|
|
1399
1682
|
/**
|
|
1400
1683
|
* Detect the current runtime environment
|
|
1401
1684
|
* @returns The detected environment type
|
|
@@ -1423,19 +1706,19 @@ class N {
|
|
|
1423
1706
|
* @returns A resource loader instance appropriate for the current platform
|
|
1424
1707
|
* @throws Error if the environment is not supported
|
|
1425
1708
|
*/
|
|
1426
|
-
static async create(
|
|
1427
|
-
const
|
|
1428
|
-
switch (
|
|
1709
|
+
static async create(t) {
|
|
1710
|
+
const e = t?.forceEnvironment || this.detectEnvironment();
|
|
1711
|
+
switch (e) {
|
|
1429
1712
|
case "browser":
|
|
1430
|
-
return await this.createBrowserLoader(
|
|
1713
|
+
return await this.createBrowserLoader(t);
|
|
1431
1714
|
case "node":
|
|
1432
|
-
return await this.createNodeLoader(
|
|
1715
|
+
return await this.createNodeLoader(t);
|
|
1433
1716
|
case "unknown":
|
|
1434
1717
|
throw new Error(
|
|
1435
1718
|
"Unsupported environment: Unable to determine runtime environment. Please specify forceEnvironment in options."
|
|
1436
1719
|
);
|
|
1437
1720
|
default:
|
|
1438
|
-
throw new Error(`Unsupported environment: ${
|
|
1721
|
+
throw new Error(`Unsupported environment: ${e}`);
|
|
1439
1722
|
}
|
|
1440
1723
|
}
|
|
1441
1724
|
/**
|
|
@@ -1443,18 +1726,18 @@ class N {
|
|
|
1443
1726
|
* @param options Optional factory configuration
|
|
1444
1727
|
* @returns A browser resource loader instance
|
|
1445
1728
|
*/
|
|
1446
|
-
static async createBrowserLoader(
|
|
1447
|
-
const { BrowserResourceLoader:
|
|
1448
|
-
return new t
|
|
1729
|
+
static async createBrowserLoader(t) {
|
|
1730
|
+
const { BrowserResourceLoader: e } = await Promise.resolve().then(() => tt);
|
|
1731
|
+
return new e(t?.baseUrl, t?.timeout);
|
|
1449
1732
|
}
|
|
1450
1733
|
/**
|
|
1451
1734
|
* Create a Node.js resource loader
|
|
1452
1735
|
* @param options Optional factory configuration
|
|
1453
1736
|
* @returns A Node.js resource loader instance
|
|
1454
1737
|
*/
|
|
1455
|
-
static async createNodeLoader(
|
|
1456
|
-
const { NodeResourceLoader:
|
|
1457
|
-
return new t
|
|
1738
|
+
static async createNodeLoader(t) {
|
|
1739
|
+
const { NodeResourceLoader: e } = await Promise.resolve().then(() => rt);
|
|
1740
|
+
return new e(t?.baseDir);
|
|
1458
1741
|
}
|
|
1459
1742
|
/**
|
|
1460
1743
|
* Create a resource loader with automatic fallback
|
|
@@ -1463,36 +1746,36 @@ class N {
|
|
|
1463
1746
|
* @param options Optional factory configuration
|
|
1464
1747
|
* @returns A resource loader instance
|
|
1465
1748
|
*/
|
|
1466
|
-
static async createWithFallback(
|
|
1749
|
+
static async createWithFallback(t, e) {
|
|
1467
1750
|
try {
|
|
1468
|
-
return
|
|
1751
|
+
return e = { ...e, forceEnvironment: t }, await this.create(e);
|
|
1469
1752
|
} catch {
|
|
1470
|
-
return await this.create({ ...
|
|
1753
|
+
return await this.create({ ...e, forceEnvironment: void 0 });
|
|
1471
1754
|
}
|
|
1472
1755
|
}
|
|
1473
1756
|
}
|
|
1474
|
-
async function
|
|
1475
|
-
return await
|
|
1757
|
+
async function it(c) {
|
|
1758
|
+
return await Y.create(c);
|
|
1476
1759
|
}
|
|
1477
|
-
const
|
|
1760
|
+
const st = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1478
1761
|
__proto__: null,
|
|
1479
1762
|
Environment: I,
|
|
1480
|
-
ResourceLoaderFactory:
|
|
1481
|
-
createResourceLoader:
|
|
1763
|
+
ResourceLoaderFactory: Y,
|
|
1764
|
+
createResourceLoader: it
|
|
1482
1765
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1483
|
-
class
|
|
1484
|
-
constructor(
|
|
1485
|
-
this.cache = /* @__PURE__ */ new Map(), this.enabled =
|
|
1766
|
+
class ot {
|
|
1767
|
+
constructor(t = !0) {
|
|
1768
|
+
this.cache = /* @__PURE__ */ new Map(), this.enabled = t;
|
|
1486
1769
|
}
|
|
1487
|
-
get(
|
|
1770
|
+
get(t) {
|
|
1488
1771
|
if (this.enabled)
|
|
1489
|
-
return this.cache.get(
|
|
1772
|
+
return this.cache.get(t);
|
|
1490
1773
|
}
|
|
1491
|
-
set(
|
|
1492
|
-
this.enabled && this.cache.set(
|
|
1774
|
+
set(t, e) {
|
|
1775
|
+
this.enabled && this.cache.set(t, e);
|
|
1493
1776
|
}
|
|
1494
|
-
has(
|
|
1495
|
-
return this.enabled ? this.cache.has(
|
|
1777
|
+
has(t) {
|
|
1778
|
+
return this.enabled ? this.cache.has(t) : !1;
|
|
1496
1779
|
}
|
|
1497
1780
|
clear() {
|
|
1498
1781
|
this.cache.clear();
|
|
@@ -1507,14 +1790,14 @@ class ie {
|
|
|
1507
1790
|
this.enabled = !1;
|
|
1508
1791
|
}
|
|
1509
1792
|
}
|
|
1510
|
-
class
|
|
1793
|
+
class nt {
|
|
1511
1794
|
/**
|
|
1512
1795
|
* Create a new resource loading pipeline
|
|
1513
1796
|
* @param loader Resource loader instance
|
|
1514
1797
|
* @param options Pipeline configuration options
|
|
1515
1798
|
*/
|
|
1516
|
-
constructor(
|
|
1517
|
-
this.loader =
|
|
1799
|
+
constructor(t, e) {
|
|
1800
|
+
this.loader = t, this.concurrency = e?.concurrency ?? 10, this.cache = new ot(e?.cache ?? !0);
|
|
1518
1801
|
}
|
|
1519
1802
|
/**
|
|
1520
1803
|
* Load a single resource with caching support
|
|
@@ -1522,12 +1805,12 @@ class oe {
|
|
|
1522
1805
|
* @param options Optional loading options
|
|
1523
1806
|
* @returns Promise resolving to the resource content
|
|
1524
1807
|
*/
|
|
1525
|
-
async load(
|
|
1526
|
-
const r = this.cache.get(
|
|
1808
|
+
async load(t, e) {
|
|
1809
|
+
const r = this.cache.get(t);
|
|
1527
1810
|
if (r !== void 0)
|
|
1528
1811
|
return r;
|
|
1529
|
-
const
|
|
1530
|
-
return this.cache.set(
|
|
1812
|
+
const i = await this.loader.load(t, e);
|
|
1813
|
+
return this.cache.set(t, i), i;
|
|
1531
1814
|
}
|
|
1532
1815
|
/**
|
|
1533
1816
|
* Load multiple resources with concurrency control
|
|
@@ -1535,19 +1818,19 @@ class oe {
|
|
|
1535
1818
|
* @param options Optional loading options
|
|
1536
1819
|
* @returns Promise resolving to batch load result
|
|
1537
1820
|
*/
|
|
1538
|
-
async loadBatch(
|
|
1539
|
-
const r = /* @__PURE__ */ new Map(),
|
|
1540
|
-
for (let
|
|
1541
|
-
const o =
|
|
1821
|
+
async loadBatch(t, e) {
|
|
1822
|
+
const r = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map();
|
|
1823
|
+
for (let s = 0; s < t.length; s += this.concurrency) {
|
|
1824
|
+
const o = t.slice(s, s + this.concurrency), n = await this.loader.loadMultiple(o, e);
|
|
1542
1825
|
for (const a of n)
|
|
1543
|
-
a.success ? (r.set(a.path, a.data), this.cache.set(a.path, a.data)) :
|
|
1826
|
+
a.success ? (r.set(a.path, a.data), this.cache.set(a.path, a.data)) : i.set(a.path, a.error || "Unknown error");
|
|
1544
1827
|
}
|
|
1545
1828
|
return {
|
|
1546
1829
|
succeeded: r,
|
|
1547
|
-
failed:
|
|
1548
|
-
total:
|
|
1830
|
+
failed: i,
|
|
1831
|
+
total: t.length,
|
|
1549
1832
|
successCount: r.size,
|
|
1550
|
-
failureCount:
|
|
1833
|
+
failureCount: i.size
|
|
1551
1834
|
};
|
|
1552
1835
|
}
|
|
1553
1836
|
/**
|
|
@@ -1557,12 +1840,12 @@ class oe {
|
|
|
1557
1840
|
* @param options Optional loading options
|
|
1558
1841
|
* @returns Promise resolving to shader source code
|
|
1559
1842
|
*/
|
|
1560
|
-
async loadShader(
|
|
1561
|
-
const [
|
|
1562
|
-
this.load(
|
|
1563
|
-
this.load(
|
|
1843
|
+
async loadShader(t, e, r) {
|
|
1844
|
+
const [i, s] = await Promise.all([
|
|
1845
|
+
this.load(t, r),
|
|
1846
|
+
this.load(e, r)
|
|
1564
1847
|
]);
|
|
1565
|
-
return { vertex:
|
|
1848
|
+
return { vertex: i, fragment: s };
|
|
1566
1849
|
}
|
|
1567
1850
|
/**
|
|
1568
1851
|
* Load multiple shaders
|
|
@@ -1570,17 +1853,17 @@ class oe {
|
|
|
1570
1853
|
* @param options Optional loading options
|
|
1571
1854
|
* @returns Promise resolving to array of named shader sources
|
|
1572
1855
|
*/
|
|
1573
|
-
async loadShaders(
|
|
1856
|
+
async loadShaders(t, e) {
|
|
1574
1857
|
return await Promise.all(
|
|
1575
|
-
|
|
1576
|
-
const
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1858
|
+
t.map(async (i) => {
|
|
1859
|
+
const s = await this.loadShader(
|
|
1860
|
+
i.vertex,
|
|
1861
|
+
i.fragment,
|
|
1862
|
+
e
|
|
1580
1863
|
);
|
|
1581
1864
|
return {
|
|
1582
|
-
name:
|
|
1583
|
-
...
|
|
1865
|
+
name: i.name,
|
|
1866
|
+
...s
|
|
1584
1867
|
};
|
|
1585
1868
|
})
|
|
1586
1869
|
);
|
|
@@ -1591,9 +1874,9 @@ class oe {
|
|
|
1591
1874
|
* @param options Optional loading options
|
|
1592
1875
|
* @returns Promise resolving to batch load result
|
|
1593
1876
|
*/
|
|
1594
|
-
async loadFromManifest(
|
|
1595
|
-
const r = await this.load(
|
|
1596
|
-
return this.loadBatch(
|
|
1877
|
+
async loadFromManifest(t, e) {
|
|
1878
|
+
const r = await this.load(t, e), i = JSON.parse(r);
|
|
1879
|
+
return this.loadBatch(i.resources, e);
|
|
1597
1880
|
}
|
|
1598
1881
|
/**
|
|
1599
1882
|
* Preload resources for faster access later
|
|
@@ -1601,24 +1884,24 @@ class oe {
|
|
|
1601
1884
|
* @param options Optional loading options
|
|
1602
1885
|
* @returns Promise resolving when all resources are loaded
|
|
1603
1886
|
*/
|
|
1604
|
-
async preload(
|
|
1605
|
-
await this.loadBatch(
|
|
1887
|
+
async preload(t, e) {
|
|
1888
|
+
await this.loadBatch(t, e);
|
|
1606
1889
|
}
|
|
1607
1890
|
/**
|
|
1608
1891
|
* Check if a resource is cached
|
|
1609
1892
|
* @param path Resource path
|
|
1610
1893
|
* @returns true if the resource is in the cache
|
|
1611
1894
|
*/
|
|
1612
|
-
isCached(
|
|
1613
|
-
return this.cache.has(
|
|
1895
|
+
isCached(t) {
|
|
1896
|
+
return this.cache.has(t);
|
|
1614
1897
|
}
|
|
1615
1898
|
/**
|
|
1616
1899
|
* Get a resource from cache without loading
|
|
1617
1900
|
* @param path Resource path
|
|
1618
1901
|
* @returns Cached content or undefined if not cached
|
|
1619
1902
|
*/
|
|
1620
|
-
getCached(
|
|
1621
|
-
return this.cache.get(
|
|
1903
|
+
getCached(t) {
|
|
1904
|
+
return this.cache.get(t);
|
|
1622
1905
|
}
|
|
1623
1906
|
/**
|
|
1624
1907
|
* Clear the resource cache
|
|
@@ -1649,8 +1932,8 @@ class oe {
|
|
|
1649
1932
|
* Set the maximum concurrency for batch operations
|
|
1650
1933
|
* @param concurrency Maximum concurrent loads
|
|
1651
1934
|
*/
|
|
1652
|
-
setConcurrency(
|
|
1653
|
-
this.concurrency = Math.max(1,
|
|
1935
|
+
setConcurrency(t) {
|
|
1936
|
+
this.concurrency = Math.max(1, t);
|
|
1654
1937
|
}
|
|
1655
1938
|
/**
|
|
1656
1939
|
* Get the underlying resource loader
|
|
@@ -1660,18 +1943,18 @@ class oe {
|
|
|
1660
1943
|
return this.loader;
|
|
1661
1944
|
}
|
|
1662
1945
|
}
|
|
1663
|
-
async function
|
|
1664
|
-
const { ResourceLoaderFactory:
|
|
1946
|
+
async function at(c) {
|
|
1947
|
+
const { ResourceLoaderFactory: t } = await Promise.resolve().then(() => st), e = await t.create({
|
|
1665
1948
|
baseUrl: c?.baseUrl,
|
|
1666
1949
|
baseDir: c?.baseDir,
|
|
1667
1950
|
timeout: c?.timeout
|
|
1668
1951
|
});
|
|
1669
|
-
return new
|
|
1952
|
+
return new nt(e, c);
|
|
1670
1953
|
}
|
|
1671
|
-
const
|
|
1954
|
+
const P = {
|
|
1672
1955
|
width: 800,
|
|
1673
1956
|
height: 600
|
|
1674
|
-
},
|
|
1957
|
+
}, U = {
|
|
1675
1958
|
quad: {
|
|
1676
1959
|
vertices: new Float32Array([
|
|
1677
1960
|
// Position TexCoord
|
|
@@ -1738,17 +2021,17 @@ const L = {
|
|
|
1738
2021
|
"resources/shaders/glow.frag"
|
|
1739
2022
|
]
|
|
1740
2023
|
};
|
|
1741
|
-
async function
|
|
2024
|
+
async function bt() {
|
|
1742
2025
|
console.log("🩸 Bloody Engine - Resource Loader Demo"), console.log(`==========================================
|
|
1743
2026
|
`);
|
|
1744
|
-
const c =
|
|
2027
|
+
const c = Y.detectEnvironment();
|
|
1745
2028
|
if (console.log(`✓ Environment detected: ${c}`), c !== I.BROWSER) {
|
|
1746
2029
|
console.warn("⚠ This demo is designed for browser environment");
|
|
1747
2030
|
return;
|
|
1748
2031
|
}
|
|
1749
2032
|
console.log(`
|
|
1750
2033
|
1. Creating Resource Pipeline...`);
|
|
1751
|
-
const
|
|
2034
|
+
const t = await at({
|
|
1752
2035
|
concurrency: 5,
|
|
1753
2036
|
cache: !0,
|
|
1754
2037
|
timeout: 1e4,
|
|
@@ -1756,35 +2039,35 @@ async function ge() {
|
|
|
1756
2039
|
});
|
|
1757
2040
|
console.log("✓ Resource pipeline created"), console.log(" - Concurrency: 5"), console.log(" - Caching: enabled"), console.log(`
|
|
1758
2041
|
2. Batch Loading Resources...`), console.log(`Loading ${M.resources.length} resources...`);
|
|
1759
|
-
const
|
|
1760
|
-
if (console.log("✓ Batch loading complete"), console.log(` - Succeeded: ${
|
|
2042
|
+
const e = await t.loadBatch(M.resources);
|
|
2043
|
+
if (console.log("✓ Batch loading complete"), console.log(` - Succeeded: ${e.successCount}`), console.log(` - Failed: ${e.failureCount}`), e.failureCount > 0) {
|
|
1761
2044
|
console.log(`
|
|
1762
2045
|
❌ Failed resources:`);
|
|
1763
|
-
for (const [
|
|
1764
|
-
console.log(` - ${
|
|
2046
|
+
for (const [v, T] of e.failed)
|
|
2047
|
+
console.log(` - ${v}: ${T}`);
|
|
1765
2048
|
console.log(`
|
|
1766
2049
|
⚠️ Falling back to inline shaders...`);
|
|
1767
2050
|
}
|
|
1768
2051
|
console.log(`
|
|
1769
2052
|
3. Loading Shaders...`);
|
|
1770
|
-
const r = await
|
|
2053
|
+
const r = await t.loadShaders(M.shaders);
|
|
1771
2054
|
console.log(`✓ Loaded ${r.length} shaders:`);
|
|
1772
|
-
for (const
|
|
1773
|
-
console.log(` - ${
|
|
2055
|
+
for (const v of r)
|
|
2056
|
+
console.log(` - ${v.name}:`), console.log(` Vertex: ${v.vertex.length} chars`), console.log(` Fragment: ${v.fragment.length} chars`);
|
|
1774
2057
|
console.log(`
|
|
1775
2058
|
4. Testing Cache...`);
|
|
1776
|
-
const
|
|
1777
|
-
console.log(`✓ Cache contains ${
|
|
1778
|
-
for (const
|
|
1779
|
-
const
|
|
1780
|
-
console.log(` - ${
|
|
2059
|
+
const i = t.getCacheSize();
|
|
2060
|
+
console.log(`✓ Cache contains ${i} resources`);
|
|
2061
|
+
for (const v of M.shaders) {
|
|
2062
|
+
const T = t.isCached(v.vertex), z = t.isCached(v.fragment);
|
|
2063
|
+
console.log(` - ${v.name}:`), console.log(` Vertex cached: ${T}`), console.log(` Fragment cached: ${z}`);
|
|
1781
2064
|
}
|
|
1782
2065
|
console.log(`
|
|
1783
2066
|
5. Initializing Graphics Device...`);
|
|
1784
|
-
const
|
|
1785
|
-
console.log("✓ Graphics device initialized"), console.log(` - Resolution: ${
|
|
2067
|
+
const s = new k(P.width, P.height), o = s.getGLContext();
|
|
2068
|
+
console.log("✓ Graphics device initialized"), console.log(` - Resolution: ${P.width}x${P.height}`), console.log(`
|
|
1786
2069
|
6. Creating Shader from Loaded Source...`);
|
|
1787
|
-
let n = r.find((
|
|
2070
|
+
let n = r.find((v) => v.name === "glow");
|
|
1788
2071
|
(!n || !n.vertex || !n.fragment) && (console.warn("⚠️ Glow shader not loaded or empty, using inline fallback"), n = {
|
|
1789
2072
|
name: "glow",
|
|
1790
2073
|
vertex: `attribute vec3 aPosition;
|
|
@@ -1817,77 +2100,77 @@ void main() {
|
|
|
1817
2100
|
gl_FragColor = vec4(glowColor, texColor.a);
|
|
1818
2101
|
}`
|
|
1819
2102
|
});
|
|
1820
|
-
const a =
|
|
2103
|
+
const a = s.createShader(n.vertex, n.fragment);
|
|
1821
2104
|
console.log("✓ Shader compiled from loaded source code"), console.log(" - Vertex shader: compiled"), console.log(" - Fragment shader: compiled"), console.log(" - Program: linked"), console.log(`
|
|
1822
2105
|
7. Creating Texture...`);
|
|
1823
|
-
const h =
|
|
2106
|
+
const h = _.createGradient(
|
|
1824
2107
|
o,
|
|
1825
2108
|
S.size,
|
|
1826
2109
|
S.size
|
|
1827
2110
|
);
|
|
1828
2111
|
console.log("✓ Gradient texture created"), console.log(` - Size: ${S.size}x${S.size}`), console.log(`
|
|
1829
2112
|
8. Creating Geometry Buffers...`);
|
|
1830
|
-
const { VertexBuffer:
|
|
2113
|
+
const { VertexBuffer: g } = await Promise.resolve().then(() => Z), l = new g(
|
|
1831
2114
|
o,
|
|
1832
|
-
|
|
1833
|
-
|
|
2115
|
+
U.quad.vertices,
|
|
2116
|
+
U.quad.stride
|
|
1834
2117
|
);
|
|
1835
2118
|
console.log("✓ Quad buffer created"), console.log(` - Vertices: ${l.getVertexCount()}`), console.log(`
|
|
1836
2119
|
9. Setting up Rendering...`), a.use();
|
|
1837
|
-
const
|
|
1838
|
-
l.bind(), o.enableVertexAttribArray(
|
|
1839
|
-
|
|
2120
|
+
const f = a.getAttributeLocation("aPosition"), d = a.getAttributeLocation("aTexCoord"), A = a.getUniformLocation("uTexture"), x = a.getUniformLocation("uMatrix"), w = a.getUniformLocation("uColor"), y = a.getUniformLocation("uGlowIntensity");
|
|
2121
|
+
l.bind(), o.enableVertexAttribArray(f), o.vertexAttribPointer(f, 3, o.FLOAT, !1, U.quad.stride, 0), o.enableVertexAttribArray(d), o.vertexAttribPointer(
|
|
2122
|
+
d,
|
|
1840
2123
|
2,
|
|
1841
2124
|
o.FLOAT,
|
|
1842
2125
|
!1,
|
|
1843
|
-
|
|
2126
|
+
U.quad.stride,
|
|
1844
2127
|
12
|
|
1845
|
-
), console.log("✓ Vertex attributes configured"), h.bind(0), o.uniform1i(
|
|
1846
|
-
const u =
|
|
2128
|
+
), console.log("✓ Vertex attributes configured"), h.bind(0), o.uniform1i(A, 0), console.log("✓ Texture bound to unit 0");
|
|
2129
|
+
const u = s.getRenderingContext().canvas;
|
|
1847
2130
|
u && (u.style.display = "block", u.style.margin = "0 auto", u.style.border = "2px solid #333", u.style.backgroundColor = "#1a1a1a"), document.body.style.margin = "0", document.body.style.padding = "20px", document.body.style.backgroundColor = "#0a0a0a", document.body.style.fontFamily = "monospace", document.body.style.color = "#aaa";
|
|
1848
|
-
const
|
|
1849
|
-
|
|
2131
|
+
const m = document.createElement("h1");
|
|
2132
|
+
m.textContent = "🩸 Resource Loader Demo", m.style.textAlign = "center", m.style.color = "#fff", u && u.parentNode ? u.parentNode.insertBefore(m, u) : document.body.insertBefore(m, document.body.firstChild);
|
|
1850
2133
|
const b = document.createElement("div");
|
|
1851
2134
|
b.style.textAlign = "center", b.style.marginTop = "10px", b.style.fontSize = "12px", b.innerHTML = `
|
|
1852
2135
|
<div>Environment: <strong>${c}</strong></div>
|
|
1853
2136
|
<div>Shaders loaded: <strong>${r.length}</strong></div>
|
|
1854
|
-
<div>Cached resources: <strong>${
|
|
2137
|
+
<div>Cached resources: <strong>${i}</strong></div>
|
|
1855
2138
|
`, document.body.appendChild(b);
|
|
1856
|
-
let
|
|
1857
|
-
const
|
|
1858
|
-
function
|
|
1859
|
-
const
|
|
1860
|
-
|
|
1861
|
-
const
|
|
2139
|
+
let R = 0;
|
|
2140
|
+
const B = Date.now();
|
|
2141
|
+
function L() {
|
|
2142
|
+
const v = Date.now(), T = (v - B) / 1e3;
|
|
2143
|
+
s.clear({ r: 0.1, g: 0.1, b: 0.1, a: 1 });
|
|
2144
|
+
const z = [
|
|
1862
2145
|
{ x: -0.3, y: 0.3, color: [1, 0.2, 0.2], glow: 1.5 },
|
|
1863
2146
|
{ x: 0.3, y: 0.3, color: [0.2, 1, 0.2], glow: 1.8 },
|
|
1864
2147
|
{ x: -0.3, y: -0.3, color: [0.2, 0.5, 1], glow: 2 },
|
|
1865
2148
|
{ x: 0.3, y: -0.3, color: [1, 1, 0.2], glow: 1.6 }
|
|
1866
2149
|
];
|
|
1867
|
-
for (const
|
|
1868
|
-
const
|
|
1869
|
-
if (
|
|
2150
|
+
for (const F of z) {
|
|
2151
|
+
const $ = ht();
|
|
2152
|
+
if (ct($, F.x, F.y, 0), lt($, 0.4, 0.4, 1), x && o.uniformMatrix4fv(x, !1, $), w && o.uniform3f(
|
|
1870
2153
|
w,
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
),
|
|
1875
|
-
const
|
|
1876
|
-
o.uniform1f(
|
|
2154
|
+
F.color[0],
|
|
2155
|
+
F.color[1],
|
|
2156
|
+
F.color[2]
|
|
2157
|
+
), y) {
|
|
2158
|
+
const G = F.glow + Math.sin(T * 2) * 0.3;
|
|
2159
|
+
o.uniform1f(y, G);
|
|
1877
2160
|
}
|
|
1878
2161
|
o.drawArrays(o.TRIANGLES, 0, l.getVertexCount());
|
|
1879
2162
|
}
|
|
1880
|
-
|
|
1881
|
-
const V = (
|
|
2163
|
+
s.present(), R++;
|
|
2164
|
+
const V = (v - B) / 1e3, N = R / V;
|
|
1882
2165
|
b.innerHTML = `
|
|
1883
|
-
<div>FPS: <strong>${
|
|
1884
|
-
<div>Environment: <strong>${c}</strong> | Shaders loaded: <strong>${r.length}</strong> | Cached: <strong>${
|
|
1885
|
-
`, requestAnimationFrame(
|
|
2166
|
+
<div>FPS: <strong>${N.toFixed(1)}</strong> | Frame: <strong>${R}</strong> | Elapsed: <strong>${V.toFixed(2)}s</strong></div>
|
|
2167
|
+
<div>Environment: <strong>${c}</strong> | Shaders loaded: <strong>${r.length}</strong> | Cached: <strong>${i}</strong></div>
|
|
2168
|
+
`, requestAnimationFrame(L);
|
|
1886
2169
|
}
|
|
1887
2170
|
console.log(`
|
|
1888
|
-
✓ Demo started! Rendering animation...`),
|
|
2171
|
+
✓ Demo started! Rendering animation...`), L();
|
|
1889
2172
|
}
|
|
1890
|
-
function
|
|
2173
|
+
function ht() {
|
|
1891
2174
|
return new Float32Array([
|
|
1892
2175
|
1,
|
|
1893
2176
|
0,
|
|
@@ -1907,31 +2190,34 @@ function ae() {
|
|
|
1907
2190
|
1
|
|
1908
2191
|
]);
|
|
1909
2192
|
}
|
|
1910
|
-
function
|
|
1911
|
-
c[12] +=
|
|
2193
|
+
function ct(c, t, e, r) {
|
|
2194
|
+
c[12] += t, c[13] += e, c[14] += r;
|
|
1912
2195
|
}
|
|
1913
|
-
function
|
|
1914
|
-
c[0] *=
|
|
2196
|
+
function lt(c, t, e, r) {
|
|
2197
|
+
c[0] *= t, c[5] *= e, c[10] *= r;
|
|
1915
2198
|
}
|
|
1916
2199
|
export {
|
|
1917
|
-
|
|
1918
|
-
|
|
2200
|
+
gt as BatchRenderer,
|
|
2201
|
+
O as BrowserRenderingContext,
|
|
1919
2202
|
J as BrowserResourceLoader,
|
|
1920
|
-
|
|
2203
|
+
vt as Camera,
|
|
1921
2204
|
I as Environment,
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
2205
|
+
wt as GPUBasedSpriteBatchRenderer,
|
|
2206
|
+
k as GraphicsDevice,
|
|
2207
|
+
K as IndexBuffer,
|
|
2208
|
+
D as Matrix4,
|
|
2209
|
+
q as NodeRenderingContext,
|
|
2210
|
+
et as NodeResourceLoader,
|
|
2211
|
+
mt as ProjectionConfig,
|
|
2212
|
+
X as RenderingContextFactory,
|
|
2213
|
+
Y as ResourceLoaderFactory,
|
|
2214
|
+
nt as ResourcePipeline,
|
|
2215
|
+
ft as SDLWindow,
|
|
1930
2216
|
H as Shader,
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
2217
|
+
xt as SpriteBatchRenderer,
|
|
2218
|
+
_ as Texture,
|
|
2219
|
+
j as VertexBuffer,
|
|
2220
|
+
it as createResourceLoader,
|
|
2221
|
+
at as createResourcePipeline,
|
|
2222
|
+
bt as runBrowserResourceLoaderDemo
|
|
1937
2223
|
};
|