@woosh/meep-engine 2.62.0 → 2.64.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.
Files changed (54) hide show
  1. package/build/meep.cjs +1061 -1058
  2. package/build/meep.min.js +1 -1
  3. package/build/meep.module.js +1061 -1058
  4. package/package.json +1 -1
  5. package/src/core/binary/EncodingBinaryBuffer.js +7 -43
  6. package/src/core/binary/EncodingBinaryBuffer.spec.js +16 -0
  7. package/src/core/binary/UINT16_MAX.js +5 -0
  8. package/src/core/bvh2/bvh3/EBBVHLeafProxy.js +4 -2
  9. package/src/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js +5 -5
  10. package/src/core/bvh2/bvh3/query/BVHQueryIntersectsFrustum.js +8 -10
  11. package/src/core/bvh2/bvh3/query/BVHQueryIntersectsRay.js +7 -7
  12. package/src/core/bvh2/bvh3/query/BVHQueryIntersectsSphere.js +37 -0
  13. package/src/core/bvh2/bvh3/query/bvh_query_user_data_generic.js +12 -4
  14. package/src/core/bvh2/bvh3/query/bvh_query_user_data_generic.spec.js +29 -0
  15. package/src/core/cache/LoadingCache.js +4 -1
  16. package/src/core/collection/list/List.js +9 -3
  17. package/src/core/collection/map/BiMap.js +49 -0
  18. package/src/core/geom/3d/aabb/aabb3_from_v3_array.js +11 -4
  19. package/src/core/geom/Vector2.js +6 -4
  20. package/src/engine/ecs/components/Tag.d.ts +2 -0
  21. package/src/engine/ecs/components/Tag.js +19 -28
  22. package/src/engine/ecs/components/Tag.spec.js +47 -0
  23. package/src/engine/ecs/fow/FogOfWar.js +4 -0
  24. package/src/engine/ecs/fow/FogOfWarEditor.js +3 -0
  25. package/src/engine/ecs/terrain/TerrainPreview.js +45 -44
  26. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrain.js +22 -4
  27. package/src/engine/ecs/terrain/tiles/TerrainTile.js +17 -12
  28. package/src/engine/graphics/ecs/mesh/Mesh.d.ts +0 -4
  29. package/src/engine/graphics/ecs/mesh/Mesh.js +0 -11
  30. package/src/engine/graphics/ecs/mesh/MeshSystem.js +57 -67
  31. package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js +49 -86
  32. package/src/engine/graphics/particles/particular/engine/emitter/ParticlePool.js +41 -72
  33. package/src/engine/graphics/particles/particular/engine/emitter/write_particle_patch_uv.js +28 -0
  34. package/src/engine/grid/ORTHOGONAL_NEIGHBOURHOOD_MASK.js +11 -0
  35. package/src/engine/sound/ecs/emitter/SoundEmitterSystem.js +17 -17
  36. package/src/core/binary/stringToByteArray.js +0 -24
  37. package/src/core/bvh2/bvh3/query/bvh_query_user_data_overlaps_sphere.js +0 -81
  38. package/src/engine/ecs/foliage/Foliage.js +0 -151
  39. package/src/engine/ecs/foliage/FoliageLoader.js +0 -39
  40. package/src/engine/ecs/foliage/FoliageVisibilitySetBuilder.js +0 -27
  41. package/src/engine/ecs/foliage/ImpostorFoliage.js +0 -106
  42. package/src/engine/ecs/foliage/InstancedFoliage.js +0 -395
  43. package/src/engine/ecs/foliage/ViewState.js +0 -181
  44. package/src/engine/ecs/foliage/ecs/Foliage2System.js +0 -333
  45. package/src/engine/ecs/foliage/ecs/InstancedMeshComponent.js +0 -70
  46. package/src/engine/ecs/foliage/ecs/InstancedMeshLayer.js +0 -138
  47. package/src/engine/ecs/foliage/ecs/InstancedMeshSerializationAdapter.js +0 -28
  48. package/src/engine/ecs/foliage/ecs/convertInstancedMeshComponents2Entities.js +0 -64
  49. package/src/engine/ecs/foliage/ecs/optimizeIndividualMeshesEntitiesToInstances.js +0 -233
  50. package/src/engine/save/storage/GooglePlayStorage.js +0 -47
  51. package/src/engine/save/storage/JsonStringCodec.js +0 -24
  52. package/src/engine/save/storage/LocalStorage.js +0 -148
  53. package/src/engine/save/storage/MsgPackCodec.js +0 -22
  54. /package/src/engine/sound/ecs/emitter/{SoundEmitter.spec.js → SoundEmitterSerializationAdapter.spec.js} +0 -0
@@ -1,233 +0,0 @@
1
- import {buildTreeOptimizationTask} from "../../../../core/bvh2/BVHTasks.js";
2
- import Task from "../../../../core/process/task/Task.js";
3
- import {TaskSignal} from "../../../../core/process/task/TaskSignal.js";
4
- import {countTask} from "../../../../core/process/task/util/countTask.js";
5
- import {promiseTask} from "../../../../core/process/task/util/promiseTask.js";
6
- import Mesh, {MeshFlags} from "../../../graphics/ecs/mesh/Mesh.js";
7
- import Entity from "../../Entity.js";
8
- import {Transform} from "../../transform/Transform.js";
9
- import {InstancedFoliage} from "../InstancedFoliage.js";
10
- import {InstancedMeshComponent} from "./InstancedMeshComponent.js";
11
- import {InstancedMeshLayer} from "./InstancedMeshLayer.js";
12
-
13
- /**
14
- *
15
- * @param {EntityComponentDataset} dataset
16
- * @param {number} threshold minimum number of instances required before conversion happens
17
- * @returns {{main:Task, tasks:Task[]}}
18
- */
19
- export function optimizeIndividualMeshesEntitiesToInstances(dataset, threshold = 30) {
20
- //get all entities that have a translation and mesh only
21
- const candidates = {};
22
- const not_loaded = {};
23
-
24
- /**
25
- *
26
- * @param {Mesh} mesh
27
- * @param {Transform} transform
28
- * @param {int} entity
29
- */
30
- function visitMeshTransformEntity(mesh, transform, entity) {
31
- const model_url = mesh.url;
32
-
33
- if (model_url === undefined || model_url === null || model_url.trim().length === 0) {
34
- //not a valid URL
35
- return;
36
- }
37
-
38
- if (mesh.getFlag(MeshFlags.Loaded) && (mesh.mesh.isMesh !== true || mesh.mesh.isSkinnedMesh === true)) {
39
- // mesh is not compatible with instancing
40
- return;
41
- }
42
-
43
- if (!mesh.getFlag(MeshFlags.Loaded)) {
44
- let misses = not_loaded[model_url];
45
-
46
- if (misses === undefined) {
47
- misses = not_loaded[model_url] = [];
48
- }
49
-
50
- misses.push(entity);
51
-
52
- return;
53
- }
54
-
55
- let list;
56
- if (!candidates.hasOwnProperty(model_url)) {
57
- list = [];
58
- candidates[model_url] = {
59
- mesh,
60
- list
61
- };
62
- } else {
63
- list = candidates[model_url].list;
64
- }
65
-
66
- list.push({
67
- entity,
68
- position: transform.position,
69
- rotation: transform.rotation,
70
- scale: transform.scale
71
- });
72
- }
73
-
74
- // traverse entities that have only Mesh and a Transform
75
- dataset.traverseEntitiesExact([Mesh, Transform], visitMeshTransformEntity);
76
-
77
- for (const mesh_url in not_loaded) {
78
-
79
- console.warn(`Mesh[${mesh_url}] not loaded, ${not_loaded[mesh_url].length} entities affected`);
80
- }
81
-
82
- const tasks = [];
83
-
84
- const foliage2 = new InstancedMeshComponent();
85
-
86
- const tBuild = new Task({
87
- name: "Build Meshes",
88
- cycleFunction: function () {
89
- const entityBuilder = new Entity();
90
-
91
- entityBuilder.add(foliage2);
92
-
93
- entityBuilder.build(dataset);
94
-
95
- return TaskSignal.EndSuccess;
96
- },
97
- computeProgress: function () {
98
- return 1;
99
- }
100
- });
101
-
102
- tasks.push(tBuild);
103
-
104
- let modelURL;
105
-
106
-
107
- function createLayerForInstances(group, modelURL) {
108
- const instances = group.list;
109
- const numInstances = instances.length;
110
-
111
- if (numInstances < threshold) {
112
- //too new instances to convert
113
- return;
114
- }
115
-
116
- //build up instanced mesh
117
- const instancedFoliage = new InstancedFoliage();
118
-
119
- const tLoadGeometry = promiseTask(new Promise(function (resolve, reject) {
120
-
121
- const mesh = group.mesh.mesh;
122
- const geometry = mesh.geometry;
123
-
124
- instancedFoliage.setInstance(geometry, mesh.material);
125
-
126
- resolve();
127
- }), 'Loading Instance Geometry');
128
-
129
- tasks.push(tLoadGeometry);
130
-
131
-
132
- const tPopulate = countTask(0, numInstances, function (i) {
133
- const instance = instances[i];
134
-
135
- //check for 0 scale
136
- if (instance.scale.isZero()) {
137
- //ignore an instance with 0 scale, it is not visible.
138
- return;
139
- }
140
-
141
- //check for duplicates before
142
- for (let j = i - 1; j >= 0; j--) {
143
-
144
- const instanceTemp = instances[j];
145
-
146
- if (instance.position.equals(instanceTemp.position) && instance.rotation.equals(instanceTemp.rotation) && instance.scale.equals(instanceTemp.scale)) {
147
- //identical instance was found in the past, skip
148
- return;
149
- }
150
- }
151
-
152
- instancedFoliage.add(instance.position, instance.rotation, instance.scale);
153
- });
154
-
155
- tPopulate.addDependency(tLoadGeometry);
156
-
157
- tPopulate.name = `Populate instanced of '${modelURL}'`;
158
-
159
- tasks.push(tPopulate);
160
-
161
- //
162
- const tOptimization = buildTreeOptimizationTask(instancedFoliage.bvh, instancedFoliage.data.length * 4);
163
- tOptimization.addDependency(tPopulate);
164
-
165
- tasks.push(tOptimization);
166
-
167
- const tGenerateLayer = new Task({
168
- name: "Serialize data",
169
- cycleFunction: function () {
170
-
171
- //create foliage layer
172
- const layer = new InstancedMeshLayer();
173
-
174
- layer.data = instancedFoliage;
175
- layer.modelURL.set(modelURL);
176
-
177
- //TODO shadow settings are just assumptions
178
- layer.castShadow.set(true);
179
- layer.receiveShadow.set(true);
180
-
181
- instancedFoliage.castShadow = layer.castShadow.getValue();
182
- instancedFoliage.receiveShadow = layer.receiveShadow.getValue();
183
-
184
- foliage2.layers.add(layer);
185
-
186
- return TaskSignal.EndSuccess;
187
- },
188
- computeProgress: function () {
189
- return 1;
190
- }
191
- });
192
-
193
- tGenerateLayer.addDependency(tOptimization);
194
-
195
- tasks.push(tGenerateLayer);
196
-
197
- //make layer building task a dependency to the main task
198
- tBuild.addDependency(tGenerateLayer);
199
-
200
- //make a task to destroy original entities
201
- const tCleanup = countTask(0, numInstances, function (i) {
202
- const instance = instances[i];
203
-
204
- const entity = instance.entity;
205
-
206
- dataset.removeEntity(entity);
207
- });
208
-
209
- tCleanup.name = `Remove Original Instances of '${modelURL}'`;
210
-
211
- tCleanup.addDependency(tBuild);
212
-
213
- tasks.push(tCleanup);
214
- }
215
-
216
- for (modelURL in candidates) {
217
-
218
- if (!candidates.hasOwnProperty(modelURL)) {
219
- //by some black magic - the candidates don't have this modelURL. This is a sanity check
220
- continue;
221
- }
222
-
223
- const instances = candidates[modelURL];
224
-
225
- createLayerForInstances(instances, modelURL);
226
-
227
- }
228
-
229
- return {
230
- main: tBuild,
231
- tasks
232
- };
233
- }
@@ -1,47 +0,0 @@
1
- /**
2
- * Created by Alex on 22/02/2017.
3
- */
4
-
5
- import Storage from '../Storage.js';
6
-
7
- class GooglePlayStorage extends Storage {
8
- constructor(gapi) {
9
- super();
10
- if (typeof gapi.client.games !== "object") {
11
- gapi.client.load('games', 'v1', function (response) {
12
- console.log('loaded google games API');
13
- });
14
- }
15
- this.api = gapi;
16
- }
17
-
18
- store(key, value, resolve, reject, progress) {
19
- this.api.client.request({
20
- path: '/games/v1/snapshots',
21
- params: {
22
- snapshotId: key
23
- },
24
- method: "put",
25
- body: value
26
- }).then(function (r) {
27
- console.log(r);
28
- });
29
- }
30
-
31
- load(key, resolve, reject, progress) {
32
- this.api.client.games.snapshots.get(key, function (r) {
33
- console.log("Snapshot loaded", r);
34
- resolve(r);
35
- });
36
- }
37
-
38
- list(keyRead) {
39
- this.api.client.games.snapshots.list({
40
- playerId: "me"
41
- }, function (r) {
42
- console.log("Snapshot list obtained", r);
43
- });
44
- }
45
- }
46
-
47
- export default GooglePlayStorage;
@@ -1,24 +0,0 @@
1
- /**
2
- * Created by Alex on 12/06/2017.
3
- */
4
-
5
-
6
- import { stringify } from "../../../core/json/JsonUtils.js";
7
- import {byteArrayToString} from "../../../core/binary/byteArrayToString.js";
8
-
9
- function JsonStringCodec() {
10
- }
11
-
12
- JsonStringCodec.prototype.encode = function (json) {
13
- console.time("stringification of value");
14
- const saveString = stringify(json);
15
- console.timeEnd("stringification of value");
16
- return saveString;
17
- };
18
-
19
- JsonStringCodec.prototype.decode = function (bytes) {
20
- const stringValue = byteArrayToString(bytes);
21
- return JSON.parse(stringValue);
22
- };
23
-
24
- export default JsonStringCodec;
@@ -1,148 +0,0 @@
1
- /**
2
- * Created by Alex on 22/02/2017.
3
- */
4
-
5
-
6
- import MsgPackCodec from './MsgPackCodec.js';
7
-
8
- import Storage from '../Storage.js';
9
- import { InMemoryLocalStorage } from "./InMemoryLocalStorage.js";
10
- import {stringToByteArray} from "../../../core/binary/stringToByteArray.js";
11
- import {byteArrayToString} from "../../../core/binary/byteArrayToString.js";
12
-
13
-
14
- class LocalStorage extends Storage {
15
- constructor(namespace, services) {
16
- super();
17
- this.namespace = namespace;
18
- this.services = services;
19
-
20
- this.compressionLevel = 2;
21
- this.compressionEnabled = false;
22
-
23
- this.codec = new MsgPackCodec();
24
-
25
- try {
26
- console.log('Accessing Window.localStorage...');
27
- this.localStorage = window.localStorage;
28
- console.log('LocalStorage acquired');
29
- } catch (e) {
30
- console.error(`Failed to get localStorage:`, e);
31
-
32
- // This fallback allows the system to continue functioning at least
33
- this.localStorage = new InMemoryLocalStorage();
34
-
35
- console.warn(`Falling back to in-memory storage`);
36
- }
37
-
38
- const item = this.localStorage.getItem(this.namespace + "-list");
39
- let stored;
40
-
41
- try {
42
- stored = JSON.parse(item);
43
- } catch (e) {
44
- console.error('Failed to parse loaded item:', e, item);
45
- console.warn('Ignoring previously stored data');
46
- stored = null;
47
- }
48
-
49
- if (stored !== null && typeof stored === "object" && typeof stored.length === "number") {
50
- this.__list = stored;
51
- } else {
52
- this.__list = [];
53
- }
54
- }
55
-
56
- makeObjectId(key) {
57
- return this.namespace + '-item-' + key;
58
- }
59
-
60
- storeBinary(key, value, resolve, reject, progress) {
61
- const self = this;
62
-
63
- function store(data) {
64
- const compressedUint8Array = new Uint8Array(data.length);
65
- compressedUint8Array.set(data, 0);
66
-
67
- if (compressedUint8Array.length !== value.length) {
68
- console.log("Compressed size:", compressedUint8Array.length, "bytes, original ", value.length, ".", (compressedUint8Array.length / value.length * 100).toFixed(2) + "% of the original");
69
- }
70
-
71
- const compressedString = byteArrayToString(compressedUint8Array);
72
-
73
- self.localStorage.setItem(self.makeObjectId(key), compressedString);
74
-
75
- if (self.__list.indexOf(key) === -1) {
76
- //update the list
77
- self.__list.push(key);
78
- self.localStorage.setItem(self.namespace + "-list", JSON.stringify(self.__list));
79
- }
80
-
81
- if (typeof resolve === "function") {
82
- resolve();
83
- }
84
- }
85
-
86
- if (this.compressionEnabled) {
87
- const compressionService = this.services.compression;
88
-
89
- compressionService
90
- .encode(value, this.compressionLevel)
91
- .then(store, reject);
92
- } else {
93
- store(value);
94
- }
95
- }
96
-
97
- store(key, value, resolve, reject, progress) {
98
- const rawData = this.codec.encode(value);
99
-
100
- this.storeBinary(key, rawData, resolve, reject, progress);
101
- }
102
-
103
- loadBinary(key, resolve, reject, progress) {
104
-
105
- let compressedString = this.localStorage.getItem(this.makeObjectId(key));
106
-
107
- if (compressedString === null) {
108
- //no data
109
- resolve(new ArrayBuffer(0));
110
- return;
111
- }
112
-
113
- const uint8array = stringToByteArray(compressedString);
114
-
115
- const data = uint8array.buffer;
116
- // console.log("compressedBytes", compressedBytes);
117
-
118
- if (this.compressionEnabled) {
119
- const compressionService = this.services.compression;
120
-
121
- compressionService.decode(data).then(resolve, reject);
122
- } else {
123
- resolve(data);
124
- }
125
- }
126
-
127
- load(key, resolve, reject, progress) {
128
- const codec = this.codec;
129
-
130
- this.loadBinary(key, function (binary) {
131
- let result;
132
-
133
- try {
134
- result = codec.decode(new Uint8Array(binary));
135
- } catch (e) {
136
- reject(e);
137
- }
138
-
139
- resolve(result);
140
- }, reject, progress);
141
- }
142
-
143
- list(resolve, reject) {
144
- resolve(this.__list);
145
- }
146
- }
147
-
148
- export default LocalStorage;
@@ -1,22 +0,0 @@
1
- /**
2
- * Created by Alex on 12/06/2017.
3
- */
4
-
5
- import msgpack from 'msgpack-lite';
6
-
7
- function MsgPackCodec() {
8
-
9
- }
10
-
11
- MsgPackCodec.prototype.encode = function (json) {
12
- console.time("encoding of value");
13
- const result = msgpack.encode(json);
14
- console.timeEnd("encoding of value");
15
- return result;
16
- };
17
-
18
- MsgPackCodec.prototype.decode = function (bytes) {
19
- return msgpack.decode(bytes);
20
- };
21
-
22
- export default MsgPackCodec;