emeraldengine 2.2.1 → 3.1.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 +2198 -968
- package/dist/types/index.d.ts +75 -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} +6 -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} +75 -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 +81 -0
- package/dist/types/src/ParticleEmitter.d.ts +131 -0
- package/dist/types/src/Physics.d.ts +337 -0
- 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 +102 -0
- package/dist/types/src/components/GameObject.d.ts +135 -0
- package/dist/types/src/components/PolygonCollider.d.ts +33 -0
- package/dist/types/src/components/RigidBody.d.ts +456 -0
- package/dist/types/src/importers/Aseprite.d.ts +79 -0
- package/dist/types/src/importers/ForgeLevel.d.ts +97 -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/Gamepad.d.ts +102 -0
- package/dist/types/src/managers/IDManager.d.ts +31 -0
- package/dist/types/src/managers/InputManager.d.ts +381 -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/dist/types/src/physics/AABB.d.ts +92 -0
- package/dist/types/src/physics/Body.d.ts +435 -0
- package/dist/types/src/physics/BodyType.d.ts +6 -0
- package/dist/types/src/physics/BroadPhase.d.ts +210 -0
- package/dist/types/src/physics/Collision.d.ts +102 -0
- package/dist/types/src/physics/Contact.d.ts +206 -0
- package/dist/types/src/physics/ContactSolver.d.ts +108 -0
- package/dist/types/src/physics/Distance.d.ts +54 -0
- package/dist/types/src/physics/DistanceJoint.d.ts +90 -0
- package/dist/types/src/physics/Fixture.d.ts +221 -0
- package/dist/types/src/physics/Island.d.ts +52 -0
- package/dist/types/src/physics/Joint.d.ts +59 -0
- package/dist/types/src/physics/Math2D.d.ts +371 -0
- package/dist/types/src/physics/RevoluteJoint.d.ts +119 -0
- package/dist/types/src/physics/Settings.d.ts +22 -0
- package/dist/types/src/physics/Shapes.d.ts +207 -0
- package/dist/types/src/physics/TimeOfImpact.d.ts +22 -0
- package/dist/types/src/physics/World.d.ts +274 -0
- package/dist/types/src/physics/index.d.ts +34 -0
- package/index.js +78 -0
- package/package.json +73 -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 +26 -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 +308 -127
- package/src/Interpolator.js +124 -0
- package/src/Material.js +202 -0
- package/src/MathUtils.js +134 -0
- package/src/ParticleEmitter.js +284 -0
- package/src/Physics.js +431 -40
- 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 +29 -12
- package/src/components/BoxColliderDebug.js +3 -4
- package/src/components/CircleCollider.js +26 -12
- package/src/components/CircleColliderDebug.js +25 -24
- package/src/components/Collider.js +150 -34
- package/src/components/GameObject.js +130 -21
- package/src/components/PolygonCollider.js +55 -0
- package/src/components/RigidBody.js +556 -8
- package/src/importers/Aseprite.js +142 -0
- package/src/importers/ForgeLevel.js +581 -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/Gamepad.js +126 -0
- package/src/managers/IDManager.js +24 -2
- package/src/managers/InputManager.js +905 -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/src/physics/AABB.js +207 -0
- package/src/physics/Body.js +862 -0
- package/src/physics/BodyType.js +16 -0
- package/src/physics/BroadPhase.js +641 -0
- package/src/physics/Collision.js +534 -0
- package/src/physics/Contact.js +500 -0
- package/src/physics/ContactSolver.js +526 -0
- package/src/physics/Distance.js +403 -0
- package/src/physics/DistanceJoint.js +227 -0
- package/src/physics/Fixture.js +346 -0
- package/src/physics/Island.js +203 -0
- package/src/physics/Joint.js +78 -0
- package/src/physics/Math2D.js +573 -0
- package/src/physics/RevoluteJoint.js +278 -0
- package/src/physics/Settings.js +78 -0
- package/src/physics/Shapes.js +549 -0
- package/src/physics/TimeOfImpact.js +87 -0
- package/src/physics/World.js +731 -0
- package/src/physics/index.js +79 -0
- 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/Physics.d.ts +0 -139
- 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
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @class Interpolator
|
|
3
|
+
* @description Snapshot interpolation buffer for smoothing networked state.
|
|
4
|
+
* Authoritative updates arrive at a low, irregular rate (e.g. 10–20 Hz); this
|
|
5
|
+
* buffers timestamped snapshots and lets you sample a position "in the past" by
|
|
6
|
+
* a fixed render delay, so remote entities move smoothly between updates instead
|
|
7
|
+
* of teleporting.
|
|
8
|
+
*
|
|
9
|
+
* It is transport-agnostic and pure (no network/DOM dependency), so it works
|
|
10
|
+
* with the built-in NetworkManager, any other transport, or in tests.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* const interp = new Interpolator({ delay: 0.1 });
|
|
14
|
+
* // on each server update for an entity:
|
|
15
|
+
* interp.push(entityId, { x, y }, serverTimeSeconds);
|
|
16
|
+
* // each frame:
|
|
17
|
+
* const pos = interp.sample(entityId, nowSeconds); // { x, y } or null
|
|
18
|
+
*/
|
|
19
|
+
class Interpolator {
|
|
20
|
+
/**
|
|
21
|
+
* @param {Object} [options] - { delay = 0.1, maxBuffer = 60 }
|
|
22
|
+
*/
|
|
23
|
+
constructor(options = {}) {
|
|
24
|
+
this.delay = options.delay ?? 0.1;
|
|
25
|
+
this.maxBuffer = options.maxBuffer ?? 60;
|
|
26
|
+
/** @private */
|
|
27
|
+
this._buffers = new Map();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @method push
|
|
32
|
+
* @description Records a snapshot for an entity at a given timestamp.
|
|
33
|
+
* @param {string|number} id - Entity id
|
|
34
|
+
* @param {Object} state - Any object with numeric fields to interpolate (e.g. {x,y})
|
|
35
|
+
* @param {number} time - Snapshot timestamp in seconds
|
|
36
|
+
*/
|
|
37
|
+
push(id, state, time) {
|
|
38
|
+
let buf = this._buffers.get(id);
|
|
39
|
+
if (!buf) {
|
|
40
|
+
buf = [];
|
|
41
|
+
this._buffers.set(id, buf);
|
|
42
|
+
}
|
|
43
|
+
buf.push({ t: time, state });
|
|
44
|
+
if (buf.length > 1 && buf[buf.length - 2].t > time) {
|
|
45
|
+
buf.sort((a, b) => a.t - b.t);
|
|
46
|
+
}
|
|
47
|
+
if (buf.length > this.maxBuffer) buf.shift();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @method sample
|
|
52
|
+
* @description Returns the interpolated state for an entity at (now - delay).
|
|
53
|
+
* Linearly interpolates numeric fields between the two surrounding snapshots.
|
|
54
|
+
* Returns the latest snapshot if rendering ahead of the buffer, or null if no
|
|
55
|
+
* data exists.
|
|
56
|
+
* @param {string|number} id - Entity id
|
|
57
|
+
* @param {number} now - Current time in seconds
|
|
58
|
+
* @returns {Object|null} - Interpolated state, or null
|
|
59
|
+
*/
|
|
60
|
+
sample(id, now) {
|
|
61
|
+
const buf = this._buffers.get(id);
|
|
62
|
+
if (!buf || buf.length === 0) return null;
|
|
63
|
+
const renderTime = now - this.delay;
|
|
64
|
+
|
|
65
|
+
if (renderTime <= buf[0].t) return { ...buf[0].state };
|
|
66
|
+
const last = buf[buf.length - 1];
|
|
67
|
+
if (renderTime >= last.t) return { ...last.state };
|
|
68
|
+
|
|
69
|
+
let a = buf[0];
|
|
70
|
+
let b = buf[buf.length - 1];
|
|
71
|
+
for (let i = 0; i < buf.length - 1; i++) {
|
|
72
|
+
if (buf[i].t <= renderTime && buf[i + 1].t >= renderTime) {
|
|
73
|
+
a = buf[i];
|
|
74
|
+
b = buf[i + 1];
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const span = b.t - a.t;
|
|
80
|
+
const k = span <= 0 ? 0 : (renderTime - a.t) / span;
|
|
81
|
+
const out = {};
|
|
82
|
+
for (const key in a.state) {
|
|
83
|
+
const av = a.state[key];
|
|
84
|
+
const bv = b.state[key];
|
|
85
|
+
out[key] =
|
|
86
|
+
typeof av === "number" && typeof bv === "number"
|
|
87
|
+
? av + (bv - av) * k
|
|
88
|
+
: bv;
|
|
89
|
+
}
|
|
90
|
+
return out;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @method remove
|
|
95
|
+
* @description Drops an entity's buffer (e.g. when it leaves).
|
|
96
|
+
*/
|
|
97
|
+
remove(id) {
|
|
98
|
+
this._buffers.delete(id);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* @method prune
|
|
103
|
+
* @description Drops snapshots older than (now - delay - keep) to bound memory
|
|
104
|
+
* for long-lived entities.
|
|
105
|
+
* @param {number} now - Current time in seconds
|
|
106
|
+
* @param {number} [keep] - Extra history to retain past the render point
|
|
107
|
+
*/
|
|
108
|
+
prune(now, keep = 1) {
|
|
109
|
+
const cutoff = now - this.delay - keep;
|
|
110
|
+
for (const buf of this._buffers.values()) {
|
|
111
|
+
while (buf.length > 2 && buf[0].t < cutoff) buf.shift();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* @method clear
|
|
117
|
+
* @description Removes all buffered snapshots.
|
|
118
|
+
*/
|
|
119
|
+
clear() {
|
|
120
|
+
this._buffers.clear();
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export default Interpolator;
|
package/src/Material.js
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { initShaderProgram } from "./GLUtils.js";
|
|
2
|
+
import { STANDARD_VERTEX_SHADER } from "./Shaders.js";
|
|
3
|
+
import GLManager from "./managers/GLManager.js";
|
|
4
|
+
|
|
5
|
+
const MATERIAL_FRAGMENT_HEADER = `
|
|
6
|
+
#ifdef GL_ES
|
|
7
|
+
precision highp float;
|
|
8
|
+
#endif
|
|
9
|
+
varying highp vec2 vTexCoord;
|
|
10
|
+
varying vec2 vFragPos;
|
|
11
|
+
varying vec4 vInstanceColor;
|
|
12
|
+
uniform sampler2D uSampler;
|
|
13
|
+
uniform vec4 uColor;
|
|
14
|
+
uniform float uOpacity;
|
|
15
|
+
uniform float uTime;
|
|
16
|
+
`;
|
|
17
|
+
|
|
18
|
+
const MATERIAL_VERTEX_HEADER = `
|
|
19
|
+
attribute vec4 aVertexPosition;
|
|
20
|
+
attribute vec2 aTextureCoord;
|
|
21
|
+
uniform mat4 uProjectionMatrix;
|
|
22
|
+
uniform mat4 uModelViewMatrix;
|
|
23
|
+
uniform float uTime;
|
|
24
|
+
varying highp vec2 vTexCoord;
|
|
25
|
+
varying vec2 vFragPos;
|
|
26
|
+
varying vec4 vInstanceColor;
|
|
27
|
+
`;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @class Material
|
|
31
|
+
* @description A custom shader for a Drawable. By default it reuses the engine's
|
|
32
|
+
* standard vertex shader (so transforms, the camera, and instancing keep
|
|
33
|
+
* working) and only overrides the fragment program. Pass `options.vertex` to
|
|
34
|
+
* also supply a custom VERTEX program: the escape hatch for effects the fixed
|
|
35
|
+
* pipeline can't express (perspective tilt, vertex waves, billboarding, ...).
|
|
36
|
+
*
|
|
37
|
+
* The fragment shader always has: `vTexCoord`, `vFragPos`, `vInstanceColor`,
|
|
38
|
+
* `uSampler`, `uColor`, `uOpacity`, `uTime`. A custom vertex shader gets
|
|
39
|
+
* `aVertexPosition`, `aTextureCoord`, `uProjectionMatrix`, `uModelViewMatrix`,
|
|
40
|
+
* `uTime`, and must write `vTexCoord` + `gl_Position`.
|
|
41
|
+
*
|
|
42
|
+
* Declare extra uniforms and set them via `set(name, value)`. A uniform value
|
|
43
|
+
* may be a number, an array (vec2/3/4), or a FUNCTION: the function is called
|
|
44
|
+
* each draw and receives the Drawable currently rendering, so a single shared
|
|
45
|
+
* Material can read PER-OBJECT state (e.g. each card's own tilt angle).
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* // Per-object 3D tilt with one shared material:
|
|
49
|
+
* const tilt = new Material(fragSrc, {
|
|
50
|
+
* vertex: tiltVertexSrc,
|
|
51
|
+
* uniforms: { uTiltX: (d) => d._tiltX || 0, uTiltY: (d) => d._tiltY || 0 },
|
|
52
|
+
* });
|
|
53
|
+
* cardA.setMaterial(tilt); cardB.setMaterial(tilt);
|
|
54
|
+
* cardA.getComponent(Texture)._tiltX = 0.3; // each object animates independently
|
|
55
|
+
*/
|
|
56
|
+
class Material {
|
|
57
|
+
/**
|
|
58
|
+
* @param {string} fragmentSource - Fragment shader body (declares void main)
|
|
59
|
+
* @param {Object} [options] - { vertex?: string, uniforms?: { name: value|function } }
|
|
60
|
+
*/
|
|
61
|
+
constructor(fragmentSource, options = {}) {
|
|
62
|
+
const gl = GLManager.getGL();
|
|
63
|
+
this.gl = gl;
|
|
64
|
+
|
|
65
|
+
const vertexSource = options.vertex
|
|
66
|
+
? MATERIAL_VERTEX_HEADER + options.vertex
|
|
67
|
+
: STANDARD_VERTEX_SHADER;
|
|
68
|
+
|
|
69
|
+
/** @private */
|
|
70
|
+
this._vertexSource = vertexSource;
|
|
71
|
+
/** @private */
|
|
72
|
+
this._fragmentSource = MATERIAL_FRAGMENT_HEADER + fragmentSource;
|
|
73
|
+
|
|
74
|
+
this.program = initShaderProgram(
|
|
75
|
+
gl,
|
|
76
|
+
this._vertexSource,
|
|
77
|
+
this._fragmentSource
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
this.programInfo = {
|
|
81
|
+
program: this.program,
|
|
82
|
+
attribLocations: {
|
|
83
|
+
vertexPosition: gl.getAttribLocation(this.program, "aVertexPosition"),
|
|
84
|
+
aTexCoord: gl.getAttribLocation(this.program, "aTextureCoord"),
|
|
85
|
+
},
|
|
86
|
+
uniformLocations: {
|
|
87
|
+
projectionMatrix: gl.getUniformLocation(
|
|
88
|
+
this.program,
|
|
89
|
+
"uProjectionMatrix"
|
|
90
|
+
),
|
|
91
|
+
globalViewMatrix: gl.getUniformLocation(
|
|
92
|
+
this.program,
|
|
93
|
+
"uModelViewMatrix"
|
|
94
|
+
),
|
|
95
|
+
useInstances: gl.getUniformLocation(this.program, "useInstances"),
|
|
96
|
+
uSampler: gl.getUniformLocation(this.program, "uSampler"),
|
|
97
|
+
color: gl.getUniformLocation(this.program, "uColor"),
|
|
98
|
+
uOpacity: gl.getUniformLocation(this.program, "uOpacity"),
|
|
99
|
+
uTime: gl.getUniformLocation(this.program, "uTime"),
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
this.uniforms = Object.assign({}, options.uniforms);
|
|
104
|
+
/** @private */
|
|
105
|
+
this._locCache = new Map();
|
|
106
|
+
|
|
107
|
+
GLManager.registerRestorable(this);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @method _restoreGL
|
|
112
|
+
* @description Recompiles the material's program and refreshes every cached
|
|
113
|
+
* location after a WebGL context loss.
|
|
114
|
+
* @private
|
|
115
|
+
*/
|
|
116
|
+
_restoreGL() {
|
|
117
|
+
const gl = this.gl;
|
|
118
|
+
if (!gl) return;
|
|
119
|
+
this.program = initShaderProgram(
|
|
120
|
+
gl,
|
|
121
|
+
this._vertexSource,
|
|
122
|
+
this._fragmentSource
|
|
123
|
+
);
|
|
124
|
+
this._locCache.clear();
|
|
125
|
+
this.programInfo.program = this.program;
|
|
126
|
+
const a = this.programInfo.attribLocations;
|
|
127
|
+
a.vertexPosition = gl.getAttribLocation(this.program, "aVertexPosition");
|
|
128
|
+
a.aTexCoord = gl.getAttribLocation(this.program, "aTextureCoord");
|
|
129
|
+
const u = this.programInfo.uniformLocations;
|
|
130
|
+
u.projectionMatrix = gl.getUniformLocation(
|
|
131
|
+
this.program,
|
|
132
|
+
"uProjectionMatrix"
|
|
133
|
+
);
|
|
134
|
+
u.globalViewMatrix = gl.getUniformLocation(
|
|
135
|
+
this.program,
|
|
136
|
+
"uModelViewMatrix"
|
|
137
|
+
);
|
|
138
|
+
u.useInstances = gl.getUniformLocation(this.program, "useInstances");
|
|
139
|
+
u.uSampler = gl.getUniformLocation(this.program, "uSampler");
|
|
140
|
+
u.color = gl.getUniformLocation(this.program, "uColor");
|
|
141
|
+
u.uOpacity = gl.getUniformLocation(this.program, "uOpacity");
|
|
142
|
+
u.uTime = gl.getUniformLocation(this.program, "uTime");
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* @method set
|
|
147
|
+
* @description Sets (or schedules) a custom uniform value. Numbers, arrays
|
|
148
|
+
* (vec2/3/4), and functions returning those are supported. A function uniform
|
|
149
|
+
* receives the Drawable currently being rendered.
|
|
150
|
+
* @param {string} name - Uniform name
|
|
151
|
+
* @param {number|number[]|Function} value
|
|
152
|
+
* @returns {Material} - this
|
|
153
|
+
*/
|
|
154
|
+
set(name, value) {
|
|
155
|
+
this.uniforms[name] = value;
|
|
156
|
+
return this;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** @private */
|
|
160
|
+
_loc(name) {
|
|
161
|
+
if (!this._locCache.has(name)) {
|
|
162
|
+
this._locCache.set(name, this.gl.getUniformLocation(this.program, name));
|
|
163
|
+
}
|
|
164
|
+
return this._locCache.get(name);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* @method applyCustomUniforms
|
|
169
|
+
* @description Uploads all user-declared uniforms. Called by Drawable each draw
|
|
170
|
+
* after the program is bound. Inferred by value shape. Function uniforms are
|
|
171
|
+
* called with the rendering Drawable so shared materials can read per-object data.
|
|
172
|
+
* @param {Drawable} [drawable] - The drawable currently rendering
|
|
173
|
+
*/
|
|
174
|
+
applyCustomUniforms(drawable) {
|
|
175
|
+
const gl = this.gl;
|
|
176
|
+
for (const name in this.uniforms) {
|
|
177
|
+
let value = this.uniforms[name];
|
|
178
|
+
if (typeof value === "function") value = value(drawable);
|
|
179
|
+
const loc = this._loc(name);
|
|
180
|
+
if (loc == null) continue;
|
|
181
|
+
if (typeof value === "number") {
|
|
182
|
+
gl.uniform1f(loc, value);
|
|
183
|
+
} else if (Array.isArray(value) || value instanceof Float32Array) {
|
|
184
|
+
switch (value.length) {
|
|
185
|
+
case 2:
|
|
186
|
+
gl.uniform2fv(loc, value);
|
|
187
|
+
break;
|
|
188
|
+
case 3:
|
|
189
|
+
gl.uniform3fv(loc, value);
|
|
190
|
+
break;
|
|
191
|
+
case 4:
|
|
192
|
+
gl.uniform4fv(loc, value);
|
|
193
|
+
break;
|
|
194
|
+
default:
|
|
195
|
+
gl.uniform1fv(loc, value);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export default Material;
|
package/src/MathUtils.js
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @class MathUtils
|
|
3
|
+
* @description Common math helpers for games: interpolation, clamping, angle
|
|
4
|
+
* conversion, random ranges, and lightweight 2D vector operations that work on
|
|
5
|
+
* any `{ x, y }` object (including the physics engine's Vec2 and Emerald
|
|
6
|
+
* Vector2).
|
|
7
|
+
*/
|
|
8
|
+
class MathUtils {
|
|
9
|
+
/**
|
|
10
|
+
* Clamps a value to the [min, max] range.
|
|
11
|
+
*/
|
|
12
|
+
static clamp(value, min, max) {
|
|
13
|
+
return value < min ? min : value > max ? max : value;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Linearly interpolates between a and b by t (t is not clamped).
|
|
18
|
+
*/
|
|
19
|
+
static lerp(a, b, t) {
|
|
20
|
+
return a + (b - a) * t;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Inverse lerp: returns the t for which lerp(a, b, t) === value.
|
|
25
|
+
*/
|
|
26
|
+
static inverseLerp(a, b, value) {
|
|
27
|
+
return a === b ? 0 : (value - a) / (b - a);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Remaps a value from one range to another.
|
|
32
|
+
*/
|
|
33
|
+
static map(value, inMin, inMax, outMin, outMax) {
|
|
34
|
+
return MathUtils.lerp(
|
|
35
|
+
outMin,
|
|
36
|
+
outMax,
|
|
37
|
+
MathUtils.inverseLerp(inMin, inMax, value)
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Converts degrees to radians.
|
|
43
|
+
*/
|
|
44
|
+
static degToRad(degrees) {
|
|
45
|
+
return (degrees * Math.PI) / 180;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Converts radians to degrees.
|
|
50
|
+
*/
|
|
51
|
+
static radToDeg(radians) {
|
|
52
|
+
return (radians * 180) / Math.PI;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Returns a random float in [min, max).
|
|
57
|
+
*/
|
|
58
|
+
static randomRange(min, max) {
|
|
59
|
+
return min + Math.random() * (max - min);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Returns a random integer in [min, max] (inclusive).
|
|
64
|
+
*/
|
|
65
|
+
static randomInt(min, max) {
|
|
66
|
+
return Math.floor(min + Math.random() * (max - min + 1));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Returns a random element of an array (or undefined if empty).
|
|
71
|
+
*/
|
|
72
|
+
static randomChoice(array) {
|
|
73
|
+
return array.length
|
|
74
|
+
? array[Math.floor(Math.random() * array.length)]
|
|
75
|
+
: undefined;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Euclidean distance between two `{ x, y }` points.
|
|
80
|
+
*/
|
|
81
|
+
static distance(a, b) {
|
|
82
|
+
const dx = a.x - b.x;
|
|
83
|
+
const dy = a.y - b.y;
|
|
84
|
+
return Math.sqrt(dx * dx + dy * dy);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Squared distance between two points (cheaper than distance for comparisons).
|
|
89
|
+
*/
|
|
90
|
+
static distanceSquared(a, b) {
|
|
91
|
+
const dx = a.x - b.x;
|
|
92
|
+
const dy = a.y - b.y;
|
|
93
|
+
return dx * dx + dy * dy;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Vector length (magnitude) of an `{ x, y }`.
|
|
98
|
+
*/
|
|
99
|
+
static length(v) {
|
|
100
|
+
return Math.sqrt(v.x * v.x + v.y * v.y);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Returns a normalized copy of `{ x, y }` as a plain object. Zero-length
|
|
105
|
+
* vectors return { x: 0, y: 0 }.
|
|
106
|
+
*/
|
|
107
|
+
static normalize(v) {
|
|
108
|
+
const len = MathUtils.length(v);
|
|
109
|
+
return len === 0 ? { x: 0, y: 0 } : { x: v.x / len, y: v.y / len };
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Dot product of two `{ x, y }` vectors.
|
|
114
|
+
*/
|
|
115
|
+
static dot(a, b) {
|
|
116
|
+
return a.x * b.x + a.y * b.y;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Angle in radians from a to b.
|
|
121
|
+
*/
|
|
122
|
+
static angleBetween(a, b) {
|
|
123
|
+
return Math.atan2(b.y - a.y, b.x - a.x);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Linearly interpolates between two `{ x, y }` points, returning a plain object.
|
|
128
|
+
*/
|
|
129
|
+
static lerpVector(a, b, t) {
|
|
130
|
+
return { x: MathUtils.lerp(a.x, b.x, t), y: MathUtils.lerp(a.y, b.y, t) };
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export default MathUtils;
|