@woosh/meep-engine 2.33.26 → 2.33.30

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.
Files changed (54) hide show
  1. package/core/binary/BitSet.js +151 -167
  2. package/core/binary/BitSet.spec.js +99 -1
  3. package/core/binary/ValidatingBitSetWrapper.js +81 -0
  4. package/core/bvh2/aabb3/AABB3.js +3 -10
  5. package/core/cache/Cache.d.ts +4 -2
  6. package/core/cache/Cache.js +5 -2
  7. package/core/collection/HashMap.d.ts +9 -2
  8. package/core/collection/HashSet.d.ts +7 -2
  9. package/core/collection/HashSet.js +7 -2
  10. package/core/collection/array/typed/typed_array_copy.js +1 -1
  11. package/core/geom/3d/frustum/array_setFromProjectionMatrix.js +3 -3
  12. package/core/model/ObservedBoolean.d.ts +2 -0
  13. package/core/parser/simple/Token.d.ts +13 -0
  14. package/core/parser/simple/Token.js +61 -27
  15. package/editor/tools/FoliagePaintTool.js +4 -4
  16. package/engine/asset/loaders/GLTFAssetLoader.js +52 -1
  17. package/engine/asset/loaders/image/ImageDecoderWorker.js +4 -3
  18. package/engine/asset/loaders/image/ImageRGBADataAsset.js +3 -2
  19. package/engine/asset/loaders/image/ImageRGBADataLoader.js +3 -3
  20. package/engine/asset/loaders/image/codec/NativeImageDecoder.js +2 -1
  21. package/engine/asset/loaders/image/png/PNG.js +113 -6
  22. package/engine/asset/loaders/image/png/PNGReader.js +5 -0
  23. package/engine/asset/loaders/material/bitmap2sampler_gl.js +1 -1
  24. package/engine/asset/loaders/material/computeImageBitmapEquality.js +6 -1
  25. package/engine/asset/loaders/material/computeTextureEquality.js +40 -49
  26. package/engine/ecs/EntityComponentDataset.js +1 -1
  27. package/engine/ecs/foliage/InstancedFoliage.js +277 -266
  28. package/engine/ecs/foliage/ecs/Foliage2System.js +7 -7
  29. package/engine/ecs/foliage/ecs/InstancedMeshComponent.js +37 -0
  30. package/engine/ecs/foliage/ecs/{Foliage2.js → InstancedMeshLayer.js} +3 -45
  31. package/engine/ecs/foliage/ecs/InstancedMeshSerializationAdapter.js +6 -5
  32. package/engine/ecs/foliage/ecs/InstancedMeshUtils.js +7 -6
  33. package/engine/ecs/storage/binary/BinarySerializationRegistry.js +1 -1
  34. package/engine/ecs/terrain/ecs/layers/TerrainLayer.js +12 -16
  35. package/engine/graphics/geometry/instancing/InstancedMeshGroup.js +14 -72
  36. package/engine/graphics/geometry/instancing/rewriteMaterial.js +70 -0
  37. package/engine/graphics/material/manager/MaterialManager.js +2 -1
  38. package/engine/graphics/micron/render/instanced/AttributeDataTexture.js +6 -4
  39. package/engine/graphics/micron/render/instanced/ThreeInstancedAdapter.js +0 -2
  40. package/engine/graphics/particles/particular/engine/shader/ShaderManager.js +1 -2
  41. package/engine/graphics/particles/particular/engine/shader/debugAtlas.js +1 -1
  42. package/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +5 -2
  43. package/engine/graphics/render/buffer/simple-fx/ao/AmbientOcclusionPostProcessEffect.js +3 -4
  44. package/engine/graphics/render/forward_plus/materials/FPlusDebugMaterial.js +3 -3
  45. package/engine/graphics/render/forward_plus/materials/ForwardPlusThreeMaterial.js +1 -1
  46. package/engine/graphics/render/forward_plus/prototypeLightManager.js +4 -4
  47. package/engine/graphics/render/forward_plus/query/point_light_inside_volume.js +10 -9
  48. package/engine/graphics/texture/atlas/ManagedTextureAtlas.js +12 -1
  49. package/engine/graphics/texture/sampler/Sampler2D.js +3 -1
  50. package/engine/graphics/texture/sampler/convertTexture2Sampler2D.js +1 -1
  51. package/engine/graphics/texture/sampler/copy_Sampler2D_channel_data.js +66 -0
  52. package/engine/input/devices/KeyCodes.d.ts +1 -0
  53. package/package.json +1 -1
  54. package/view/minimap/gl/MinimapWorldGL.js +12 -5
@@ -0,0 +1,81 @@
1
+ //
2
+
3
+ /**
4
+ * Debug tool to verify correct behavior of a BitSet
5
+ */
6
+ export class ValidatingBitSetWrapper {
7
+ /**
8
+ *
9
+ * @param {BitSet} source
10
+ */
11
+ constructor(source) {
12
+ this.__source = source;
13
+ }
14
+
15
+ preventShrink() {
16
+ this.__source.preventShrink();
17
+ }
18
+
19
+ setShrinkFactor(x) {
20
+ this.__source.setShrinkFactor(x);
21
+ }
22
+
23
+ setCapacity(x) {
24
+ this.__source.setCapacity(x);
25
+ }
26
+
27
+ size() {
28
+ return this.__source.size();
29
+ }
30
+
31
+ capacity() {
32
+ return this.__source.capacity();
33
+ }
34
+
35
+ previousSetBit(i) {
36
+ const bit = this.__source.previousSetBit(i);
37
+
38
+ if (bit !== -1 && (this.__source.get(bit) !== true || bit > i)) {
39
+ debugger;
40
+ }
41
+
42
+ return bit;
43
+ }
44
+
45
+ nextSetBit(i) {
46
+ const bit = this.__source.nextSetBit(i);
47
+
48
+ if (bit !== -1 && (this.__source.get(bit) !== true || bit < i)) {
49
+ debugger;
50
+ }
51
+
52
+ return bit;
53
+ }
54
+
55
+ nextClearBit(i) {
56
+ const bit = this.__source.nextClearBit(i);
57
+
58
+ if (bit !== -1 && (this.__source.get(bit) !== false || bit < i)) {
59
+ debugger;
60
+ }
61
+
62
+ return bit;
63
+ }
64
+
65
+ set(x, y) {
66
+ this.__source.set(x, y);
67
+ }
68
+
69
+ clear(i) {
70
+ this.__source.clear(i);
71
+ }
72
+
73
+ get(i) {
74
+ return this.__source.get(i);
75
+ }
76
+
77
+
78
+ reset() {
79
+ this.__source.reset();
80
+ }
81
+ }
@@ -761,16 +761,9 @@ AABB3.prototype.computePlaneSide = function computePlaneSide(plane) {
761
761
  const normal = plane.normal;
762
762
 
763
763
  return computeAABB3PlaneSide(
764
- normal.x,
765
- normal.y,
766
- normal.z,
767
- plane.constant,
768
- this.x0,
769
- this.y0,
770
- this.z0,
771
- this.x1,
772
- this.y1,
773
- this.z1
764
+ normal.x, normal.y, normal.z, plane.constant,
765
+ this.x0, this.y0, this.z0,
766
+ this.x1, this.y1, this.z1
774
767
  );
775
768
  };
776
769
 
@@ -4,13 +4,15 @@ export class Cache<K, V> {
4
4
  keyWeigher,
5
5
  valueWeigher,
6
6
  keyHashFunction,
7
- keyEqualityFunction
7
+ keyEqualityFunction,
8
+ capacity
8
9
  }?: {
9
10
  maxWeight?: number,
10
11
  keyWeigher?: (key: K) => number,
11
12
  valueWeigher?: (value: V) => number,
12
13
  keyHashFunction?: (key: K) => number,
13
- keyEqualityFunction?: (a: K, b: K) => boolean
14
+ keyEqualityFunction?: (a: K, b: K) => boolean,
15
+ capacity?: number
14
16
  })
15
17
 
16
18
  size(): number
@@ -16,6 +16,7 @@ export class Cache {
16
16
  * @param {function(key:Key, value:Value)} [removeListener] will be notified when element is either explicitly removed or evicted
17
17
  * @param {function(Key):number} [keyHashFunction]
18
18
  * @param {function(Key, Key):boolean} [keyEqualityFunction]
19
+ * @param {number} capacity initial capacity for the cache, helps prevent early resizing
19
20
  * @constructor
20
21
  * @template Key, Value
21
22
  */
@@ -25,7 +26,8 @@ export class Cache {
25
26
  valueWeigher = returnOne,
26
27
  removeListener = noop,
27
28
  keyHashFunction = returnZero,
28
- keyEqualityFunction = strictEquals
29
+ keyEqualityFunction = strictEquals,
30
+ capacity
29
31
  } = {}) {
30
32
 
31
33
  assert.isNumber(maxWeight, 'maxWeight');
@@ -95,7 +97,8 @@ export class Cache {
95
97
  */
96
98
  this.data = new HashMap({
97
99
  keyHashFunction,
98
- keyEqualityFunction
100
+ keyEqualityFunction,
101
+ capacity
99
102
  });
100
103
 
101
104
  /**
@@ -1,7 +1,14 @@
1
1
  export class HashMap<K, V> implements Iterable<[V, K]> {
2
- constructor({keyHashFunction, keyEqualityFunction}: {
2
+ constructor({
3
+ keyHashFunction,
4
+ keyEqualityFunction,
5
+ capacity,
6
+ loadFactor
7
+ }: {
3
8
  keyHashFunction: (k: K) => number,
4
- keyEqualityFunction: (a: K, b: K) => boolean
9
+ keyEqualityFunction: (a: K, b: K) => boolean,
10
+ capacity?: number,
11
+ loadFactor?: number
5
12
  })
6
13
 
7
14
  constructor()
@@ -1,7 +1,12 @@
1
1
  export class HashSet<T> {
2
- constructor({keyHashFunction, keyEqualityFunction}: {
2
+ constructor({
3
+ keyHashFunction,
4
+ keyEqualityFunction,
5
+ capacity
6
+ }: {
3
7
  keyHashFunction: (k: T) => number,
4
- keyEqualityFunction: (a: T, b: T) => boolean
8
+ keyEqualityFunction: (a: T, b: T) => boolean,
9
+ capacity?: number
5
10
  })
6
11
 
7
12
  constructor()
@@ -11,7 +11,11 @@ export class HashSet {
11
11
  /**
12
12
  * @template T
13
13
  */
14
- constructor({ keyHashFunction = invokeObjectHash, keyEqualityFunction = invokeObjectEquals } = {}) {
14
+ constructor({
15
+ keyHashFunction = invokeObjectHash,
16
+ keyEqualityFunction = invokeObjectEquals,
17
+ capacity
18
+ } = {}) {
15
19
 
16
20
  /**
17
21
  * Using HashMap as a backing, this is not the most efficient approach, but it works
@@ -20,7 +24,8 @@ export class HashSet {
20
24
  */
21
25
  this.__map = new HashMap({
22
26
  keyHashFunction,
23
- keyEqualityFunction
27
+ keyEqualityFunction,
28
+ capacity
24
29
  });
25
30
  }
26
31
 
@@ -2,7 +2,7 @@ import { array_copy } from "../copyArray.js";
2
2
 
3
3
 
4
4
  /**
5
- *
5
+ * Assumes arrays have the same type
6
6
  * @param {TypedArray|Float32Array} source
7
7
  * @param {TypedArray|Float32Array} destination
8
8
  */
@@ -1,5 +1,3 @@
1
- import { v3_length } from "../../v3_length.js";
2
-
3
1
  /**
4
2
  *
5
3
  * @param {number[]} destination
@@ -10,10 +8,12 @@ import { v3_length } from "../../v3_length.js";
10
8
  * @param {number} w
11
9
  */
12
10
  function array_set_plane_normalized(destination, destination_offset, x, y, z, w) {
13
- const length = v3_length(x, y, z);
11
+ // compute vector length
12
+ const length = Math.hypot(x, y, z);
14
13
 
15
14
  const inverseNormalLength = 1.0 / length;
16
15
 
16
+ // apply normalization
17
17
  destination[destination_offset] = x * inverseNormalLength;
18
18
  destination[destination_offset + 1] = y * inverseNormalLength;
19
19
  destination[destination_offset + 2] = z * inverseNormalLength;
@@ -1,4 +1,6 @@
1
1
  export default class ObservedBoolean {
2
+ constructor(value: boolean)
3
+
2
4
  set(value: boolean): ObservedBoolean
3
5
 
4
6
  getValue(): boolean
@@ -0,0 +1,13 @@
1
+ export class Token<V = string, T = string> {
2
+ readonly value: V
3
+ readonly start: number
4
+ readonly end: number
5
+ readonly name: string
6
+ readonly type: T
7
+
8
+ constructor(value: V, start: number, end: number, name: string, type: T)
9
+
10
+ equals(other: Token<V, T>): boolean
11
+
12
+ hash(): number
13
+ }
@@ -1,31 +1,65 @@
1
- function Token(value, start, end, name, type) {
2
- this.value = value;
3
- this.start = start;
4
- this.end = end;
5
- this.name = name;
6
- this.type = type;
7
- }
1
+ class Token {
2
+ /**
3
+ * @template V,T
4
+ * @param {V} value
5
+ * @param {number} start
6
+ * @param {number} end
7
+ * @param {string} name
8
+ * @param {T} type
9
+ */
10
+ constructor(value, start, end, name, type) {
11
+ /**
12
+ * @readonly
13
+ * @type {V}
14
+ */
15
+ this.value = value;
16
+ /**
17
+ * Starting position in the input
18
+ * @readonly
19
+ * @type {number}
20
+ */
21
+ this.start = start;
22
+ /**
23
+ * End position in the input
24
+ * @readonly
25
+ * @type {number}
26
+ */
27
+ this.end = end;
28
+ /**
29
+ * @readonly
30
+ * @type {string}
31
+ */
32
+ this.name = name;
33
+ /**
34
+ * Token type
35
+ * @readonly
36
+ * @type {T}
37
+ */
38
+ this.type = type;
39
+ }
8
40
 
9
- /**
10
- *
11
- * @param {Token} other
12
- * @returns {boolean}
13
- */
14
- Token.prototype.equals = function (other) {
15
- return this.value === other.value &&
16
- this.start === other.start &&
17
- this.end === other.end &&
18
- this.name === other.name &&
19
- this.type === other.type
20
- ;
21
- };
41
+ /**
42
+ *
43
+ * @param {Token} other
44
+ * @returns {boolean}
45
+ */
46
+ equals(other) {
47
+ return this.value === other.value &&
48
+ this.start === other.start &&
49
+ this.end === other.end &&
50
+ this.name === other.name &&
51
+ this.type === other.type
52
+ ;
53
+ }
22
54
 
23
- /**
24
- *
25
- * @return {number}
26
- */
27
- Token.prototype.hash = function () {
28
- return 0;
29
- };
55
+ /**
56
+ *
57
+ * @return {number}
58
+ */
59
+ hash() {
60
+ // TODO make an actual hash
61
+ return 0;
62
+ }
63
+ }
30
64
 
31
65
  export default Token;
@@ -6,7 +6,7 @@ import { parseHex } from "../../core/color/ColorUtils.js";
6
6
  import Vector4 from "../../core/geom/Vector4.js";
7
7
  import loadSampler2D from "../../engine/graphics/texture/sampler/loadSampler2D.js";
8
8
  import convertSampler2D2Canvas from "../../engine/graphics/texture/sampler/Sampler2D2Canvas.js";
9
- import { Foliage2 } from "../../engine/ecs/foliage/ecs/Foliage2.js";
9
+ import { InstancedMeshComponent } from "../../engine/ecs/foliage/ecs/InstancedMeshComponent.js";
10
10
 
11
11
  class FoliagePaintTool extends Tool {
12
12
  constructor() {
@@ -100,7 +100,7 @@ class FoliagePaintTool extends Tool {
100
100
 
101
101
  /**
102
102
  *
103
- * @param {Foliage2} foliage
103
+ * @param {InstancedMeshComponent} foliage
104
104
  * @param {Number} entity
105
105
  */
106
106
  function visit(foliage, entity) {
@@ -149,9 +149,9 @@ class FoliagePaintTool extends Tool {
149
149
 
150
150
  /**
151
151
  *
152
- * @type {Foliage2}
152
+ * @type {InstancedMeshComponent}
153
153
  */
154
- const foliage = entityManger.getComponent(entity, Foliage2);
154
+ const foliage = entityManger.getComponent(entity, InstancedMeshComponent);
155
155
 
156
156
 
157
157
  if (foliage === null) {
@@ -24,10 +24,42 @@ import { HashSet } from "../../../core/collection/HashSet.js";
24
24
  import { computeGeometryHash } from "./geometry/geometry/computeGeometryHash.js";
25
25
  import { computeGeometryEquality } from "./geometry/geometry/computeGeometryEquality.js";
26
26
  import { traverseThreeObject } from "../../graphics/ecs/highlight/renderer/traverseThreeObject.js";
27
+ import { computeTextureHash } from "./material/computeTextureHash.js";
28
+ import { computeTextureEquality } from "./material/computeTextureEquality.js";
27
29
 
28
30
  const animationOptimizer = new AnimationOptimizer();
29
31
  const materialCache = StaticMaterialCache.Global;
30
32
 
33
+ /**
34
+ *
35
+ * @param {THREE.Material} material
36
+ * @param {HashSet<Texture>} texture_cache
37
+ */
38
+ function replace_material_textures_from_cache(material, texture_cache) {
39
+ const attachments = TextureAttachmentsByMaterialType[material.type];
40
+
41
+ if (attachments === undefined) {
42
+ // unsupported material
43
+ return;
44
+ }
45
+
46
+ const attachment_count = attachments.length;
47
+
48
+ for (let i = 0; i < attachment_count; i++) {
49
+ const attachment = attachments[i];
50
+
51
+ const texture = attachment.read(material);
52
+ if (texture !== undefined && texture !== null) {
53
+ const cached = texture_cache.ensure(texture);
54
+
55
+ if (cached !== texture) {
56
+ // got an existing cached texture, write that instead
57
+ attachment.write(material, cached);
58
+ }
59
+ }
60
+ }
61
+ }
62
+
31
63
  /**
32
64
  * Transfer any transform on the root down to the children instead
33
65
  * @param {Object3D} root
@@ -154,7 +186,20 @@ export class GLTFAssetLoader extends AssetLoader {
154
186
  */
155
187
  this.__geometry_cache = new HashSet({
156
188
  keyHashFunction: computeGeometryHash,
157
- keyEqualityFunction: computeGeometryEquality
189
+ keyEqualityFunction: computeGeometryEquality,
190
+ capacity: 1024
191
+ });
192
+
193
+
194
+ /**
195
+ *
196
+ * @type {HashSet<Texture>}
197
+ * @private
198
+ */
199
+ this.__texture_cache = new HashSet({
200
+ keyHashFunction: computeTextureHash,
201
+ keyEqualityFunction: computeTextureEquality,
202
+ capacity: 2048
158
203
  });
159
204
  }
160
205
 
@@ -234,9 +279,12 @@ export class GLTFAssetLoader extends AssetLoader {
234
279
  }
235
280
  }
236
281
 
282
+
237
283
  load(path, success, failure, progress) {
238
284
  const loader = this.loader;
239
285
  const geometry_cache = this.__geometry_cache;
286
+ const texture_cache = this.__texture_cache;
287
+
240
288
 
241
289
  /**
242
290
  *
@@ -253,6 +301,9 @@ export class GLTFAssetLoader extends AssetLoader {
253
301
  geometry = geometry_cache.ensure(geometry);
254
302
  mesh.geometry = geometry;
255
303
 
304
+ // replace textures from cache
305
+ replace_material_textures_from_cache(mesh.material, texture_cache);
306
+
256
307
  const isSkinned = mesh.isSkinnedMesh === true;
257
308
 
258
309
 
@@ -10,7 +10,7 @@ async function decode_png(png_bytes) {
10
10
 
11
11
  const png = reader.parse();
12
12
 
13
- const data = png.getRGBA8Array();
13
+ const uint_channels = png.getUint8Data();
14
14
 
15
15
  const width = png.getWidth();
16
16
  const height = png.getHeight();
@@ -19,9 +19,10 @@ async function decode_png(png_bytes) {
19
19
  // console.profileEnd('decode');
20
20
 
21
21
  resolve({
22
- data,
22
+ data: uint_channels.data,
23
23
  width,
24
- height
24
+ height,
25
+ itemSize: uint_channels.itemSize
25
26
  });
26
27
  });
27
28
  }
@@ -6,8 +6,9 @@ export class ImageRGBADataAsset extends Asset {
6
6
  * @param {number[]|Uint8Array} data
7
7
  * @param {number} width
8
8
  * @param {number} height
9
+ * @param {number} [itemSize]
9
10
  */
10
- constructor(data, width, height) {
11
+ constructor(data, width, height, itemSize = 4) {
11
12
  super();
12
13
 
13
14
  /**
@@ -32,7 +33,7 @@ export class ImageRGBADataAsset extends Asset {
32
33
  * Number of channels
33
34
  * @type {number}
34
35
  */
35
- this.itemSize = 4;
36
+ this.itemSize = itemSize;
36
37
 
37
38
  this.byteSize = data.length;
38
39
  }
@@ -23,7 +23,7 @@ export class ImageRGBADataLoader extends AssetLoader {
23
23
  /**
24
24
  *
25
25
  * @param {string} path
26
- * @returns {Promise<{data:ArrayBuffer, width: number, height:number}>}
26
+ * @returns {Promise<{data:ArrayBuffer, width: number, height:number, itemSize: number}>}
27
27
  * @private
28
28
  */
29
29
  async __decode_via_worker(path) {
@@ -45,7 +45,7 @@ export class ImageRGBADataLoader extends AssetLoader {
45
45
 
46
46
  const bitmap = await this.__decode_via_worker(path);
47
47
 
48
- return new ImageRGBADataAsset(new Uint8Array(bitmap.data), bitmap.width, bitmap.height);
48
+ return new ImageRGBADataAsset(new Uint8Array(bitmap.data), bitmap.width, bitmap.height, bitmap.itemSize);
49
49
  }
50
50
 
51
51
  load(path, success, failure, progress) {
@@ -65,7 +65,7 @@ export class ImageRGBADataLoader extends AssetLoader {
65
65
 
66
66
  texture.dispose();
67
67
 
68
- const f = new ImageRGBADataAsset(sampler2D.data, sampler2D.width, sampler2D.height);
68
+ const f = new ImageRGBADataAsset(sampler2D.data, sampler2D.width, sampler2D.height, sampler2D.itemSize);
69
69
 
70
70
  success(f);
71
71
 
@@ -45,7 +45,8 @@ export class NativeImageDecoder extends Codec {
45
45
  return {
46
46
  data: rgba_data,
47
47
  width: width,
48
- height: height
48
+ height: height,
49
+ itemSize: 4
49
50
  };
50
51
  }
51
52
  }