@woosh/meep-engine 2.35.17 → 2.36.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 (63) hide show
  1. package/core/binary/BinaryBuffer.js +42 -17
  2. package/core/bvh2/BinaryNode.js +1 -1
  3. package/core/bvh2/aabb3/AABB3.js +2 -2
  4. package/core/bvh2/aabb3/aabb3_array_combine.js +20 -0
  5. package/core/bvh2/aabb3/aabb3_array_intersects_frustum_array.js +20 -0
  6. package/core/bvh2/aabb3/aabb3_array_intersects_ray.js +1 -0
  7. package/core/bvh2/aabb3/aabb3_array_intersects_ray_array.js +14 -0
  8. package/core/bvh2/{aabb3_combined_surface_area.js → aabb3/aabb3_combined_surface_area.js} +3 -3
  9. package/core/bvh2/aabb3/aabb3_intersects_frustum_array.js +1 -19
  10. package/core/bvh2/bvh3/BVHNodeProxy.js +53 -0
  11. package/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js +848 -0
  12. package/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.spec.js +142 -0
  13. package/core/bvh2/bvh3/bvh_query_leaves_generic.js +79 -0
  14. package/core/bvh2/bvh3/bvh_query_leaves_ray.js +95 -0
  15. package/core/bvh2/bvh3/query/BVHQuery.js +11 -0
  16. package/core/bvh2/bvh3/query/BVHQueryIntersectsFrustum.js +36 -0
  17. package/core/bvh2/bvh3/query/BVHQueryIntersectsRay.js +36 -0
  18. package/core/collection/array/copyArray.js +2 -2
  19. package/core/collection/table/RowFirstTable.js +25 -7
  20. package/core/collection/table/RowFirstTableSpec.js +4 -4
  21. package/core/geom/3d/aabb/aabb3_matrix4_project.spec.js +1 -1
  22. package/{engine/graphics/util → core/geom/3d/aabb}/computeBoundingBoxFromVertexData.js +1 -1
  23. package/core/geom/3d/compose_matrix4_array.js +53 -0
  24. package/{engine/graphics/util → core/geom/3d}/decompose_matrix_4_array.js +0 -0
  25. package/core/geom/Vector1.js +2 -3
  26. package/engine/asset/loaders/GLTFAssetLoader.js +3 -0
  27. package/engine/asset/loaders/gltf/GLTFAssetTransformMikkTSpaceTangents.js +27 -0
  28. package/engine/ecs/EntityComponentDataset.js +7 -4
  29. package/engine/ecs/foliage/InstancedFoliage.js +1 -1
  30. package/engine/ecs/foliage/ViewState.js +1 -1
  31. package/engine/ecs/transform/Transform.js +2 -2
  32. package/engine/graphics/ecs/mesh-v2/ShadedGeometry.d.ts +5 -0
  33. package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +46 -12
  34. package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +81 -95
  35. package/engine/graphics/ecs/mesh-v2/render/ShadedGeometryRendererContext.js +16 -5
  36. package/engine/graphics/ecs/mesh-v2/sample/load_gltf.js +1 -0
  37. package/engine/graphics/ecs/mesh-v2/sample/prototypeShadedGeometry.js +1 -1
  38. package/engine/graphics/ecs/path/tube/build/computeFrenetFrames.js +1 -2
  39. package/engine/graphics/geometry/MikkT/MikkTSpace.js +2210 -0
  40. package/engine/graphics/geometry/MikkT/MikkTSpace.spec.js +22 -0
  41. package/engine/graphics/geometry/MikkT/buffer_geometry_ensure_tangents.js +34 -0
  42. package/engine/graphics/geometry/MikkT/buffer_geometry_generate_tangents.js +28 -0
  43. package/engine/graphics/{compute_geometry_polycount.js → geometry/compute_geometry_polycount.js} +0 -0
  44. package/engine/graphics/geometry/skining/computeSkinnedMeshBoundingVolumes.js +1 -1
  45. package/engine/graphics/micron/format/serialization/collection/geometry_collection_serialization.js +83 -0
  46. package/engine/graphics/micron/plugin/GLTFAssetTransformer.js +42 -19
  47. package/engine/graphics/micron/plugin/GLTF_MICRON_ID_FIELD.js +5 -0
  48. package/engine/graphics/micron/plugin/MicronRenderPlugin.js +0 -4
  49. package/engine/graphics/micron/render/refinement/ActivePatchList.js +2 -2
  50. package/engine/graphics/micron/render/refinement/get_geometry_patch_cut.js +2 -2
  51. package/engine/graphics/render/forward_plus/LightManager.js +5 -5
  52. package/engine/graphics/render/forward_plus/data/channelCountToThreIntegerTextureType.js +3 -3
  53. package/engine/graphics/texture/channelCountToThreeTextureFormat.js +2 -2
  54. package/engine/graphics/util/composeMatrix4.js +1 -53
  55. package/engine/graphics/util/composeMatrix4RotationScale.js +1 -1
  56. package/engine/intelligence/blackboard/AbstractBlackboard.js +9 -0
  57. package/engine/notify/Notification.js +1 -1
  58. package/engine/ui/notification/ViewEmitter.js +7 -1
  59. package/engine/ui/notification/notificationGenerator.js +1 -1
  60. package/engine/ui/scene/SceneGUIContext.js +11 -130
  61. package/engine/ui/scene/initializeNotifications.js +141 -0
  62. package/package.json +1 -1
  63. package/view/elements/notify/NotificationView.js +1 -2
@@ -0,0 +1,22 @@
1
+ import { genTangSpace, SMikkTSpaceContext } from "./MikkTSpace.js";
2
+
3
+ test('empty geometry', () => {
4
+ const ctx = new SMikkTSpaceContext();
5
+
6
+ expect(() => {
7
+ genTangSpace(ctx);
8
+ }).not.toThrow();
9
+
10
+ });
11
+
12
+ test('single triangle', () => {
13
+ const ctx = new SMikkTSpaceContext();
14
+
15
+ ctx.geometry_buffer_index = [0, 1, 2];
16
+ ctx.geometry_buffer_vertex_position = [1, 2, 3, 4, 5, 6, 7, 8, 9];
17
+ ctx.geometry_buffer_vertex_normal = [0, 1, 0, 0, 1, 0, 0, 1, 0];
18
+ ctx.geometry_buffer_vertex_uv = [0, 0, 0, 0, 0, 0];
19
+
20
+ genTangSpace(ctx);
21
+
22
+ });
@@ -0,0 +1,34 @@
1
+ import { buffer_geometry_generate_tangents } from "./buffer_geometry_generate_tangents.js";
2
+
3
+ /**
4
+ *
5
+ * @param {THREE.BufferGeometry} geo
6
+ */
7
+ export function buffer_geometry_ensure_tangents(geo) {
8
+ if (geo.getAttribute('tangent') !== undefined) {
9
+ // already got tangents
10
+ return;
11
+ }
12
+
13
+ if (geo.getIndex() === null) {
14
+ // non-indexed, unsupported
15
+ return;
16
+ }
17
+
18
+ if (geo.getAttribute('normal') === undefined) {
19
+ // no normals
20
+ return;
21
+ }
22
+
23
+ if (geo.getAttribute('uv') === undefined) {
24
+ // UVs are required by the algorithm
25
+ return;
26
+ }
27
+
28
+ if (geo.getAttribute('position') === undefined) {
29
+ // positions are required as well
30
+ return;
31
+ }
32
+
33
+ buffer_geometry_generate_tangents(geo);
34
+ }
@@ -0,0 +1,28 @@
1
+ import { BufferAttribute } from "three";
2
+ import { genTangSpace, SMikkTSpaceContext } from "./MikkTSpace.js";
3
+
4
+ /**
5
+ * only works with indexed geometries
6
+ * @param {THREE.BufferGeometry} geo
7
+ */
8
+ export function buffer_geometry_generate_tangents(geo) {
9
+
10
+ const attribute_position = geo.getAttribute('position');
11
+
12
+ if (geo.getAttribute('tangent') === undefined) {
13
+ geo.setAttribute('tangent', new BufferAttribute(new Float32Array(attribute_position.count * 4), 4, false));
14
+ }
15
+
16
+ const attribute_tangent = geo.getAttribute('tangent');
17
+
18
+
19
+ const ctx = new SMikkTSpaceContext();
20
+
21
+ ctx.geometry_buffer_index = geo.getIndex().array;
22
+ ctx.geometry_buffer_vertex_position = attribute_position.array;
23
+ ctx.geometry_buffer_vertex_normal = geo.getAttribute('normal').array;
24
+ ctx.geometry_buffer_vertex_uv = geo.getAttribute('uv').array;
25
+ ctx.geometry_buffer_vertex_tangent = attribute_tangent.array;
26
+
27
+ genTangSpace(ctx);
28
+ }
@@ -3,7 +3,7 @@ import { AABB3 } from "../../../../core/bvh2/aabb3/AABB3.js";
3
3
  import Vector4 from "../../../../core/geom/Vector4.js";
4
4
  import { computeBoundingSphereFromVertexData } from "../computeBoundingSphereFromVertexData.js";
5
5
  import { Box3, Sphere as ThreeSphere, Vector3 as ThreeVector3 } from "three";
6
- import { computeBoundingBoxFromVertexData } from "../../util/computeBoundingBoxFromVertexData.js";
6
+ import { computeBoundingBoxFromVertexData } from "../../../../core/geom/3d/aabb/computeBoundingBoxFromVertexData.js";
7
7
 
8
8
  /**
9
9
  *
@@ -0,0 +1,83 @@
1
+ import { MicronGeometryBinarySerializationAdapter } from "../MicronGeometryBinarySerializationAdapter.js";
2
+ import { MicronGeometry } from "../../MicronGeometry.js";
3
+
4
+ const SUPPORTED_ADAPTER_VERSION = 0;
5
+ const HEADER_MAGIC_TEXT = 'MICRON#001';
6
+
7
+ function obtain_micron_adapter() {
8
+
9
+ const ga = new MicronGeometryBinarySerializationAdapter();
10
+
11
+ if (ga.version !== SUPPORTED_ADAPTER_VERSION) {
12
+ throw new Error(`Incorrect version of serialization adapter, expected ${SUPPORTED_ADAPTER_VERSION}, instead got ${ga.version}`);
13
+ }
14
+
15
+ return ga;
16
+ }
17
+
18
+ /**
19
+ *
20
+ * @param {MicronGeometry[]} destination
21
+ * @param {BinaryBuffer} buffer
22
+ * @returns {number} how many geometries were read
23
+ */
24
+ export function deserialize_geometry_collection(destination, buffer) {
25
+ // read header
26
+ const header_text = buffer.readASCIICharacters(HEADER_MAGIC_TEXT.length);
27
+
28
+ if (header_text !== HEADER_MAGIC_TEXT) {
29
+ throw new Error(`Wrong header magic, expected '${HEADER_MAGIC_TEXT}', instead got '${header_text}'`);
30
+ }
31
+
32
+ // read how many geometries we're expecting
33
+ const geometry_occupies_count = buffer.readUint32();
34
+
35
+ const ga = obtain_micron_adapter();
36
+
37
+ for (let i = 0; i < geometry_occupies_count; i++) {
38
+ // read key
39
+ const key = buffer.readUint32();
40
+
41
+ const geometry = new MicronGeometry();
42
+
43
+ ga.deserialize(buffer, geometry);
44
+
45
+ destination[key] = geometry;
46
+ }
47
+
48
+ return geometry_occupies_count;
49
+ }
50
+
51
+ /**
52
+ *
53
+ * @param {MicronGeometry[]} geometries
54
+ * @param {BinaryBuffer} buffer
55
+ */
56
+ export function serialize_geometry_collection(geometries, buffer) {
57
+ // write header
58
+ buffer.writeASCIIString(HEADER_MAGIC_TEXT); // magic bytes
59
+
60
+ // count geometries
61
+ let geometry_occupied_count = 0;
62
+ const geometry_count = geometries.length;
63
+ for (let i = 0; i < geometry_count; i++) {
64
+ if (geometries[i] === undefined) {
65
+ geometry_occupied_count++;
66
+ }
67
+ }
68
+
69
+ buffer.writeUint32(geometry_occupied_count); // how many geometries to expect
70
+
71
+ const ga = obtain_micron_adapter();
72
+
73
+ for (let i = 0; i < geometry_count; i++) {
74
+ const geometry = geometries[i];
75
+ if (geometry === undefined) {
76
+ continue;
77
+ }
78
+
79
+ buffer.writeUint32(i); // key
80
+
81
+ ga.serialize(buffer, geometry);
82
+ }
83
+ }
@@ -1,15 +1,15 @@
1
1
  import { AssetTransformer } from "../../../asset/AssetTransformer.js";
2
- import { MicronGeometryBinarySerializationAdapter } from "../format/serialization/MicronGeometryBinarySerializationAdapter.js";
3
- import { MICRON_URI_FIELD } from "../MICRON_URI_FIELD.js";
4
2
  import { computePathDirectory } from "../../../../core/FilePath.js";
5
3
  import { BinaryBuffer } from "../../../../core/binary/BinaryBuffer.js";
6
4
  import { MicronGeometry } from "../format/MicronGeometry.js";
7
5
  import { MICRON_GEOMETRY_FIELD } from "../MICRON_GEOMETRY_FIELD.js";
8
6
  import { async_traverse_three_object } from "../../../asset/loaders/async_traverse_three_object.js";
9
7
  import { convert_three_object_to_micron } from "../convert_three_object_to_micron.js";
10
- import { compute_geometry_polycount } from "../../compute_geometry_polycount.js";
8
+ import { compute_geometry_polycount } from "../../geometry/compute_geometry_polycount.js";
11
9
  import { traverseThreeObject } from "../../ecs/highlight/renderer/traverseThreeObject.js";
12
10
  import { max2 } from "../../../../core/math/max2.js";
11
+ import { deserialize_geometry_collection } from "../format/serialization/collection/geometry_collection_serialization.js";
12
+ import { GLTF_MICRON_ID_FIELD } from "./GLTF_MICRON_ID_FIELD.js";
13
13
 
14
14
  export const ASSET_TYPE_ARRAY_BUFFER = "arraybuffer";
15
15
 
@@ -85,10 +85,10 @@ export class GLTFAssetTransformer extends AssetTransformer {
85
85
 
86
86
  /**
87
87
  *
88
- * @type {MicronGeometryBinarySerializationAdapter}
88
+ * @type {MicronGeometry[]}
89
89
  * @private
90
90
  */
91
- this.__serde = new MicronGeometryBinarySerializationAdapter();
91
+ this.__active_mesh_micron_cache = [];
92
92
  }
93
93
 
94
94
  /**
@@ -116,23 +116,52 @@ export class GLTFAssetTransformer extends AssetTransformer {
116
116
  */
117
117
  const geometry = object.geometry;
118
118
 
119
- const micron_uri = geometry.userData[MICRON_URI_FIELD];
119
+ const micron_geometry_index = geometry.userData[GLTF_MICRON_ID_FIELD];
120
120
 
121
- if (typeof micron_uri !== "string") {
121
+ if (typeof micron_geometry_index !== "number") {
122
122
  return;
123
123
  }
124
124
 
125
+ const micron_geometry = this.__active_mesh_micron_cache[micron_geometry_index];
125
126
 
126
- /**
127
- * @type {AssetDescription}
128
- */
129
- const ad = ctx.asset;
127
+ if (micron_geometry === undefined) {
128
+ console.error(`Micron geometry '${micron_geometry_index}' not found`);
129
+ return;
130
+ }
131
+
132
+ // set proxy for raycasting
133
+ micron_geometry.proxy = geometry;
134
+
135
+ geometry[MICRON_GEOMETRY_FIELD] = micron_geometry;
136
+ }
137
+
138
+
139
+ /**
140
+ *
141
+ * @param {{userData:{}}} gltf
142
+ * @param {AssetDescription} ad
143
+ * @private
144
+ */
145
+ async __load_mesh_micron_data(gltf, ad) {
146
+ // clear active cache
147
+ this.__active_mesh_micron_cache = [];
148
+
149
+ const micron_metadata = gltf.userData.micron;
150
+
151
+ if (micron_metadata === undefined) {
152
+ return;
153
+ }
154
+
155
+ const uri = micron_metadata.geometry_data_uri;
156
+ if (uri === undefined) {
157
+ return;
158
+ }
130
159
 
131
160
  const base = computePathDirectory(ad.path);
132
161
 
133
162
  let micron_data;
134
163
 
135
- const micron_path = `${base}/${micron_uri}`;
164
+ const micron_path = `${base}/${uri}`;
136
165
 
137
166
  try {
138
167
  micron_data = await this.__am.promise(micron_path, ASSET_TYPE_ARRAY_BUFFER);
@@ -143,14 +172,8 @@ export class GLTFAssetTransformer extends AssetTransformer {
143
172
 
144
173
  // deserialize micron data
145
174
  const buffer = BinaryBuffer.fromArrayBuffer(micron_data.create());
146
- const micron_geometry = new MicronGeometry();
147
175
 
148
- this.__serde.deserialize(buffer, micron_geometry);
149
-
150
- // set proxy for raycasting
151
- micron_geometry.proxy = geometry;
152
-
153
- geometry[MICRON_GEOMETRY_FIELD] = micron_geometry;
176
+ deserialize_geometry_collection(this.__active_mesh_micron_cache, buffer);
154
177
  }
155
178
 
156
179
 
@@ -0,0 +1,5 @@
1
+ /**
2
+ *
3
+ * @type {string}
4
+ */
5
+ export const GLTF_MICRON_ID_FIELD = '@micron_geometry_index';
@@ -135,10 +135,6 @@ export class MicronRenderPlugin extends EnginePlugin {
135
135
  view.on.preRender.remove(observer);
136
136
  }
137
137
 
138
- __ingest_cache() {
139
- this.engine.storage.lo
140
- }
141
-
142
138
  async startup() {
143
139
 
144
140
  const engine = this.engine;
@@ -2,7 +2,7 @@ import { ActivePatchRecord } from "./ActivePatchRecord.js";
2
2
  import { ActivePatchFlags } from "./ActivePatchFlags.js";
3
3
  import { aabb3_project_to_2d } from "../../../../../core/geom/3d/aabb/aabb3_compute_projected_area.js";
4
4
  import { BitSet } from "../../../../../core/binary/BitSet.js";
5
- import { aabb3_intersects_frustum_array } from "../../../../../core/bvh2/aabb3/aabb3_intersects_frustum_array.js";
5
+ import { aabb3_array_intersects_frustum_array } from "../../../../../core/bvh2/aabb3/aabb3_array_intersects_frustum_array.js";
6
6
 
7
7
  export class ActivePatchList {
8
8
  constructor() {
@@ -199,7 +199,7 @@ export class ActivePatchList {
199
199
  check if node is in view frustum
200
200
  NOTE: following suggestion in "FastMesh: Efficient View-dependent Meshing" by Renato Pajarola et al, we can do a more coarse frustum test approximating frustum as a cone initially
201
201
  */
202
- const in_view_frustum = aabb3_intersects_frustum_array(node.bounding_box, frustum_planes);
202
+ const in_view_frustum = aabb3_array_intersects_frustum_array(node.bounding_box, frustum_planes);
203
203
 
204
204
  if (!in_view_frustum) {
205
205
  // outside of view frustum, cull
@@ -1,5 +1,5 @@
1
1
  import { BitSet } from "../../../../../core/binary/BitSet.js";
2
- import { aabb3_intersects_frustum_array } from "../../../../../core/bvh2/aabb3/aabb3_intersects_frustum_array.js";
2
+ import { aabb3_array_intersects_frustum_array } from "../../../../../core/bvh2/aabb3/aabb3_array_intersects_frustum_array.js";
3
3
  import { aabb3_estimate_projected_area2 } from "../../../../../core/geom/3d/aabb/aabb3_estimate_projected_area2.js";
4
4
 
5
5
 
@@ -67,7 +67,7 @@ export function get_geometry_patch_cut(
67
67
  check if node is in view frustum
68
68
  NOTE: following suggestion in "FastMesh: Efficient View-dependent Meshing" by Renato Pajarola et al, we can do a more coarse frustum test approximating frustum as a cone initially
69
69
  */
70
- const in_view_frustum = aabb3_intersects_frustum_array(patch.bounding_box, frustum_planes);
70
+ const in_view_frustum = aabb3_array_intersects_frustum_array(patch.bounding_box, frustum_planes);
71
71
 
72
72
  if (!in_view_frustum) {
73
73
  continue;
@@ -9,7 +9,7 @@ import {
9
9
  LinearMipMapLinearFilter,
10
10
  NearestFilter,
11
11
  RGBAFormat,
12
- RGBIntegerFormat,
12
+ RGBAIntegerFormat,
13
13
  UnsignedByteType,
14
14
  UnsignedShortType
15
15
  } from "three";
@@ -158,8 +158,8 @@ export class LightManager {
158
158
  this.__cluster_texture.minFilter = NearestFilter;
159
159
 
160
160
  this.__cluster_texture.type = UnsignedShortType;
161
- this.__cluster_texture.format = RGBIntegerFormat;
162
- this.__cluster_texture.internalFormat = "RGB16UI";
161
+ this.__cluster_texture.format = RGBAIntegerFormat;
162
+ this.__cluster_texture.internalFormat = "RGBA16UI";
163
163
 
164
164
  /**
165
165
  *
@@ -347,7 +347,7 @@ export class LightManager {
347
347
 
348
348
  const texture = this.__cluster_texture;
349
349
 
350
- const channelCount = 3;
350
+ const channelCount = 4;
351
351
 
352
352
  texture.dispose();
353
353
 
@@ -826,7 +826,7 @@ export class LightManager {
826
826
 
827
827
  const tile_index = slice_offset + (i_y_0 * tr_x) + i_x_0;
828
828
 
829
- const tile_address = tile_index * 3;
829
+ const tile_address = tile_index * 4;
830
830
 
831
831
 
832
832
  // construct tile data
@@ -1,4 +1,4 @@
1
- import { RedIntegerFormat, RGBAIntegerFormat, RGBIntegerFormat, RGIntegerFormat } from "three";
1
+ import { RedIntegerFormat, RGBAIntegerFormat, RGIntegerFormat } from "three";
2
2
 
3
3
  export function channelCountToThreIntegerTextureType(channel_count) {
4
4
  switch (channel_count) {
@@ -6,10 +6,10 @@ export function channelCountToThreIntegerTextureType(channel_count) {
6
6
  return RedIntegerFormat;
7
7
  case 2:
8
8
  return RGIntegerFormat;
9
- case 3:
10
- return RGBIntegerFormat;
11
9
  case 4:
12
10
  return RGBAIntegerFormat;
11
+ case 3:
12
+ // see https://github.com/mrdoob/three.js/pull/23228
13
13
  default:
14
14
  throw new Error(`Unsupported channel count '${channel_count}'`);
15
15
  }
@@ -1,4 +1,4 @@
1
- import { RedFormat, RGBAFormat, RGBFormat, RGFormat } from "three";
1
+ import { RedFormat, RGBAFormat, RGFormat } from "three";
2
2
 
3
3
  /**
4
4
  *
@@ -12,7 +12,7 @@ export function channelCountToThreeTextureFormat(count) {
12
12
  case 2:
13
13
  return RGFormat;
14
14
  case 3:
15
- return RGBFormat;
15
+ // see https://github.com/mrdoob/three.js/pull/23228
16
16
  case 4:
17
17
  return RGBAFormat;
18
18
  default:
@@ -1,56 +1,4 @@
1
- /**
2
- *
3
- * @param {number[]|Float32Array|mat4} result
4
- * @param {Vector3} position
5
- * @param {Quaternion} rotation
6
- * @param {Vector3} scale
7
- */
8
- export function compose_matrix4_array(result, position, rotation, scale) {
9
- const x = rotation.x;
10
- const y = rotation.y;
11
- const z = rotation.z;
12
- const w = rotation.w;
13
-
14
- const x2 = x + x;
15
- const y2 = y + y;
16
- const z2 = z + z;
17
-
18
- const xx = x * x2;
19
- const xy = x * y2;
20
- const xz = x * z2;
21
-
22
- const yy = y * y2;
23
- const yz = y * z2;
24
- const zz = z * z2;
25
-
26
- const wx = w * x2;
27
- const wy = w * y2;
28
- const wz = w * z2;
29
-
30
- const sx = scale.x;
31
- const sy = scale.y;
32
- const sz = scale.z;
33
-
34
- result[0] = (1 - (yy + zz)) * sx;
35
- result[1] = (xy + wz) * sx;
36
- result[2] = (xz - wy) * sx;
37
- result[3] = 0;
38
-
39
- result[4] = (xy - wz) * sy;
40
- result[5] = (1 - (xx + zz)) * sy;
41
- result[6] = (yz + wx) * sy;
42
- result[7] = 0;
43
-
44
- result[8] = (xz + wy) * sz;
45
- result[9] = (yz - wx) * sz;
46
- result[10] = (1 - (xx + yy)) * sz;
47
- result[11] = 0;
48
-
49
- result[12] = position.x;
50
- result[13] = position.y;
51
- result[14] = position.z;
52
- result[15] = 1;
53
- }
1
+ import { compose_matrix4_array } from "../../../core/geom/3d/compose_matrix4_array.js";
54
2
 
55
3
  /**
56
4
  *
@@ -1,5 +1,5 @@
1
- import { compose_matrix4_array } from "./composeMatrix4.js";
2
1
  import Vector3 from "../../../core/geom/Vector3.js";
2
+ import { compose_matrix4_array } from "../../../core/geom/3d/compose_matrix4_array.js";
3
3
 
4
4
  /**
5
5
  *
@@ -48,6 +48,15 @@ export class AbstractBlackboard {
48
48
  return this.acquire(name, DataType.Number, initialValue);
49
49
  }
50
50
 
51
+ /**
52
+ *
53
+ * @param {string} name
54
+ * @returns {void}
55
+ */
56
+ incrementNumber(name) {
57
+ this.acquireNumber(name).increment();
58
+ }
59
+
51
60
  /**
52
61
  *
53
62
  * @param {string} name
@@ -16,7 +16,7 @@ export class Notification {
16
16
  * @constructor
17
17
  */
18
18
  constructor({ title = "", description = "", image = "", classList = [] }) {
19
- assert.ok(Array.isArray(classList), 'classList must be an array, was something else instead');
19
+ assert.isArray(classList, 'classList');
20
20
 
21
21
  this.title = title;
22
22
 
@@ -1,7 +1,9 @@
1
1
  import Vector2 from "../../../core/geom/Vector2.js";
2
2
  import { AnimatedObjectEmitter } from "./AnimatedObjectEmitter.js";
3
3
 
4
-
4
+ /**
5
+ * @template T
6
+ */
5
7
  class ViewEmitter {
6
8
  /**
7
9
  *
@@ -24,6 +26,10 @@ class ViewEmitter {
24
26
  return view;
25
27
  };
26
28
 
29
+ /**
30
+ *
31
+ * @type {(T)=>View}
32
+ */
27
33
  this.viewFactory = null;
28
34
 
29
35
  /**
@@ -41,7 +41,7 @@ function notificationGenerator(callback, timeout = 5) {
41
41
  *
42
42
  * @param {NotificationManager} notifications
43
43
  */
44
- function testNotifications(notifications) {
44
+ export function testNotifications(notifications) {
45
45
  notificationGenerator(n => {
46
46
  notifications.addNotification(n, NotificationAreaKind.Primary);
47
47
  }, 1.3);