@woosh/meep-engine 2.49.9 → 2.50.1
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/editor/actions/concrete/ArrayCopyAction.js +1 -1
- package/package.json +1 -1
- package/src/core/binary/BinaryBuffer.js +1 -1
- package/src/core/binary/BinaryBuffer.spec.js +128 -0
- package/src/core/binary/int32_to_binary_string.js +4 -1
- package/src/core/binary/int32_to_binary_string.spec.js +9 -0
- package/src/core/bvh2/BinaryNode.js +0 -30
- package/src/core/bvh2/binary/2/BinaryUint32BVH.js +1 -1
- package/src/core/bvh2/binary/IndexedBinaryBVH.js +1 -1
- package/src/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js +1 -1
- package/src/core/bvh2/bvh3/query/compute_tight_near_far_clipping_planes.js +1 -1
- package/src/core/cache/Cache.js +31 -29
- package/src/core/cache/Cache.spec.js +4 -1
- package/src/core/collection/HashMap.js +1 -1
- package/src/core/collection/array/{copyArray.js → array_copy.js} +1 -24
- package/src/core/collection/array/array_copy_entire.js +21 -0
- package/src/core/collection/array/typed/typed_array_copy.js +1 -1
- package/src/core/collection/queue/Deque.d.ts +4 -0
- package/src/core/collection/queue/Deque.js +5 -7
- package/src/core/collection/queue/Deque.spec.js +107 -0
- package/src/core/collection/table/RowFirstTable.js +1 -1
- package/src/core/geom/2d/aabb/AABB2.d.ts +14 -0
- package/src/core/geom/2d/aabb/AABB2.js +9 -7
- package/src/core/geom/2d/aabb/AABB2.spec.js +100 -0
- package/src/core/geom/2d/aabb/aabb2_compute_center_from_multiple.spec.js +11 -0
- package/src/core/geom/2d/aabb/aabb2_compute_overlap.spec.js +56 -0
- package/src/core/geom/2d/aabb/aabb2_contains.spec.js +40 -0
- package/src/core/geom/2d/bvh/Node2.js +1 -1
- package/src/core/geom/2d/convex-hull/fixed_convex_hull_humus.js +1 -1
- package/src/core/geom/2d/convex-hull/fixed_convex_hull_relaxation.js +1 -1
- package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_2d.js +35 -0
- package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_array_2d.js +51 -0
- package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_vectors_2d.js +15 -0
- package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_vectors_array_2d.js +30 -0
- package/src/core/geom/2d/line/line_segment_line_segment_intersection_exists_2d.js +29 -0
- package/src/core/geom/3d/aabb/AABB3.d.ts +4 -0
- package/src/core/geom/3d/aabb/AABB3.spec.js +30 -0
- package/src/core/geom/3d/aabb/aabb3_detailed_volume_intersection.js +4 -4
- package/src/core/geom/3d/frustum/frustum3_computeNearestPointToPoint.js +5 -5
- package/src/core/geom/3d/matrix/m4_make_translation.js +1 -1
- package/src/core/geom/3d/plane/is_point_within_planes.js +1 -1
- package/src/core/geom/3d/plane/lerp_planes_to_array.js +2 -0
- package/src/core/geom/3d/plane/{plane_computeConvex3PlaneIntersection.js → plane3_compute_convex_3_plane_intersection.js} +1 -1
- package/src/core/geom/3d/plane/{plane3_computeLineSegmentIntersection.js → plane3_compute_line_segment_intersection.js} +1 -1
- package/src/core/geom/3d/plane/{computePlanePlaneIntersection.js → plane3_compute_plane_intersection.js} +15 -11
- package/src/core/geom/3d/plane/{computePlaneLineIntersection.js → plane3_compute_ray_intersection.js} +5 -1
- package/src/core/geom/3d/plane/plane3_intersect_plane.js +14 -0
- package/src/core/geom/3d/plane/{plane_three_compute_convex3_plane_intersection.js → plane3_three_compute_convex_3_plane_intersection.js} +7 -4
- package/src/core/geom/3d/plane/planeRayIntersection.js +2 -2
- package/src/core/geom/3d/sphere/harmonics/sh3_dering_optimize_positive.js +1 -1
- package/src/core/geom/3d/tetrahedra/TetrahedralMesh.js +1 -1
- package/src/core/geom/3d/tetrahedra/compute_bounding_simplex_3d.js +5 -5
- package/src/core/geom/3d/tetrahedra/compute_circumsphere.js +1 -1
- package/src/core/geom/3d/tetrahedra/delaunay/fill_in_a_cavity.js +1 -1
- package/src/core/geom/3d/topology/bounds/computeTriangleClusterNormalBoundingCone.js +1 -1
- package/src/core/geom/3d/topology/expandConnectivityByLocality.js +1 -1
- package/src/core/geom/3d/topology/struct/binary/BinaryTopology.js +1 -1
- package/src/core/geom/Quaternion.d.ts +11 -0
- package/src/core/geom/Quaternion.js +36 -27
- package/src/core/geom/Quaternion.spec.js +141 -0
- package/src/core/geom/Vector2.d.ts +5 -1
- package/src/core/geom/Vector2.js +24 -0
- package/src/core/geom/Vector3.d.ts +6 -0
- package/src/core/geom/Vector3.spec.js +60 -0
- package/src/core/graph/GraphUtils.js +4 -2
- package/src/core/graph/layout/CircleLayout.js +4 -2
- package/src/core/math/vector_nd_dot.js +16 -0
- package/src/core/math/{normalizeArrayVector.js → vector_nd_normalize.js} +3 -3
- package/src/core/math/{normalizeArrayVector.spec.js → vector_nd_normalize.spec.js} +3 -3
- package/src/core/process/PromiseWatcher.spec.js +1 -1
- package/src/engine/animation/curve/compression/downsample_float_array_curve_by_error.js +1 -1
- package/src/engine/ecs/EntityBlueprint.d.ts +14 -0
- package/src/engine/ecs/EntityBlueprint.js +2 -2
- package/src/engine/ecs/EntityBlueprint.spec.js +52 -0
- package/src/engine/ecs/EntityBuilder.js +8 -0
- package/src/engine/ecs/EntityManager.d.ts +1 -0
- package/src/engine/ecs/EntityManager.js +17 -213
- package/src/engine/ecs/EntityManager.spec.js +62 -1
- package/src/engine/ecs/System.js +8 -2
- package/src/engine/ecs/fow/FogOfWar.js +1 -1
- package/src/engine/ecs/guid/GUID.js +1 -1
- package/src/engine/ecs/terrain/ecs/splat/SplatMapping.js +1 -1
- package/src/engine/ecs/terrain/overlay/TerrainOverlay.js +1 -1
- package/src/engine/ecs/terrain/tiles/TerrainTile.js +1 -1
- package/src/engine/ecs/transform/Transform.d.ts +2 -0
- package/src/engine/ecs/transform/Transform.spec.js +63 -0
- package/src/engine/ecs/transform-attachment/TransformAttachment.d.ts +17 -1
- package/src/engine/ecs/transform-attachment/TransformAttachment.js +12 -2
- package/src/engine/ecs/transform-attachment/TransformAttachment.spec.js +103 -0
- package/src/engine/graphics/ecs/camera/Camera.js +2 -2
- package/src/engine/graphics/ecs/path/entity/EntityPath.js +1 -1
- package/src/engine/graphics/ecs/path/tube/build/computeFrenetFrames.js +1 -1
- package/src/engine/graphics/geometry/MikkT/GenerateTSpaces.js +1 -1
- package/src/engine/graphics/geometry/MikkT/m_getNormal.js +1 -1
- package/src/engine/graphics/geometry/MikkT/m_getTexCoord.js +1 -1
- package/src/engine/graphics/geometry/bvh/buffered/BVHGeometryRaycaster.js +1 -1
- package/src/engine/graphics/geometry/instancing/InstancedMeshGroup.js +1 -1
- package/src/engine/graphics/geometry/optimization/merge/merge_geometry_hierarchy.js +1 -1
- package/src/engine/graphics/impostors/octahedral/util/build_cutout_from_atlas_by_alpha.js +1 -1
- package/src/engine/graphics/particles/particular/engine/utils/volume/AttributeValue.js +1 -1
- package/src/engine/graphics/render/Lines.js +1 -1
- package/src/engine/graphics/render/buffer/simple-fx/taa/TemporalSupersamplingRenderPlugin.js +1 -1
- package/src/engine/graphics/render/forward_plus/LightManager.js +1 -1
- package/src/engine/graphics/render/forward_plus/computeFrustumCorners.js +10 -10
- package/src/engine/graphics/render/forward_plus/model/Decal.js +1 -1
- package/src/engine/graphics/render/forward_plus/prototype/prototypeLightManager.js +1 -1
- package/src/engine/graphics/render/gizmo/GizmoShapeRenderingInterface.js +1 -1
- package/src/engine/graphics/render/layers/RenderLayerUtils.js +3 -3
- package/src/engine/graphics/render/view/CameraView.js +1 -1
- package/src/engine/graphics/render/visibility/hiz/query/BatchOcclusionQuery.js +1 -1
- package/src/engine/graphics/render/webgpu/sample/MeshInstance.js +1 -1
- package/src/engine/graphics/sh3/LightProbeVolume.js +1 -1
- package/src/engine/graphics/sh3/path_tracer/PathTracedMesh.js +1 -1
- package/src/engine/graphics/sh3/path_tracer/PathTracer.js +1 -1
- package/src/engine/graphics/sh3/path_tracer/make_sky_hosek.js +1 -1
- package/src/engine/graphics/sh3/prototypeSH3Probe.js +1 -1
- package/src/engine/graphics/texture/3d/scs3d_read_2d_slice.js +1 -1
- package/src/engine/graphics/texture/CanvasClone.js +5 -1
- package/src/engine/graphics/texture/sampler/Sampler2D.js +14 -75
- package/src/engine/graphics/texture/sampler/bicubic.js +19 -19
- package/src/engine/graphics/texture/sampler/convertSampler2D2DataURL.spec.js +10 -0
- package/src/engine/graphics/texture/sampler/copy_Sampler2D_channel_data.spec.js +90 -0
- package/src/engine/graphics/texture/sampler/differenceSampler.js +13 -8
- package/src/engine/graphics/texture/sampler/distance/computeSignedDistanceField_Chamfer.js +140 -0
- package/src/engine/graphics/texture/sampler/distance/computeSignedDistanceField_NaiveFlood.js +130 -0
- package/src/engine/graphics/texture/sampler/distance/computeUnsignedDistanceField.js +10 -0
- package/src/engine/graphics/texture/sampler/distance/computeUnsignedDistanceField.spec.js +183 -0
- package/src/engine/graphics/texture/sampler/distance/computeUnsignedDistanceField_Chamfer.js +133 -0
- package/src/engine/graphics/texture/sampler/filter/mitchell.js +4 -0
- package/src/engine/graphics/texture/sampler/loadSampler2D.js +5 -2
- package/src/engine/graphics/texture/sampler/resize/sampler2d_downsample_mipmap.js +8 -3
- package/src/engine/graphics/texture/sampler/resize/sampler2d_downsample_mipmap.spec.js +13 -0
- package/src/engine/graphics/texture/sampler/sampler2d_channel_compute_min_indices.js +58 -0
- package/src/engine/graphics/trail/TemporalPath.js +0 -36
- package/src/engine/intelligence/behavior/composite/ParallelBehavior.spec.js +12 -12
- package/src/engine/intelligence/behavior/composite/SequenceBehavior.spec.js +17 -0
- package/src/engine/intelligence/behavior/primitive/SucceedingBehavior.js +3 -1
- package/src/engine/knowledge/database/StaticKnowledgeDataTable.d.ts +7 -1
- package/src/engine/knowledge/database/StaticKnowledgeDataTable.spec.js +21 -0
- package/src/engine/knowledge/database/StaticKnowledgeDataTableDescriptor.d.ts +2 -2
- package/src/engine/logging/ConsoleLoggerBackend.js +4 -0
- package/src/engine/logging/VoidLoggerBackend.js +12 -0
- package/src/engine/navigation/ecs/components/computeCatmullRomSpline.js +1 -1
- package/src/engine/navigation/ecs/components/computeCatmullRomSplineUniformDistance.js +1 -1
- package/src/engine/physics/cannon/CannonJSPhysicsSystem.js +1 -1
- package/src/engine/save/GameStateLoader.js +1 -1
- package/src/engine/scene/Scene.d.ts +2 -0
- package/src/engine/scene/Scene.js +2 -2
- package/src/engine/scene/Scene.spec.js +20 -0
- package/src/engine/scene/SceneManager.d.ts +4 -0
- package/src/engine/scene/SceneManager.js +46 -23
- package/src/engine/scene/SceneManager.spec.js +131 -0
- package/src/engine/sound/material/detector/terrain/TerrainSoundMaterialSurfaceDetector.js +2 -2
- package/src/engine/ui/GUIEngine.js +1 -1
- package/src/generation/grid/GridData.js +8 -2
- package/src/generation/grid/GridData.spec.js +5 -0
- package/src/generation/grid/generation/util/buildUnsignedDistanceField.js +3 -1
- package/src/generation/markers/MarkerNode.js +2 -2
- package/src/generation/markers/actions/MarkerNodeActionEntityPlacement.js +1 -1
- package/src/generation/theme/AreaMask.js +3 -1
- package/src/view/elements/progress/RectangularPieProgressView.js +8 -6
- package/src/view/minimap/dom/MinimapCameraView.js +3 -3
- package/src/core/geom/2d/LineSegment2.js +0 -175
- package/src/core/geom/3d/plane/computePlaneRayIntersection.js +0 -55
- package/src/core/geom/Matrix4.js +0 -275
- package/src/engine/graphics/texture/sampler/distanceField.js +0 -411
- package/src/engine/graphics/texture/sampler/distanceField.spec.js +0 -184
- package/src/engine/physics/cannon/cannon.min.js +0 -27
- package/src/generation/grid/MarkerMatchCounter.js +0 -25
- /package/src/engine/physics/spring/{Spring.js → computeHookeForce.js} +0 -0
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
sky_hosek_precompute
|
|
4
4
|
} from "../sky/hosek/sky_hosek_compute_irradiance_by_direction.js";
|
|
5
5
|
import { vec3 } from "gl-matrix";
|
|
6
|
-
import { array_copy } from "../../../../core/collection/array/
|
|
6
|
+
import { array_copy } from "../../../../core/collection/array/array_copy.js";
|
|
7
7
|
import { max2 } from "../../../../core/math/max2.js";
|
|
8
8
|
|
|
9
9
|
export function make_sky_hosek(sun = [0, 1, 0], turbidity = 1, overcast = 0, albedo = [0, 0, 0]) {
|
|
@@ -19,7 +19,7 @@ import { Transform } from "../../ecs/transform/Transform.js";
|
|
|
19
19
|
import Vector3 from "../../../core/geom/Vector3.js";
|
|
20
20
|
import { BinaryBuffer } from "../../../core/binary/BinaryBuffer.js";
|
|
21
21
|
import { is_typed_array_equals } from "../../../core/collection/array/typed/is_typed_array_equals.js";
|
|
22
|
-
import { array_copy } from "../../../core/collection/array/
|
|
22
|
+
import { array_copy } from "../../../core/collection/array/array_copy.js";
|
|
23
23
|
import { randomFloatBetween } from "../../../core/math/random/randomFloatBetween.js";
|
|
24
24
|
import { GLTFAssetLoader } from "../../asset/loaders/GLTFAssetLoader.js";
|
|
25
25
|
import { three_object_to_entity_composition } from "../ecs/mesh-v2/three_object_to_entity_composition.js";
|
|
@@ -92,50 +92,14 @@ export class Sampler2D {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
/**
|
|
95
|
+
* @deprecated
|
|
95
96
|
* @param {number[]} result
|
|
97
|
+
* @param {number} result_offset
|
|
96
98
|
* @param {number} [channel=0]
|
|
99
|
+
* @returns {number} number of matches written to result array
|
|
97
100
|
*/
|
|
98
|
-
computeMinIndices(result, channel = 0) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
assert.typeOf(channel, "number", "channel");
|
|
102
|
-
assert.ok(channel >= 0, `channel must be >= 0, was ${channel}`);
|
|
103
|
-
assert.ok(channel < itemSize, `channel must be less than itemSize(=${itemSize}), was ${channel}`);
|
|
104
|
-
|
|
105
|
-
assert.ok(Array.isArray(result), "result is not an array");
|
|
106
|
-
|
|
107
|
-
const data = this.data;
|
|
108
|
-
|
|
109
|
-
const l = data.length;
|
|
110
|
-
|
|
111
|
-
if (l === 0) {
|
|
112
|
-
//no data
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
let bestValue = data[channel];
|
|
117
|
-
|
|
118
|
-
let resultCount = 0;
|
|
119
|
-
|
|
120
|
-
for (let i = channel + itemSize; i < l; i += itemSize) {
|
|
121
|
-
const value = data[i];
|
|
122
|
-
|
|
123
|
-
if (bestValue > value) {
|
|
124
|
-
bestValue = value;
|
|
125
|
-
//drop result
|
|
126
|
-
resultCount = 1;
|
|
127
|
-
|
|
128
|
-
result[0] = i;
|
|
129
|
-
} else if (value === bestValue) {
|
|
130
|
-
result[resultCount++] = i;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
//crop results
|
|
136
|
-
if (resultCount < result.length) {
|
|
137
|
-
result.splice(resultCount, result.length - resultCount);
|
|
138
|
-
}
|
|
101
|
+
computeMinIndices(result, result_offset = 0, channel = 0) {
|
|
102
|
+
throw new Error("deprecated, use sampler2d_channel_compute_min_indices")
|
|
139
103
|
}
|
|
140
104
|
|
|
141
105
|
/**
|
|
@@ -410,7 +374,7 @@ export class Sampler2D {
|
|
|
410
374
|
*
|
|
411
375
|
* @param {number} x
|
|
412
376
|
* @param {number} y
|
|
413
|
-
* @param {number[]} result
|
|
377
|
+
* @param {number[]|Float32Array|Float64Array} result
|
|
414
378
|
* @param {number} result_offset
|
|
415
379
|
*/
|
|
416
380
|
sampleBilinear(x, y, result, result_offset = 0) {
|
|
@@ -446,6 +410,12 @@ export class Sampler2D {
|
|
|
446
410
|
* @returns {number}
|
|
447
411
|
*/
|
|
448
412
|
sampleChannelBilinear(x, y, channel) {
|
|
413
|
+
assert.isNumber(x, 'x');
|
|
414
|
+
assert.notNaN(x, 'x');
|
|
415
|
+
|
|
416
|
+
assert.isNumber(y, 'y');
|
|
417
|
+
assert.notNaN(y, 'y');
|
|
418
|
+
|
|
449
419
|
assert.isNonNegativeInteger(channel, 'channel');
|
|
450
420
|
|
|
451
421
|
const itemSize = this.itemSize;
|
|
@@ -548,6 +518,7 @@ export class Sampler2D {
|
|
|
548
518
|
assert.isNumber(channel, "channel");
|
|
549
519
|
|
|
550
520
|
assert.isNonNegativeInteger(channel, 'channel');
|
|
521
|
+
assert.lessThanOrEqual(channel, this.itemSize);
|
|
551
522
|
|
|
552
523
|
const index = (y * this.width + x) * this.itemSize + channel;
|
|
553
524
|
|
|
@@ -933,6 +904,7 @@ export class Sampler2D {
|
|
|
933
904
|
|
|
934
905
|
/**
|
|
935
906
|
* Fill data values with zeros for a given area
|
|
907
|
+
* Specialized version of `fill` method, optimized for speed
|
|
936
908
|
* @param {Number} x
|
|
937
909
|
* @param {Number} y
|
|
938
910
|
* @param {Number} width
|
|
@@ -1205,39 +1177,6 @@ export class Sampler2D {
|
|
|
1205
1177
|
throw new Error('Deprecated, use Sampler2DSerializationAdapter instead');
|
|
1206
1178
|
}
|
|
1207
1179
|
|
|
1208
|
-
/**
|
|
1209
|
-
*
|
|
1210
|
-
* @param {number} x
|
|
1211
|
-
* @param {number} y
|
|
1212
|
-
* @param {function(x:number, y:number, value:number, index:number):boolean?} visitor
|
|
1213
|
-
* @param {*} [thisArg]
|
|
1214
|
-
*/
|
|
1215
|
-
traverseOrthogonalNeighbours(x, y, visitor, thisArg) {
|
|
1216
|
-
const width = this.width;
|
|
1217
|
-
const height = this.height;
|
|
1218
|
-
|
|
1219
|
-
const index = this.point2index(x, y);
|
|
1220
|
-
|
|
1221
|
-
let i = 0;
|
|
1222
|
-
const data = this.data;
|
|
1223
|
-
if (x > 0) {
|
|
1224
|
-
i = index - 1;
|
|
1225
|
-
visitor.call(thisArg, x - 1, y, data[i], i);
|
|
1226
|
-
}
|
|
1227
|
-
if (x < width - 1) {
|
|
1228
|
-
i = index + 1;
|
|
1229
|
-
visitor.call(thisArg, x + 1, y, data[i], i);
|
|
1230
|
-
}
|
|
1231
|
-
if (y > 0) {
|
|
1232
|
-
i = index - width;
|
|
1233
|
-
visitor.call(thisArg, x, y - 1, data[i], i);
|
|
1234
|
-
}
|
|
1235
|
-
if (y < height - 1) {
|
|
1236
|
-
i = index + width;
|
|
1237
|
-
visitor.call(thisArg, x, y + 1, data[i], i);
|
|
1238
|
-
}
|
|
1239
|
-
}
|
|
1240
|
-
|
|
1241
1180
|
/**
|
|
1242
1181
|
*
|
|
1243
1182
|
* @param {Sampler2D} other
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @see https://github.com/hughsk/bicubic/blob/master/index.js
|
|
3
|
-
* @param xf
|
|
4
|
-
* @param yf
|
|
5
|
-
* @param p00
|
|
6
|
-
* @param p01
|
|
7
|
-
* @param p02
|
|
8
|
-
* @param p03
|
|
9
|
-
* @param p10
|
|
10
|
-
* @param p11
|
|
11
|
-
* @param p12
|
|
12
|
-
* @param p13
|
|
13
|
-
* @param p20
|
|
14
|
-
* @param p21
|
|
15
|
-
* @param p22
|
|
16
|
-
* @param p23
|
|
17
|
-
* @param p30
|
|
18
|
-
* @param p31
|
|
19
|
-
* @param p32
|
|
20
|
-
* @param p33
|
|
21
|
-
* @returns {
|
|
3
|
+
* @param {number} xf
|
|
4
|
+
* @param {number} yf
|
|
5
|
+
* @param {number} p00
|
|
6
|
+
* @param {number} p01
|
|
7
|
+
* @param {number} p02
|
|
8
|
+
* @param {number} p03
|
|
9
|
+
* @param {number} p10
|
|
10
|
+
* @param {number} p11
|
|
11
|
+
* @param {number} p12
|
|
12
|
+
* @param {number} p13
|
|
13
|
+
* @param {number} p20
|
|
14
|
+
* @param {number} p21
|
|
15
|
+
* @param {number} p22
|
|
16
|
+
* @param {number} p23
|
|
17
|
+
* @param {number} p30
|
|
18
|
+
* @param {number} p31
|
|
19
|
+
* @param {number} p32
|
|
20
|
+
* @param {number} p33
|
|
21
|
+
* @returns {number}
|
|
22
22
|
*/
|
|
23
23
|
export function bicubic(
|
|
24
24
|
xf, yf
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { convertSampler2D2DataURL } from "./convertSampler2D2DataURL.js";
|
|
2
|
+
import { Sampler2D } from "./Sampler2D.js";
|
|
3
|
+
|
|
4
|
+
// currently does not run in Node.js context due to reliance on HTMLCanvasElement that is absent in Node.js
|
|
5
|
+
test.skip("result is a data URL", () => {
|
|
6
|
+
const result = convertSampler2D2DataURL(Sampler2D.uint8(4, 1, 1));
|
|
7
|
+
|
|
8
|
+
expect(typeof result).toBe('string');
|
|
9
|
+
expect(result.startsWith("data://")).toBe(true);
|
|
10
|
+
});
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { copy_Sampler2D_channel_data } from "./copy_Sampler2D_channel_data.js";
|
|
2
|
+
import { Sampler2D } from "./Sampler2D.js";
|
|
3
|
+
|
|
4
|
+
test("should throw when dimensions do not match", () => {
|
|
5
|
+
expect(() => copy_Sampler2D_channel_data(
|
|
6
|
+
Sampler2D.uint8(1, 1, 1),
|
|
7
|
+
Sampler2D.uint8(1, 2, 1),
|
|
8
|
+
)).toThrow();
|
|
9
|
+
|
|
10
|
+
expect(() => copy_Sampler2D_channel_data(
|
|
11
|
+
Sampler2D.uint8(1, 2, 1),
|
|
12
|
+
Sampler2D.uint8(1, 1, 1),
|
|
13
|
+
)).toThrow();
|
|
14
|
+
|
|
15
|
+
expect(() => copy_Sampler2D_channel_data(
|
|
16
|
+
Sampler2D.uint8(1, 1, 2),
|
|
17
|
+
Sampler2D.uint8(1, 1, 1),
|
|
18
|
+
)).toThrow();
|
|
19
|
+
|
|
20
|
+
expect(() => copy_Sampler2D_channel_data(
|
|
21
|
+
Sampler2D.uint8(1, 1, 1),
|
|
22
|
+
Sampler2D.uint8(1, 1, 2),
|
|
23
|
+
)).toThrow();
|
|
24
|
+
|
|
25
|
+
expect(() => copy_Sampler2D_channel_data(
|
|
26
|
+
Sampler2D.uint8(1, 2, 2),
|
|
27
|
+
Sampler2D.uint8(1, 1, 1),
|
|
28
|
+
)).toThrow();
|
|
29
|
+
|
|
30
|
+
expect(() => copy_Sampler2D_channel_data(
|
|
31
|
+
Sampler2D.uint8(1, 1, 1),
|
|
32
|
+
Sampler2D.uint8(1, 2, 2),
|
|
33
|
+
)).toThrow();
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test("channel counts match", () => {
|
|
37
|
+
const source = Sampler2D.uint8(1, 1, 1);
|
|
38
|
+
source.writeChannel(0, 0, 0, 7);
|
|
39
|
+
|
|
40
|
+
const target = Sampler2D.uint8(1, 1, 1);
|
|
41
|
+
|
|
42
|
+
copy_Sampler2D_channel_data(source, target);
|
|
43
|
+
|
|
44
|
+
expect(target.readChannel(0, 0, 0)).toEqual(7);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test("from 2 channels to 1", () => {
|
|
48
|
+
|
|
49
|
+
const source = Sampler2D.uint8(2, 1, 1);
|
|
50
|
+
source.writeChannel(0, 0, 0, 7);
|
|
51
|
+
source.writeChannel(0, 0, 1, 13);
|
|
52
|
+
|
|
53
|
+
const target = Sampler2D.uint8(1, 1, 1);
|
|
54
|
+
|
|
55
|
+
copy_Sampler2D_channel_data(source, target);
|
|
56
|
+
|
|
57
|
+
expect(target.readChannel(0, 0, 0)).toEqual(7);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test("from 3 channels to 4", () => {
|
|
61
|
+
|
|
62
|
+
const source = Sampler2D.uint8(3, 1, 1);
|
|
63
|
+
source.set(0, 0, [3, 7, 13]);
|
|
64
|
+
|
|
65
|
+
const target = Sampler2D.uint8(4, 1, 1);
|
|
66
|
+
|
|
67
|
+
copy_Sampler2D_channel_data(source, target);
|
|
68
|
+
|
|
69
|
+
const sample = [];
|
|
70
|
+
|
|
71
|
+
target.read(0, 0, sample);
|
|
72
|
+
|
|
73
|
+
expect(sample).toEqual([3, 7, 13, 255]);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test("from 2 channels to 4", () => {
|
|
77
|
+
|
|
78
|
+
const source = Sampler2D.uint8(2, 1, 1);
|
|
79
|
+
source.set(0, 0, [3, 7]);
|
|
80
|
+
|
|
81
|
+
const target = Sampler2D.uint8(4, 1, 1);
|
|
82
|
+
|
|
83
|
+
copy_Sampler2D_channel_data(source, target);
|
|
84
|
+
|
|
85
|
+
const sample = [];
|
|
86
|
+
|
|
87
|
+
target.read(0, 0, sample);
|
|
88
|
+
|
|
89
|
+
expect(sample).toEqual([3, 3, 3, 7]);
|
|
90
|
+
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import Vector4 from "../../../../core/geom/Vector4.js";
|
|
2
1
|
import { Sampler2D } from "./Sampler2D.js";
|
|
2
|
+
import { vector_nd_normalize } from "../../../../core/math/vector_nd_normalize.js";
|
|
3
|
+
import { vector_nd_dot } from "../../../../core/math/vector_nd_dot.js";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
*
|
|
@@ -8,8 +9,10 @@ import { Sampler2D } from "./Sampler2D.js";
|
|
|
8
9
|
* @returns {Sampler2D}
|
|
9
10
|
*/
|
|
10
11
|
export function differenceSampler(sampler0, sampler1) {
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
const dimension_count = sampler0.itemSize;
|
|
13
|
+
|
|
14
|
+
const v0 = new Float64Array(dimension_count);
|
|
15
|
+
const v1 = new Float64Array(dimension_count);
|
|
13
16
|
//
|
|
14
17
|
const width = sampler0.width;
|
|
15
18
|
const height = sampler0.height;
|
|
@@ -17,12 +20,14 @@ export function differenceSampler(sampler0, sampler1) {
|
|
|
17
20
|
const difference = new Float32Array(width * height);
|
|
18
21
|
for (let y = 0; y < height; y++) {
|
|
19
22
|
for (let x = 0; x < width; x++) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
sampler0.sampleBilinear(x, y, v0);
|
|
24
|
+
sampler1.sampleBilinear(x, y, v1);
|
|
25
|
+
|
|
26
|
+
vector_nd_normalize(v0, v0, dimension_count);
|
|
27
|
+
vector_nd_normalize(v1, v1, dimension_count);
|
|
28
|
+
|
|
24
29
|
//check distance
|
|
25
|
-
difference[x + y * width] = 1 - v0
|
|
30
|
+
difference[x + y * width] = 1 - vector_nd_dot(v0, v1, dimension_count);
|
|
26
31
|
}
|
|
27
32
|
}
|
|
28
33
|
//
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { clamp } from "../../../../../core/math/clamp.js";
|
|
2
|
+
import { min2 } from "../../../../../core/math/min2.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* algorithm proposed by Borgefors, Chamfer distance [J. ACM 15 (1968) 600, Comput. Vis. Graph. Image Process. 34 (1986) 344], h
|
|
6
|
+
* @param {Sampler2D} source
|
|
7
|
+
* @param {Sampler2D} distanceField
|
|
8
|
+
* @param {number} emptyValue
|
|
9
|
+
* @param {number} d1 distance between two adjacent pixels in either x or y direction
|
|
10
|
+
* @param {number} d2 distance between two diagonally adjacent pixels
|
|
11
|
+
* @param maxD
|
|
12
|
+
*/
|
|
13
|
+
export function computeSignedDistanceField_Chamfer(source, distanceField, emptyValue, d1, d2, maxD) {
|
|
14
|
+
const sourceData = source.data;
|
|
15
|
+
const distanceFieldData = distanceField.data;
|
|
16
|
+
|
|
17
|
+
const width = source.width;
|
|
18
|
+
const height = source.height;
|
|
19
|
+
|
|
20
|
+
const maxX = width - 1;
|
|
21
|
+
const maxY = height - 1;
|
|
22
|
+
|
|
23
|
+
function getS(x, y) {
|
|
24
|
+
x = clamp(x, 0, maxX);
|
|
25
|
+
y = clamp(y, 0, maxY);
|
|
26
|
+
|
|
27
|
+
const index = x + y * width;
|
|
28
|
+
|
|
29
|
+
return sourceData[index];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function getD(x, y) {
|
|
33
|
+
x = clamp(x, 0, maxX);
|
|
34
|
+
y = clamp(y, 0, maxY);
|
|
35
|
+
|
|
36
|
+
const index = x + y * width;
|
|
37
|
+
|
|
38
|
+
return distanceFieldData[index];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function setD(x, y, v) {
|
|
42
|
+
x = clamp(x, 0, maxX);
|
|
43
|
+
y = clamp(y, 0, maxY);
|
|
44
|
+
|
|
45
|
+
const index = x + y * width;
|
|
46
|
+
|
|
47
|
+
distanceFieldData[index] = min2(v, maxD);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let x, y;
|
|
51
|
+
|
|
52
|
+
//initialize distance field
|
|
53
|
+
for (y = 0; y < height; y++) {
|
|
54
|
+
for (x = 0; x < width; x++) {
|
|
55
|
+
if (
|
|
56
|
+
getS(x - 1, y) !== getS(x, y)
|
|
57
|
+
|| getS(x + 1, y) !== getS(x, y)
|
|
58
|
+
|| getS(x, y - 1) !== getS(x, y)
|
|
59
|
+
|| getS(x, y + 1) !== getS(x, y)
|
|
60
|
+
) {
|
|
61
|
+
setD(x, y, 0);
|
|
62
|
+
} else {
|
|
63
|
+
setD(x, y, 255);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
//first pass (forward)
|
|
69
|
+
for (y = 0; y < height; y++) {
|
|
70
|
+
for (x = 0; x < width; x++) {
|
|
71
|
+
|
|
72
|
+
const v = getD(x, y);
|
|
73
|
+
|
|
74
|
+
const v0 = getD(x - 1, y - 1) + d2;
|
|
75
|
+
|
|
76
|
+
if (v0 < v) {
|
|
77
|
+
setD(x, y, v0);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const v1 = getD(x, y - 1) + d1;
|
|
81
|
+
|
|
82
|
+
if (v1 < v) {
|
|
83
|
+
setD(x, y, v1);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const v2 = getD(x + 1, y - 1) + d2;
|
|
87
|
+
|
|
88
|
+
if (v2 < v) {
|
|
89
|
+
setD(x, y, v2);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const v3 = getD(x - 1, y) + d1;
|
|
93
|
+
|
|
94
|
+
if (v3 < v) {
|
|
95
|
+
setD(x, y, v3);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
//second pass (backward)
|
|
101
|
+
for (y = maxY; y >= 0; y--) {
|
|
102
|
+
for (x = maxX; x >= 0; x--) {
|
|
103
|
+
const v = getD(x, y);
|
|
104
|
+
|
|
105
|
+
const v0 = getD(x + 1, y) + d1;
|
|
106
|
+
|
|
107
|
+
if (v0 < v) {
|
|
108
|
+
setD(x, y, v0);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const v1 = getD(x - 1, y + 1) + d2;
|
|
112
|
+
|
|
113
|
+
if (v1 < v) {
|
|
114
|
+
setD(x, y, v1);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const v2 = getD(x, y + 1) + d1;
|
|
118
|
+
|
|
119
|
+
if (v2 < v) {
|
|
120
|
+
setD(x, y, v2);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const v3 = getD(x + 1, y + 1) + d2;
|
|
124
|
+
|
|
125
|
+
if (v3 < v) {
|
|
126
|
+
setD(x, y, v3);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
//indicate inside & outside
|
|
132
|
+
for (y = 0; y < height; y++) {
|
|
133
|
+
for (x = 0; x < width; x++) {
|
|
134
|
+
if (getS(x, y) !== emptyValue) {
|
|
135
|
+
//inside
|
|
136
|
+
setD(x, y, -getD(x, y));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { assert } from "../../../../../core/assert.js";
|
|
2
|
+
import { BitSet } from "../../../../../core/binary/BitSet.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Naive flood implementation of a distance field computation algorithm
|
|
6
|
+
* @author Alex Goldring Dec 2018
|
|
7
|
+
* @param {Sampler2D} source
|
|
8
|
+
* @param {Sampler2D} destination
|
|
9
|
+
* @param {number} emptyValue
|
|
10
|
+
*/
|
|
11
|
+
export function computeSignedDistanceField_NaiveFlood(source, destination, emptyValue) {
|
|
12
|
+
assert.equal(source.itemSize, 1, `unsupported source.itemSize, expected 1, got '${source.itemSize}'`);
|
|
13
|
+
assert.typeOf(emptyValue, 'number', 'emptyValue');
|
|
14
|
+
|
|
15
|
+
let i, j;
|
|
16
|
+
|
|
17
|
+
const distanceData = destination.data;
|
|
18
|
+
|
|
19
|
+
const visited = new BitSet();
|
|
20
|
+
|
|
21
|
+
const openSet = new BitSet();
|
|
22
|
+
|
|
23
|
+
//use "flood" algorithm
|
|
24
|
+
|
|
25
|
+
//mark all visible tiles as visited
|
|
26
|
+
const samplerData = source.data;
|
|
27
|
+
const totalCellCount = samplerData.length;
|
|
28
|
+
|
|
29
|
+
function traverseNeighbours(index, visitor) {
|
|
30
|
+
let i = index - (width + 1);
|
|
31
|
+
|
|
32
|
+
const top = index > width;
|
|
33
|
+
const bottom = index < (totalCellCount - width);
|
|
34
|
+
|
|
35
|
+
const x = index % width;
|
|
36
|
+
|
|
37
|
+
const left = x > 0;
|
|
38
|
+
const right = x < width - 1;
|
|
39
|
+
|
|
40
|
+
if (top) {
|
|
41
|
+
if (left) {
|
|
42
|
+
visitor(i);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
visitor(i + 1);
|
|
46
|
+
|
|
47
|
+
if (right) {
|
|
48
|
+
visitor(i + 2);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
i += width;
|
|
53
|
+
|
|
54
|
+
if (left) {
|
|
55
|
+
visitor(i);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (right) {
|
|
59
|
+
visitor(i + 2);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
i += width;
|
|
63
|
+
|
|
64
|
+
if (bottom) {
|
|
65
|
+
if (left) {
|
|
66
|
+
visitor(i);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
visitor(i + 1);
|
|
70
|
+
|
|
71
|
+
if (right) {
|
|
72
|
+
visitor(i + 2);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const width = destination.width;
|
|
79
|
+
|
|
80
|
+
for (i = 0; i < totalCellCount; i++) {
|
|
81
|
+
const sampleValue = samplerData[i];
|
|
82
|
+
if (sampleValue !== emptyValue) {
|
|
83
|
+
visited.set(i, true);
|
|
84
|
+
//write distance data
|
|
85
|
+
distanceData[i] = 0;
|
|
86
|
+
} else {
|
|
87
|
+
distanceData[i] = 255;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
//populate initial open set
|
|
92
|
+
for (i = visited.nextSetBit(0); i !== -1; i = visited.nextSetBit(i + 1)) {
|
|
93
|
+
j = 0;
|
|
94
|
+
traverseNeighbours(i, function (neighbourIndex) {
|
|
95
|
+
if (!visited.get(neighbourIndex)) {
|
|
96
|
+
//increment number of not visited
|
|
97
|
+
j++;
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
if (j === 0) {
|
|
102
|
+
//all neighbours are visited, we can safely ignore this cell
|
|
103
|
+
} else {
|
|
104
|
+
openSet.set(i, true);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
for (i = openSet.nextSetBit(0); i !== -1; i = openSet.nextSetBit(0)) {
|
|
109
|
+
//remove from open set
|
|
110
|
+
openSet.set(i, false);
|
|
111
|
+
|
|
112
|
+
const value = distanceData[i];
|
|
113
|
+
|
|
114
|
+
traverseNeighbours(i, function (neighbourIndex) {
|
|
115
|
+
const neighbourValue = value + 1;
|
|
116
|
+
|
|
117
|
+
if (visited.get(neighbourIndex)) {
|
|
118
|
+
if (distanceData[neighbourIndex] <= neighbourValue) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
} else {
|
|
122
|
+
visited.set(neighbourIndex, true);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
distanceData[neighbourIndex] = neighbourValue;
|
|
126
|
+
//add neighbour to open set
|
|
127
|
+
openSet.set(neighbourIndex, true);
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { computeUnsignedDistanceField_Chamfer } from "./computeUnsignedDistanceField_Chamfer.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @param {Sampler2D} source
|
|
5
|
+
* @param {Sampler2D} distanceField
|
|
6
|
+
* @param {number} emptyValue
|
|
7
|
+
*/
|
|
8
|
+
export function computeUnsignedDistanceField(source, distanceField, emptyValue) {
|
|
9
|
+
computeUnsignedDistanceField_Chamfer(source, distanceField, emptyValue, 1, 1, 255);
|
|
10
|
+
}
|