@woosh/meep-engine 3.0.0 → 3.0.1
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/editor/particles/rebuildParticleEmitter.js +8 -26
- package/editor/process/symbolic/CameraSymbolicDisplay.js +146 -146
- package/editor/tools/SelectionTool.js +1 -2
- package/editor/tools/TransformToolV2.js +2 -3
- package/editor/tools/v2/BlenderCameraOrientationGizmo.js +501 -501
- package/editor/tools/v2/TransformControls.js +1 -1
- package/package.json +95 -96
- package/src/core/geom/3d/mat4/m4_look_at.d.ts +25 -0
- package/src/core/geom/3d/mat4/m4_look_at.d.ts.map +1 -0
- package/src/core/geom/3d/mat4/m4_look_at.js +96 -0
- package/src/core/geom/3d/mat4/m4_make_rotation_x.d.ts +18 -0
- package/src/core/geom/3d/mat4/m4_make_rotation_x.d.ts.map +1 -0
- package/src/core/geom/3d/mat4/m4_make_rotation_x.js +47 -0
- package/src/core/geom/3d/mat4/m4_make_rotation_y.d.ts +18 -0
- package/src/core/geom/3d/mat4/m4_make_rotation_y.d.ts.map +1 -0
- package/src/core/geom/3d/mat4/m4_make_rotation_y.js +47 -0
- package/src/core/geom/3d/mat4/m4_make_rotation_z.d.ts +18 -0
- package/src/core/geom/3d/mat4/m4_make_rotation_z.d.ts.map +1 -0
- package/src/core/geom/3d/mat4/m4_make_rotation_z.js +47 -0
- package/src/core/geom/3d/mat4/m4_perspective.d.ts +25 -0
- package/src/core/geom/3d/mat4/m4_perspective.d.ts.map +1 -0
- package/src/core/geom/3d/mat4/m4_perspective.js +66 -0
- package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts.map +1 -1
- package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +2045 -2052
- package/src/engine/ecs/gui/hud/testHudEdgeStick.js +2 -2
- package/src/engine/ecs/terrain/ecs/TerrainSystem.d.ts.map +1 -1
- package/src/engine/ecs/terrain/ecs/TerrainSystem.js +14 -27
- package/src/engine/ecs/terrain/util/loadVisibleTerrainTiles.d.ts.map +1 -1
- package/src/engine/ecs/terrain/util/loadVisibleTerrainTiles.js +129 -126
- package/src/engine/graphics/ecs/camera/Camera.d.ts +36 -48
- package/src/engine/graphics/ecs/camera/Camera.d.ts.map +1 -1
- package/src/engine/graphics/ecs/camera/Camera.js +165 -303
- package/src/engine/graphics/ecs/camera/camera_active_frustum.d.ts +14 -0
- package/src/engine/graphics/ecs/camera/camera_active_frustum.d.ts.map +1 -0
- package/src/engine/graphics/ecs/camera/camera_active_frustum.js +25 -0
- package/src/engine/graphics/ecs/camera/camera_find_active.d.ts +16 -0
- package/src/engine/graphics/ecs/camera/camera_find_active.d.ts.map +1 -0
- package/src/engine/graphics/ecs/camera/camera_find_active.js +28 -0
- package/src/engine/graphics/ecs/camera/camera_traverse_active.d.ts +12 -0
- package/src/engine/graphics/ecs/camera/camera_traverse_active.d.ts.map +1 -0
- package/src/engine/graphics/ecs/camera/camera_traverse_active.js +18 -0
- package/src/engine/graphics/ecs/camera/pp/PerfectPanner.js +170 -170
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.d.ts +5 -1
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.d.ts.map +1 -1
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.js +296 -281
- package/src/engine/graphics/ecs/render_layers_compute_depth_range.d.ts +1 -1
- package/src/engine/graphics/ecs/render_layers_compute_depth_range.js +1 -1
- package/src/engine/graphics/geometry/AttributeData.d.ts +52 -0
- package/src/engine/graphics/geometry/AttributeData.d.ts.map +1 -0
- package/src/engine/graphics/geometry/AttributeData.js +84 -0
- package/src/engine/graphics/particles/particular/engine/ParticularEngine.d.ts +1 -14
- package/src/engine/graphics/particles/particular/engine/ParticularEngine.d.ts.map +1 -1
- package/src/engine/graphics/particles/particular/engine/ParticularEngine.js +229 -253
- package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.d.ts +25 -12
- package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.d.ts.map +1 -1
- package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js +1149 -1194
- package/src/engine/graphics/particles/particular/engine/emitter/ParticlePool.d.ts +4 -8
- package/src/engine/graphics/particles/particular/engine/emitter/ParticlePool.d.ts.map +1 -1
- package/src/engine/graphics/particles/particular/engine/emitter/ParticlePool.js +472 -540
- package/src/engine/graphics/particles/particular/engine/shader/ShaderManager.d.ts +19 -90
- package/src/engine/graphics/particles/particular/engine/shader/ShaderManager.d.ts.map +1 -1
- package/src/engine/graphics/particles/particular/engine/shader/ShaderManager.js +135 -514
- package/src/engine/graphics3/CameraSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/CameraSystem3.js +10 -1
- package/src/engine/graphics3/GraphicsEngine3.d.ts +3 -3
- package/src/engine/graphics3/GraphicsEngine3.js +3 -3
- package/src/engine/graphics3/ParticleEmitterSystem3.d.ts +11 -0
- package/src/engine/graphics3/ParticleEmitterSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/ParticleEmitterSystem3.js +289 -265
- package/src/engine/graphics3/ShadeCameraAdapter.d.ts +3 -3
- package/src/engine/graphics3/ShadeCameraAdapter.js +3 -3
- package/src/engine/graphics3/camera_sync_from_transform.d.ts +2 -2
- package/src/engine/graphics3/camera_sync_from_transform.js +2 -2
- package/src/engine/graphics3/shade_camera_projection_ray.js +2 -2
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/shade/renderer/camera/Camera.d.ts +3 -5
- package/src/shade/renderer/camera/Camera.d.ts.map +1 -1
- package/src/shade/renderer/camera/Camera.js +281 -280
- package/src/shade/renderer/camera/GPUCameraContext.js +233 -233
- package/src/shade/renderer/loader/usd/parse_usda.js +1 -1
- package/src/shade/renderer/loader/usd/usd_build_scene.d.ts.map +1 -1
- package/src/shade/renderer/loader/usd/usd_build_scene.js +658 -652
- package/src/shade/renderer/loader/usd/usd_compose_transform.d.ts.map +1 -1
- package/src/shade/renderer/loader/usd/usd_compose_transform.js +58 -23
- package/src/shade/renderer/particles/prototypeParticleSystem.js +450 -443
- package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.d.ts.map +1 -1
- package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.js +7 -3
- package/src/view/minimap/dom/MinimapCameraView.d.ts +2 -2
- package/src/view/minimap/dom/MinimapCameraView.js +206 -206
- package/src/engine/graphics/ecs/camera/CameraSystem.d.ts +0 -74
- package/src/engine/graphics/ecs/camera/CameraSystem.d.ts.map +0 -1
- package/src/engine/graphics/ecs/camera/CameraSystem.js +0 -331
- package/src/engine/graphics/ecs/camera/auto_set_camera_clipping_planes.d.ts +0 -10
- package/src/engine/graphics/ecs/camera/auto_set_camera_clipping_planes.d.ts.map +0 -1
- package/src/engine/graphics/ecs/camera/auto_set_camera_clipping_planes.js +0 -105
- package/src/engine/graphics/ecs/camera/build_three_camera_object.d.ts +0 -7
- package/src/engine/graphics/ecs/camera/build_three_camera_object.d.ts.map +0 -1
- package/src/engine/graphics/ecs/camera/build_three_camera_object.js +0 -29
- package/src/engine/graphics/ecs/camera/frustum_from_camera.d.ts +0 -8
- package/src/engine/graphics/ecs/camera/frustum_from_camera.d.ts.map +0 -1
- package/src/engine/graphics/ecs/camera/frustum_from_camera.js +0 -20
- package/src/engine/graphics/ecs/camera/set_camera_aspect_ratio.d.ts +0 -9
- package/src/engine/graphics/ecs/camera/set_camera_aspect_ratio.d.ts.map +0 -1
- package/src/engine/graphics/ecs/camera/set_camera_aspect_ratio.js +0 -46
- package/src/engine/graphics/ecs/camera/unprojectPoint.d.ts +0 -9
- package/src/engine/graphics/ecs/camera/unprojectPoint.d.ts.map +0 -1
- package/src/engine/graphics/ecs/camera/unprojectPoint.js +0 -14
- package/src/engine/graphics/ecs/camera/update_camera_transform.d.ts +0 -6
- package/src/engine/graphics/ecs/camera/update_camera_transform.d.ts.map +0 -1
- package/src/engine/graphics/ecs/camera/update_camera_transform.js +0 -17
- package/src/engine/graphics/particles/ecs/ParticleEmitterSystem.d.ts +0 -67
- package/src/engine/graphics/particles/ecs/ParticleEmitterSystem.d.ts.map +0 -1
- package/src/engine/graphics/particles/ecs/ParticleEmitterSystem.js +0 -291
- package/src/engine/graphics/particles/particular/engine/renderers/billboard/ParticleBillboardMaterial.d.ts +0 -11
- package/src/engine/graphics/particles/particular/engine/renderers/billboard/ParticleBillboardMaterial.d.ts.map +0 -1
- package/src/engine/graphics/particles/particular/engine/renderers/billboard/ParticleBillboardMaterial.js +0 -497
- package/src/engine/graphics/particles/particular/engine/shader/MaterialRecord.d.ts +0 -40
- package/src/engine/graphics/particles/particular/engine/shader/MaterialRecord.d.ts.map +0 -1
- package/src/engine/graphics/particles/particular/engine/shader/MaterialRecord.js +0 -47
- package/src/engine/graphics/texture/sampler/writeSampler2DDataToDataTexture.d.ts +0 -7
- package/src/engine/graphics/texture/sampler/writeSampler2DDataToDataTexture.d.ts.map +0 -1
- package/src/engine/graphics/texture/sampler/writeSampler2DDataToDataTexture.js +0 -40
|
@@ -1,514 +1,135 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
*
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
*/
|
|
137
|
-
this.spriteTexture = buildDataTexture({
|
|
138
|
-
generateMipmaps: true,
|
|
139
|
-
minFilter: LinearMipMapLinearFilter,
|
|
140
|
-
magFilter: LinearFilter,
|
|
141
|
-
anisotropy: 0 // sprites are always facing the screen, anisotropic filtering would be pointless
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
this.spriteTexture.name = 'Sprite sheet';
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* material map is identified by parameter hash
|
|
148
|
-
* @readonly
|
|
149
|
-
* @private
|
|
150
|
-
* @type {HashMap<ParticleEmitter, MaterialRecord>}
|
|
151
|
-
*/
|
|
152
|
-
this.materialMap = new HashMap({
|
|
153
|
-
keyHashFunction: computeEmitterMaterialHash,
|
|
154
|
-
keyEqualityFunction: computeEmitterMaterialEquality
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* @readonly
|
|
159
|
-
* @private
|
|
160
|
-
* @type {HashMap<ParticleEmitter, MaterialRecord>}
|
|
161
|
-
*/
|
|
162
|
-
this.recordGraveyard = new HashMap({
|
|
163
|
-
keyHashFunction: computeEmitterMaterialHash,
|
|
164
|
-
keyEqualityFunction: computeEmitterMaterialEquality
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
*
|
|
169
|
-
* @type {Vector2}
|
|
170
|
-
*/
|
|
171
|
-
this.viewportSize = new Vector2(0, 0);
|
|
172
|
-
|
|
173
|
-
//watch atlas updates
|
|
174
|
-
this.spriteAtlas.atlas.on.painted.add(this.updateSpriteTexture, this);
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Common shader uniforms, inherited by every material and updated centrally (here)
|
|
178
|
-
* @private
|
|
179
|
-
*/
|
|
180
|
-
this.__common_uniforms = {
|
|
181
|
-
tSpriteAtlas: {
|
|
182
|
-
value: this.spriteTexture
|
|
183
|
-
},
|
|
184
|
-
tDepth: {
|
|
185
|
-
value: null
|
|
186
|
-
},
|
|
187
|
-
resolution: {
|
|
188
|
-
value: new ThreeVector2()
|
|
189
|
-
},
|
|
190
|
-
projectionMatrix: {
|
|
191
|
-
value: null
|
|
192
|
-
},
|
|
193
|
-
modelViewMatrix: {
|
|
194
|
-
value: null
|
|
195
|
-
},
|
|
196
|
-
cameraNear: {
|
|
197
|
-
value: 0
|
|
198
|
-
},
|
|
199
|
-
cameraFar: {
|
|
200
|
-
value: 0
|
|
201
|
-
},
|
|
202
|
-
uViewInverse: { type: 'm4', value: new Matrix4() },
|
|
203
|
-
uProjectionInverse: { type: 'm4', value: new Matrix4() },
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
// debugAtlas(this.spriteAtlas.atlas, { scale: new Vector2(1, 1) });
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* Should be called before using shaders managed by this
|
|
211
|
-
*/
|
|
212
|
-
update() {
|
|
213
|
-
this.spriteAtlas.atlas.update();
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* @private
|
|
219
|
-
*/
|
|
220
|
-
updateSpriteTexture() {
|
|
221
|
-
// console.time("ShaderManager.updateSpriteTexture");
|
|
222
|
-
|
|
223
|
-
const atlas = this.spriteAtlas.atlas.sampler;
|
|
224
|
-
|
|
225
|
-
const dataTexture = this.spriteTexture;
|
|
226
|
-
|
|
227
|
-
writeSample2DDataToDataTexture(atlas, dataTexture);
|
|
228
|
-
|
|
229
|
-
this.materialMap.forEach(function (entry) {
|
|
230
|
-
|
|
231
|
-
const emitters = entry.emitters;
|
|
232
|
-
const emitter_count = emitters.length;
|
|
233
|
-
|
|
234
|
-
for (let i = 0; i < emitter_count; i++) {
|
|
235
|
-
const emitter = emitters[i];
|
|
236
|
-
//mark sprites for an update
|
|
237
|
-
emitter.setFlag(ParticleEmitterFlag.SpritesNeedUpdate);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
// console.timeEnd("ShaderManager.updateSpriteTexture");
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
/**
|
|
246
|
-
* @private
|
|
247
|
-
* @returns {Reference<Material>}
|
|
248
|
-
* @param {ParticleEmitter} emitter
|
|
249
|
-
*/
|
|
250
|
-
buildMaterial(emitter) {
|
|
251
|
-
const lights_enabled = emitter.getFlag(ParticleEmitterFlag.Lit);
|
|
252
|
-
|
|
253
|
-
const shader = make_particle_billboard_shader({ lights: lights_enabled });
|
|
254
|
-
|
|
255
|
-
shader.uniforms = Object.assign(shader.uniforms, this.__common_uniforms);
|
|
256
|
-
|
|
257
|
-
// write defines
|
|
258
|
-
const defs = shader.defines;
|
|
259
|
-
|
|
260
|
-
defs.DEPTH_READ_ENABLED = !emitter.getFlag(ParticleEmitterFlag.DepthReadDisabled);
|
|
261
|
-
defs.DEPTH_SOFT_ENABLED = !emitter.getFlag(ParticleEmitterFlag.DepthSoftDisabled);
|
|
262
|
-
defs.ALIGN_DIRECTION_ENABLED = emitter.getFlag(ParticleEmitterFlag.AlignOnVelocity);
|
|
263
|
-
|
|
264
|
-
return this.__material_manager.obtain(shader);
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
/**
|
|
268
|
-
*
|
|
269
|
-
* @param {ParticleEmitter} emitter
|
|
270
|
-
*/
|
|
271
|
-
register(emitter) {
|
|
272
|
-
const spriteAtlas = this.spriteAtlas;
|
|
273
|
-
|
|
274
|
-
// load sprites
|
|
275
|
-
const particle_layers = emitter.layers;
|
|
276
|
-
const layer_count = particle_layers.length;
|
|
277
|
-
|
|
278
|
-
for (let i = 0; i < layer_count; i++) {
|
|
279
|
-
const layer = particle_layers.get(i);
|
|
280
|
-
|
|
281
|
-
const patchPromise = spriteAtlas.acquire(layer.imageURL);
|
|
282
|
-
|
|
283
|
-
patchPromise.then(ref => {
|
|
284
|
-
this.#sprite_references.set(layer, ref);
|
|
285
|
-
layer.setAtlasPatch(ref.getValue());
|
|
286
|
-
});
|
|
287
|
-
|
|
288
|
-
patchPromise.catch((e) => {
|
|
289
|
-
console.warn(`Failed to load sprite '${layer.imageURL}':`, e);
|
|
290
|
-
});
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
// obtain material
|
|
294
|
-
let material, entry;
|
|
295
|
-
if (this.materialMap.has(emitter)) {
|
|
296
|
-
entry = this.materialMap.get(emitter);
|
|
297
|
-
|
|
298
|
-
// the record is in use again, so it is no longer a candidate for the graveyard eviction in
|
|
299
|
-
// `cleanup`, which releases the material reference the record still hands to live emitters
|
|
300
|
-
this.recordGraveyard.delete(emitter);
|
|
301
|
-
|
|
302
|
-
material = entry.material;
|
|
303
|
-
} else {
|
|
304
|
-
|
|
305
|
-
// entry is not in the cache, create it
|
|
306
|
-
entry = createShaderEntry(emitter, this);
|
|
307
|
-
|
|
308
|
-
material = entry.material;
|
|
309
|
-
|
|
310
|
-
this.materialMap.set(emitter, entry);
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
entry.lastAccessTime = performance.now();
|
|
314
|
-
|
|
315
|
-
entry.count++;
|
|
316
|
-
|
|
317
|
-
entry.emitters.push(emitter);
|
|
318
|
-
|
|
319
|
-
// assign material
|
|
320
|
-
emitter.mesh.material = material;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* Perform intenal cleanup, remove unused material records
|
|
325
|
-
*/
|
|
326
|
-
cleanup() {
|
|
327
|
-
const recordGraveyardSize = this.recordGraveyardSize;
|
|
328
|
-
|
|
329
|
-
while (this.recordGraveyard.size > recordGraveyardSize) {
|
|
330
|
-
let bestAccessTime = Infinity;
|
|
331
|
-
let bestKey = null;
|
|
332
|
-
|
|
333
|
-
this.recordGraveyard.forEach(function (value, key) {
|
|
334
|
-
if (value.lastAccessTime < bestAccessTime) {
|
|
335
|
-
bestAccessTime = value.lastAccessTime;
|
|
336
|
-
bestKey = key;
|
|
337
|
-
}
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
const evicted = this.recordGraveyard.get(bestKey);
|
|
341
|
-
|
|
342
|
-
if (!this.recordGraveyard.delete(bestKey)) {
|
|
343
|
-
console.error(`Failed to remove record from the graveyard`, bestKey, this.recordGraveyard);
|
|
344
|
-
|
|
345
|
-
this.recordGraveyard.verifyHashes(console.error);
|
|
346
|
-
|
|
347
|
-
console.warn('Recomputing hashes ... ');
|
|
348
|
-
|
|
349
|
-
this.recordGraveyard.rebuild();
|
|
350
|
-
this.materialMap.rebuild();
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
this.materialMap.delete(bestKey);
|
|
354
|
-
|
|
355
|
-
// the record is leaving both maps, so this is the last chance to hand the material back;
|
|
356
|
-
// only unused records reach the graveyard, `register` takes a resurrected one back out of it
|
|
357
|
-
evicted.material_reference.release();
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
/**
|
|
362
|
-
*
|
|
363
|
-
* @param {ParticleEmitter} emitter
|
|
364
|
-
*/
|
|
365
|
-
deregister(emitter) {
|
|
366
|
-
const entry = this.materialMap.get(emitter);
|
|
367
|
-
|
|
368
|
-
if (entry === undefined) {
|
|
369
|
-
console.error(`Attempted to deregister emitter that was not registered (not found in materialMap). Request ignored.`, emitter);
|
|
370
|
-
return;
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
entry.count--;
|
|
374
|
-
|
|
375
|
-
//release material
|
|
376
|
-
const spriteAtlas = this.spriteAtlas;
|
|
377
|
-
|
|
378
|
-
//release sprites
|
|
379
|
-
const particle_layers = emitter.layers;
|
|
380
|
-
const layer_count = particle_layers.length;
|
|
381
|
-
for (let i = 0; i < layer_count; i++) {
|
|
382
|
-
const layer = particle_layers.get(i);
|
|
383
|
-
|
|
384
|
-
// TODO deal with the case where we remove the layer before sprite is loaded
|
|
385
|
-
const ref = this.#sprite_references.get(layer);
|
|
386
|
-
|
|
387
|
-
if (ref !== undefined) {
|
|
388
|
-
ref.release();
|
|
389
|
-
|
|
390
|
-
// the reference is spent, and the map is what keeps the layer reachable
|
|
391
|
-
this.#sprite_references.delete(layer);
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
layer.setAtlasPatch(null); // clear patch
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
if (entry.count <= 0) {
|
|
398
|
-
//last usage removed
|
|
399
|
-
this.recordGraveyard.set(emitter, entry);
|
|
400
|
-
this.cleanup();
|
|
401
|
-
|
|
402
|
-
} else {
|
|
403
|
-
//remove reference to material from the entry
|
|
404
|
-
const emitterIndex = entry.emitters.indexOf(emitter);
|
|
405
|
-
|
|
406
|
-
if (emitterIndex === -1) {
|
|
407
|
-
console.warn('Emitter was not found in the shader manager');
|
|
408
|
-
return;
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
//remove
|
|
412
|
-
entry.emitters.splice(emitterIndex, 1);
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
/**
|
|
417
|
-
*
|
|
418
|
-
* @param {Camera} camera THREE.js Camera object
|
|
419
|
-
*/
|
|
420
|
-
setCamera(camera) {
|
|
421
|
-
this.camera = camera;
|
|
422
|
-
|
|
423
|
-
const projectionMatrix = camera.projectionMatrix;
|
|
424
|
-
const modelViewMatrix = (new Matrix4()).multiplyMatrices(camera.matrixWorldInverse, camera.matrixWorld);
|
|
425
|
-
const cameraNear = camera.near;
|
|
426
|
-
const cameraFar = camera.far;
|
|
427
|
-
|
|
428
|
-
const uniforms = this.__common_uniforms;
|
|
429
|
-
|
|
430
|
-
uniforms.projectionMatrix.value = projectionMatrix;
|
|
431
|
-
uniforms.modelViewMatrix.value = modelViewMatrix;
|
|
432
|
-
uniforms.cameraNear.value = cameraNear;
|
|
433
|
-
uniforms.cameraFar.value = cameraFar;
|
|
434
|
-
|
|
435
|
-
uniforms.uProjectionInverse.value.copy(camera.projectionMatrixInverse);
|
|
436
|
-
uniforms.uViewInverse.value.copy(camera.matrixWorld);
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
/**
|
|
440
|
-
*
|
|
441
|
-
* @param {Texture} texture
|
|
442
|
-
*/
|
|
443
|
-
setDepthTexture(texture) {
|
|
444
|
-
this.depthTexture = texture;
|
|
445
|
-
|
|
446
|
-
this.__common_uniforms.tDepth.value = texture;
|
|
447
|
-
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
/**
|
|
451
|
-
*
|
|
452
|
-
* @param {number} x
|
|
453
|
-
* @param {number} y
|
|
454
|
-
*/
|
|
455
|
-
setViewportSize(x, y) {
|
|
456
|
-
this.viewportSize.set(x, y);
|
|
457
|
-
|
|
458
|
-
this.__common_uniforms.resolution.value.set(x, y);
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
/**
|
|
462
|
-
* Hand back every resource this manager acquired.
|
|
463
|
-
*
|
|
464
|
-
* Materials are given back to the {@link MaterialManager} rather than disposed here: the compiled
|
|
465
|
-
* material is shared by content hash with every other consumer that asked for the same shader, so the
|
|
466
|
-
* manager is the only thing that can know when the last user is gone. Releasing is therefore safe
|
|
467
|
-
* whichever way the teardown ordering falls, even for a material a live mesh still points at.
|
|
468
|
-
*
|
|
469
|
-
* The manager is left able to re-acquire, so a system that starts up again gets working materials and
|
|
470
|
-
* a working sprite sheet without being rebuilt.
|
|
471
|
-
*/
|
|
472
|
-
dispose() {
|
|
473
|
-
// the graveyard is a subset of `materialMap` - `deregister` adds an unused record to the graveyard
|
|
474
|
-
// without taking it out of the material map, and `cleanup` is what drops it from both
|
|
475
|
-
this.materialMap.forEach(record => {
|
|
476
|
-
record.material_reference.release();
|
|
477
|
-
});
|
|
478
|
-
|
|
479
|
-
this.materialMap.clear();
|
|
480
|
-
this.recordGraveyard.clear();
|
|
481
|
-
|
|
482
|
-
for (const reference of this.#sprite_references.values()) {
|
|
483
|
-
reference.release();
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
this.#sprite_references.clear();
|
|
487
|
-
|
|
488
|
-
this.spriteTexture.dispose();
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
/**
|
|
493
|
-
*
|
|
494
|
-
* @param {ParticleEmitter} emitter
|
|
495
|
-
* @param {ShaderManager} shaderManager
|
|
496
|
-
* @returns {MaterialRecord}
|
|
497
|
-
*/
|
|
498
|
-
function createShaderEntry(emitter, shaderManager) {
|
|
499
|
-
const entry = new MaterialRecord();
|
|
500
|
-
entry.count = 0;
|
|
501
|
-
entry.parameters = emitter.parameters;
|
|
502
|
-
|
|
503
|
-
const material_reference = shaderManager.buildMaterial(emitter);
|
|
504
|
-
|
|
505
|
-
entry.material_reference = material_reference;
|
|
506
|
-
entry.material = material_reference.getValue();
|
|
507
|
-
|
|
508
|
-
//link all signal bindings
|
|
509
|
-
entry.signalBindings.forEach(function (b) {
|
|
510
|
-
b.link();
|
|
511
|
-
});
|
|
512
|
-
|
|
513
|
-
return entry;
|
|
514
|
-
}
|
|
1
|
+
import { assert } from "../../../../../../core/assert.js";
|
|
2
|
+
import { ManagedAtlas } from "../../../../texture/atlas/ManagedTextureAtlas.js";
|
|
3
|
+
import { ParticleEmitterFlag } from "../emitter/ParticleEmitterFlag.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The sprite sheet the particle system draws from.
|
|
7
|
+
*
|
|
8
|
+
* **Every emitter's layers share one atlas**, so a hundred effects using the same puff of smoke pay
|
|
9
|
+
* for one image; a layer holds a reference to the patch it was given and hands it back when the
|
|
10
|
+
* emitter is deregistered, and the atlas repacks when the set of patches changes.
|
|
11
|
+
*
|
|
12
|
+
* The class used to carry a second job — a compiled shader per emitter, keyed on the four flags
|
|
13
|
+
* that change the shader, with a graveyard of unused records to avoid recompiling. That was three's
|
|
14
|
+
* `ShaderMaterial`, and it is gone: the particles are drawn by a Shade pass that owns its own
|
|
15
|
+
* pipeline and reads the atlas sampler directly.
|
|
16
|
+
*/
|
|
17
|
+
export class ShaderManager {
|
|
18
|
+
/**
|
|
19
|
+
* The atlas patch each registered layer holds, so that deregistering can give it back.
|
|
20
|
+
*
|
|
21
|
+
* @type {Map<ParticleLayer, Reference<AtlasPatch>>}
|
|
22
|
+
*/
|
|
23
|
+
#sprite_references = new Map();
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The emitters currently drawing from the atlas. A repack has to reach all of them, and a
|
|
27
|
+
* layer does not know which emitter it belongs to.
|
|
28
|
+
*
|
|
29
|
+
* @type {Set<ParticleEmitter>}
|
|
30
|
+
*/
|
|
31
|
+
#emitters = new Set();
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @param {AssetManager} asset_manager
|
|
35
|
+
*/
|
|
36
|
+
constructor(asset_manager) {
|
|
37
|
+
assert.defined(asset_manager, "asset_manager");
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
*
|
|
41
|
+
* @type {ManagedAtlas}
|
|
42
|
+
*/
|
|
43
|
+
this.spriteAtlas = new ManagedAtlas(asset_manager);
|
|
44
|
+
|
|
45
|
+
this.spriteAtlas.atlas.on.painted.add(this.#handleAtlasPainted, this);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Should be called before using the sprite sheet.
|
|
50
|
+
*/
|
|
51
|
+
update() {
|
|
52
|
+
this.spriteAtlas.atlas.update();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* A repack moves every patch, so every particle already carrying UVs is carrying the wrong ones.
|
|
57
|
+
*/
|
|
58
|
+
#handleAtlasPainted() {
|
|
59
|
+
for (const emitter of this.#emitters) {
|
|
60
|
+
emitter.setFlag(ParticleEmitterFlag.SpritesNeedUpdate);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Take out a reference to every sprite the emitter's layers name.
|
|
66
|
+
*
|
|
67
|
+
* @param {ParticleEmitter} emitter
|
|
68
|
+
*/
|
|
69
|
+
register(emitter) {
|
|
70
|
+
const spriteAtlas = this.spriteAtlas;
|
|
71
|
+
|
|
72
|
+
this.#emitters.add(emitter);
|
|
73
|
+
|
|
74
|
+
const particle_layers = emitter.layers;
|
|
75
|
+
const layer_count = particle_layers.length;
|
|
76
|
+
|
|
77
|
+
for (let i = 0; i < layer_count; i++) {
|
|
78
|
+
const layer = particle_layers.get(i);
|
|
79
|
+
|
|
80
|
+
const patchPromise = spriteAtlas.acquire(layer.imageURL);
|
|
81
|
+
|
|
82
|
+
patchPromise.then(ref => {
|
|
83
|
+
this.#sprite_references.set(layer, ref);
|
|
84
|
+
layer.setAtlasPatch(ref.getValue());
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
patchPromise.catch((e) => {
|
|
88
|
+
console.warn(`Failed to load sprite '${layer.imageURL}':`, e);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Hand back every sprite the emitter's layers hold.
|
|
95
|
+
*
|
|
96
|
+
* @param {ParticleEmitter} emitter
|
|
97
|
+
*/
|
|
98
|
+
deregister(emitter) {
|
|
99
|
+
this.#emitters.delete(emitter);
|
|
100
|
+
|
|
101
|
+
const particle_layers = emitter.layers;
|
|
102
|
+
const layer_count = particle_layers.length;
|
|
103
|
+
|
|
104
|
+
for (let i = 0; i < layer_count; i++) {
|
|
105
|
+
const layer = particle_layers.get(i);
|
|
106
|
+
|
|
107
|
+
// TODO deal with the case where we remove the layer before sprite is loaded
|
|
108
|
+
const ref = this.#sprite_references.get(layer);
|
|
109
|
+
|
|
110
|
+
if (ref !== undefined) {
|
|
111
|
+
ref.release();
|
|
112
|
+
|
|
113
|
+
// the reference is spent, and the map is what keeps the layer reachable
|
|
114
|
+
this.#sprite_references.delete(layer);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
layer.setAtlasPatch(null); // clear patch
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Hand back every sprite this manager acquired.
|
|
123
|
+
*
|
|
124
|
+
* The manager is left able to re-acquire, so a system that starts up again gets a working
|
|
125
|
+
* sprite sheet without being rebuilt.
|
|
126
|
+
*/
|
|
127
|
+
dispose() {
|
|
128
|
+
for (const reference of this.#sprite_references.values()) {
|
|
129
|
+
reference.release();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
this.#sprite_references.clear();
|
|
133
|
+
this.#emitters.clear();
|
|
134
|
+
}
|
|
135
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CameraSystem3.d.ts","sourceRoot":"","sources":["../../../../src/engine/graphics3/CameraSystem3.js"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;GAgBG;AACH;IAoBI;;OAEG;IACH,uCAQC;IADG,mDAAuC;IAG3C,2CAEC;IAED,4CAIC;IAED;;;;OAIG;IACH,4BAEC;IAED;;;;OAIG;IACH,aAJW,MAAM,aACN,SAAS,UACT,MAAM,QAUhB;IAED;;;;OAIG;IACH,eAJW,MAAM,aACN,SAAS,UACT,MAAM,QAIhB;;
|
|
1
|
+
{"version":3,"file":"CameraSystem3.d.ts","sourceRoot":"","sources":["../../../../src/engine/graphics3/CameraSystem3.js"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;GAgBG;AACH;IAoBI;;OAEG;IACH,uCAQC;IADG,mDAAuC;IAG3C,2CAEC;IAED,4CAIC;IAED;;;;OAIG;IACH,4BAEC;IAED;;;;OAIG;IACH,aAJW,MAAM,aACN,SAAS,UACT,MAAM,QAUhB;IAED;;;;OAIG;IACH,eAJW,MAAM,aACN,SAAS,UACT,MAAM,QAIhB;;CAsEJ;uBAtKsB,kBAAkB;0BACf,+BAA+B;uBAClC,kCAAkC"}
|
|
@@ -100,7 +100,7 @@ export class CameraSystem3 extends System {
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
/**
|
|
103
|
-
* Copy the active camera entity onto the camera Shade draws with.
|
|
103
|
+
* Copy the active camera entity onto the camera Shade draws with, and its frustum back.
|
|
104
104
|
*
|
|
105
105
|
* @param {number} time_delta
|
|
106
106
|
*/
|
|
@@ -122,6 +122,15 @@ export class CameraSystem3 extends System {
|
|
|
122
122
|
target.far = entry.camera.clip_far;
|
|
123
123
|
|
|
124
124
|
camera_sync_from_transform(target, entry.transform);
|
|
125
|
+
|
|
126
|
+
/*
|
|
127
|
+
The return trip. Gameplay asks what the camera can see — which armies to generate now,
|
|
128
|
+
which terrain tiles a scene has to have before it is shown — and the honest answer is the
|
|
129
|
+
frustum the renderer is drawing with, not a second one derived from the component. It is
|
|
130
|
+
copied rather than aliased because the renderer's camera is one object and any number of
|
|
131
|
+
camera entities can pass through it.
|
|
132
|
+
*/
|
|
133
|
+
entry.camera.publishFrustum(target.frustum);
|
|
125
134
|
}
|
|
126
135
|
|
|
127
136
|
/**
|