@woosh/meep-engine 2.33.36 → 2.33.40
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/core/bvh2/binary/2/BinaryUint32BVH.js +3 -3
- package/core/collection/HashMap.js +19 -12
- package/core/collection/array/typed/typed_array_copy.js +2 -2
- package/core/collection/table/RowFirstTable.js +13 -8
- package/core/collection/table/RowFirstTableSpec.js +6 -0
- package/core/color/Color.js +5 -9
- package/core/color/ColorUtils.js +4 -150
- package/core/color/YCbCr_to_rgb_uint24.js +20 -0
- package/core/color/hsv2rgb.js +54 -0
- package/core/color/int2rgb.js +12 -0
- package/core/color/parseHex.js +18 -0
- package/core/color/rgb2hex.js +16 -0
- package/core/color/rgb2hsv.js +47 -0
- package/core/color/rgb2uint24.js +17 -0
- package/core/color/rgb_to_YCbCr_uint24.js +18 -0
- package/core/geom/3d/aabb/aabb3_matrix4_project_by_corners.js +1 -1
- package/core/geom/3d/aabb/compute_aabb_from_points.js +28 -0
- package/core/geom/3d/morton/mortonEncode_magicbits.js +7 -6
- package/core/geom/3d/morton/v3_morton_encode_transformed.js +15 -11
- package/core/geom/3d/plane/orient3d_fast.js +51 -0
- package/core/geom/3d/plane/plane_computeConvex3PlaneIntersection.js +5 -0
- package/core/geom/3d/tetrahedra/GetDepthForTetrahedronProbe.glsl +43 -0
- package/core/geom/3d/tetrahedra/compute_bounding_simplex_3d.js +177 -0
- package/core/geom/3d/tetrahedra/compute_bounding_simplex_3d.spec.js +66 -0
- package/core/geom/3d/tetrahedra/compute_circumsphere.js +271 -0
- package/core/geom/3d/tetrahedra/compute_delaunay_tetrahedral_mesh.js +50 -0
- package/core/geom/3d/tetrahedra/compute_delaunay_tetrahedral_mesh.spec.js +14 -0
- package/core/geom/3d/tetrahedra/point_in_tetrahedron_circumsphere.js +77 -0
- package/core/geom/3d/tetrahedra/tetrahedra_collection.js +454 -0
- package/core/geom/3d/tetrahedra/tetrahedron_contains_point.js +26 -0
- package/core/geom/Quaternion.js +4 -0
- package/core/math/hash/murmur3_32.js +39 -0
- package/core/process/undo/ActionProcessor.d.ts +2 -0
- package/core/process/undo/ActionProcessor.js +15 -4
- package/editor/tools/FoliagePaintTool.js +1 -1
- package/editor/tools/GridPaintTool.js +1 -1
- package/engine/asset/loaders/GLTFAssetLoader.js +4 -8
- package/engine/ecs/System.d.ts +24 -1
- package/engine/ecs/foliage/InstancedFoliage.js +45 -0
- package/engine/ecs/foliage/ecs/InstancedMeshLayer.js +4 -0
- package/engine/ecs/storage/BinaryBufferSerializer.js +48 -38
- package/engine/ecs/storage/binary/collection/BinaryCollectionSerializer.js +1 -1
- package/engine/ecs/terrain/ecs/splat/SplatMapOptimizerDebugger.js +1 -1
- package/engine/ecs/terrain/tiles/TerrainTile.js +1 -1
- package/engine/graphics/GraphicsEngine.js +7 -0
- package/engine/graphics/ecs/light/binding/fp/FPLightBinding.js +1 -1
- package/engine/graphics/ecs/mesh/Mesh.js +2 -2
- package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +13 -0
- package/engine/graphics/geometry/instancing/InstancedMeshGroup.js +339 -314
- package/engine/graphics/micron/prototypeVirtualGeometry.js +4 -1
- package/engine/graphics/micron/render/v1/VGThreeRenderer.js +6 -2
- package/engine/graphics/particles/node-based/rendering/billboard/ParticleBillboardShader.js +1 -1
- package/engine/graphics/particles/particular/engine/parameter/ParameterLookupTable.js +20 -24
- package/engine/graphics/particles/particular/engine/renderers/billboard/ParticleBillboardMaterial.js +100 -55
- package/engine/graphics/particles/particular/engine/shader/ShaderManager.js +7 -2
- package/engine/graphics/particles/particular/engine/utils/volume/ParticleVolume.js +1 -0
- package/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +2 -2
- package/engine/graphics/render/buffer/simple-fx/DepthLimitedBlur.js +9 -4
- package/engine/graphics/render/buffer/simple-fx/ao/AmbientOcclusionPostProcessEffect.js +7 -1
- package/engine/graphics/render/forward_plus/LightManager.js +295 -51
- package/engine/graphics/render/forward_plus/LightManager.spec.js +1 -1
- package/engine/graphics/render/forward_plus/PointLightData.js +9 -13
- package/engine/graphics/render/forward_plus/cluster/compute_light_data_hash_0.js +1 -1
- package/engine/graphics/render/forward_plus/data/TextureBackedMemoryRegion.js +10 -1
- package/engine/graphics/render/forward_plus/debug/LightClusterVolumeMaterial.js +1 -1
- package/engine/graphics/render/forward_plus/debug/buildLightClusterWidget.js +3 -1
- package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_ACCUMULATION.js +31 -18
- package/engine/graphics/render/forward_plus/materials/fp_build_fragment_shader.js +18 -4
- package/engine/graphics/render/forward_plus/model/AbstractLight.js +50 -0
- package/engine/graphics/render/forward_plus/model/Decal.js +68 -0
- package/engine/graphics/render/forward_plus/{PointLight.js → model/PointLight.js} +19 -11
- package/engine/graphics/render/forward_plus/{SpotLight.js → model/SpotLight.js} +20 -12
- package/engine/graphics/render/forward_plus/plugin/ForwardPlusRenderingPlugin.js +1 -1
- package/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +6 -5
- package/engine/graphics/render/forward_plus/{prototypeLightManager.js → prototype/prototypeLightManager.js} +100 -25
- package/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_texture.js +29 -20
- package/engine/graphics/render/visibility/IncrementalDeltaSet.d.ts +2 -0
- package/engine/graphics/render/visibility/IncrementalDeltaSet.js +1 -0
- package/engine/graphics/render/visibility/VisibilityComputer.js +8 -7
- package/engine/graphics/shaders/TerrainShader.js +5 -5
- package/engine/graphics/shadows/testShadowMapRendering.js +192 -0
- package/engine/graphics/texture/atlas/AbstractTextureAtlas.js +19 -0
- package/engine/graphics/texture/atlas/CachingTextureAtlas.js +99 -0
- package/engine/graphics/texture/atlas/ManagedTextureAtlas.js +19 -39
- package/engine/graphics/texture/atlas/ReferencedTextureAtlas.js +75 -0
- package/engine/graphics/texture/atlas/TextureAtlas.js +22 -2
- package/engine/reference/v2/Reference.d.ts +4 -0
- package/engine/reference/v2/Reference.js +3 -1
- package/package.json +2 -1
- package/view/elements/ColorPickerView.js +2 -1
|
@@ -74,6 +74,7 @@ export class IncrementalDeltaSet {
|
|
|
74
74
|
*
|
|
75
75
|
* @param {function(T):number} score_function
|
|
76
76
|
* @param {*} [score_context]
|
|
77
|
+
* @returns {void}
|
|
77
78
|
*/
|
|
78
79
|
sort(score_function, score_context) {
|
|
79
80
|
arrayQuickSort(this.elements, score_function, score_context, 0, this.size - 1);
|
|
@@ -9,6 +9,12 @@ const frustum = new Frustum();
|
|
|
9
9
|
*/
|
|
10
10
|
const objectFilters = [];
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
* @type {function[]}
|
|
15
|
+
*/
|
|
16
|
+
const objectFilterExecutors = [];
|
|
17
|
+
|
|
12
18
|
export const SOURCE_RENDER_LAYER_PROPERTY = '@meep-render-layer';
|
|
13
19
|
|
|
14
20
|
export class VisibilityComputer {
|
|
@@ -135,12 +141,6 @@ export class VisibilityComputer {
|
|
|
135
141
|
// clear visible set
|
|
136
142
|
// this.__output.initializeUpdate();
|
|
137
143
|
|
|
138
|
-
/**
|
|
139
|
-
*
|
|
140
|
-
* @type {function[]}
|
|
141
|
-
*/
|
|
142
|
-
const objectFilterExecutors = [];
|
|
143
|
-
|
|
144
144
|
const filters = this.filters;
|
|
145
145
|
const filterCount = filters.length;
|
|
146
146
|
|
|
@@ -151,7 +151,7 @@ export class VisibilityComputer {
|
|
|
151
151
|
|
|
152
152
|
if (f.enabled && f.layerPredicate(layer)) {
|
|
153
153
|
objectFilters[objectFilterCount] = f;
|
|
154
|
-
objectFilterExecutors
|
|
154
|
+
objectFilterExecutors[objectFilterCount] = f.objectPredicateExecute;
|
|
155
155
|
|
|
156
156
|
objectFilterCount++;
|
|
157
157
|
}
|
|
@@ -165,6 +165,7 @@ export class VisibilityComputer {
|
|
|
165
165
|
f.objectPredicateInitialize(this.__view.camera);
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
+
objectFilterExecutors.length = objectFilterCount;
|
|
168
169
|
|
|
169
170
|
layer.buildVisibleSet(this.__frustums, objectFilterExecutors, this.__includeObject, this);
|
|
170
171
|
|
|
@@ -366,27 +366,27 @@ function fragment() {
|
|
|
366
366
|
gl_FragColor = vec4( outgoingLight, diffuseColor.a );
|
|
367
367
|
|
|
368
368
|
#if defined( TONE_MAPPING )
|
|
369
|
-
gl_FragColor.rgb = toneMapping(
|
|
369
|
+
gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );
|
|
370
370
|
#endif
|
|
371
371
|
|
|
372
372
|
//encode fragment
|
|
373
|
-
|
|
373
|
+
gl_FragColor = linearToOutputTexel( gl_FragColor );
|
|
374
374
|
#ifdef USE_FOG
|
|
375
375
|
#ifdef FOG_EXP2
|
|
376
376
|
float fogFactor = 1.0 - exp( - fogDensity * fogDensity * fogDepth * fogDepth );
|
|
377
377
|
#else
|
|
378
378
|
float fogFactor = smoothstep( fogNear, fogFar, fogDepth );
|
|
379
379
|
#endif
|
|
380
|
-
gl_FragColor.rgb = mix(
|
|
380
|
+
gl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );
|
|
381
381
|
#endif
|
|
382
382
|
|
|
383
383
|
#ifdef PREMULTIPLIED_ALPHA
|
|
384
384
|
// Get get normal blending with premultipled, use with CustomBlending, OneFactor, OneMinusSrcAlphaFactor, AddEquation.
|
|
385
|
-
gl_FragColor.rgb *=
|
|
385
|
+
gl_FragColor.rgb *= gl_FragColor.a;
|
|
386
386
|
#endif
|
|
387
387
|
|
|
388
388
|
#ifdef DITHERING
|
|
389
|
-
|
|
389
|
+
gl_FragColor.rgb = dithering( gl_FragColor.rgb );
|
|
390
390
|
#endif
|
|
391
391
|
}
|
|
392
392
|
`;
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { EngineHarness } from "../../EngineHarness.js";
|
|
2
|
+
import { loadSerializedScene } from "../../scene/SerializedScene.js";
|
|
3
|
+
import { EngineConfiguration } from "../../EngineConfiguration.js";
|
|
4
|
+
import { MeshSystem } from "../ecs/mesh/MeshSystem.js";
|
|
5
|
+
import GUIElementSystem from "../../ecs/gui/GUIElementSystem.js";
|
|
6
|
+
import HeadsUpDisplaySystem from "../../ecs/gui/hud/HeadsUpDisplaySystem.js";
|
|
7
|
+
import TagSystem from "../../ecs/systems/TagSystem.js";
|
|
8
|
+
import { AttachmentSocketsSystem } from "../../ecs/sockets/AttachmentSocketsSystem.js";
|
|
9
|
+
import { AttachmentSystem } from "../../ecs/attachment/AttachmentSystem.js";
|
|
10
|
+
import { SoundEmitterSystem } from "../../sound/ecs/emitter/SoundEmitterSystem.js";
|
|
11
|
+
import SoundControllerSystem from "../../sound/ecs/SoundControllerSystem.js";
|
|
12
|
+
import SoundListenerSystem from "../../sound/ecs/SoundListenerSystem.js";
|
|
13
|
+
import AnimationSystem from "../../ecs/systems/AnimationSystem.js";
|
|
14
|
+
import TopDownCameraControllerSystem from "../ecs/camera/topdown/TopDownCameraControllerSystem.js";
|
|
15
|
+
import { CameraSystem } from "../ecs/camera/CameraSystem.js";
|
|
16
|
+
import ClingToTerrainSystem from "../../ecs/terrain/ecs/ClingToTerrainSystem.js";
|
|
17
|
+
import TerrainSystem from "../../ecs/terrain/ecs/TerrainSystem.js";
|
|
18
|
+
import Trail2DSystem from "../ecs/trail2d/Trail2DSystem.js";
|
|
19
|
+
import { Foliage2System } from "../../ecs/foliage/ecs/Foliage2System.js";
|
|
20
|
+
import ViewportPositionSystem from "../../ecs/gui/position/ViewportPositionSystem.js";
|
|
21
|
+
import SynchronizePositionSystem from "../../ecs/systems/SynchronizePositionSystem.js";
|
|
22
|
+
import InputControllerSystem from "../../input/ecs/systems/InputControllerSystem.js";
|
|
23
|
+
import { InputSystem } from "../../input/ecs/systems/InputSystem.js";
|
|
24
|
+
import MeshHighlightSystem from "../ecs/highlight/system/MeshHighlightSystem.js";
|
|
25
|
+
import LightSystem from "../ecs/light/LightSystem.js";
|
|
26
|
+
import { BehaviorSystem } from "../../intelligence/behavior/ecs/BehaviorSystem.js";
|
|
27
|
+
import { SerializationMetadataSystem } from "../../ecs/systems/SerializationMetadataSystem.js";
|
|
28
|
+
import { PathDisplaySystem } from "../ecs/path/PathDisplaySystem.js";
|
|
29
|
+
import { ParticleEmitterSystem } from "../particles/ecs/ParticleEmitterSystem.js";
|
|
30
|
+
import { ShadedGeometrySystem } from "../ecs/mesh-v2/ShadedGeometrySystem.js";
|
|
31
|
+
import { ArrayBufferLoader } from "../../asset/loaders/ArrayBufferLoader.js";
|
|
32
|
+
import { initializeGameBinarySerializationRegistry } from "../../../../model/game/GameBinarySerializationRegistry.js";
|
|
33
|
+
import WaterSystem from "../ecs/water/WaterSystem.js";
|
|
34
|
+
import Army from "../../../../model/game/ecs/component/army/Army.js";
|
|
35
|
+
import Mesh from "../ecs/mesh/Mesh.js";
|
|
36
|
+
import EntityBuilder from "../../ecs/EntityBuilder.js";
|
|
37
|
+
import { buildCanvasViewFromTexture } from "../render/visibility/hiz/buildCanvasViewFromTexture.js";
|
|
38
|
+
import ViewportPosition from "../../ecs/gui/position/ViewportPosition.js";
|
|
39
|
+
import Vector2 from "../../../core/geom/Vector2.js";
|
|
40
|
+
import GUIElement from "../../ecs/gui/GUIElement.js";
|
|
41
|
+
import { enableEditor } from "../../../editor/enableEditor.js";
|
|
42
|
+
import { SerializationMetadata } from "../../ecs/components/SerializationMetadata.js";
|
|
43
|
+
|
|
44
|
+
const eh = new EngineHarness();
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
*
|
|
48
|
+
* @param {Engine} engine
|
|
49
|
+
* @returns {EngineConfiguration}
|
|
50
|
+
*/
|
|
51
|
+
function makeConfig(engine) {
|
|
52
|
+
|
|
53
|
+
const config = new EngineConfiguration();
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
*
|
|
57
|
+
* @type {SoundEngine}
|
|
58
|
+
*/
|
|
59
|
+
const sound = engine.sound;
|
|
60
|
+
const graphics = engine.graphics;
|
|
61
|
+
const assetManager = engine.assetManager;
|
|
62
|
+
const devices = engine.devices;
|
|
63
|
+
|
|
64
|
+
// graphics.renderer.shadowMap.type = BasicShadowMap;
|
|
65
|
+
|
|
66
|
+
const guiSystem = new GUIElementSystem(engine.gui.view, engine);
|
|
67
|
+
const headsUpDisplaySystem = new HeadsUpDisplaySystem(graphics);
|
|
68
|
+
|
|
69
|
+
config.addLoader('arraybuffer', new ArrayBufferLoader());
|
|
70
|
+
|
|
71
|
+
initializeGameBinarySerializationRegistry(engine.binarySerializationRegistry);
|
|
72
|
+
|
|
73
|
+
config.addManySystems(
|
|
74
|
+
new TagSystem(),
|
|
75
|
+
new AttachmentSocketsSystem(),
|
|
76
|
+
new AttachmentSystem(),
|
|
77
|
+
new SoundEmitterSystem(assetManager, sound.destination, sound.context),
|
|
78
|
+
new SoundControllerSystem(),
|
|
79
|
+
new SoundListenerSystem(sound.context),
|
|
80
|
+
guiSystem,
|
|
81
|
+
new AnimationSystem(graphics.viewport.size),
|
|
82
|
+
new TopDownCameraControllerSystem(graphics),
|
|
83
|
+
new CameraSystem(graphics.scene, graphics),
|
|
84
|
+
new MeshSystem(engine),
|
|
85
|
+
new ClingToTerrainSystem(),
|
|
86
|
+
new TerrainSystem(graphics, assetManager),
|
|
87
|
+
new Trail2DSystem(engine),
|
|
88
|
+
new Foliage2System(assetManager, graphics),
|
|
89
|
+
new ViewportPositionSystem(graphics.viewport.size),
|
|
90
|
+
new SynchronizePositionSystem(),
|
|
91
|
+
new InputControllerSystem(devices),
|
|
92
|
+
new InputSystem(devices),
|
|
93
|
+
new MeshHighlightSystem(engine),
|
|
94
|
+
new LightSystem(engine, {
|
|
95
|
+
shadowResolution: 2048
|
|
96
|
+
}),
|
|
97
|
+
headsUpDisplaySystem,
|
|
98
|
+
new BehaviorSystem(engine),
|
|
99
|
+
new SerializationMetadataSystem(),
|
|
100
|
+
new PathDisplaySystem(engine),
|
|
101
|
+
new ParticleEmitterSystem(engine),
|
|
102
|
+
new ShadedGeometrySystem(engine),
|
|
103
|
+
new WaterSystem(graphics)
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
// Knowledge
|
|
108
|
+
|
|
109
|
+
return config;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
*
|
|
114
|
+
* @param {Engine} engine
|
|
115
|
+
*/
|
|
116
|
+
function get_three_light(engine) {
|
|
117
|
+
|
|
118
|
+
return engine.graphics.scene.children.find(l => l.isDirectionalLight);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
*
|
|
123
|
+
* @param {Engine} engine
|
|
124
|
+
*/
|
|
125
|
+
function init_shadowmap_preview(engine) {
|
|
126
|
+
const ecd = engine.entityManager.dataset;
|
|
127
|
+
|
|
128
|
+
const graphics = engine.graphics;
|
|
129
|
+
const preview = buildCanvasViewFromTexture({
|
|
130
|
+
width: 512,
|
|
131
|
+
height: 512,
|
|
132
|
+
renderer: graphics.renderer,
|
|
133
|
+
texture: null
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
graphics.on.postOpaquePass.add(() => {
|
|
137
|
+
|
|
138
|
+
const light = get_three_light(engine);
|
|
139
|
+
|
|
140
|
+
if (light !== undefined) {
|
|
141
|
+
preview.texture = light.shadow.map.texture;
|
|
142
|
+
|
|
143
|
+
preview.render();
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
new EntityBuilder()
|
|
149
|
+
.add(ViewportPosition.fromJSON({
|
|
150
|
+
offset: new Vector2(10, 10)
|
|
151
|
+
}))
|
|
152
|
+
.add(GUIElement.fromView(preview.view))
|
|
153
|
+
.add(SerializationMetadata.Transient)
|
|
154
|
+
.build(ecd);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
*
|
|
159
|
+
* @param {Engine} engine
|
|
160
|
+
* @returns {Promise<void>}
|
|
161
|
+
*/
|
|
162
|
+
async function main(engine) {
|
|
163
|
+
|
|
164
|
+
const ecd = engine.entityManager.dataset;
|
|
165
|
+
await loadSerializedScene('data/levels/character_creation/level.bin', ecd, engine);
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
const character = ecd.getAnyComponent(Army);
|
|
169
|
+
|
|
170
|
+
const entity = EntityBuilder.readFromDataset(character.entity, ecd);
|
|
171
|
+
|
|
172
|
+
entity.getComponent(Mesh).url = "data/models/Conqueror Mech/Conqueror Mech.gltf";
|
|
173
|
+
|
|
174
|
+
init_shadowmap_preview(engine);
|
|
175
|
+
|
|
176
|
+
window.light = get_three_light(engine);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
async function init(engineHarness) {
|
|
180
|
+
|
|
181
|
+
const engine = await engineHarness.initialize();
|
|
182
|
+
|
|
183
|
+
const config = makeConfig(engine);
|
|
184
|
+
|
|
185
|
+
await config.apply(engine);
|
|
186
|
+
|
|
187
|
+
enableEditor(engine);
|
|
188
|
+
|
|
189
|
+
main(engine);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
init(eh);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export class AbstractTextureAtlas {
|
|
2
|
+
/**
|
|
3
|
+
*
|
|
4
|
+
* @param {Sampler2D} sampler
|
|
5
|
+
* @returns {AtlasPatch}
|
|
6
|
+
*/
|
|
7
|
+
add(sampler) {
|
|
8
|
+
throw new Error('Not Implemented');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
*
|
|
13
|
+
* @param {AtlasPatch} patch
|
|
14
|
+
* @returns {boolean}
|
|
15
|
+
*/
|
|
16
|
+
remove(patch) {
|
|
17
|
+
throw new Error('Not Implemented')
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { Cache } from "../../../../core/cache/Cache.js";
|
|
2
|
+
import { AbstractTextureAtlas } from "./AbstractTextureAtlas.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 4Mb
|
|
6
|
+
* @type {number}
|
|
7
|
+
*/
|
|
8
|
+
const DEFAULT_CACHE_SIZE = 4194304;
|
|
9
|
+
|
|
10
|
+
export class CachingTextureAtlas extends AbstractTextureAtlas {
|
|
11
|
+
/**
|
|
12
|
+
*
|
|
13
|
+
* @param {AbstractTextureAtlas} atlas
|
|
14
|
+
* @param {number} cache_size
|
|
15
|
+
*/
|
|
16
|
+
constructor({
|
|
17
|
+
atlas,
|
|
18
|
+
cache_size = DEFAULT_CACHE_SIZE
|
|
19
|
+
}) {
|
|
20
|
+
super();
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
*
|
|
24
|
+
* @type {Cache<Sampler2D, AtlasPatch>}
|
|
25
|
+
* @private
|
|
26
|
+
*/
|
|
27
|
+
this.__cached_patches = new Cache({
|
|
28
|
+
maxWeight: cache_size,
|
|
29
|
+
keyWeigher(sampler) {
|
|
30
|
+
return sampler.computeByteSize();
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
*
|
|
36
|
+
* @type {TextureAtlas}
|
|
37
|
+
* @private
|
|
38
|
+
*/
|
|
39
|
+
this.__atals = atlas;
|
|
40
|
+
|
|
41
|
+
this.__cached_patches.onEvicted.add(this.__handle_cache_eviction, this);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
*
|
|
46
|
+
* @returns {AbstractTextureAtlas}
|
|
47
|
+
*/
|
|
48
|
+
get atlas() {
|
|
49
|
+
return this.__atals;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
*
|
|
54
|
+
* @param {Sampler2D} sampler
|
|
55
|
+
* @param {AtlasPatch} patch
|
|
56
|
+
* @private
|
|
57
|
+
*/
|
|
58
|
+
__handle_cache_eviction(sampler, patch) {
|
|
59
|
+
this.__atals.remove(patch);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
reset() {
|
|
63
|
+
this.__cached_patches.drop();
|
|
64
|
+
this.__atals.reset();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
*
|
|
69
|
+
* @param {Sampler2D} sampler
|
|
70
|
+
* @returns {AtlasPatch}
|
|
71
|
+
*/
|
|
72
|
+
add(sampler) {
|
|
73
|
+
const existing_patch = this.__cached_patches.get(sampler);
|
|
74
|
+
|
|
75
|
+
if (existing_patch !== null) {
|
|
76
|
+
// cache hit
|
|
77
|
+
return existing_patch;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return this.__atals.add(sampler);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
*
|
|
85
|
+
* @param {AtlasPatch} patch
|
|
86
|
+
*/
|
|
87
|
+
remove(patch) {
|
|
88
|
+
|
|
89
|
+
// validate presence of patch in the atlas
|
|
90
|
+
if (!this.__atals.contains(patch)) {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// push to cache, let eviction logic handle the rest
|
|
95
|
+
this.__cached_patches.put(patch.sampler, patch);
|
|
96
|
+
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { TextureAtlas } from "./TextureAtlas.js";
|
|
2
2
|
import { ReferenceManager } from "../../../reference/v1/ReferenceManager.js";
|
|
3
3
|
import { Sampler2D } from "../sampler/Sampler2D.js";
|
|
4
|
-
import { Cache } from "../../../../core/cache/Cache.js";
|
|
5
4
|
import { GameAssetType } from "../../../asset/GameAssetType.js";
|
|
6
5
|
import { HashMap } from "../../../../core/collection/HashMap.js";
|
|
7
6
|
import { strictEquals } from "../../../../core/function/Functions.js";
|
|
8
7
|
import { computeStringHash } from "../../../../core/primitives/strings/computeStringHash.js";
|
|
9
8
|
import { copy_Sampler2D_channel_data } from "../sampler/copy_Sampler2D_channel_data.js";
|
|
10
|
-
|
|
11
|
-
const CACHE_SIZE = 4194304;
|
|
9
|
+
import { CachingTextureAtlas } from "./CachingTextureAtlas.js";
|
|
12
10
|
|
|
13
11
|
export class ManagedAtlas {
|
|
14
12
|
/**
|
|
@@ -26,28 +24,20 @@ export class ManagedAtlas {
|
|
|
26
24
|
|
|
27
25
|
/**
|
|
28
26
|
*
|
|
29
|
-
* @type {
|
|
27
|
+
* @type {WeakMap<string, Sampler2D>}
|
|
28
|
+
* @private
|
|
30
29
|
*/
|
|
31
|
-
this.
|
|
30
|
+
this.__cached_samplers = new Map();
|
|
31
|
+
const cached_samplers = this.__cached_samplers;
|
|
32
32
|
|
|
33
|
+
const cached_atlas = new CachingTextureAtlas({ atlas });
|
|
34
|
+
this.__caching_atlas = cached_atlas;
|
|
33
35
|
|
|
34
36
|
/**
|
|
35
37
|
*
|
|
36
|
-
* @type {
|
|
38
|
+
* @type {TextureAtlas}
|
|
37
39
|
*/
|
|
38
|
-
|
|
39
|
-
maxWeight: CACHE_SIZE,
|
|
40
|
-
keyHashFunction: computeStringHash,
|
|
41
|
-
keyEqualityFunction: strictEquals,
|
|
42
|
-
valueWeigher(patch) {
|
|
43
|
-
return patch.sampler.data.length;
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
// watch for patches being removed
|
|
48
|
-
patchesInactive.onRemoved.add((key, value) => {
|
|
49
|
-
atlas.remove(value);
|
|
50
|
-
});
|
|
40
|
+
this.atlas = atlas;
|
|
51
41
|
|
|
52
42
|
/**
|
|
53
43
|
*
|
|
@@ -64,19 +54,12 @@ export class ManagedAtlas {
|
|
|
64
54
|
*/
|
|
65
55
|
this.patchesActive = activePatches;
|
|
66
56
|
|
|
67
|
-
/**
|
|
68
|
-
* @private
|
|
69
|
-
* @type {Cache<String, AtlasPatch>}
|
|
70
|
-
*/
|
|
71
|
-
this.patchesInactive = patchesInactive;
|
|
72
|
-
|
|
73
57
|
/**
|
|
74
58
|
* Automatically update TextureAtlas
|
|
75
59
|
* @type {boolean}
|
|
76
60
|
*/
|
|
77
61
|
this.autoUpdate = true;
|
|
78
62
|
|
|
79
|
-
|
|
80
63
|
this.rebuildDelay = 200; //in milliseconds
|
|
81
64
|
|
|
82
65
|
let counterLoadingAssets = 0;
|
|
@@ -97,7 +80,7 @@ export class ManagedAtlas {
|
|
|
97
80
|
|
|
98
81
|
/**
|
|
99
82
|
*
|
|
100
|
-
* @param {
|
|
83
|
+
* @param {string} url
|
|
101
84
|
* @returns {Promise<AtlasPatch>}
|
|
102
85
|
*/
|
|
103
86
|
function creator(url) {
|
|
@@ -110,14 +93,10 @@ export class ManagedAtlas {
|
|
|
110
93
|
return;
|
|
111
94
|
}
|
|
112
95
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
if (patch !== null) {
|
|
116
|
-
//move to active
|
|
117
|
-
patchesInactive.silentRemove(url);
|
|
118
|
-
|
|
119
|
-
activePatches.set(url, patch);
|
|
96
|
+
const cached_sampler = cached_samplers.get(url);
|
|
120
97
|
|
|
98
|
+
if (cached_sampler !== undefined) {
|
|
99
|
+
patch = cached_atlas.add(cached_sampler);
|
|
121
100
|
resolve(patch);
|
|
122
101
|
return;
|
|
123
102
|
}
|
|
@@ -154,7 +133,10 @@ export class ManagedAtlas {
|
|
|
154
133
|
sampler = source;
|
|
155
134
|
}
|
|
156
135
|
|
|
157
|
-
|
|
136
|
+
cached_samplers.set(url, sampler);
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
const patch = cached_atlas.add(sampler);
|
|
158
140
|
|
|
159
141
|
//record active patch
|
|
160
142
|
activePatches.set(url, patch);
|
|
@@ -197,8 +179,7 @@ export class ManagedAtlas {
|
|
|
197
179
|
//remove from active
|
|
198
180
|
activePatches.delete(url);
|
|
199
181
|
|
|
200
|
-
|
|
201
|
-
patchesInactive.put(url, patch);
|
|
182
|
+
self.__caching_atlas.remove(patch);
|
|
202
183
|
}
|
|
203
184
|
});
|
|
204
185
|
}
|
|
@@ -218,8 +199,7 @@ export class ManagedAtlas {
|
|
|
218
199
|
|
|
219
200
|
reset() {
|
|
220
201
|
this.references.reset();
|
|
221
|
-
this.
|
|
222
|
-
this.patchesInactive.drop();
|
|
202
|
+
this.__caching_atlas.reset();
|
|
223
203
|
this.patchesActive.clear();
|
|
224
204
|
}
|
|
225
205
|
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { AbstractTextureAtlas } from "./AbstractTextureAtlas.js";
|
|
2
|
+
import { Reference } from "../../../reference/v2/Reference.js";
|
|
3
|
+
|
|
4
|
+
export class ReferencedTextureAtlas extends AbstractTextureAtlas {
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @param {AbstractTextureAtlas} atlas
|
|
8
|
+
*/
|
|
9
|
+
constructor(atlas) {
|
|
10
|
+
super();
|
|
11
|
+
|
|
12
|
+
this.__atlas = atlas;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
*
|
|
16
|
+
* @type {Map<Sampler2D, AtlasPatch>}
|
|
17
|
+
* @private
|
|
18
|
+
*/
|
|
19
|
+
this.__patches = new Map();
|
|
20
|
+
/**
|
|
21
|
+
*
|
|
22
|
+
* @type {Map<AtlasPatch, number>}
|
|
23
|
+
* @private
|
|
24
|
+
*/
|
|
25
|
+
this.__ref_counts = new Map();
|
|
26
|
+
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
*
|
|
31
|
+
* @param {Reference} ref
|
|
32
|
+
* @param {AtlasPatch} patch
|
|
33
|
+
* @private
|
|
34
|
+
*/
|
|
35
|
+
__handle_ref_release(ref, patch) {
|
|
36
|
+
const ref_counts = this.__ref_counts;
|
|
37
|
+
|
|
38
|
+
const ref_count = ref_counts.get(patch);
|
|
39
|
+
ref_counts.set(patch, ref_count - 1);
|
|
40
|
+
|
|
41
|
+
if (ref_count === 1) {
|
|
42
|
+
// clear patch
|
|
43
|
+
this.__atlas.remove(patch);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
*
|
|
50
|
+
* @param {Sampler2D} sampler
|
|
51
|
+
* @returns {Reference<AtlasPatch>}
|
|
52
|
+
*/
|
|
53
|
+
acquire(sampler) {
|
|
54
|
+
|
|
55
|
+
let patch = this.__patches.get(sampler);
|
|
56
|
+
|
|
57
|
+
const ref_counts = this.__ref_counts;
|
|
58
|
+
|
|
59
|
+
const atlas = this.__atlas;
|
|
60
|
+
|
|
61
|
+
if (patch === undefined) {
|
|
62
|
+
patch = atlas.add(sampler);
|
|
63
|
+
ref_counts.set(patch, 1)
|
|
64
|
+
} else {
|
|
65
|
+
ref_counts.set(patch, ref_counts.get(patch) + 1);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const ref = new Reference();
|
|
69
|
+
ref.bind(patch);
|
|
70
|
+
|
|
71
|
+
ref.onReleased.add(this.__handle_ref_release, this);
|
|
72
|
+
|
|
73
|
+
return ref;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -11,8 +11,9 @@ import { assert } from "../../../../core/assert.js";
|
|
|
11
11
|
import { DataType } from "../../../../core/collection/table/DataType.js";
|
|
12
12
|
import { DataType2TypedArrayConstructorMapping } from "../../../../core/collection/table/DataType2TypedArrayConstructorMapping.js";
|
|
13
13
|
import { invokeObjectClone } from "../../../../core/model/ObjectUtils.js";
|
|
14
|
+
import { AbstractTextureAtlas } from "./AbstractTextureAtlas.js";
|
|
14
15
|
|
|
15
|
-
export class TextureAtlas {
|
|
16
|
+
export class TextureAtlas extends AbstractTextureAtlas {
|
|
16
17
|
/**
|
|
17
18
|
*
|
|
18
19
|
* @param {number} [size]
|
|
@@ -20,6 +21,8 @@ export class TextureAtlas {
|
|
|
20
21
|
* @constructor
|
|
21
22
|
*/
|
|
22
23
|
constructor(size = 16, data_type = DataType.Uint8) {
|
|
24
|
+
super();
|
|
25
|
+
|
|
23
26
|
/**
|
|
24
27
|
*
|
|
25
28
|
* @type {IdPool}
|
|
@@ -68,6 +71,23 @@ export class TextureAtlas {
|
|
|
68
71
|
this.__needsUpdate = false;
|
|
69
72
|
}
|
|
70
73
|
|
|
74
|
+
/**
|
|
75
|
+
*
|
|
76
|
+
* @param {Sampler2D} sampler
|
|
77
|
+
* @returns {AtlasPatch|undefined}
|
|
78
|
+
*/
|
|
79
|
+
getPatch(sampler) {
|
|
80
|
+
const patches = this.patches;
|
|
81
|
+
const patch_count = patches.length;
|
|
82
|
+
for (let i = 0; i < patch_count; i++) {
|
|
83
|
+
const patch = patches[i];
|
|
84
|
+
|
|
85
|
+
if (patch.sampler === sampler) {
|
|
86
|
+
return patch;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
71
91
|
/**
|
|
72
92
|
* Whether or not current state of atlas requires calling {#update}
|
|
73
93
|
* @returns {boolean}
|
|
@@ -222,7 +242,7 @@ export class TextureAtlas {
|
|
|
222
242
|
/**
|
|
223
243
|
*
|
|
224
244
|
* @param {Sampler2D} sampler
|
|
225
|
-
* @param {number} padding
|
|
245
|
+
* @param {number} [padding]
|
|
226
246
|
* @return {AtlasPatch}
|
|
227
247
|
*/
|
|
228
248
|
add(sampler, padding = 4) {
|
|
@@ -73,12 +73,14 @@ export class Reference {
|
|
|
73
73
|
return;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
const v = this.__value;
|
|
77
|
+
|
|
76
78
|
// prevent further usage of the reference
|
|
77
79
|
this.__value = null;
|
|
78
80
|
|
|
79
81
|
this.__is_bound = false;
|
|
80
82
|
|
|
81
|
-
this.__onReleased.
|
|
83
|
+
this.__onReleased.send2(this,v);
|
|
82
84
|
}
|
|
83
85
|
}
|
|
84
86
|
|
package/package.json
CHANGED
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
"productName": "Meep",
|
|
6
6
|
"description": "production-ready JavaScript game engine based on Entity Component System Architecture",
|
|
7
7
|
"author": "Alexander Goldring",
|
|
8
|
-
"version": "2.33.
|
|
8
|
+
"version": "2.33.40",
|
|
9
9
|
"dependencies": {
|
|
10
|
+
"gl-matrix": "3.4.3",
|
|
10
11
|
"fast-levenshtein": "2.0.6",
|
|
11
12
|
"opentype.js": "1.3.3",
|
|
12
13
|
"simplex-noise": "2.4.0",
|