@woosh/meep-engine 2.59.0 → 2.59.2
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/build/meep.cjs +710 -644
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +710 -644
- package/editor/process/symbolic/SymbolicDisplayInternalAPI.js +3 -3
- package/editor/process/symbolic/makeParticleEmitterSymbolicDisplay.js +1 -1
- package/editor/process/symbolic/makePathSymbolicDisplay.js +1 -1
- package/editor/process/symbolic/makeSoundEmitterSymbolicDisplay.js +1 -1
- package/editor/tools/TopDownCameraControlTool.js +2 -2
- package/editor/tools/v2/TransformControls.js +1 -1
- package/editor/tools/v2/prototypeTransformControls.js +1 -1
- package/package.json +1 -1
- package/samples/generation/main.js +1 -1
- package/samples/terrain/editor.js +1 -1
- package/src/core/collection/array/arraySetDiff.js +11 -7
- package/src/core/geom/3d/aabb/aabb3_array_intersects_point.spec.js +48 -0
- package/src/core/geom/3d/aabb/aabb3_array_intersects_ray.js +5 -1
- package/src/core/geom/3d/aabb/aabb3_expand_array.spec.js +16 -0
- package/src/core/geom/3d/aabb/aabb3_raycast.spec.js +37 -0
- package/src/core/geom/3d/aabb/aabb3_score_boxes_SAH.js +11 -12
- package/src/core/geom/3d/aabb/aabb3_score_boxes_SAH.spec.js +14 -0
- package/src/core/geom/3d/aabb/aabb3_transformed_compute_plane_side.js +6 -4
- package/src/core/geom/3d/aabb/compute_aabb_from_points.js +6 -3
- package/src/core/geom/3d/matrix/m4_multiply.spec.js +24 -0
- package/src/core/geom/3d/matrix/m4_multiply_alphatensor.js +56 -40
- package/src/core/geom/3d/matrix/m4_multiply_alphatensor.spec.js +24 -0
- package/src/core/geom/3d/shape/util/shape_to_visual_entity.js +2 -2
- package/src/core/geom/Vector3.spec.js +24 -14
- package/src/engine/EngineHarness.js +1 -1
- package/src/engine/control/ControlContext.js +1 -1
- package/src/engine/ecs/Entity.d.ts +2 -0
- package/src/engine/ecs/Entity.js +40 -37
- package/src/engine/ecs/Entity.spec.js +2 -2
- package/src/engine/ecs/EntityBuilderUtils.js +2 -2
- package/src/engine/ecs/EntityComponentDataset.js +91 -89
- package/src/engine/ecs/EntityFlags.js +4 -4
- package/src/engine/ecs/attachment/Attachment.js +5 -2
- package/src/engine/ecs/binding/ComponentPropertyBinding.js +13 -13
- package/src/engine/ecs/dynamic_actions/RuleExecution.js +1 -1
- package/src/engine/ecs/parent/EntityNode.js +2 -2
- package/src/engine/ecs/parent/EntityNode.spec.js +2 -2
- package/src/engine/ecs/tooltip/testTooltipComponentSystem.js +1 -1
- package/src/engine/ecs/util/hideEntityGracefully.js +6 -6
- package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +1 -0
- package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMesh.d.ts +3 -0
- package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMesh.js +69 -28
- package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMeshSystem.js +21 -15
- package/src/engine/graphics/ecs/mesh-v2/render/SGThreeObjectCache.js +30 -7
- package/src/engine/graphics/ecs/mesh-v2/sample/load_gltf.js +1 -1
- package/src/engine/graphics/ecs/mesh-v2/sample/prototypeShadedGeometry.js +71 -34
- package/src/engine/graphics/ecs/mesh-v2/sample/prototype_sg_raycast.js +1 -1
- package/src/engine/graphics/ecs/path/PathDisplaySystem.js +4 -4
- package/src/engine/graphics/ecs/path/entity/EntityPathMarker.js +1 -1
- package/src/engine/graphics/ecs/path/highlight/PathDisplayHighlightSystem.js +3 -3
- package/src/engine/graphics/render/buffer/buffers/prototypeNormalFrameBuffer.js +5 -5
- package/src/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +2 -2
- package/src/engine/graphics/render/visibility/hiz/prototypeHiZ.js +1 -1
- package/src/engine/graphics/sh3/prototypeSH3Probe.js +2 -2
- package/src/engine/intelligence/behavior/ecs/EntityBehavior.js +14 -17
- package/src/engine/intelligence/behavior/util/DelayBehavior.js +6 -6
- package/src/engine/ui/GUIEngine.js +368 -371
- package/src/engine/ui/notification/NotificationManager.js +1 -1
- package/src/generation/markers/actions/placement/MarkerNodeEntityProcessor.js +1 -1
- package/src/view/tooltip/gml/TooltipParser.js +21 -28
- package/src/view/tooltip/gml/compiler/GMLReferenceCompiler.js +3 -2
- package/src/core/geom/3d/aabb/aabb3_intersects_ray_branchless.js +0 -52
- package/src/core/geom/3d/aabb/aabb3_intersects_ray_fast.js +0 -176
- package/src/core/geom/3d/aabb/aabb3_intersects_ray_slab.js +0 -91
|
@@ -27,7 +27,7 @@ export class SymbolicDisplayInternalAPI {
|
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
*
|
|
30
|
-
* @type {List<
|
|
30
|
+
* @type {List<Entity>}
|
|
31
31
|
* @private
|
|
32
32
|
*/
|
|
33
33
|
this.__managed_entities = new List();
|
|
@@ -56,11 +56,11 @@ export class SymbolicDisplayInternalAPI {
|
|
|
56
56
|
|
|
57
57
|
/**
|
|
58
58
|
*
|
|
59
|
-
* @param {
|
|
59
|
+
* @param {Entity} entity
|
|
60
60
|
*/
|
|
61
61
|
emit(entity) {
|
|
62
62
|
assert.defined(entity, 'entity');
|
|
63
|
-
assert.equal(entity.
|
|
63
|
+
assert.equal(entity.isEntity, true, 'entity.isEntity !== true');
|
|
64
64
|
|
|
65
65
|
if (entity.getComponent(EditorEntity) === null) {
|
|
66
66
|
entity.add(new EditorEntity({ referenceEntity: this.__source_entity }));
|
|
@@ -40,7 +40,7 @@ export function makeParticleEmitterSymbolicDisplay(engine) {
|
|
|
40
40
|
* @param {Transform} transform
|
|
41
41
|
* @param {number} entity
|
|
42
42
|
* @param {SymbolicDisplayInternalAPI} api
|
|
43
|
-
* @returns {
|
|
43
|
+
* @returns {Entity}
|
|
44
44
|
*/
|
|
45
45
|
function factory([emitter, transform, entity], api) {
|
|
46
46
|
|
|
@@ -52,7 +52,7 @@ export function makePathSymbolicDisplay(engine) {
|
|
|
52
52
|
* @param {Path} path
|
|
53
53
|
* @param entity
|
|
54
54
|
* @param {SymbolicDisplayInternalAPI} api
|
|
55
|
-
* @return {
|
|
55
|
+
* @return {Entity}
|
|
56
56
|
*/
|
|
57
57
|
function factory([path, entity], api) {
|
|
58
58
|
const pathObjectMaterial = new LineBasicMaterial({ color: 0xFF0000, opacity: 0.4 });
|
|
@@ -38,7 +38,7 @@ export function makeSoundEmitterSymbolicDisplay(engine) {
|
|
|
38
38
|
* @param {Transform} transform
|
|
39
39
|
* @param {number} entity
|
|
40
40
|
* @param {SymbolicDisplayInternalAPI} api
|
|
41
|
-
* @returns {
|
|
41
|
+
* @returns {Entity}
|
|
42
42
|
*/
|
|
43
43
|
function factory([emitter, transform, entity], api) {
|
|
44
44
|
|
|
@@ -16,7 +16,7 @@ class TopDownCameraControlTool extends Tool {
|
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
*
|
|
19
|
-
* @type {
|
|
19
|
+
* @type {Entity}
|
|
20
20
|
* @private
|
|
21
21
|
*/
|
|
22
22
|
this.__controller = null;
|
|
@@ -39,7 +39,7 @@ class TopDownCameraControlTool extends Tool {
|
|
|
39
39
|
|
|
40
40
|
this.__controller = makeOrbitalCameraController({
|
|
41
41
|
ecd: ecd,
|
|
42
|
-
camera_entity: editor.cameraEntity.
|
|
42
|
+
camera_entity: editor.cameraEntity.id,
|
|
43
43
|
dom_element: engine.graphics.domElement
|
|
44
44
|
});
|
|
45
45
|
|
|
@@ -58,7 +58,7 @@ async function main(engine) {
|
|
|
58
58
|
|
|
59
59
|
controls.build(ecd); // add controls to the scene
|
|
60
60
|
// controls.attach(cube_entity); // make controls target the cube
|
|
61
|
-
controls.attach(entityNode.entity.
|
|
61
|
+
controls.attach(entityNode.entity.id); // make controls target the cube
|
|
62
62
|
|
|
63
63
|
new Entity()
|
|
64
64
|
.add(new InputController([{
|
package/package.json
CHANGED
|
@@ -166,7 +166,7 @@ function prepare_gen_task({
|
|
|
166
166
|
// prepare gameplay-specific things on top of the generated level
|
|
167
167
|
|
|
168
168
|
//build minimap
|
|
169
|
-
const terrainPreview = generateTerrainPreview(terrainBuilder.
|
|
169
|
+
const terrainPreview = generateTerrainPreview(terrainBuilder.id, ecd);
|
|
170
170
|
terrain.preview.copy(terrainPreview);
|
|
171
171
|
});
|
|
172
172
|
|
|
@@ -307,7 +307,7 @@ async function main(engine) {
|
|
|
307
307
|
|
|
308
308
|
EngineHarness.buildLights({ engine });
|
|
309
309
|
const camera = EngineHarness.buildCamera({ engine });
|
|
310
|
-
EngineHarness.buildOrbitalCameraController({ engine, cameraEntity: camera.
|
|
310
|
+
EngineHarness.buildOrbitalCameraController({ engine, cameraEntity: camera.id })
|
|
311
311
|
|
|
312
312
|
await EngineHarness.buildTerrain({ engine });
|
|
313
313
|
|
|
@@ -1,35 +1,39 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import {strictEquals} from "../../function/Functions.js";
|
|
2
|
+
import {arrayIndexByEquality} from "./arrayIndexByEquality.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
+
* Compute a diff between two arrays, result is a 3 way split between common items, unique items in `a` array and unique items in `b` array
|
|
5
6
|
* @template T
|
|
6
7
|
* @param {T[]} a
|
|
7
8
|
* @param {T[]} b
|
|
8
|
-
* @param {function(a:T,b:T):boolean} [equals]
|
|
9
|
+
* @param {function(a:T,b:T):boolean} [equals] method to determine equality between two elements
|
|
9
10
|
* @returns {{uniqueA:T[], uniqueB:T[], common:T[]}}
|
|
10
11
|
*/
|
|
11
12
|
export function arraySetDiff(a, b, equals = strictEquals) {
|
|
13
|
+
// TODO we can do this faster if we use a comparator instead of equality and pre-sort the data
|
|
12
14
|
const uniqueA = a.slice();
|
|
13
15
|
const uniqueB = b.slice();
|
|
14
16
|
|
|
15
17
|
const common = [];
|
|
16
18
|
|
|
17
|
-
let
|
|
19
|
+
let a_length = uniqueA.length;
|
|
18
20
|
|
|
19
|
-
let i;
|
|
20
|
-
for (i = 0; i < lA; i++) {
|
|
21
|
+
for (let i = 0; i < a_length; i++) {
|
|
21
22
|
const elA = uniqueA[i];
|
|
22
23
|
|
|
23
24
|
const j = arrayIndexByEquality(uniqueB, elA, equals);
|
|
24
25
|
|
|
25
26
|
if (j !== -1) {
|
|
27
|
+
// common element found
|
|
28
|
+
|
|
26
29
|
common.push(elA);
|
|
27
30
|
|
|
31
|
+
// remove from respective unique sets
|
|
28
32
|
uniqueA.splice(i, 1);
|
|
29
33
|
uniqueB.splice(j, 1);
|
|
30
34
|
|
|
31
35
|
i--;
|
|
32
|
-
|
|
36
|
+
a_length--;
|
|
33
37
|
}
|
|
34
38
|
}
|
|
35
39
|
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import {aabb3_array_intersects_point} from "./aabb3_array_intersects_point.js";
|
|
2
|
+
|
|
3
|
+
test("", () => {
|
|
4
|
+
expect(aabb3_array_intersects_point([
|
|
5
|
+
0, 0, 0,
|
|
6
|
+
0, 0, 0
|
|
7
|
+
], 0, 0, 0)).toBe(true);
|
|
8
|
+
|
|
9
|
+
expect(aabb3_array_intersects_point([
|
|
10
|
+
1, 1, 1,
|
|
11
|
+
2, 2, 2
|
|
12
|
+
], 0, 0, 0)).toBe(false);
|
|
13
|
+
|
|
14
|
+
expect(aabb3_array_intersects_point([
|
|
15
|
+
1, 1, 1,
|
|
16
|
+
2, 2, 2
|
|
17
|
+
], 1, 0, 0)).toBe(false);
|
|
18
|
+
|
|
19
|
+
expect(aabb3_array_intersects_point([
|
|
20
|
+
1, 1, 1,
|
|
21
|
+
2, 2, 2
|
|
22
|
+
], 0, 1, 0)).toBe(false);
|
|
23
|
+
|
|
24
|
+
expect(aabb3_array_intersects_point([
|
|
25
|
+
1, 1, 1,
|
|
26
|
+
2, 2, 2
|
|
27
|
+
], 0, 0, 1)).toBe(false);
|
|
28
|
+
|
|
29
|
+
expect(aabb3_array_intersects_point([
|
|
30
|
+
1, 1, 1,
|
|
31
|
+
2, 2, 2
|
|
32
|
+
], 2, 0, 0)).toBe(false);
|
|
33
|
+
|
|
34
|
+
expect(aabb3_array_intersects_point([
|
|
35
|
+
1, 1, 1,
|
|
36
|
+
2, 2, 2
|
|
37
|
+
], 0, 2, 0)).toBe(false);
|
|
38
|
+
|
|
39
|
+
expect(aabb3_array_intersects_point([
|
|
40
|
+
1, 1, 1,
|
|
41
|
+
2, 2, 2
|
|
42
|
+
], 0, 0, 2)).toBe(false);
|
|
43
|
+
|
|
44
|
+
expect(aabb3_array_intersects_point([
|
|
45
|
+
1, 1, 1,
|
|
46
|
+
2, 2, 2
|
|
47
|
+
], 1.5, 1.5, 1.5)).toBe(true);
|
|
48
|
+
});
|
|
@@ -12,7 +12,11 @@ import { aabb3_intersects_ray } from "./aabb3_intersects_ray.js";
|
|
|
12
12
|
* @param {number} direction_y
|
|
13
13
|
* @param {number} direction_z
|
|
14
14
|
*/
|
|
15
|
-
export function aabb3_array_intersects_ray(
|
|
15
|
+
export function aabb3_array_intersects_ray(
|
|
16
|
+
aabb,
|
|
17
|
+
origin_x, origin_y, origin_z,
|
|
18
|
+
direction_x, direction_y, direction_z
|
|
19
|
+
) {
|
|
16
20
|
return aabb3_intersects_ray(aabb[0], aabb[1], aabb[2], aabb[3], aabb[4], aabb[5],
|
|
17
21
|
origin_x, origin_y, origin_z,
|
|
18
22
|
direction_x, direction_y, direction_z
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import {aabb3_raycast} from "./aabb3_raycast.js";
|
|
2
|
+
|
|
3
|
+
test("basics", () => {
|
|
4
|
+
|
|
5
|
+
const result = [];
|
|
6
|
+
|
|
7
|
+
let hit_found;
|
|
8
|
+
|
|
9
|
+
hit_found = aabb3_raycast(
|
|
10
|
+
result, 0,
|
|
11
|
+
1, 3, 5,
|
|
12
|
+
7, 11, 13,
|
|
13
|
+
-1, 4, 6,
|
|
14
|
+
1, 0, 0
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
expect(hit_found).toBe(true);
|
|
18
|
+
expect(result).toEqual([
|
|
19
|
+
1, 4, 6,
|
|
20
|
+
-1, 0, 0
|
|
21
|
+
]);
|
|
22
|
+
|
|
23
|
+
hit_found = aabb3_raycast(
|
|
24
|
+
result, 0,
|
|
25
|
+
1, 3, 5,
|
|
26
|
+
7, 11, 13,
|
|
27
|
+
8, 4, 6,
|
|
28
|
+
-1, 0, 0
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
expect(hit_found).toBe(true);
|
|
32
|
+
expect(result).toEqual([
|
|
33
|
+
7, 4, 6,
|
|
34
|
+
1, 0, 0
|
|
35
|
+
]);
|
|
36
|
+
|
|
37
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {aabb3_compute_half_surface_area} from "./aabb3_compute_half_surface_area.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Compute surface area for a box contain both inputs
|
|
@@ -7,9 +7,8 @@ import { aabb3_compute_half_surface_area } from "./aabb3_compute_half_surface_ar
|
|
|
7
7
|
* @returns {number}
|
|
8
8
|
*/
|
|
9
9
|
function aabb3_score_boxes_SAH(a, b) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
//
|
|
10
|
+
|
|
11
|
+
// read out bounds
|
|
13
12
|
|
|
14
13
|
const ax0 = a.x0;
|
|
15
14
|
const ay0 = a.y0;
|
|
@@ -25,19 +24,19 @@ function aabb3_score_boxes_SAH(a, b) {
|
|
|
25
24
|
const by1 = b.y1;
|
|
26
25
|
const bz1 = b.z1;
|
|
27
26
|
|
|
28
|
-
//
|
|
27
|
+
// compute combined bounds
|
|
29
28
|
|
|
30
|
-
x0 = ax0 < bx0 ? ax0 : bx0;
|
|
31
|
-
y0 = ay0 < by0 ? ay0 : by0;
|
|
32
|
-
z0 = az0 < bz0 ? az0 : bz0;
|
|
29
|
+
const x0 = ax0 < bx0 ? ax0 : bx0;
|
|
30
|
+
const y0 = ay0 < by0 ? ay0 : by0;
|
|
31
|
+
const z0 = az0 < bz0 ? az0 : bz0;
|
|
33
32
|
|
|
34
|
-
x1 = ax1 > bx1 ? ax1 : bx1;
|
|
35
|
-
y1 = ay1 > by1 ? ay1 : by1;
|
|
36
|
-
z1 = az1 > bz1 ? az1 : bz1;
|
|
33
|
+
const x1 = ax1 > bx1 ? ax1 : bx1;
|
|
34
|
+
const y1 = ay1 > by1 ? ay1 : by1;
|
|
35
|
+
const z1 = az1 > bz1 ? az1 : bz1;
|
|
37
36
|
|
|
38
37
|
//
|
|
39
38
|
|
|
40
39
|
return aabb3_compute_half_surface_area(x0, y0, z0, x1, y1, z1);
|
|
41
40
|
}
|
|
42
41
|
|
|
43
|
-
export {
|
|
42
|
+
export {aabb3_score_boxes_SAH};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {AABB3} from "./AABB3.js";
|
|
2
|
+
import {aabb3_score_boxes_SAH} from "./aabb3_score_boxes_SAH.js";
|
|
3
|
+
|
|
4
|
+
test("basics", () => {
|
|
5
|
+
|
|
6
|
+
const value = aabb3_score_boxes_SAH(
|
|
7
|
+
new AABB3(0, 0, 0, 0, 0, 0),
|
|
8
|
+
new AABB3(0, 0, 0, 0, 0, 0)
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
expect(typeof value).toEqual("number");
|
|
12
|
+
expect(value).not.toBeNaN();
|
|
13
|
+
|
|
14
|
+
});
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import {v3_distance_above_plane} from "../../vec3/v3_distance_above_plane.js";
|
|
2
|
+
import {aabb3_build_corners} from "./aabb3_build_corners.js";
|
|
3
|
+
import {aabb3_matrix4_project_by_corners} from "./aabb3_matrix4_project_by_corners.js";
|
|
4
4
|
|
|
5
5
|
const scratch_corners = new Float32Array(24);
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* Figure out which side of a plane an Axis-Aligned Bounding Box lies, after applying transform matrix to it
|
|
9
9
|
* 2,0,or -2; 2: above, -2 : below, 0 : intersects plane
|
|
10
10
|
* @param {number} x0
|
|
11
11
|
* @param {number} y0
|
|
@@ -25,6 +25,8 @@ export function aabb3_transformed_compute_plane_side(
|
|
|
25
25
|
plane_normal_x, plane_normal_y, plane_normal_z, plane_offset,
|
|
26
26
|
transform_matrix
|
|
27
27
|
) {
|
|
28
|
+
// TODO consider transforming the plane instead?
|
|
29
|
+
|
|
28
30
|
|
|
29
31
|
aabb3_build_corners(
|
|
30
32
|
scratch_corners, 0,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import {min2} from "../../../math/min2.js";
|
|
2
|
+
import {max2} from "../../../math/max2.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Multidimensional axis-aligned bounding box calculation
|
|
@@ -26,8 +26,11 @@ export function compute_aabb_from_points(
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
for (i = 0; i < input_count; i++) {
|
|
29
|
+
|
|
30
|
+
const offset_0 = input_count + i * d;
|
|
31
|
+
|
|
29
32
|
for (j = 0; j < d; j++) {
|
|
30
|
-
const v = input[
|
|
33
|
+
const v = input[offset_0 + j];
|
|
31
34
|
|
|
32
35
|
result[j] = min2(result[j], v);
|
|
33
36
|
result[j + d] = max2(result[j + d], v);
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import {MATRIX_4_IDENTITY} from "./MATRIX_4_IDENTITY.js";
|
|
2
2
|
import {m4_multiply} from "./m4_multiply.js";
|
|
3
|
+
import {m4_multiply_alphatensor} from "./m4_multiply_alphatensor.js";
|
|
4
|
+
import {number_pretty_print} from "../../../primitives/numbers/number_pretty_print.js";
|
|
3
5
|
|
|
4
6
|
test("identity multiplication", () => {
|
|
5
7
|
|
|
@@ -8,4 +10,26 @@ test("identity multiplication", () => {
|
|
|
8
10
|
m4_multiply(result, MATRIX_4_IDENTITY, MATRIX_4_IDENTITY);
|
|
9
11
|
|
|
10
12
|
expect(result).toEqual(MATRIX_4_IDENTITY);
|
|
13
|
+
});
|
|
14
|
+
test.skip("benchmark 1,000,000", () => {
|
|
15
|
+
|
|
16
|
+
const COUNT = 1000000;
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
const memory = new ArrayBuffer(16 * 3 * 4);
|
|
20
|
+
|
|
21
|
+
const m0 = new Float32Array(memory, 16 * 4 * 0, 16);
|
|
22
|
+
const m1 = new Float32Array(memory, 16 * 4 * 1, 16);
|
|
23
|
+
const m2 = new Float32Array(memory, 16 * 4 * 2, 16);
|
|
24
|
+
|
|
25
|
+
const t0 = performance.now();
|
|
26
|
+
|
|
27
|
+
for (let i = 0; i < COUNT; i++) {
|
|
28
|
+
m4_multiply(m0, m1, m2);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const t1 = performance.now();
|
|
32
|
+
|
|
33
|
+
const span_ms = t1 - t0;
|
|
34
|
+
console.log(`total time ${span_ms}ms, ${ number_pretty_print(COUNT / (span_ms * 1e-3))} Operations/s`)
|
|
11
35
|
});
|
|
@@ -1,45 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Performs 4x4 matrix multiplication using algorithm discovered by AlphaTensor
|
|
3
|
+
* NOTE: currently ~2.5 times slower than {@link m4_multiply}
|
|
3
4
|
* @see AlphaTensor2022 by Fawzi etAl
|
|
4
|
-
* @param {number[]} out
|
|
5
|
-
* @param {number[]} a
|
|
6
|
-
* @param {number[]} b
|
|
5
|
+
* @param {number[]|Float32Array} out
|
|
6
|
+
* @param {number[]|Float32Array} a
|
|
7
|
+
* @param {number[]|Float32Array} b
|
|
7
8
|
*/
|
|
8
9
|
export function m4_multiply_alphatensor(out, a, b) {
|
|
9
10
|
// read out matricies
|
|
10
11
|
const a11 = a[0];
|
|
11
|
-
const a12 = a[1];
|
|
12
12
|
const a13 = a[2];
|
|
13
|
-
const a14 = a[3];
|
|
14
|
-
const a21 = a[4];
|
|
15
|
-
const a22 = a[5];
|
|
16
|
-
const a23 = a[6];
|
|
17
|
-
const a24 = a[7];
|
|
18
13
|
const a31 = a[8];
|
|
19
|
-
const a32 = a[9];
|
|
20
14
|
const a33 = a[10];
|
|
21
|
-
const a34 = a[11];
|
|
22
|
-
const a41 = a[12];
|
|
23
|
-
const a42 = a[13];
|
|
24
|
-
const a43 = a[14];
|
|
25
|
-
const a44 = a[15];
|
|
26
15
|
|
|
27
16
|
const b11 = b[0];
|
|
28
|
-
const b12 = b[1];
|
|
29
17
|
const b13 = b[2];
|
|
30
|
-
const b14 = b[3];
|
|
31
|
-
const b21 = b[4];
|
|
32
|
-
const b22 = b[5];
|
|
33
|
-
const b23 = b[6];
|
|
34
|
-
const b24 = b[7];
|
|
35
18
|
const b31 = b[8];
|
|
36
|
-
const b32 = b[9];
|
|
37
19
|
const b33 = b[10];
|
|
38
|
-
|
|
39
|
-
const b41 = b[12];
|
|
40
|
-
const b42 = b[13];
|
|
41
|
-
const b43 = b[14];
|
|
42
|
-
const b44 = b[15];
|
|
20
|
+
|
|
43
21
|
|
|
44
22
|
// apply multiplication algorithm
|
|
45
23
|
const h1 = (a11 + a31) * (b11 + b31)
|
|
@@ -48,6 +26,26 @@ export function m4_multiply_alphatensor(out, a, b) {
|
|
|
48
26
|
const h4 = -a33 * -b33
|
|
49
27
|
const h5 = -a31 * -b13
|
|
50
28
|
const h6 = (a11 - a13 + a31 - a33) * -b31
|
|
29
|
+
|
|
30
|
+
const b21 = b[4];
|
|
31
|
+
const b22 = b[5];
|
|
32
|
+
const b23 = b[6];
|
|
33
|
+
const b24 = b[7];
|
|
34
|
+
const b41 = b[12];
|
|
35
|
+
const b42 = b[13];
|
|
36
|
+
const b43 = b[14];
|
|
37
|
+
const b44 = b[15];
|
|
38
|
+
|
|
39
|
+
const a21 = a[4];
|
|
40
|
+
const a22 = a[5];
|
|
41
|
+
const a23 = a[6];
|
|
42
|
+
const a24 = a[7];
|
|
43
|
+
const a41 = a[12];
|
|
44
|
+
const a42 = a[13];
|
|
45
|
+
const a43 = a[14];
|
|
46
|
+
const a44 = a[15];
|
|
47
|
+
|
|
48
|
+
|
|
51
49
|
const h7 = (-a21 + a22 - a23 - a24) * (-b21 + b22 - b23 - b24)
|
|
52
50
|
const h8 = (-a21 + a22 - a23 - a24 - a41 + a42) * (-b21 + b22 - b23 - b24 - b41 + b42)
|
|
53
51
|
const h9 = (a11 - a13) * (b11 - b13)
|
|
@@ -55,9 +53,24 @@ export function m4_multiply_alphatensor(out, a, b) {
|
|
|
55
53
|
const h11 = (a41 - a42) * (-b23 - b24)
|
|
56
54
|
const h12 = (-a21 + a22 - a23 - a24 - a41 + a42 - a43 - a44) * (b41 - b42)
|
|
57
55
|
const h13 = (-a23 - a24) * (-b21 + b22 - b23 - b24 - b41 + b42 - b43 - b44)
|
|
56
|
+
|
|
57
|
+
const a12 = a[1];
|
|
58
|
+
|
|
59
|
+
const b12 = b[1];
|
|
60
|
+
const b14 = b[3];
|
|
61
|
+
|
|
58
62
|
const h14 = (a11 - a12 + a21 - a22) * (-b12 - b14)
|
|
63
|
+
|
|
64
|
+
const a14 = a[3];
|
|
65
|
+
|
|
59
66
|
const h15 = (-a12 - a14) * -b21
|
|
60
67
|
const h16 = (a12 + a14 - a21 + a22 + a23 + a24) * (b12 + b14 - b21 + b22 + b23 + b24)
|
|
68
|
+
|
|
69
|
+
const b32 = b[9];
|
|
70
|
+
const b34 = b[11];
|
|
71
|
+
const a32 = a[9];
|
|
72
|
+
const a34 = a[11];
|
|
73
|
+
|
|
61
74
|
const h17 = (a12 + a14 - a21 + a22 + a23 + a24 + a32 + a41 - a42) * (b12 + b14 - b21 + b22 + b23 + b24 + b32 + b41 - b42)
|
|
62
75
|
const h18 = (a12 - a21 + a22 + a32 + a41 - a42) * (b12 - b21 + b22 + b32 + b41 - b42)
|
|
63
76
|
const h19 = (a14 + a23 + a24) * (b12 + b14 - b21 + b22 + b23 + b24 + b32 + b34 + b41 - b42 - b43 - b44)
|
|
@@ -91,39 +104,42 @@ export function m4_multiply_alphatensor(out, a, b) {
|
|
|
91
104
|
const h47 = (a41 - a43) * (-b13 - b14 - b23 - b24)
|
|
92
105
|
const h48 = (-a43 - a44) * (-b43 - b44)
|
|
93
106
|
const h49 = -a23 * (-b31 + b32 + b41 - b42)
|
|
107
|
+
|
|
94
108
|
const c11 = h1 - h2 - h5 + h9 + h15 + h33
|
|
95
109
|
const c12 = -h15 - h16 + h17 - h18 - h21 + h22 - h23 + h26 - h33 - h41 + h44 + h49
|
|
96
110
|
const c13 = h2 + h5 + h6 - h9 - h29 - h33 + h34 + h38
|
|
97
111
|
const c14 = -h16 + h17 - h20 - h21 + h22 - h23 + h25 + h26 - h29 - h32 - h33 + h34 + h38 - h41 + h42 + h43
|
|
98
|
-
const c21 = -h7 + h8 - h10 + h11 - h14 + h15 + h16 - h17 + h18 + h21 - h31 + h33 - h35 - h36
|
|
99
|
-
const c22 = h7 - h8 + h10 - h11 - h15 - h16 + h17 - h18 - h21 + h22 - h23 + h26 - h33 + h44
|
|
100
|
-
const c23 = -h7 + h8 + h11 + h12 - h16 + h17 - h20 - h21 - h29 - h33 + h34 + h36 + h38 + h46
|
|
101
|
-
const c24 = -h7 + h8 + h11 + h12 - h16 + h17 - h20 - h21 + h22 - h23 + h25 + h26 - h29 - h33 + h34 + h38
|
|
102
|
-
const c31 = h1 - h2 + h3 - h5 + h33 - h34 + h37 - h40
|
|
103
|
-
const c32 = h17 - h18 - h19 - h21 - h23 + h24 + h26 - h33 + h34 - h37 + h40 - h43 + h44 + h45 - h47 + h49
|
|
104
|
-
const c33 = h4 + h5 - h29 - h33 + h34 + h40
|
|
105
|
-
const c34 = -h21 + h26 - h27 + h28 - h29 - h32 - h33 + h34 + h40 - h47
|
|
106
|
-
const c41 = h8 - h10 + h11 - h13 + h17 - h18 - h19 - h21 + h31 - h33 + h34 + h35 + h36 - h37 - h39 + h40
|
|
107
|
-
const c42 = -h8 + h10 - h11 + h13 - h17 + h18 + h19 + h21 + h23 - h24 - h26 + h33 - h34 + h37 - h40 - h44
|
|
108
|
-
const c43 = h11 + h21 - h28 + h29 + h30 + h33 - h34 - h35 - h36 + h39 - h40 + h48
|
|
109
|
-
const c44 = h11 + h21 - h26 + h27 - h28 + h29 + h33 - h34 - h40 + h48
|
|
110
112
|
|
|
111
|
-
// write out results
|
|
112
113
|
out[0] = c11;
|
|
113
114
|
out[1] = c12;
|
|
114
115
|
out[2] = c13;
|
|
115
116
|
out[3] = c14;
|
|
116
117
|
|
|
118
|
+
const c21 = -h7 + h8 - h10 + h11 - h14 + h15 + h16 - h17 + h18 + h21 - h31 + h33 - h35 - h36
|
|
119
|
+
const c22 = h7 - h8 + h10 - h11 - h15 - h16 + h17 - h18 - h21 + h22 - h23 + h26 - h33 + h44
|
|
120
|
+
const c23 = -h7 + h8 + h11 + h12 - h16 + h17 - h20 - h21 - h29 - h33 + h34 + h36 + h38 + h46
|
|
121
|
+
const c24 = -h7 + h8 + h11 + h12 - h16 + h17 - h20 - h21 + h22 - h23 + h25 + h26 - h29 - h33 + h34 + h38
|
|
122
|
+
|
|
117
123
|
out[4] = c21;
|
|
118
124
|
out[5] = c22;
|
|
119
125
|
out[6] = c23;
|
|
120
126
|
out[7] = c24;
|
|
121
127
|
|
|
128
|
+
const c31 = h1 - h2 + h3 - h5 + h33 - h34 + h37 - h40
|
|
129
|
+
const c32 = h17 - h18 - h19 - h21 - h23 + h24 + h26 - h33 + h34 - h37 + h40 - h43 + h44 + h45 - h47 + h49
|
|
130
|
+
const c33 = h4 + h5 - h29 - h33 + h34 + h40
|
|
131
|
+
const c34 = -h21 + h26 - h27 + h28 - h29 - h32 - h33 + h34 + h40 - h47
|
|
132
|
+
|
|
122
133
|
out[8] = c31;
|
|
123
134
|
out[9] = c32;
|
|
124
135
|
out[10] = c33;
|
|
125
136
|
out[11] = c34;
|
|
126
137
|
|
|
138
|
+
const c41 = h8 - h10 + h11 - h13 + h17 - h18 - h19 - h21 + h31 - h33 + h34 + h35 + h36 - h37 - h39 + h40
|
|
139
|
+
const c42 = -h8 + h10 - h11 + h13 - h17 + h18 + h19 + h21 + h23 - h24 - h26 + h33 - h34 + h37 - h40 - h44
|
|
140
|
+
const c43 = h11 + h21 - h28 + h29 + h30 + h33 - h34 - h35 - h36 + h39 - h40 + h48
|
|
141
|
+
const c44 = h11 + h21 - h26 + h27 - h28 + h29 + h33 - h34 - h40 + h48
|
|
142
|
+
|
|
127
143
|
out[12] = c41;
|
|
128
144
|
out[13] = c42;
|
|
129
145
|
out[14] = c43;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {m4_multiply_alphatensor} from "./m4_multiply_alphatensor.js";
|
|
2
2
|
import {MATRIX_4_IDENTITY} from "./MATRIX_4_IDENTITY.js";
|
|
3
|
+
import {number_pretty_print} from "../../../primitives/numbers/number_pretty_print.js";
|
|
3
4
|
|
|
4
5
|
test("identity multiplication", () => {
|
|
5
6
|
|
|
@@ -8,4 +9,27 @@ test("identity multiplication", () => {
|
|
|
8
9
|
m4_multiply_alphatensor(result, MATRIX_4_IDENTITY, MATRIX_4_IDENTITY);
|
|
9
10
|
|
|
10
11
|
expect(result).toEqual(MATRIX_4_IDENTITY);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test.skip("benchmark 1,000,000", () => {
|
|
15
|
+
|
|
16
|
+
const COUNT = 1000000;
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
const memory = new ArrayBuffer(16 * 3 * 4);
|
|
20
|
+
|
|
21
|
+
const m0 = new Float32Array(memory, 16 * 4 * 0, 16);
|
|
22
|
+
const m1 = new Float32Array(memory, 16 * 4 * 1, 16);
|
|
23
|
+
const m2 = new Float32Array(memory, 16 * 4 * 2, 16);
|
|
24
|
+
|
|
25
|
+
const t0 = performance.now();
|
|
26
|
+
|
|
27
|
+
for (let i = 0; i < COUNT; i++) {
|
|
28
|
+
m4_multiply_alphatensor(m0, m1, m2);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const t1 = performance.now();
|
|
32
|
+
|
|
33
|
+
const span_ms = t1 - t0;
|
|
34
|
+
console.log(`total time ${span_ms}ms, ${ number_pretty_print(COUNT / (span_ms * 1e-3))} Operations/s`)
|
|
11
35
|
});
|
|
@@ -55,7 +55,7 @@ function composite_shape_to_entity(shape, ecd) {
|
|
|
55
55
|
|
|
56
56
|
child_entity.add(Attachment.fromJSON({
|
|
57
57
|
socket: 0,
|
|
58
|
-
parent: parent.
|
|
58
|
+
parent: parent.id,
|
|
59
59
|
immediate: true
|
|
60
60
|
}));
|
|
61
61
|
|
|
@@ -127,7 +127,7 @@ function transformed_shape_to_entity(shape, ecd) {
|
|
|
127
127
|
|
|
128
128
|
const attachment = Attachment.fromJSON({
|
|
129
129
|
socket: 0,
|
|
130
|
-
parent: parent.
|
|
130
|
+
parent: parent.id,
|
|
131
131
|
immediate: true
|
|
132
132
|
});
|
|
133
133
|
|