@woosh/meep-engine 2.43.3 → 2.43.4

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 (48) hide show
  1. package/core/binary/BinaryBuffer.js +13 -1
  2. package/core/binary/BitSet.js +2 -2
  3. package/core/collection/array/array_range_equal_strict.js +22 -0
  4. package/core/color/sRGB_to_linear.js +9 -4
  5. package/core/geom/3d/plane/orient3d_fast.js +3 -0
  6. package/core/geom/3d/plane/orient3d_robust.js +41 -0
  7. package/core/geom/3d/sphere/harmonics/README.md +15 -0
  8. package/core/geom/3d/sphere/harmonics/sh3_add.js +21 -0
  9. package/core/geom/3d/sphere/harmonics/sh3_dering_optimize_positive.js +618 -0
  10. package/core/geom/3d/sphere/harmonics/sh3_sample_by_direction.js +49 -0
  11. package/core/geom/3d/sphere/harmonics/sh3_sample_irradiance_by_direction.js +53 -0
  12. package/core/geom/3d/tetrahedra/TetrahedralMesh.js +251 -68
  13. package/core/geom/3d/tetrahedra/TetrahedralMesh.spec.js +80 -3
  14. package/core/geom/3d/tetrahedra/build_tetrahedral_mesh_buffer_geometry.js +75 -0
  15. package/core/geom/3d/tetrahedra/delaunay/Cavity.js +5 -1
  16. package/core/geom/3d/tetrahedra/delaunay/compute_delaunay_tetrahedral_mesh.js +30 -31
  17. package/core/geom/3d/tetrahedra/delaunay/fill_in_a_cavity.js +54 -18
  18. package/core/geom/3d/tetrahedra/delaunay/push_boundary_with_validation.js +27 -0
  19. package/core/geom/3d/tetrahedra/delaunay/tetrahedral_mesh_compute_cavity.js +89 -0
  20. package/core/geom/3d/tetrahedra/delaunay/{tetrahedral_mesh_walk_toward_cavity.js → tetrahedral_mesh_walk_towards_containing_tetrahedron.js} +15 -12
  21. package/core/geom/3d/tetrahedra/delaunay/validate_cavity_boundary.js +60 -0
  22. package/core/geom/3d/tetrahedra/{point_in_tetrahedron_circumsphere.js → in_sphere_fast.js} +2 -4
  23. package/core/geom/3d/tetrahedra/in_sphere_robust.js +53 -0
  24. package/core/geom/3d/tetrahedra/prototypeTetrahedraBuilder.js +44 -35
  25. package/core/geom/3d/tetrahedra/validate_tetrahedral_mesh.js +85 -38
  26. package/core/geom/3d/util/make_justified_point_grid.js +31 -0
  27. package/core/process/delay.js +5 -0
  28. package/editor/Editor.js +3 -0
  29. package/editor/ecs/component/editors/ecs/ParameterLookupTableEditor.js +195 -11
  30. package/editor/ecs/component/editors/ecs/ParameterTrackSetEditor.js +16 -0
  31. package/editor/ecs/component/editors/ecs/ParticleEmitterLayerEditor.js +4 -0
  32. package/engine/EngineHarness.js +11 -5
  33. package/engine/ecs/terrain/ecs/TerrainSystem.js +7 -1
  34. package/engine/ecs/transform/copy_three_transform.js +15 -0
  35. package/engine/graphics/ecs/light/Light.js +6 -1
  36. package/engine/graphics/ecs/light/LightSystem.d.ts +1 -1
  37. package/engine/graphics/ecs/mesh-v2/three_object_to_entity_composition.js +2 -17
  38. package/engine/graphics/geometry/instancing/InstancedMeshGroup.js +2 -2
  39. package/engine/graphics/sh3/LightProbeVolume.js +595 -0
  40. package/engine/graphics/sh3/SH3VisualisationMaterial.js +79 -0
  41. package/engine/graphics/sh3/prototypeSH3Probe.js +427 -0
  42. package/engine/graphics/sh3/visualise_probe.js +40 -0
  43. package/engine/graphics/texture/atlas/TextureAtlas.js +15 -3
  44. package/engine/intelligence/blackboard/AbstractBlackboard.d.ts +1 -1
  45. package/package.json +2 -1
  46. package/samples/terrain/from_image_2.js +127 -82
  47. package/core/geom/3d/tetrahedra/delaunay/tetrahedral_mesh_compute_cavity2.js +0 -224
  48. package/core/geom/3d/tetrahedra/delaunay/tetrahedral_mesh_insert_point.js +0 -98
@@ -0,0 +1,427 @@
1
+ import { EngineHarness } from "../../EngineHarness.js";
2
+ import { seededRandom } from "../../../core/math/random/seededRandom.js";
3
+ import { ShadedGeometrySystem } from "../ecs/mesh-v2/ShadedGeometrySystem.js";
4
+ import { GizmoRenderingPlugin } from "../render/gizmo/GizmoRenderingPlugin.js";
5
+ import { LightProbeVolume } from "./LightProbeVolume.js";
6
+ import EntityBuilder from "../../ecs/EntityBuilder.js";
7
+ import { ShadedGeometry } from "../ecs/mesh-v2/ShadedGeometry.js";
8
+ import {
9
+ ClampToEdgeWrapping,
10
+ DataTexture,
11
+ LinearFilter,
12
+ MeshBasicMaterial,
13
+ MeshStandardMaterial,
14
+ NearestFilter,
15
+ PlaneBufferGeometry,
16
+ RGBAFormat,
17
+ UnsignedByteType
18
+ } from "three";
19
+ import { Transform } from "../../ecs/transform/Transform.js";
20
+ import Vector3 from "../../../core/geom/Vector3.js";
21
+ import { BinaryBuffer } from "../../../core/binary/BinaryBuffer.js";
22
+ import { is_typed_array_equals } from "../../../core/collection/array/typed/is_typed_array_equals.js";
23
+ import { array_copy } from "../../../core/collection/array/copyArray.js";
24
+ import { randomFloatBetween } from "../../../core/math/random/randomFloatBetween.js";
25
+ import { GLTFAssetLoader } from "../../asset/loaders/GLTFAssetLoader.js";
26
+ import { three_object_to_entity_composition } from "../ecs/mesh-v2/three_object_to_entity_composition.js";
27
+ import { TransformAttachmentSystem } from "../../ecs/transform-attachment/TransformAttachmentSystem.js";
28
+ import { ShadedGeometryFlags } from "../ecs/mesh-v2/ShadedGeometryFlags.js";
29
+ import { AABB3 } from "../../../core/bvh2/aabb3/AABB3.js";
30
+ import { delay } from "../../../core/process/delay.js";
31
+ import { make_justified_point_grid } from "../../../core/geom/3d/util/make_justified_point_grid.js";
32
+ import LightSystem from "../ecs/light/LightSystem.js";
33
+ import { Light } from "../ecs/light/Light.js";
34
+ import { LightType } from "../ecs/light/LightType.js";
35
+
36
+ /**
37
+ *
38
+ * @param {Storage} storage
39
+ * @param {*} component
40
+ * @param {BinaryClassSerializationAdapter} adapter
41
+ * @param {string} key
42
+ * @param {Signal[]} signals
43
+ */
44
+ async function persist_component(storage, component, adapter, key = 'temp', signals) {
45
+
46
+
47
+ const current_state = new BinaryBuffer();
48
+
49
+ const full_key = `persisted_transform:${key}`;
50
+
51
+ if (await storage.promiseContains(full_key)) {
52
+
53
+ const loaded = await storage.promiseLoadBinary(full_key);
54
+
55
+ const buffer = BinaryBuffer.fromArrayBuffer(loaded);
56
+
57
+ adapter.deserialize(buffer, component);
58
+ }
59
+
60
+ // make a binary state copy
61
+ adapter.serialize(current_state, component);
62
+
63
+
64
+ for (let i = 0; i < signals.length; i++) {
65
+ signals[i].add(store);
66
+ }
67
+
68
+ function store() {
69
+
70
+ const buffer = new BinaryBuffer();
71
+
72
+ adapter.serialize(buffer, component);
73
+
74
+ buffer.trim();
75
+
76
+
77
+ if (!is_typed_array_equals(current_state.__data_uint8, buffer.__data_uint8)) {
78
+ // change detected
79
+
80
+ storage.promiseStoreBinary(full_key, buffer.data);
81
+
82
+
83
+ current_state.setCapacity(buffer.length);
84
+ array_copy(buffer.__data_uint8, 0, current_state.__data_uint8, 0, buffer.length);
85
+ }
86
+ }
87
+
88
+
89
+ }
90
+
91
+ /**
92
+ *
93
+ * @param {number|Vector3} scale
94
+ * @param {Vector3} offset
95
+ * @param {Vector3} direction
96
+ * @param up
97
+ * @param shadow
98
+ * @param material
99
+ * @param {Engine} engine
100
+ */
101
+ function make_plane({
102
+ scale,
103
+ offset,
104
+ direction = Vector3.forward,
105
+ up = Vector3.up,
106
+ shadow = true,
107
+ material = new MeshBasicMaterial({ color: 0xFFFFFF }),
108
+ engine
109
+ }) {
110
+
111
+ const t1 = Transform.fromJSON({
112
+ position: offset,
113
+ scale: scale
114
+ });
115
+ t1.rotation.lookRotation(direction, up);
116
+
117
+ if (engine) {
118
+ material = engine.graphics.getMaterialManager().obtain(material).getValue();
119
+ }
120
+
121
+ const sg = ShadedGeometry.from(new PlaneBufferGeometry(), material);
122
+
123
+ sg.writeFlag(ShadedGeometryFlags.CastShadow, shadow);
124
+ sg.writeFlag(ShadedGeometryFlags.ReceiveShadow, shadow);
125
+
126
+ return new EntityBuilder()
127
+ .add(sg)
128
+ .add(t1);
129
+
130
+ }
131
+
132
+ function make_cornel_box(ecd) {
133
+
134
+
135
+ make_plane({
136
+ scale: 20,
137
+ offset: new Vector3(10, 10, 0),
138
+ direction: Vector3.forward,
139
+ material: new MeshBasicMaterial({ color: 0xFF0000 })
140
+ }).build(ecd);
141
+ make_plane({
142
+ scale: 20,
143
+ offset: new Vector3(10, 10, 20),
144
+ direction: Vector3.left,
145
+ material: new MeshBasicMaterial({ color: 0x00FF00 })
146
+ }).build(ecd);
147
+ make_plane({
148
+ scale: 20,
149
+ offset: new Vector3(0, 10, 10),
150
+ direction: Vector3.right,
151
+ material: new MeshBasicMaterial({ color: 0xFFFFFF })
152
+ }).build(ecd);
153
+
154
+ }
155
+
156
+ function make_test_texture(t = 1) {
157
+ const t1 = (1 - t) * 0.5;
158
+ const tex = new DataTexture(new Uint8ClampedArray([
159
+ 255 * t, 255 * t1, 255 * t1, 255,
160
+ 255 * t1, 255 * t, 255 * t1, 255,
161
+ 255 * t1, 255 * t1, 255 * t, 255,
162
+ 255 * t, 255 * t, 255 * t1, 255
163
+ ]), 2, 2, RGBAFormat, UnsignedByteType);
164
+
165
+ tex.flipY = false;
166
+ tex.wrapS = ClampToEdgeWrapping;
167
+ tex.wrapT = ClampToEdgeWrapping;
168
+ tex.magFilter = NearestFilter;
169
+ tex.minFilter = LinearFilter;
170
+ tex.generateMipmaps = false;
171
+
172
+ tex.needsUpdate = true;
173
+
174
+ return tex;
175
+ }
176
+
177
+ /**
178
+ *
179
+ * @param {Engine} engine
180
+ * @return {Promise<void>}
181
+ */
182
+ async function main(engine) {
183
+ await EngineHarness.buildBasics({
184
+ engine,
185
+ enableWater: false,
186
+ enableTerrain: false,
187
+ enableLights: false,
188
+ cameraFarDistance: 200,
189
+ focus: { x: 0, y: 0, z: 0 },
190
+ pitch: 0.5500000000000453,
191
+ yaw: -2.4300000000000566,
192
+ distance: 10,
193
+ shadowmapResolution: 4096
194
+ });
195
+
196
+ const ecd = engine.entityManager.dataset;
197
+
198
+
199
+ // const path = 'data/models/LowPolyTownshipSet/Small_house/Small_house.gltf';
200
+ const path = 'data/models/sibenik/model.gltf';
201
+ // const path = 'data/models/sponza-pbr/gltf/sponza.glb';
202
+ // const path = 'data/models/LowPolyTownshipSet/Town_Hall/model.gltf';
203
+ // const path = 'data/models/Slaughter Mech/Slaugter Mech.gltf';
204
+
205
+ const mesh_asset = await engine.assetManager.promise(path, 'gltf');
206
+ const gltf = mesh_asset.gltf;
207
+
208
+
209
+ const composition = three_object_to_entity_composition(gltf.scene);
210
+
211
+ composition.traverse(n => {
212
+
213
+ /**
214
+ * @type {ShadedGeometry}
215
+ */
216
+ const sg = n.entity.getComponent(ShadedGeometry);
217
+
218
+ if (sg !== null) {
219
+ sg.setFlag(ShadedGeometryFlags.CastShadow);
220
+ sg.setFlag(ShadedGeometryFlags.ReceiveShadow);
221
+ }
222
+ });
223
+
224
+
225
+ // model_bounds.setNegativelyInfiniteBounds();
226
+ // composition.traverse((n) => {
227
+ //
228
+ // /**
229
+ // * @type {ShadedGeometry}
230
+ // */
231
+ // const sg = n.entity.getComponent(ShadedGeometry);
232
+ //
233
+ // if (sg !== null) {
234
+ // const aabb3 = new AABB3();
235
+ // sg.getBoundingBox(aabb3);
236
+ //
237
+ // model_bounds.expandToFit(aabb3);
238
+ // }
239
+ // })
240
+
241
+ composition.transform.scale.setScalar(1);
242
+ composition.transform.position.set(0, -mesh_asset.boundingBox.y0, 0);
243
+
244
+ composition.build(ecd);
245
+
246
+ const model_footprint = Math.hypot(mesh_asset.boundingBox.getExtentsX(), mesh_asset.boundingBox.getExtentsY(), mesh_asset.boundingBox.getExtentsZ());
247
+
248
+
249
+ make_plane({
250
+ engine,
251
+ scale: 2 * model_footprint,
252
+ offset: new Vector3(0, 0, 0),
253
+ direction: Vector3.up,
254
+ up: Vector3.forward,
255
+ material: new MeshStandardMaterial({
256
+ color: 0x111111,
257
+ // map: make_test_texture()
258
+ })
259
+ }).build(ecd);
260
+
261
+ //
262
+ // make_plane({
263
+ // scale: 3 * model_footprint,
264
+ // offset: new Vector3(0, mesh_asset.boundingBox.y1 + 2, 0),
265
+ // direction: Vector3.down,
266
+ // up: Vector3.forward,
267
+ // shadow: false,
268
+ // material: new MeshStandardMaterial({ color: '#c6f5ff' })
269
+ // }).build(ecd);
270
+
271
+ const points = [
272
+ 0, 0, 0,
273
+ 10, 0, 0,
274
+ 10, 0, 10,
275
+ 0, 0, 10,
276
+
277
+ 0, 10, 0,
278
+ 10, 10, 0,
279
+ 10, 10, 10,
280
+ 0, 10, 10,
281
+ ];
282
+
283
+ //
284
+ // new EntityBuilder()
285
+ // .add(Transform.fromJSON({
286
+ // position: {
287
+ // x: mesh_asset.boundingBox.x0,
288
+ // y: mesh_asset.boundingBox.getCenterY(),
289
+ // z: mesh_asset.boundingBox.getCenterZ()
290
+ // }
291
+ // }))
292
+ // .add(Light.fromJSON({
293
+ // distance: model_footprint * 2,
294
+ // type: LightType.POINT,
295
+ // intensity: 10,
296
+ // color: 0xFF0000
297
+ // }))
298
+ // .build(ecd);
299
+ //
300
+ // new EntityBuilder()
301
+ // .add(Transform.fromJSON({
302
+ // position: {
303
+ // x: mesh_asset.boundingBox.x1,
304
+ // y: mesh_asset.boundingBox.getCenterY(),
305
+ // z: mesh_asset.boundingBox.getCenterZ()
306
+ // }
307
+ // }))
308
+ // .add(Light.fromJSON({
309
+ // distance: model_footprint * 2,
310
+ // type: LightType.POINT,
311
+ // intensity: 10,
312
+ // color: '#00f7ff'
313
+ // }))
314
+ // .build(ecd);
315
+
316
+ const random = seededRandom();
317
+
318
+ for (let i = 0; i < 16; i++) {
319
+
320
+ new EntityBuilder()
321
+ .add(Transform.fromJSON({
322
+ position: {
323
+ x: randomFloatBetween(random, mesh_asset.boundingBox.x0, mesh_asset.boundingBox.x1),
324
+ y: randomFloatBetween(random, mesh_asset.boundingBox.y0, mesh_asset.boundingBox.y1),
325
+ z: randomFloatBetween(random, mesh_asset.boundingBox.z0, mesh_asset.boundingBox.z1),
326
+ }
327
+ }))
328
+ .add(Light.fromJSON({
329
+ distance: model_footprint *0.2,
330
+ type: LightType.POINT,
331
+ intensity: 1,
332
+ color: `hsv(${random()},${1},1)`
333
+ }))
334
+ .build(ecd);
335
+ }
336
+
337
+
338
+ const lpv = new LightProbeVolume();
339
+
340
+ // lpv.add_point(10, 5, 10);
341
+
342
+ const desired_density = 15;
343
+
344
+
345
+ // const light_volume_bounds = new AABB3(-10, 0.5, -10, 10, 11, 10);
346
+ const probe_grid_spacing_dense = Math.min(mesh_asset.boundingBox.getExtentsX(), mesh_asset.boundingBox.getExtentsY(), mesh_asset.boundingBox.getExtentsZ()) / desired_density;
347
+ const probe_grid_spacing_sparse = Math.max(mesh_asset.boundingBox.getExtentsX(), mesh_asset.boundingBox.getExtentsY(), mesh_asset.boundingBox.getExtentsZ()) / desired_density;
348
+
349
+ const probe_grid_spacing = (probe_grid_spacing_sparse / probe_grid_spacing_dense) < 2 ? probe_grid_spacing_dense : probe_grid_spacing_sparse * 0.5;
350
+ //
351
+ // const probe_grid_spacing =desired_density/ (mesh_asset.boundingBox.getExtentsX()* mesh_asset.boundingBox.getExtentsY()* mesh_asset.boundingBox.getExtentsZ());
352
+
353
+ const model_bounds = new AABB3(-10, 0.5, -10, 10, 11, 10);
354
+ model_bounds.copy(mesh_asset.boundingBox);
355
+ model_bounds.grow(probe_grid_spacing * 1.1);
356
+
357
+
358
+ // sg_hierarchy_compute_bounding_box_via_parent_entity(light_volume_bounds, composition.entity.entity, ecd);
359
+
360
+ // for (let i = 0; i < 100; i++) {
361
+ // lpv.add_point(
362
+ // randomFloatBetween(random, light_volume_bounds.x0, light_volume_bounds.x1),
363
+ // randomFloatBetween(random, light_volume_bounds.y0, light_volume_bounds.y1),
364
+ // randomFloatBetween(random, light_volume_bounds.z0, light_volume_bounds.z1),
365
+ // );
366
+ // }
367
+
368
+ make_justified_point_grid(model_bounds, probe_grid_spacing, (x, y, z) => {
369
+ lpv.add_point(x, y, z);
370
+ });
371
+
372
+ // lpv.add_point(10, 1, -10);
373
+
374
+ await delay(2000);
375
+
376
+ //
377
+ // console.profile('lpv build');
378
+ //
379
+ lpv.build(engine);
380
+ // console.profileEnd('lpv build');
381
+
382
+ // fill probes with random data
383
+ // for (let i = 0; i < lpv.__length * 27; i++) {
384
+ // lpv.__probe_data[i] = random();
385
+ // }
386
+
387
+ // for (let i = 0; i < lpv.__length; i++) {
388
+ //
389
+ // for (let j = 0; j < 9; j++) {
390
+ // lpv.__probe_data[(i * 9 + j) * 3] = max2(0, (lpv.__positions[i * 3] + 10) / 20);
391
+ // lpv.__probe_data[(i * 9 + j) * 3 + 1] = max2(0, (lpv.__positions[i * 3 + 1] - 0.5) / 10.5);
392
+ // lpv.__probe_data[(i * 9 + j) * 3 + 2] = max2(0, (lpv.__positions[i * 3 + 2] + 10) / 20);
393
+ // }
394
+ // }
395
+
396
+ // lpv.white_probe(0, [
397
+ // 0.7953949, 0.4405923, 0.5459412,
398
+ // 0.3981450, 0.3526911, 0.6097158,
399
+ // -0.3424573, -0.1838151, -0.2715583,
400
+ //
401
+ // -0.2944621, -0.0560606, 0.0095193,
402
+ // -0.1123051, -0.0513088, -0.1232869,
403
+ // -0.2645007, -0.2257996, -0.4785847,
404
+ //
405
+ // -0.1569444, -0.0954703, -0.1485053,
406
+ // 0.5646247, 0.2161586, 0.1402643,
407
+ // 0.2137442, -0.0547578, -0.3061700], 0);
408
+
409
+
410
+ // lpv.visualize_mesh({ ecd: ecd });
411
+ lpv.visualize_probes({ ecd: ecd, size: probe_grid_spacing * 0.08 });
412
+
413
+
414
+ console.log(lpv);
415
+ }
416
+
417
+ new EngineHarness().initialize({
418
+ configuration(config, engine) {
419
+ config.addSystem(new ShadedGeometrySystem(engine));
420
+ config.addSystem(new TransformAttachmentSystem());
421
+ config.addSystem(new LightSystem(engine));
422
+
423
+ config.addLoader('gltf', new GLTFAssetLoader());
424
+
425
+ config.addPlugin(GizmoRenderingPlugin);
426
+ }
427
+ }).then(main);
@@ -0,0 +1,40 @@
1
+ import { SH3VisualisationMaterial } from "./SH3VisualisationMaterial.js";
2
+ import EntityBuilder from "../../ecs/EntityBuilder.js";
3
+ import { Transform } from "../../ecs/transform/Transform.js";
4
+ import { ShadedGeometry } from "../ecs/mesh-v2/ShadedGeometry.js";
5
+ import { OctahedronBufferGeometry } from "three";
6
+ import { ShadedGeometryFlags } from "../ecs/mesh-v2/ShadedGeometryFlags.js";
7
+
8
+ /**
9
+ *
10
+ * @param {number} [size]
11
+ * @param position
12
+ * @param position_offset
13
+ * @param sh
14
+ * @param sh_offset
15
+ * @return {EntityBuilder}
16
+ */
17
+ export function visualise_probe({ size = 1,shadow=false, position, position_offset = 0, sh, sh_offset = 0 }) {
18
+
19
+ const mat = new SH3VisualisationMaterial();
20
+
21
+ for (let i = 0; i < 9; i++) {
22
+ mat.uniforms.sh.value[i].fromArray(sh, sh_offset + i * 3);
23
+ }
24
+
25
+ const shadedGeometry = ShadedGeometry.from(new OctahedronBufferGeometry(1, 5), mat);
26
+
27
+ shadedGeometry.writeFlag(ShadedGeometryFlags.ReceiveShadow,shadow);
28
+ shadedGeometry.writeFlag(ShadedGeometryFlags.CastShadow,shadow);
29
+
30
+ return new EntityBuilder()
31
+ .add(Transform.fromJSON({
32
+ position: {
33
+ x: position[position_offset],
34
+ y: position[position_offset + 1],
35
+ z: position[position_offset + 2],
36
+ },
37
+ scale: size
38
+ }))
39
+ .add(shadedGeometry);
40
+ }
@@ -20,11 +20,16 @@ export class TextureAtlas extends AbstractTextureAtlas {
20
20
  *
21
21
  * @param {number} [size]
22
22
  * @param {DataType} [data_type]
23
+ * @param {number} [channel_count]
23
24
  * @constructor
24
25
  */
25
- constructor(size = 16, data_type = DataType.Uint8) {
26
+ constructor(size = 16, data_type = DataType.Uint8, channel_count = 4) {
26
27
  super();
27
28
 
29
+ assert.isNonNegativeInteger(size, 'size');
30
+ assert.enum(data_type, DataType, 'data_type');
31
+ assert.isNonNegativeInteger(channel_count, 'channel_count');
32
+
28
33
  /**
29
34
  *
30
35
  * @type {IdPool}
@@ -46,8 +51,6 @@ export class TextureAtlas extends AbstractTextureAtlas {
46
51
 
47
52
  const TypeArrayConstructor = DataType2TypedArrayConstructorMapping[data_type];
48
53
 
49
- const channel_count = 4;
50
-
51
54
  /**
52
55
  * @private
53
56
  * @readonly
@@ -150,6 +153,9 @@ export class TextureAtlas extends AbstractTextureAtlas {
150
153
  * @returns {boolean} true if resizing successful, false otherwise
151
154
  */
152
155
  resize(x, y) {
156
+ assert.isNonNegativeInteger(x, 'x');
157
+ assert.isNonNegativeInteger(y, 'y');
158
+
153
159
  //check if any patches would be cut
154
160
  const patches = this.patches;
155
161
  const numPatches = patches.length;
@@ -255,6 +261,12 @@ export class TextureAtlas extends AbstractTextureAtlas {
255
261
  * @return {AtlasPatch}
256
262
  */
257
263
  add(sampler, padding = 4) {
264
+
265
+ assert.notNull(sampler, 'sampler');
266
+ assert.defined(sampler, 'sampler');
267
+
268
+ assert.isNonNegativeInteger(padding, 'padding');
269
+
258
270
  // console.log('#add');
259
271
 
260
272
  const patch = new AtlasPatch();
@@ -1,5 +1,5 @@
1
1
  import ObservedBoolean from "../../../core/model/ObservedBoolean";
2
- import {Vector1} from "../../../core/geom/Vector1";
2
+ import Vector1 from "../../../core/geom/Vector1";
3
3
  import ObservedString from "../../../core/model/ObservedString";
4
4
 
5
5
  export class AbstractBlackboard {
package/package.json CHANGED
@@ -5,12 +5,13 @@
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.43.3",
8
+ "version": "2.43.4",
9
9
  "dependencies": {
10
10
  "gl-matrix": "3.4.3",
11
11
  "fast-levenshtein": "2.0.6",
12
12
  "opentype.js": "1.3.3",
13
13
  "simplex-noise": "2.4.0",
14
+ "robust-predicates": "3.0.1",
14
15
  "three": "^0.135.0"
15
16
  },
16
17
  "devDependencies": {