emeraldengine 2.2.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2359 -968
- package/dist/types/index.d.ts +72 -32
- package/dist/types/src/Animator.d.ts +50 -0
- package/dist/types/{BitmapText.d.ts → src/BitmapText.d.ts} +19 -21
- package/dist/types/src/Camera.d.ts +122 -0
- package/dist/types/src/CameraController.d.ts +107 -0
- package/dist/types/src/CanvasText.d.ts +91 -0
- package/dist/types/src/CollisionLayers.d.ts +58 -0
- package/dist/types/{Color.d.ts → src/Color.d.ts} +5 -6
- package/dist/types/src/Coroutine.d.ts +111 -0
- package/dist/types/src/DebugOverlay.d.ts +86 -0
- package/dist/types/src/Drawable.d.ts +271 -0
- package/dist/types/src/Easing.d.ts +22 -0
- package/dist/types/src/Emerald.d.ts +420 -0
- package/dist/types/src/EmeraldDB.d.ts +159 -0
- package/dist/types/{FPSCounter.d.ts → src/FPSCounter.d.ts} +1 -3
- package/dist/types/src/GLUtils.d.ts +4 -0
- package/dist/types/{Instance.d.ts → src/Instance.d.ts} +37 -15
- package/dist/types/{InstancedTexture.d.ts → src/InstancedTexture.d.ts} +60 -23
- package/dist/types/src/Interpolator.d.ts +66 -0
- package/dist/types/src/Material.d.ts +87 -0
- package/dist/types/src/MathUtils.d.ts +80 -0
- package/dist/types/src/ParticleEmitter.d.ts +131 -0
- package/dist/types/{Physics.d.ts → src/Physics.d.ts} +88 -20
- package/dist/types/src/Pool.d.ts +53 -0
- package/dist/types/src/PostEffects.d.ts +68 -0
- package/dist/types/src/PostProcessor.d.ts +124 -0
- package/dist/types/src/RenderTarget.d.ts +56 -0
- package/dist/types/src/Scene.d.ts +62 -0
- package/dist/types/src/ScreenEffects.d.ts +111 -0
- package/dist/types/src/Serializer.d.ts +86 -0
- package/dist/types/src/Shaders.d.ts +2 -0
- package/dist/types/{Shapes.d.ts → src/Shapes.d.ts} +4 -6
- package/dist/types/src/SpatialGrid.d.ts +50 -0
- package/dist/types/src/SpriteBatch.d.ts +89 -0
- package/dist/types/src/StateMachine.d.ts +59 -0
- package/dist/types/src/Storage.d.ts +89 -0
- package/dist/types/{Texture.d.ts → src/Texture.d.ts} +3 -4
- package/dist/types/src/TextureAtlas.d.ts +55 -0
- package/dist/types/src/Tilemap.d.ts +91 -0
- package/dist/types/src/Time.d.ts +53 -0
- package/dist/types/src/Timer.d.ts +54 -0
- package/dist/types/src/Transform.d.ts +94 -0
- package/dist/types/src/Tween.d.ts +81 -0
- package/dist/types/src/UI.d.ts +121 -0
- package/dist/types/src/components/Behaviour.d.ts +71 -0
- package/dist/types/{components → src/components}/BoxCollider.d.ts +14 -14
- package/dist/types/src/components/BoxColliderDebug.d.ts +15 -0
- package/dist/types/{components → src/components}/CircleCollider.d.ts +14 -12
- package/dist/types/src/components/CircleColliderDebug.d.ts +15 -0
- package/dist/types/src/components/Collider.d.ts +96 -0
- package/dist/types/src/components/GameObject.d.ts +135 -0
- package/dist/types/src/components/RigidBody.d.ts +183 -0
- package/dist/types/src/importers/Aseprite.d.ts +79 -0
- package/dist/types/src/importers/TiledMap.d.ts +62 -0
- package/dist/types/{lights → src/lights}/DirectionalLight.d.ts +7 -9
- package/dist/types/{lights → src/lights}/PointLight.d.ts +6 -9
- package/dist/types/src/managers/AssetManager.d.ts +116 -0
- package/dist/types/src/managers/AudioManager.d.ts +259 -0
- package/dist/types/{managers → src/managers}/CameraManager.d.ts +8 -8
- package/dist/types/{managers → src/managers}/EventManager.d.ts +46 -32
- package/dist/types/src/managers/GLManager.d.ts +84 -0
- package/dist/types/src/managers/GLState.d.ts +37 -0
- package/dist/types/src/managers/IDManager.d.ts +31 -0
- package/dist/types/src/managers/InputManager.d.ts +290 -0
- package/dist/types/src/managers/NetworkManager.d.ts +93 -0
- package/dist/types/src/managers/RenderStats.d.ts +34 -0
- package/dist/types/src/managers/SceneManager.d.ts +44 -0
- package/dist/types/src/managers/ShaderManager.d.ts +55 -0
- package/dist/types/src/managers/TextureManager.d.ts +102 -0
- package/dist/types/src/particlesystem/Particle.d.ts +64 -0
- package/dist/types/{particlesystem → src/particlesystem}/ParticleSettings.d.ts +32 -24
- package/dist/types/{particlesystem → src/particlesystem}/Particles.d.ts +20 -12
- package/index.js +72 -0
- package/package.json +74 -60
- package/src/Animator.js +95 -0
- package/src/BitmapText.js +6 -5
- package/src/Camera.js +183 -0
- package/src/CameraController.js +192 -0
- package/src/CanvasText.js +281 -0
- package/src/CollisionLayers.js +86 -0
- package/src/Color.js +18 -18
- package/src/Coroutine.js +259 -0
- package/src/DebugOverlay.js +246 -0
- package/src/Drawable.js +842 -582
- package/src/Easing.js +57 -0
- package/src/Emerald.js +1150 -459
- package/src/EmeraldDB.js +328 -0
- package/src/FPSCounter.js +43 -43
- package/src/GLUtils.js +60 -67
- package/src/Instance.js +41 -5
- package/src/InstancedTexture.js +251 -118
- package/src/Interpolator.js +124 -0
- package/src/Material.js +202 -0
- package/src/MathUtils.js +133 -0
- package/src/ParticleEmitter.js +284 -0
- package/src/Physics.js +186 -5
- package/src/Pool.js +85 -0
- package/src/PostEffects.js +296 -0
- package/src/PostProcessor.js +304 -0
- package/src/RenderTarget.js +134 -0
- package/src/Scene.js +115 -83
- package/src/ScreenEffects.js +266 -0
- package/src/Serializer.js +131 -0
- package/src/Shaders.js +150 -165
- package/src/Shapes.js +118 -129
- package/src/SpatialGrid.js +111 -0
- package/src/SpriteBatch.js +299 -0
- package/src/StateMachine.js +82 -0
- package/src/Storage.js +175 -47
- package/src/Texture.js +58 -67
- package/src/TextureAtlas.js +96 -0
- package/src/Tilemap.js +274 -0
- package/src/Time.js +51 -6
- package/src/Timer.js +99 -0
- package/src/Transform.js +100 -7
- package/src/Tween.js +160 -0
- package/src/UI.js +394 -0
- package/src/components/Behaviour.js +90 -0
- package/src/components/BoxCollider.js +22 -3
- package/src/components/CircleCollider.js +19 -3
- package/src/components/CircleColliderDebug.js +24 -24
- package/src/components/Collider.js +140 -34
- package/src/components/GameObject.js +130 -21
- package/src/components/RigidBody.js +123 -2
- package/src/importers/Aseprite.js +142 -0
- package/src/importers/TiledMap.js +158 -0
- package/src/lights/DirectionalLight.js +6 -15
- package/src/lights/PointLight.js +4 -4
- package/src/managers/AssetManager.js +239 -0
- package/src/managers/AudioManager.js +565 -146
- package/src/managers/EventManager.js +488 -477
- package/src/managers/GLManager.js +57 -0
- package/src/managers/GLState.js +70 -0
- package/src/managers/IDManager.js +24 -2
- package/src/managers/InputManager.js +779 -0
- package/src/managers/NetworkManager.js +178 -0
- package/src/managers/RenderStats.js +34 -0
- package/src/managers/SceneManager.js +30 -0
- package/src/managers/ShaderManager.js +0 -2
- package/src/managers/TextureManager.js +218 -0
- package/src/particlesystem/Particle.js +82 -7
- package/src/particlesystem/ParticleSettings.js +21 -3
- package/src/particlesystem/Particles.js +80 -31
- package/dist/types/Drawable.d.ts +0 -157
- package/dist/types/Emerald.d.ts +0 -73
- package/dist/types/GLUtils.d.ts +0 -6
- package/dist/types/Scene.d.ts +0 -39
- package/dist/types/Shaders.d.ts +0 -4
- package/dist/types/Storage.d.ts +0 -46
- package/dist/types/Time.d.ts +0 -22
- package/dist/types/Transform.d.ts +0 -41
- package/dist/types/components/BoxColliderDebug.d.ts +0 -19
- package/dist/types/components/CircleColliderDebug.d.ts +0 -19
- package/dist/types/components/Collider.d.ts +0 -53
- package/dist/types/components/GameObject.d.ts +0 -72
- package/dist/types/components/RigidBody.d.ts +0 -104
- package/dist/types/managers/AudioManager.d.ts +0 -60
- package/dist/types/managers/GLManager.d.ts +0 -47
- package/dist/types/managers/IDManager.d.ts +0 -21
- package/dist/types/managers/SceneManager.d.ts +0 -22
- package/dist/types/particlesystem/Particle.d.ts +0 -42
package/src/InstancedTexture.js
CHANGED
|
@@ -3,6 +3,9 @@ import Instance from "./Instance.js";
|
|
|
3
3
|
import Drawable from "./Drawable.js";
|
|
4
4
|
import { mat4 } from "gl-matrix";
|
|
5
5
|
import GLManager from "./managers/GLManager.js";
|
|
6
|
+
import GLState from "./managers/GLState.js";
|
|
7
|
+
import IDManager from "./managers/IDManager.js";
|
|
8
|
+
import RenderStats from "./managers/RenderStats.js";
|
|
6
9
|
import RigidBody from "./components/RigidBody.js";
|
|
7
10
|
import Collider from "./components/Collider.js";
|
|
8
11
|
|
|
@@ -35,16 +38,7 @@ class InstancedTexture extends Drawable {
|
|
|
35
38
|
) {
|
|
36
39
|
const vertices = [1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0];
|
|
37
40
|
const verticesBuffer = initVertexBuffer(GLManager.getGL(), vertices);
|
|
38
|
-
const textureCoordinates = [
|
|
39
|
-
1.0,
|
|
40
|
-
1.0, // Top-right
|
|
41
|
-
0.0,
|
|
42
|
-
1.0, // Top-left
|
|
43
|
-
1.0,
|
|
44
|
-
0.0, // Bottom-right
|
|
45
|
-
0.0,
|
|
46
|
-
0.0, // Bottom-left
|
|
47
|
-
];
|
|
41
|
+
const textureCoordinates = [1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0];
|
|
48
42
|
const texCoordBuffer = initVertexBuffer(
|
|
49
43
|
GLManager.getGL(),
|
|
50
44
|
textureCoordinates
|
|
@@ -71,26 +65,52 @@ class InstancedTexture extends Drawable {
|
|
|
71
65
|
this.instanceCount = instanceCount;
|
|
72
66
|
|
|
73
67
|
this.instances = [];
|
|
74
|
-
this.instanceMatrices = new Float32Array(instanceCount * 16);
|
|
75
|
-
this.instanceTexCoords = new Float32Array(instanceCount * 8);
|
|
68
|
+
this.instanceMatrices = new Float32Array(instanceCount * 16);
|
|
69
|
+
this.instanceTexCoords = new Float32Array(instanceCount * 8);
|
|
70
|
+
this.instanceColors = new Float32Array(instanceCount * 4).fill(1);
|
|
76
71
|
|
|
77
|
-
// Create instanced buffer for matrices
|
|
78
72
|
this.instanceMatrixBuffer = initInstancedBuffer(
|
|
79
73
|
GLManager.getGL(),
|
|
80
74
|
this.instanceMatrices,
|
|
81
75
|
16
|
|
82
76
|
);
|
|
83
77
|
|
|
84
|
-
// Create instanced buffer for texture coordinates
|
|
85
78
|
this.instanceTexCoordBuffer = initInstancedBuffer(
|
|
86
79
|
GLManager.getGL(),
|
|
87
80
|
this.instanceTexCoords,
|
|
88
81
|
8
|
|
89
82
|
);
|
|
90
83
|
|
|
91
|
-
|
|
84
|
+
this.instanceColorBuffer = initInstancedBuffer(
|
|
85
|
+
GLManager.getGL(),
|
|
86
|
+
this.instanceColors,
|
|
87
|
+
4
|
|
88
|
+
);
|
|
89
|
+
|
|
92
90
|
this.instanceClickListeners = new Map();
|
|
93
91
|
this.instanceHoverListeners = new Map();
|
|
92
|
+
|
|
93
|
+
this.static = false;
|
|
94
|
+
/** @private */
|
|
95
|
+
this._matricesDirty = true;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @method setStatic
|
|
100
|
+
* @description Toggles static mode (see constructor notes).
|
|
101
|
+
* @param {boolean} isStatic - Whether instances are non-moving
|
|
102
|
+
*/
|
|
103
|
+
setStatic(isStatic) {
|
|
104
|
+
this.static = isStatic;
|
|
105
|
+
this._matricesDirty = true;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* @method markDirty
|
|
110
|
+
* @description Forces an instance-matrix rebuild on the next draw.
|
|
111
|
+
*/
|
|
112
|
+
markDirty() {
|
|
113
|
+
this._matricesDirty = true;
|
|
94
114
|
}
|
|
95
115
|
|
|
96
116
|
/**
|
|
@@ -107,6 +127,7 @@ class InstancedTexture extends Drawable {
|
|
|
107
127
|
if (this.instances.length < this.instanceCount) {
|
|
108
128
|
this.instances.push(instance);
|
|
109
129
|
instance.setParent(this);
|
|
130
|
+
this._matricesDirty = true;
|
|
110
131
|
} else {
|
|
111
132
|
console.warn("Max instance count reached.");
|
|
112
133
|
}
|
|
@@ -122,18 +143,17 @@ class InstancedTexture extends Drawable {
|
|
|
122
143
|
(instance) => instance.id === instanceID
|
|
123
144
|
);
|
|
124
145
|
if (index !== -1) {
|
|
125
|
-
this.instances.
|
|
146
|
+
const last = this.instances.length - 1;
|
|
147
|
+
if (index !== last) {
|
|
148
|
+
this.instances[index] = this.instances[last];
|
|
149
|
+
}
|
|
150
|
+
this.instances.pop();
|
|
126
151
|
|
|
127
|
-
// Clean up event listeners for this instance
|
|
128
152
|
this.instanceClickListeners.delete(instanceID);
|
|
129
153
|
this.instanceHoverListeners.delete(instanceID);
|
|
154
|
+
IDManager.release(instanceID);
|
|
130
155
|
|
|
131
|
-
this.
|
|
132
|
-
this.instanceTexCoords = new Float32Array(this.instanceCount * 8);
|
|
133
|
-
|
|
134
|
-
// Update instance matrices and texture coordinates
|
|
135
|
-
this.updateAllInstanceMatrices();
|
|
136
|
-
this.updateAllInstanceTexCoords();
|
|
156
|
+
this._matricesDirty = true;
|
|
137
157
|
} else {
|
|
138
158
|
console.warn("Instance not found:", instanceID);
|
|
139
159
|
}
|
|
@@ -144,14 +164,15 @@ class InstancedTexture extends Drawable {
|
|
|
144
164
|
* @description Clears all instances from the instanced texture
|
|
145
165
|
*/
|
|
146
166
|
clearInstances() {
|
|
167
|
+
for (const inst of this.instances) IDManager.release(inst.id);
|
|
147
168
|
this.instances = [];
|
|
148
169
|
|
|
149
|
-
// Clear all event listeners
|
|
150
170
|
this.instanceClickListeners.clear();
|
|
151
171
|
this.instanceHoverListeners.clear();
|
|
152
172
|
|
|
153
|
-
this.instanceMatrices = new Float32Array(this.instanceCount * 16);
|
|
154
|
-
this.instanceTexCoords = new Float32Array(this.instanceCount * 8);
|
|
173
|
+
this.instanceMatrices = new Float32Array(this.instanceCount * 16);
|
|
174
|
+
this.instanceTexCoords = new Float32Array(this.instanceCount * 8);
|
|
175
|
+
this.instanceColors = new Float32Array(this.instanceCount * 4).fill(1);
|
|
155
176
|
|
|
156
177
|
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.instanceMatrixBuffer);
|
|
157
178
|
this.gl.bufferData(
|
|
@@ -166,6 +187,13 @@ class InstancedTexture extends Drawable {
|
|
|
166
187
|
this.instanceTexCoords,
|
|
167
188
|
this.gl.DYNAMIC_DRAW
|
|
168
189
|
);
|
|
190
|
+
|
|
191
|
+
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.instanceColorBuffer);
|
|
192
|
+
this.gl.bufferData(
|
|
193
|
+
this.gl.ARRAY_BUFFER,
|
|
194
|
+
this.instanceColors,
|
|
195
|
+
this.gl.DYNAMIC_DRAW
|
|
196
|
+
);
|
|
169
197
|
}
|
|
170
198
|
|
|
171
199
|
/**
|
|
@@ -177,6 +205,7 @@ class InstancedTexture extends Drawable {
|
|
|
177
205
|
this.instanceCount = newCount;
|
|
178
206
|
this.instanceMatrices = new Float32Array(newCount * 16);
|
|
179
207
|
this.instanceTexCoords = new Float32Array(newCount * 8);
|
|
208
|
+
this.instanceColors = new Float32Array(newCount * 4).fill(1);
|
|
180
209
|
this.instanceMatrixBuffer = initInstancedBuffer(
|
|
181
210
|
this.gl,
|
|
182
211
|
this.instanceMatrices,
|
|
@@ -187,6 +216,11 @@ class InstancedTexture extends Drawable {
|
|
|
187
216
|
this.instanceTexCoords,
|
|
188
217
|
8
|
|
189
218
|
);
|
|
219
|
+
this.instanceColorBuffer = initInstancedBuffer(
|
|
220
|
+
this.gl,
|
|
221
|
+
this.instanceColors,
|
|
222
|
+
4
|
|
223
|
+
);
|
|
190
224
|
}
|
|
191
225
|
|
|
192
226
|
/**
|
|
@@ -219,7 +253,6 @@ class InstancedTexture extends Drawable {
|
|
|
219
253
|
mat4.rotate(matrix, matrix, rotation, [0, 0, 1]);
|
|
220
254
|
mat4.scale(matrix, matrix, scale);
|
|
221
255
|
|
|
222
|
-
// Copy matrix values to the appropriate place in instanceMatrices
|
|
223
256
|
const offset = index * 16;
|
|
224
257
|
for (let i = 0; i < 16; i++) {
|
|
225
258
|
this.instanceMatrices[offset + i] = matrix[i];
|
|
@@ -236,7 +269,6 @@ class InstancedTexture extends Drawable {
|
|
|
236
269
|
this.updateInstanceMatrix(i);
|
|
237
270
|
}
|
|
238
271
|
|
|
239
|
-
// Update the instance buffer with new matrices
|
|
240
272
|
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.instanceMatrixBuffer);
|
|
241
273
|
this.gl.bufferData(
|
|
242
274
|
this.gl.ARRAY_BUFFER,
|
|
@@ -244,8 +276,47 @@ class InstancedTexture extends Drawable {
|
|
|
244
276
|
this.gl.DYNAMIC_DRAW
|
|
245
277
|
);
|
|
246
278
|
|
|
247
|
-
// Also update texture coordinates
|
|
248
279
|
this.updateAllInstanceTexCoords();
|
|
280
|
+
this.updateAllInstanceColors();
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* @method updateInstanceColor
|
|
285
|
+
* @description Writes a single instance's RGBA tint into the color array.
|
|
286
|
+
* Reads `instance._tint` ([r,g,b,a] in 0..1) when set, else opaque white.
|
|
287
|
+
* @param {number} index - The instance index
|
|
288
|
+
*/
|
|
289
|
+
updateInstanceColor(index) {
|
|
290
|
+
if (index < 0 || index >= this.instances.length) return;
|
|
291
|
+
const tint = this.instances[index]._tint;
|
|
292
|
+
const offset = index * 4;
|
|
293
|
+
if (tint) {
|
|
294
|
+
this.instanceColors[offset] = tint[0];
|
|
295
|
+
this.instanceColors[offset + 1] = tint[1];
|
|
296
|
+
this.instanceColors[offset + 2] = tint[2];
|
|
297
|
+
this.instanceColors[offset + 3] = tint[3];
|
|
298
|
+
} else {
|
|
299
|
+
this.instanceColors[offset] = 1;
|
|
300
|
+
this.instanceColors[offset + 1] = 1;
|
|
301
|
+
this.instanceColors[offset + 2] = 1;
|
|
302
|
+
this.instanceColors[offset + 3] = 1;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* @method updateAllInstanceColors
|
|
308
|
+
* @description Rebuilds and uploads the per-instance color buffer.
|
|
309
|
+
*/
|
|
310
|
+
updateAllInstanceColors() {
|
|
311
|
+
for (let i = 0; i < this.instances.length; i++) {
|
|
312
|
+
this.updateInstanceColor(i);
|
|
313
|
+
}
|
|
314
|
+
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.instanceColorBuffer);
|
|
315
|
+
this.gl.bufferData(
|
|
316
|
+
this.gl.ARRAY_BUFFER,
|
|
317
|
+
this.instanceColors,
|
|
318
|
+
this.gl.DYNAMIC_DRAW
|
|
319
|
+
);
|
|
249
320
|
}
|
|
250
321
|
|
|
251
322
|
/**
|
|
@@ -259,8 +330,9 @@ class InstancedTexture extends Drawable {
|
|
|
259
330
|
index < this.instanceCount &&
|
|
260
331
|
index < this.instances.length
|
|
261
332
|
) {
|
|
262
|
-
const
|
|
263
|
-
const texCoords =
|
|
333
|
+
const instance = this.instances[index];
|
|
334
|
+
const texCoords =
|
|
335
|
+
instance._regionUV || this.getFrameTexCoords(instance.frame);
|
|
264
336
|
|
|
265
337
|
const offset = index * 8;
|
|
266
338
|
for (let i = 0; i < 8; i++) {
|
|
@@ -278,7 +350,6 @@ class InstancedTexture extends Drawable {
|
|
|
278
350
|
this.updateInstanceTexCoords(i);
|
|
279
351
|
}
|
|
280
352
|
|
|
281
|
-
// Update the instance texture coordinate buffer
|
|
282
353
|
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.instanceTexCoordBuffer);
|
|
283
354
|
this.gl.bufferData(
|
|
284
355
|
this.gl.ARRAY_BUFFER,
|
|
@@ -305,7 +376,6 @@ class InstancedTexture extends Drawable {
|
|
|
305
376
|
update(currentTime) {
|
|
306
377
|
let needsUpdate = false;
|
|
307
378
|
|
|
308
|
-
// Update animations for all instances
|
|
309
379
|
for (let i = 0; i < this.instances.length; i++) {
|
|
310
380
|
const instance = this.instances[i];
|
|
311
381
|
if (instance.updateAnimation(currentTime)) {
|
|
@@ -313,7 +383,6 @@ class InstancedTexture extends Drawable {
|
|
|
313
383
|
}
|
|
314
384
|
}
|
|
315
385
|
|
|
316
|
-
// If any instance frame changed, update texture coordinates
|
|
317
386
|
if (needsUpdate) {
|
|
318
387
|
this.updateAllInstanceTexCoords();
|
|
319
388
|
}
|
|
@@ -406,47 +475,115 @@ class InstancedTexture extends Drawable {
|
|
|
406
475
|
let texLeft, texRight, texTop, texBottom;
|
|
407
476
|
|
|
408
477
|
if (this.frameWidth > 0 && this.frameHeight > 0) {
|
|
409
|
-
// Spritesheet animation
|
|
410
478
|
const col = frame % this.framesPerRow;
|
|
411
479
|
const row = Math.floor(frame / this.framesPerRow);
|
|
412
480
|
|
|
413
|
-
|
|
414
|
-
|
|
481
|
+
const ix = 0.5 / this.textureWidth;
|
|
482
|
+
const iy = 0.5 / this.textureHeight;
|
|
483
|
+
|
|
484
|
+
texLeft = ((col + 1) * this.frameWidth) / this.textureWidth - ix;
|
|
485
|
+
texRight = (col * this.frameWidth) / this.textureWidth + ix;
|
|
415
486
|
texTop =
|
|
416
487
|
(this.textureHeight - row * this.frameHeight - this.frameHeight) /
|
|
417
|
-
|
|
488
|
+
this.textureHeight +
|
|
489
|
+
iy;
|
|
418
490
|
texBottom =
|
|
419
|
-
(this.textureHeight - row * this.frameHeight) / this.textureHeight;
|
|
491
|
+
(this.textureHeight - row * this.frameHeight) / this.textureHeight - iy;
|
|
420
492
|
} else {
|
|
421
|
-
// Static image
|
|
422
493
|
texLeft = 1.0;
|
|
423
494
|
texRight = 0.0;
|
|
424
495
|
texTop = 0.0;
|
|
425
496
|
texBottom = 1.0;
|
|
426
497
|
}
|
|
427
498
|
|
|
428
|
-
// Return texture coordinates (considering mirroring)
|
|
429
499
|
return this.mirrored
|
|
430
500
|
? [
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
501
|
+
texRight,
|
|
502
|
+
texBottom,
|
|
503
|
+
texLeft,
|
|
504
|
+
texBottom,
|
|
505
|
+
texRight,
|
|
506
|
+
texTop,
|
|
507
|
+
texLeft,
|
|
508
|
+
texTop,
|
|
509
|
+
]
|
|
440
510
|
: [
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
511
|
+
texLeft,
|
|
512
|
+
texBottom,
|
|
513
|
+
texRight,
|
|
514
|
+
texBottom,
|
|
515
|
+
texLeft,
|
|
516
|
+
texTop,
|
|
517
|
+
texRight,
|
|
518
|
+
texTop,
|
|
519
|
+
];
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* @method _restoreGL
|
|
524
|
+
* @description Rebuilds the per-instance buffers from their CPU-side arrays
|
|
525
|
+
* after a WebGL context loss, on top of the base Drawable restore.
|
|
526
|
+
* @private
|
|
527
|
+
*/
|
|
528
|
+
_restoreGL() {
|
|
529
|
+
if (this._disposed) return;
|
|
530
|
+
super._restoreGL();
|
|
531
|
+
const gl = this.gl;
|
|
532
|
+
if (!gl) return;
|
|
533
|
+
this.instanceMatrixBuffer = initInstancedBuffer(
|
|
534
|
+
gl,
|
|
535
|
+
this.instanceMatrices,
|
|
536
|
+
16
|
|
537
|
+
);
|
|
538
|
+
this.instanceTexCoordBuffer = initInstancedBuffer(
|
|
539
|
+
gl,
|
|
540
|
+
this.instanceTexCoords,
|
|
541
|
+
8
|
|
542
|
+
);
|
|
543
|
+
this.instanceColorBuffer = initInstancedBuffer(gl, this.instanceColors, 4);
|
|
544
|
+
this._matricesDirty = true;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
/**
|
|
548
|
+
* @method dispose
|
|
549
|
+
* @description Frees the per-instance GPU buffers on top of the base
|
|
550
|
+
* Drawable disposal. Safe to call twice.
|
|
551
|
+
*/
|
|
552
|
+
dispose() {
|
|
553
|
+
if (this._disposed) return;
|
|
554
|
+
const gl = this.gl;
|
|
555
|
+
if (gl) {
|
|
556
|
+
if (this.instanceMatrixBuffer) gl.deleteBuffer(this.instanceMatrixBuffer);
|
|
557
|
+
if (this.instanceTexCoordBuffer)
|
|
558
|
+
gl.deleteBuffer(this.instanceTexCoordBuffer);
|
|
559
|
+
if (this.instanceColorBuffer) gl.deleteBuffer(this.instanceColorBuffer);
|
|
560
|
+
}
|
|
561
|
+
this.instanceMatrixBuffer = null;
|
|
562
|
+
this.instanceTexCoordBuffer = null;
|
|
563
|
+
this.instanceColorBuffer = null;
|
|
564
|
+
this.instances = [];
|
|
565
|
+
super.dispose();
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
/**
|
|
569
|
+
* @method syncPhysics
|
|
570
|
+
* @description Copies simulation state (position + rotation) from each
|
|
571
|
+
* instance's dynamic rigidbody onto the instance transform. Driven once per
|
|
572
|
+
* frame by the owning GameObject's syncPhysics(), so draw() stays read-only.
|
|
573
|
+
*/
|
|
574
|
+
syncPhysics() {
|
|
575
|
+
for (let i = 0; i < this.instances.length; i++) {
|
|
576
|
+
const instance = this.instances[i];
|
|
577
|
+
const rigidBody = instance.getComponent(RigidBody);
|
|
578
|
+
if (!rigidBody || rigidBody.getType() !== "dynamic") continue;
|
|
579
|
+
rigidBody.syncTransform(instance.transform);
|
|
580
|
+
const collider =
|
|
581
|
+
rigidBody.getCollider() || instance.getComponent(Collider);
|
|
582
|
+
if (collider && typeof collider.syncDebugShape === "function") {
|
|
583
|
+
collider.syncDebugShape(instance.transform);
|
|
584
|
+
}
|
|
585
|
+
this._matricesDirty = true;
|
|
586
|
+
}
|
|
450
587
|
}
|
|
451
588
|
|
|
452
589
|
/**
|
|
@@ -454,62 +591,48 @@ class InstancedTexture extends Drawable {
|
|
|
454
591
|
* @description Draws the instanced texture
|
|
455
592
|
*/
|
|
456
593
|
draw() {
|
|
457
|
-
this.
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
let collider = instance.getComponent(Collider);
|
|
463
|
-
|
|
464
|
-
if (rigidBody) {
|
|
465
|
-
if (rigidBody.getType() === "dynamic") {
|
|
466
|
-
const updatedPos = rigidBody.getBody().getPosition();
|
|
467
|
-
const rigidBodyOffset = rigidBody.getOffset();
|
|
468
|
-
instance.transform.position.x =
|
|
469
|
-
updatedPos.x * rigidBody.getPhysics().getScale() -
|
|
470
|
-
rigidBodyOffset.x;
|
|
471
|
-
instance.transform.position.y =
|
|
472
|
-
updatedPos.y * rigidBody.getPhysics().getScale() -
|
|
473
|
-
rigidBodyOffset.y;
|
|
474
|
-
if (collider) {
|
|
475
|
-
collider.debugShape.gameObject.transform.position.x =
|
|
476
|
-
instance.transform.position.x;
|
|
477
|
-
collider.debugShape.gameObject.transform.position.y =
|
|
478
|
-
instance.transform.position.y;
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
}
|
|
594
|
+
if (!this.instances || this.instances.length === 0) return;
|
|
595
|
+
|
|
596
|
+
if (!this.static || this._matricesDirty) {
|
|
597
|
+
this.updateAllInstanceMatrices();
|
|
598
|
+
this._matricesDirty = false;
|
|
482
599
|
}
|
|
483
|
-
this.
|
|
600
|
+
this.update(performance.now());
|
|
601
|
+
GLState.uniform1i(
|
|
602
|
+
this.gl,
|
|
484
603
|
this.programInfo.uniformLocations.useTexture,
|
|
485
604
|
this.useTexture
|
|
486
605
|
);
|
|
487
606
|
|
|
488
|
-
|
|
607
|
+
GLState.uniform1i(
|
|
608
|
+
this.gl,
|
|
609
|
+
this.programInfo.uniformLocations.useInstances,
|
|
610
|
+
true
|
|
611
|
+
);
|
|
489
612
|
|
|
490
|
-
|
|
491
|
-
|
|
613
|
+
GLState.uniform1i(
|
|
614
|
+
this.gl,
|
|
492
615
|
this.programInfo.uniformLocations.useLighting,
|
|
493
616
|
this.useLighting
|
|
494
617
|
);
|
|
495
618
|
|
|
496
|
-
|
|
497
|
-
|
|
619
|
+
GLState.uniform4fv(
|
|
620
|
+
this.gl,
|
|
621
|
+
this.programInfo.uniformLocations.color,
|
|
622
|
+
this.color
|
|
623
|
+
);
|
|
498
624
|
|
|
499
|
-
// Set per-GameObject opacity if available (defaults to 1.0)
|
|
500
625
|
const ownerGameObject = this.getParent();
|
|
501
626
|
const ownerOpacity =
|
|
502
627
|
ownerGameObject && typeof ownerGameObject.opacity === "number"
|
|
503
628
|
? ownerGameObject.opacity
|
|
504
629
|
: 1.0;
|
|
505
|
-
|
|
506
|
-
this.gl
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
}
|
|
630
|
+
GLState.uniform1f(
|
|
631
|
+
this.gl,
|
|
632
|
+
this.programInfo.uniformLocations.uOpacity,
|
|
633
|
+
ownerOpacity
|
|
634
|
+
);
|
|
511
635
|
|
|
512
|
-
// Bind and set vertex position buffer
|
|
513
636
|
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.verticesBuffer);
|
|
514
637
|
this.gl.vertexAttribPointer(
|
|
515
638
|
this.programInfo.attribLocations.vertexPosition,
|
|
@@ -523,7 +646,6 @@ class InstancedTexture extends Drawable {
|
|
|
523
646
|
this.programInfo.attribLocations.vertexPosition
|
|
524
647
|
);
|
|
525
648
|
|
|
526
|
-
// Bind and set texture coordinate buffer (for non-instanced rendering)
|
|
527
649
|
if (this.useTexture) {
|
|
528
650
|
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.texCoordBuffer);
|
|
529
651
|
this.gl.vertexAttribPointer(
|
|
@@ -540,12 +662,11 @@ class InstancedTexture extends Drawable {
|
|
|
540
662
|
|
|
541
663
|
if (this.texture) {
|
|
542
664
|
this.gl.bindTexture(this.gl.TEXTURE_2D, this.texture);
|
|
665
|
+
RenderStats.textureBinds++;
|
|
543
666
|
}
|
|
544
667
|
|
|
545
|
-
// Set up per-instance texture coordinate attributes
|
|
546
668
|
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.instanceTexCoordBuffer);
|
|
547
669
|
|
|
548
|
-
// Each instance has 4 texture coordinates (for 4 vertices)
|
|
549
670
|
const texCoordAttribs = [
|
|
550
671
|
this.programInfo.attribLocations.instanceTexCoord0,
|
|
551
672
|
this.programInfo.attribLocations.instanceTexCoord1,
|
|
@@ -562,15 +683,22 @@ class InstancedTexture extends Drawable {
|
|
|
562
683
|
2,
|
|
563
684
|
this.gl.FLOAT,
|
|
564
685
|
false,
|
|
565
|
-
8 * 4,
|
|
566
|
-
i * 2 * 4
|
|
686
|
+
8 * 4,
|
|
687
|
+
i * 2 * 4
|
|
567
688
|
);
|
|
568
|
-
this.gl.vertexAttribDivisor(loc, 1);
|
|
689
|
+
this.gl.vertexAttribDivisor(loc, 1);
|
|
569
690
|
}
|
|
570
691
|
}
|
|
571
692
|
}
|
|
572
693
|
|
|
573
|
-
|
|
694
|
+
const colorLoc = this.programInfo.attribLocations.instanceColor;
|
|
695
|
+
if (colorLoc !== undefined && colorLoc !== -1) {
|
|
696
|
+
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.instanceColorBuffer);
|
|
697
|
+
this.gl.enableVertexAttribArray(colorLoc);
|
|
698
|
+
this.gl.vertexAttribPointer(colorLoc, 4, this.gl.FLOAT, false, 0, 0);
|
|
699
|
+
this.gl.vertexAttribDivisor(colorLoc, 1);
|
|
700
|
+
}
|
|
701
|
+
|
|
574
702
|
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.instanceMatrixBuffer);
|
|
575
703
|
|
|
576
704
|
const matrixLoc = this.programInfo.attribLocations.instanceMatrix;
|
|
@@ -585,26 +713,32 @@ class InstancedTexture extends Drawable {
|
|
|
585
713
|
16 * 4,
|
|
586
714
|
i * 4 * 4
|
|
587
715
|
);
|
|
588
|
-
this.gl.vertexAttribDivisor(loc, 1);
|
|
716
|
+
this.gl.vertexAttribDivisor(loc, 1);
|
|
589
717
|
}
|
|
590
718
|
|
|
591
|
-
// Draw all instances
|
|
592
719
|
const drawMode =
|
|
593
720
|
this.vertices.length === 8 ? this.gl.TRIANGLE_STRIP : this.gl.TRIANGLES;
|
|
721
|
+
this._applyBlend();
|
|
594
722
|
this.gl.drawArraysInstanced(
|
|
595
723
|
drawMode,
|
|
596
724
|
0,
|
|
597
725
|
this.vertices.length / 2,
|
|
598
|
-
this.instances.length
|
|
726
|
+
this.instances.length
|
|
599
727
|
);
|
|
728
|
+
this._restoreBlend();
|
|
729
|
+
RenderStats.drawCalls++;
|
|
730
|
+
RenderStats.quads += this.instances.length;
|
|
600
731
|
|
|
601
|
-
// Reset attribute divisors
|
|
602
732
|
for (let i = 0; i < 4; i++) {
|
|
603
733
|
this.gl.vertexAttribDivisor(matrixLoc + i, 0);
|
|
604
734
|
this.gl.disableVertexAttribArray(matrixLoc + i);
|
|
605
735
|
}
|
|
606
736
|
|
|
607
|
-
|
|
737
|
+
if (colorLoc !== undefined && colorLoc !== -1) {
|
|
738
|
+
this.gl.vertexAttribDivisor(colorLoc, 0);
|
|
739
|
+
this.gl.disableVertexAttribArray(colorLoc);
|
|
740
|
+
}
|
|
741
|
+
|
|
608
742
|
if (this.useTexture) {
|
|
609
743
|
const texCoordAttribs = [
|
|
610
744
|
this.programInfo.attribLocations.instanceTexCoord0,
|
|
@@ -622,7 +756,11 @@ class InstancedTexture extends Drawable {
|
|
|
622
756
|
}
|
|
623
757
|
}
|
|
624
758
|
|
|
625
|
-
|
|
759
|
+
GLState.uniform1i(
|
|
760
|
+
this.gl,
|
|
761
|
+
this.programInfo.uniformLocations.useInstances,
|
|
762
|
+
false
|
|
763
|
+
);
|
|
626
764
|
}
|
|
627
765
|
|
|
628
766
|
/**
|
|
@@ -781,9 +919,9 @@ class InstancedTexture extends Drawable {
|
|
|
781
919
|
if (listeners) {
|
|
782
920
|
listeners.forEach((func) => func(event, clickedInstance));
|
|
783
921
|
}
|
|
784
|
-
return true;
|
|
922
|
+
return true;
|
|
785
923
|
}
|
|
786
|
-
return false;
|
|
924
|
+
return false;
|
|
787
925
|
}
|
|
788
926
|
|
|
789
927
|
/**
|
|
@@ -798,7 +936,6 @@ class InstancedTexture extends Drawable {
|
|
|
798
936
|
const hoveredInstance = this.getInstanceAtPoint(x, y);
|
|
799
937
|
|
|
800
938
|
if (hoveredInstance !== lastHoveredInstance) {
|
|
801
|
-
// Handle leave event for previous instance
|
|
802
939
|
if (lastHoveredInstance) {
|
|
803
940
|
const leaveListeners = this.instanceHoverListeners.get(
|
|
804
941
|
lastHoveredInstance.id
|
|
@@ -810,7 +947,6 @@ class InstancedTexture extends Drawable {
|
|
|
810
947
|
}
|
|
811
948
|
}
|
|
812
949
|
|
|
813
|
-
// Handle enter event for new instance
|
|
814
950
|
if (hoveredInstance) {
|
|
815
951
|
const enterListeners = this.instanceHoverListeners.get(
|
|
816
952
|
hoveredInstance.id
|
|
@@ -831,7 +967,6 @@ class InstancedTexture extends Drawable {
|
|
|
831
967
|
* @param {number} speed - The speed of the animation
|
|
832
968
|
*/
|
|
833
969
|
playAnimation(frames, speed = 1000) {
|
|
834
|
-
// Override with empty implementation
|
|
835
970
|
console.warn("playAnimation is not implemented for InstancedTexture");
|
|
836
971
|
}
|
|
837
972
|
|
|
@@ -842,7 +977,6 @@ class InstancedTexture extends Drawable {
|
|
|
842
977
|
* @param {number} speed - The speed of the animation
|
|
843
978
|
*/
|
|
844
979
|
playAnimationOnce(frames, speed = 1000) {
|
|
845
|
-
// Override with empty implementation
|
|
846
980
|
console.warn("playAnimationOnce is not implemented for InstancedTexture");
|
|
847
981
|
}
|
|
848
982
|
|
|
@@ -852,7 +986,6 @@ class InstancedTexture extends Drawable {
|
|
|
852
986
|
* @returns {Array} - The animation
|
|
853
987
|
*/
|
|
854
988
|
getAnimation() {
|
|
855
|
-
// Override with empty implementation
|
|
856
989
|
console.warn("getAnimation is not implemented for InstancedTexture");
|
|
857
990
|
}
|
|
858
991
|
}
|