@woosh/meep-engine 2.49.8 → 2.49.9

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 (58) hide show
  1. package/package.json +1 -1
  2. package/src/core/math/bessel_i0.spec.js +43 -0
  3. package/src/core/math/bessel_j0.js +30 -0
  4. package/src/core/math/hash/murmur3_32.spec.js +8 -0
  5. package/src/core/math/hash/squirrel3.spec.js +16 -0
  6. package/src/core/math/interval/NumericInterval.js +1 -0
  7. package/src/core/math/{bessel_i0.js → modified_bessel_i0.js} +5 -2
  8. package/src/core/math/noise/{create_noise_2d.js → create_simplex_noise_2d.js} +2 -2
  9. package/src/core/math/noise/create_simplex_noise_2d.spec.js +21 -0
  10. package/src/core/math/normalizeArrayVector.spec.js +15 -0
  11. package/src/core/math/physics/irradiance/interpolate_irradiance_linear.spec.js +20 -0
  12. package/src/core/math/physics/irradiance/interpolate_irradiance_lograrithmic.js +4 -4
  13. package/src/core/math/physics/irradiance/interpolate_irradiance_lograrithmic.spec.js +18 -0
  14. package/src/core/math/physics/irradiance/interpolate_irradiance_smith.js +1 -1
  15. package/src/core/math/physics/irradiance/interpolate_irradiance_smith.spec.js +20 -0
  16. package/src/core/math/random/seededRandomMersenneTwister.spec.js +10 -0
  17. package/src/core/math/spline/spline_bezier3.js +1 -1
  18. package/src/core/math/spline/spline_bezier3_bounds.js +2 -1
  19. package/src/core/math/spline/spline_bezier3_bounds.spec.js +37 -0
  20. package/src/core/math/statistics/computeSampleSize_Cochran.spec.js +12 -0
  21. package/src/core/math/statistics/computeStatisticalPartialMedian.js +4 -0
  22. package/src/core/math/statistics/computeStatisticalPartialMedian.spec.js +13 -0
  23. package/src/engine/achievements/Achievement.spec.js +21 -0
  24. package/src/engine/animation/curve/compression/prototypeCurveCompression.js +2 -2
  25. package/src/engine/animation/curve/compression/{animation_curve_to_float_array.js → sample_animation_curve_to_float_array.js} +10 -3
  26. package/src/engine/animation/curve/compression/sample_animation_curve_to_float_array.spec.js +29 -0
  27. package/src/engine/animation/curve/draw/build_curve_editor.js +3 -3
  28. package/src/engine/development/performance/RingBufferMetric.js +1 -1
  29. package/src/engine/ecs/animation/Animation.js +2 -180
  30. package/src/engine/ecs/animation/AnimationClip.js +132 -0
  31. package/src/engine/ecs/animation/AnimationClip.spec.js +5 -0
  32. package/src/engine/ecs/animation/AnimationClipFlag.js +7 -0
  33. package/src/engine/ecs/animation/AnimationFlags.js +8 -0
  34. package/src/engine/ecs/animation/AnimationSerializationAdapter.js +32 -0
  35. package/src/engine/ecs/systems/AnimationSystem.js +3 -1
  36. package/src/engine/graphics/camera/testClippingPlaneComputation.js +1 -1
  37. package/src/engine/graphics/ecs/animation/AnimationControllerSystem.js +2 -1
  38. package/src/engine/graphics/ecs/path/testPathDisplaySystem.js +1 -1
  39. package/src/engine/graphics/ecs/path/tube/prototypeAnimatedPathMask.js +1 -1
  40. package/src/engine/graphics/load_and_set_cubemap_v0.js +1 -1
  41. package/src/engine/graphics/render/buffer/buffers/prototypeNormalFrameBuffer.js +1 -1
  42. package/src/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +1 -1
  43. package/src/engine/graphics/render/visibility/hiz/prototypeHiZ.js +1 -1
  44. package/src/engine/graphics/texture/sampler/filter/kaiser_1.js +8 -4
  45. package/src/engine/graphics/texture/sampler/filter/kaiser_bessel_window.js +2 -0
  46. package/src/generation/filtering/numeric/complex/CellFilterAngleToNormal.js +11 -4
  47. package/src/generation/filtering/numeric/complex/CellFilterAngleToNormal.spec.js +30 -0
  48. package/src/generation/filtering/numeric/complex/CellFilterGaussianBlur.js +18 -2
  49. package/src/generation/filtering/numeric/complex/CellFilterGaussianBlur.spec.js +17 -0
  50. package/src/generation/filtering/numeric/complex/CellFilterSimplexNoise.js +2 -2
  51. package/src/generation/grid/GridData.js +0 -60
  52. /package/src/engine/ecs/{animation → ik}/IKMath.js +0 -0
  53. /package/src/engine/ecs/{animation → ik}/IKProblem.js +0 -0
  54. /package/src/engine/ecs/{animation → ik}/IKSolver.js +0 -0
  55. /package/src/engine/ecs/{animation → ik}/InverseKinematics.js +0 -0
  56. /package/src/engine/ecs/{animation → ik}/InverseKinematicsSystem.js +0 -0
  57. /package/src/engine/ecs/{animation → ik}/OneBoneSurfaceAlignmentSolver.js +0 -0
  58. /package/src/engine/ecs/{animation → ik}/TwoBoneInverseKinematicsSolver.js +0 -0
@@ -4,157 +4,10 @@
4
4
 
5
5
 
6
6
  import List from '../../../core/collection/list/List.js';
7
- import ObservedString from "../../../core/model/ObservedString.js";
8
- import ObservedInteger from "../../../core/model/ObservedInteger.js";
9
- import Vector1 from "../../../core/geom/Vector1.js";
10
- import { BinaryClassSerializationAdapter } from "../storage/binary/BinaryClassSerializationAdapter.js";
11
7
  import { computeHashIntegerArray } from "../../../core/collection/array/computeHashIntegerArray.js";
12
8
  import { computeHashFloat } from "../../../core/primitives/numbers/computeHashFloat.js";
13
-
14
- /**
15
- *
16
- * @enum {number}
17
- */
18
- export const AnimationClipFlag = {
19
- ClampWhenFinished: 1
20
- };
21
-
22
- class AnimationClip {
23
- constructor() {
24
- this.name = new ObservedString("");
25
- this.repeatCount = new ObservedInteger(1);
26
-
27
- /**
28
- *
29
- * @type {Vector1}
30
- */
31
- this.weight = new Vector1(1);
32
-
33
- /**
34
- *
35
- * @type {Vector1}
36
- */
37
- this.timeScale = new Vector1(1);
38
-
39
- /**
40
- *
41
- * @type {number}
42
- */
43
- this.flags = 0;
44
- }
45
-
46
- /**
47
- *
48
- * @param {AnimationClip} other
49
- * @returns {boolean}
50
- */
51
- equals(other) {
52
- return this.name.equals(other.name)
53
- && this.repeatCount.equals(other.repeatCount)
54
- && this.weight.equals(other.weight)
55
- && this.timeScale.equals(other.timeScale)
56
- && this.flags === other.flags;
57
- }
58
-
59
- /**
60
- *
61
- * @returns {number}
62
- */
63
- hash() {
64
- return computeHashIntegerArray(
65
- this.name.hash(),
66
- this.repeatCount.hash(),
67
- this.weight.hash(),
68
- this.timeScale.hash(),
69
- this.flags
70
- );
71
- }
72
-
73
- /**
74
- *
75
- * @param {number|AnimationClipFlag} v
76
- * @returns {boolean}
77
- */
78
- getFlag(v) {
79
- return (this.flags & v) !== 0;
80
- }
81
-
82
- fromJSON(json) {
83
- if (typeof json.name === "string") {
84
- this.name.fromJSON(json.name);
85
- }
86
-
87
- if (typeof json.repeatCount === "number") {
88
- this.repeatCount.fromJSON(json.repeatCount);
89
- } else {
90
- this.repeatCount.set(Number.POSITIVE_INFINITY);
91
- }
92
-
93
- if (typeof json.weight === "number") {
94
- this.weight.fromJSON(json.weight);
95
- } else {
96
- this.weight.set(1);
97
- }
98
-
99
- if (typeof json.timeScale === "number") {
100
- this.timeScale.fromJSON(json.timeScale);
101
- } else {
102
- this.timeScale.set(1);
103
- }
104
-
105
- if (typeof json.flags === "number") {
106
- this.flags = json.flags;
107
- } else {
108
- this.flags = 0;
109
- }
110
- }
111
-
112
- toJSON() {
113
- return {
114
- name: this.name.toJSON(),
115
- repeatCount: this.repeatCount.toJSON(),
116
- weight: this.weight.toJSON(),
117
- timeScale: this.timeScale.toJSON(),
118
- flags: this.flags
119
- };
120
- }
121
-
122
- /**
123
- *
124
- * @param {BinaryBuffer} buffer
125
- */
126
- toBinaryBuffer(buffer) {
127
- //write flags
128
- buffer.writeUint8(this.flags);
129
-
130
- this.name.toBinaryBuffer(buffer);
131
- this.repeatCount.toBinaryBuffer(buffer);
132
- this.weight.toBinaryBuffer(buffer);
133
- this.timeScale.toBinaryBuffer(buffer);
134
- }
135
-
136
- /**
137
- *
138
- * @param {BinaryBuffer} buffer
139
- */
140
- fromBinaryBuffer(buffer) {
141
- this.flags = buffer.readUint8();
142
-
143
- this.name.fromBinaryBuffer(buffer);
144
- this.repeatCount.fromBinaryBuffer(buffer);
145
- this.weight.fromBinaryBuffer(buffer);
146
- this.timeScale.fromBinaryBuffer(buffer);
147
- }
148
- }
149
-
150
- /**
151
- *
152
- * @enum {number}
153
- */
154
- export const AnimationFlags = {
155
- Playing: 1,
156
- MeshSizeCulling: 2
157
- };
9
+ import { AnimationClip } from "./AnimationClip.js";
10
+ import { AnimationFlags } from "./AnimationFlags.js";
158
11
 
159
12
  /**
160
13
  * @class
@@ -308,8 +161,6 @@ export class Animation {
308
161
 
309
162
  }
310
163
 
311
- Animation.Clip = AnimationClip;
312
-
313
164
  /**
314
165
  *
315
166
  * @param json
@@ -324,32 +175,3 @@ Animation.fromJSON = function (json) {
324
175
  };
325
176
 
326
177
  Animation.typeName = "Animation";
327
-
328
- export class AnimationSerializationAdapter extends BinaryClassSerializationAdapter {
329
- constructor() {
330
- super();
331
-
332
- this.klass = Animation;
333
- this.version = 0;
334
- }
335
-
336
- /**
337
- *
338
- * @param {BinaryBuffer} buffer
339
- * @param {Animation} value
340
- */
341
- serialize(buffer, value) {
342
- value.clips.toBinaryBuffer(buffer);
343
- buffer.writeFloat64(value.debtTime);
344
- }
345
-
346
- /**
347
- *
348
- * @param {BinaryBuffer} buffer
349
- * @param {Animation} value
350
- */
351
- deserialize(buffer, value) {
352
- value.clips.fromBinaryBuffer(buffer, AnimationClip);
353
- value.debtTime = buffer.readFloat64();
354
- }
355
- }
@@ -0,0 +1,132 @@
1
+ import ObservedString from "../../../core/model/ObservedString.js";
2
+ import ObservedInteger from "../../../core/model/ObservedInteger.js";
3
+ import Vector1 from "../../../core/geom/Vector1.js";
4
+ import { computeHashIntegerArray } from "../../../core/collection/array/computeHashIntegerArray.js";
5
+
6
+ export class AnimationClip {
7
+ constructor() {
8
+ this.name = new ObservedString("");
9
+ this.repeatCount = new ObservedInteger(1);
10
+
11
+ /**
12
+ *
13
+ * @type {Vector1}
14
+ */
15
+ this.weight = new Vector1(1);
16
+
17
+ /**
18
+ *
19
+ * @type {Vector1}
20
+ */
21
+ this.timeScale = new Vector1(1);
22
+
23
+ /**
24
+ *
25
+ * @type {number}
26
+ */
27
+ this.flags = 0;
28
+ }
29
+
30
+ /**
31
+ *
32
+ * @param {AnimationClip} other
33
+ * @returns {boolean}
34
+ */
35
+ equals(other) {
36
+ return this.name.equals(other.name)
37
+ && this.repeatCount.equals(other.repeatCount)
38
+ && this.weight.equals(other.weight)
39
+ && this.timeScale.equals(other.timeScale)
40
+ && this.flags === other.flags;
41
+ }
42
+
43
+ /**
44
+ *
45
+ * @returns {number}
46
+ */
47
+ hash() {
48
+ return computeHashIntegerArray(
49
+ this.name.hash(),
50
+ this.repeatCount.hash(),
51
+ this.weight.hash(),
52
+ this.timeScale.hash(),
53
+ this.flags
54
+ );
55
+ }
56
+
57
+ /**
58
+ *
59
+ * @param {number|AnimationClipFlag} v
60
+ * @returns {boolean}
61
+ */
62
+ getFlag(v) {
63
+ return (this.flags & v) !== 0;
64
+ }
65
+
66
+ fromJSON(json) {
67
+ if (typeof json.name === "string") {
68
+ this.name.fromJSON(json.name);
69
+ }
70
+
71
+ if (typeof json.repeatCount === "number") {
72
+ this.repeatCount.fromJSON(json.repeatCount);
73
+ } else {
74
+ this.repeatCount.set(Number.POSITIVE_INFINITY);
75
+ }
76
+
77
+ if (typeof json.weight === "number") {
78
+ this.weight.fromJSON(json.weight);
79
+ } else {
80
+ this.weight.set(1);
81
+ }
82
+
83
+ if (typeof json.timeScale === "number") {
84
+ this.timeScale.fromJSON(json.timeScale);
85
+ } else {
86
+ this.timeScale.set(1);
87
+ }
88
+
89
+ if (typeof json.flags === "number") {
90
+ this.flags = json.flags;
91
+ } else {
92
+ this.flags = 0;
93
+ }
94
+ }
95
+
96
+ toJSON() {
97
+ return {
98
+ name: this.name.toJSON(),
99
+ repeatCount: this.repeatCount.toJSON(),
100
+ weight: this.weight.toJSON(),
101
+ timeScale: this.timeScale.toJSON(),
102
+ flags: this.flags
103
+ };
104
+ }
105
+
106
+ /**
107
+ *
108
+ * @param {BinaryBuffer} buffer
109
+ */
110
+ toBinaryBuffer(buffer) {
111
+ //write flags
112
+ buffer.writeUint8(this.flags);
113
+
114
+ this.name.toBinaryBuffer(buffer);
115
+ this.repeatCount.toBinaryBuffer(buffer);
116
+ this.weight.toBinaryBuffer(buffer);
117
+ this.timeScale.toBinaryBuffer(buffer);
118
+ }
119
+
120
+ /**
121
+ *
122
+ * @param {BinaryBuffer} buffer
123
+ */
124
+ fromBinaryBuffer(buffer) {
125
+ this.flags = buffer.readUint8();
126
+
127
+ this.name.fromBinaryBuffer(buffer);
128
+ this.repeatCount.fromBinaryBuffer(buffer);
129
+ this.weight.fromBinaryBuffer(buffer);
130
+ this.timeScale.fromBinaryBuffer(buffer);
131
+ }
132
+ }
@@ -0,0 +1,5 @@
1
+ import { AnimationClip } from "./AnimationClip.js";
2
+
3
+ test("constructor does not throw", () => {
4
+ expect(() => new AnimationClip()).not.toThrow();
5
+ });
@@ -0,0 +1,7 @@
1
+ /**
2
+ *
3
+ * @enum {number}
4
+ */
5
+ export const AnimationClipFlag = {
6
+ ClampWhenFinished: 1
7
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ *
3
+ * @enum {number}
4
+ */
5
+ export const AnimationFlags = {
6
+ Playing: 1,
7
+ MeshSizeCulling: 2
8
+ };
@@ -0,0 +1,32 @@
1
+ import { BinaryClassSerializationAdapter } from "../storage/binary/BinaryClassSerializationAdapter.js";
2
+ import { AnimationClip } from "./AnimationClip.js";
3
+ import { Animation } from "./Animation.js";
4
+
5
+ export class AnimationSerializationAdapter extends BinaryClassSerializationAdapter {
6
+ constructor() {
7
+ super();
8
+
9
+ this.klass = Animation;
10
+ this.version = 0;
11
+ }
12
+
13
+ /**
14
+ *
15
+ * @param {BinaryBuffer} buffer
16
+ * @param {Animation} value
17
+ */
18
+ serialize(buffer, value) {
19
+ value.clips.toBinaryBuffer(buffer);
20
+ buffer.writeFloat64(value.debtTime);
21
+ }
22
+
23
+ /**
24
+ *
25
+ * @param {BinaryBuffer} buffer
26
+ * @param {Animation} value
27
+ */
28
+ deserialize(buffer, value) {
29
+ value.clips.fromBinaryBuffer(buffer, AnimationClip);
30
+ value.debtTime = buffer.readFloat64();
31
+ }
32
+ }
@@ -7,7 +7,7 @@
7
7
 
8
8
  import { max3 } from "../../../core/math/max3.js";
9
9
  import { System } from '../System.js';
10
- import { Animation, AnimationClipFlag, AnimationFlags } from '../animation/Animation.js';
10
+ import { Animation } from '../animation/Animation.js';
11
11
  import Mesh from '../../graphics/ecs/mesh/Mesh.js';
12
12
  import Future, { FutureStates } from '../../../core/process/Future.js';
13
13
 
@@ -25,6 +25,8 @@ import { MeshSystem } from "../../graphics/ecs/mesh/MeshSystem.js";
25
25
  import { projectSphere } from "../../graphics/util/projectSphere.js";
26
26
  import { threeUpdateTransform } from "../../graphics/util/threeUpdateTransform.js";
27
27
  import { MeshEvents } from "../../graphics/ecs/mesh/MeshEvents.js";
28
+ import { AnimationClipFlag } from "../animation/AnimationClipFlag.js";
29
+ import { AnimationFlags } from "../animation/AnimationFlags.js";
28
30
 
29
31
  /**
30
32
  *
@@ -38,7 +38,7 @@ import { FogOfWarSystem } from "../../ecs/fow/FogOfWarSystem.js";
38
38
  import { FogOfWarRevealerSystem } from "../../ecs/fow/FogOfWarRevealerSystem.js";
39
39
  import { BehaviorSystem } from "../../intelligence/behavior/ecs/BehaviorSystem.js";
40
40
  import { SerializationMetadataSystem } from "../../ecs/systems/SerializationMetadataSystem.js";
41
- import { InverseKinematicsSystem } from "../../ecs/animation/InverseKinematicsSystem.js";
41
+ import { InverseKinematicsSystem } from "../../ecs/ik/InverseKinematicsSystem.js";
42
42
  import { PathDisplaySystem } from "../ecs/path/PathDisplaySystem.js";
43
43
  import RenderSystem from "../../ecs/systems/RenderSystem.js";
44
44
  import { makeEngineOptionsModel } from "../../../../../model/game/options/makeEngineOptionsModel.js";
@@ -6,6 +6,7 @@
6
6
  import { System } from '../../../ecs/System.js';
7
7
  import AnimationController from './AnimationController.js';
8
8
  import { Animation } from '../../../ecs/animation/Animation.js';
9
+ import { AnimationClip } from "../../../ecs/animation/AnimationClip.js";
9
10
 
10
11
  class AnimationControllerSystem extends System {
11
12
  constructor() {
@@ -33,7 +34,7 @@ class AnimationControllerSystem extends System {
33
34
  removeAnimation(animation);
34
35
 
35
36
  //create a new animation according to the rule
36
- const clip = new Animation.Clip();
37
+ const clip = new AnimationClip();
37
38
  clip.fromJSON({
38
39
  name: r.animation,
39
40
  timeScale: r.speed,
@@ -39,7 +39,7 @@ import AnimationControllerSystem from "../animation/AnimationControllerSystem.js
39
39
  import { AnimationGraphSystem } from "../animation/animator/AnimationGraphSystem.js";
40
40
  import { BehaviorSystem } from "../../../intelligence/behavior/ecs/BehaviorSystem.js";
41
41
  import { SerializationMetadataSystem } from "../../../ecs/systems/SerializationMetadataSystem.js";
42
- import { InverseKinematicsSystem } from "../../../ecs/animation/InverseKinematicsSystem.js";
42
+ import { InverseKinematicsSystem } from "../../../ecs/ik/InverseKinematicsSystem.js";
43
43
  import { PathDisplaySystem } from "./PathDisplaySystem.js";
44
44
  import { PathDisplay } from "./PathDisplay.js";
45
45
  import { PathDisplayType } from "./PathDisplayType.js";
@@ -37,7 +37,7 @@ import AnimationControllerSystem from "../../animation/AnimationControllerSystem
37
37
  import { AnimationGraphSystem } from "../../animation/animator/AnimationGraphSystem.js";
38
38
  import { BehaviorSystem } from "../../../../intelligence/behavior/ecs/BehaviorSystem.js";
39
39
  import { SerializationMetadataSystem } from "../../../../ecs/systems/SerializationMetadataSystem.js";
40
- import { InverseKinematicsSystem } from "../../../../ecs/animation/InverseKinematicsSystem.js";
40
+ import { InverseKinematicsSystem } from "../../../../ecs/ik/InverseKinematicsSystem.js";
41
41
  import { PathDisplaySystem } from "../PathDisplaySystem.js";
42
42
  import {
43
43
  AmbientOcclusionPostProcessEffect
@@ -12,7 +12,7 @@ export async function load_and_set_cubemap_v0(graphics, folder_path, file_extens
12
12
 
13
13
  const { filtered } = await load_environment_map({
14
14
  path: paths,
15
- renderer: this.renderer,
15
+ renderer: graphics.renderer,
16
16
  original: false,
17
17
  filtered: true
18
18
  });
@@ -39,7 +39,7 @@ import { FogOfWarSystem } from "../../../../ecs/fow/FogOfWarSystem.js";
39
39
  import { FogOfWarRevealerSystem } from "../../../../ecs/fow/FogOfWarRevealerSystem.js";
40
40
  import { BehaviorSystem } from "../../../../intelligence/behavior/ecs/BehaviorSystem.js";
41
41
  import { SerializationMetadataSystem } from "../../../../ecs/systems/SerializationMetadataSystem.js";
42
- import { InverseKinematicsSystem } from "../../../../ecs/animation/InverseKinematicsSystem.js";
42
+ import { InverseKinematicsSystem } from "../../../../ecs/ik/InverseKinematicsSystem.js";
43
43
  import { CanvasView } from "../../../../../view/elements/CanvasView.js";
44
44
  import Vector3 from "../../../../../core/geom/Vector3.js";
45
45
  import Vector2 from "../../../../../core/geom/Vector2.js";
@@ -40,7 +40,7 @@ import { FogOfWarSystem } from "../../../../ecs/fow/FogOfWarSystem.js";
40
40
  import { FogOfWarRevealerSystem } from "../../../../ecs/fow/FogOfWarRevealerSystem.js";
41
41
  import { BehaviorSystem } from "../../../../intelligence/behavior/ecs/BehaviorSystem.js";
42
42
  import { SerializationMetadataSystem } from "../../../../ecs/systems/SerializationMetadataSystem.js";
43
- import { InverseKinematicsSystem } from "../../../../ecs/animation/InverseKinematicsSystem.js";
43
+ import { InverseKinematicsSystem } from "../../../../ecs/ik/InverseKinematicsSystem.js";
44
44
  import { PathDisplaySystem } from "../../../ecs/path/PathDisplaySystem.js";
45
45
  import {
46
46
  BoxBufferGeometry,
@@ -39,7 +39,7 @@ import { FogOfWarSystem } from "../../../../ecs/fow/FogOfWarSystem.js";
39
39
  import { FogOfWarRevealerSystem } from "../../../../ecs/fow/FogOfWarRevealerSystem.js";
40
40
  import { BehaviorSystem } from "../../../../intelligence/behavior/ecs/BehaviorSystem.js";
41
41
  import { SerializationMetadataSystem } from "../../../../ecs/systems/SerializationMetadataSystem.js";
42
- import { InverseKinematicsSystem } from "../../../../ecs/animation/InverseKinematicsSystem.js";
42
+ import { InverseKinematicsSystem } from "../../../../ecs/ik/InverseKinematicsSystem.js";
43
43
  import Vector3 from "../../../../../core/geom/Vector3.js";
44
44
  import Vector2 from "../../../../../core/geom/Vector2.js";
45
45
  import RenderSystem from "../../../../ecs/systems/RenderSystem.js";
@@ -1,7 +1,10 @@
1
- import { bessel_i0 } from "../../../../../core/math/bessel_i0.js";
1
+ import { modified_bessel_i0 } from "../../../../../core/math/modified_bessel_i0.js";
2
2
  import { clamp } from "../../../../../core/math/clamp.js";
3
3
 
4
- const BASE_I0 = bessel_i0(6.5);
4
+ const PI2 = 2 * Math.PI;
5
+
6
+ const BASE_I0 = modified_bessel_i0(PI2);
7
+ const INV_BESSEL_I0 = 1 / BASE_I0;
5
8
 
6
9
  /**
7
10
  * Support kernel size is 1
@@ -11,9 +14,10 @@ const BASE_I0 = bessel_i0(6.5);
11
14
  */
12
15
  export function kaiser_1(x) {
13
16
  const i = clamp(x * 0.6666666666666666, -1.0, 1.0);
14
- const i0a = 1 / BASE_I0;
15
17
 
16
- return bessel_i0(6.5 * Math.sqrt(1 - i * i)) * i0a;
18
+ const t = Math.sqrt(1 - i * i);
19
+
20
+ return modified_bessel_i0(PI2 * t) * INV_BESSEL_I0;
17
21
  }
18
22
 
19
23
  kaiser_1.support = 1;
@@ -13,7 +13,9 @@ const INV_BESSEL_3_PI_3 = 1 / BESSEL_3_PI_3;
13
13
  */
14
14
  export function kaiser_bessel_window(x) {
15
15
  const i = clamp(x * 0.6666666666666666, -1.0, 1.0);
16
+
16
17
  const t = Math.sqrt(1.0 - i * i);
18
+
17
19
  return bessel_3(PI3 * t) * INV_BESSEL_3_PI_3;
18
20
  }
19
21
 
@@ -3,6 +3,12 @@ import Vector3 from "../../../../core/geom/Vector3.js";
3
3
  import { assert } from "../../../../core/assert.js";
4
4
  import { v3_angle_between } from "../../../../core/geom/v3_angle_between.js";
5
5
 
6
+ /**
7
+ * Distance from the reference point where support points will be sampled to compute derivative
8
+ * @type {number}
9
+ */
10
+ const DERIVATIVE_OFFSET = 1;
11
+
6
12
  /**
7
13
  * Builds surface normal of another filter, and then computes the angle to a fixed 3d vector
8
14
  */
@@ -27,6 +33,7 @@ export class CellFilterAngleToNormal extends CellFilter {
27
33
  *
28
34
  * @param {CellFilter} surface
29
35
  * @param {Vector3} [reference=Vector3.forward]
36
+ * @returns {CellFilterAngleToNormal}
30
37
  */
31
38
  static from(surface, reference = Vector3.forward) {
32
39
  assert.equal(surface.isCellFilter, true, 'surface.isCellFilter !== true');
@@ -51,12 +58,12 @@ export class CellFilterAngleToNormal extends CellFilter {
51
58
  const filter = this.surface;
52
59
 
53
60
  //read surrounding points
54
- const top = filter.execute(grid, x, y - 1, 0);
61
+ const top = filter.execute(grid, x, y - DERIVATIVE_OFFSET, 0);
55
62
 
56
- const left = filter.execute(grid, x - 1, y, 0);
57
- const right = filter.execute(grid, x + 1, y, 0);
63
+ const left = filter.execute(grid, x - DERIVATIVE_OFFSET, y, 0);
64
+ const right = filter.execute(grid, x + DERIVATIVE_OFFSET, y, 0);
58
65
 
59
- const bottom = filter.execute(grid, x, y + 1, 0);
66
+ const bottom = filter.execute(grid, x, y + DERIVATIVE_OFFSET, 0);
60
67
 
61
68
  // compute gradients
62
69
  const dX = (right) - (left);
@@ -0,0 +1,30 @@
1
+ import { CellFilterAngleToNormal } from "./CellFilterAngleToNormal.js";
2
+ import { CellFilterLiteralFloat } from "../CellFilterLiteralFloat.js";
3
+ import Vector3 from "../../../../core/geom/Vector3.js";
4
+ import { GridData } from "../../../grid/GridData.js";
5
+ import { DEG_TO_RAD } from "../../../../core/math/DEG_TO_RAD.js";
6
+
7
+ test("constructor does not throw", () => {
8
+ expect(() => new CellFilterAngleToNormal()).not.toThrow();
9
+ });
10
+
11
+ test("angle to flat surface exactly on normal", () => {
12
+ const data = new GridData();
13
+
14
+ const filter = CellFilterAngleToNormal.from(CellFilterLiteralFloat.from(0), new Vector3(0, 0, 1));
15
+
16
+ filter.initialize(data, 0);
17
+
18
+ expect(filter.execute(data, 0, 0, 0)).toBeCloseTo(0);
19
+ });
20
+
21
+ test("angle to flat surface at 30deg off normal", () => {
22
+
23
+ const data = new GridData();
24
+
25
+ const filter = CellFilterAngleToNormal.from(CellFilterLiteralFloat.from(0), new Vector3(0, 0.49999999999999994, 0.8660254037844386));
26
+
27
+ filter.initialize(data, 0);
28
+
29
+ expect(filter.execute(data, 0, 0, 0)).toBeCloseTo(30 * DEG_TO_RAD);
30
+ })
@@ -47,6 +47,22 @@ function buildKernel(result, samplesX, samplesY, sigma_x, sigma_y) {
47
47
  return powerTotal;
48
48
  }
49
49
 
50
+ /**
51
+ *
52
+ * even number of samples, make odd to ensure we sample reference point
53
+ * @param {number} x
54
+ * @return {number}
55
+ */
56
+ function makeNextOdd(x) {
57
+ if (x % 2 === 0) {
58
+ // even, make odd
59
+ return x + 1;
60
+ }
61
+
62
+ // already odd
63
+ return x;
64
+ }
65
+
50
66
  export class CellFilterGaussianBlur extends CellFilter {
51
67
  constructor() {
52
68
  super();
@@ -141,8 +157,8 @@ export class CellFilterGaussianBlur extends CellFilter {
141
157
 
142
158
  r.source = source;
143
159
 
144
- r.samples_x = max2(2, Math.round(quality * x));
145
- r.samples_y = max2(2, Math.round(quality * y));
160
+ r.samples_x = max2(3, makeNextOdd(Math.round(quality * x)));
161
+ r.samples_y = max2(3, makeNextOdd(Math.round(quality * y)));
146
162
 
147
163
  r.size_x = x;
148
164
  r.size_y = y;
@@ -0,0 +1,17 @@
1
+ import { CellFilterGaussianBlur } from "./CellFilterGaussianBlur.js";
2
+ import { GridData } from "../../../grid/GridData.js";
3
+ import { CellFilterLiteralFloat } from "../CellFilterLiteralFloat.js";
4
+
5
+ test("constructor does not throw", () => {
6
+ expect(() => new CellFilterGaussianBlur()).not.toThrow();
7
+ });
8
+
9
+ test("sample on constant value source", () => {
10
+ const data = new GridData();
11
+
12
+ const filter = CellFilterGaussianBlur.from(CellFilterLiteralFloat.from(7), 3, 3, 1);
13
+
14
+ filter.initialize(data, 0);
15
+
16
+ expect(filter.execute(data, 0, 0, 0)).toBeCloseTo(7);
17
+ });
@@ -4,7 +4,7 @@ import { CellFilterAdd } from "../math/algebra/CellFilterAdd.js";
4
4
  import { CellFilterMultiply } from "../math/algebra/CellFilterMultiply.js";
5
5
  import { CellFilterLiteralFloat } from "../CellFilterLiteralFloat.js";
6
6
  import { CellFilterDivide } from "../math/algebra/CellFilterDivide.js";
7
- import { createNoise2D } from "../../../../core/math/noise/create_noise_2d.js";
7
+ import { create_simplex_noise_2d } from "../../../../core/math/noise/create_simplex_noise_2d.js";
8
8
 
9
9
  export class CellFilterSimplexNoise extends CellFilter {
10
10
  constructor() {
@@ -109,7 +109,7 @@ export class CellFilterSimplexNoise extends CellFilter {
109
109
  initialize(grid, seed) {
110
110
  this.random.setCurrentSeed(seed + this.__seed);
111
111
 
112
- this.noise = createNoise2D(this.random);
112
+ this.noise = create_simplex_noise_2d(this.random);
113
113
 
114
114
  super.initialize(grid, seed);
115
115
  }