@woosh/meep-engine 2.37.17 → 2.37.20

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 (206) hide show
  1. package/core/assert.js +1 -1
  2. package/core/binary/float2uint8.js +8 -0
  3. package/core/binary/uint82float.js +8 -0
  4. package/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js +6 -4
  5. package/core/collection/array/typed/isTypedArray.js +20 -0
  6. package/core/collection/array/typedArrayToDataType.js +1 -0
  7. package/core/collection/list/List.d.ts +1 -1
  8. package/core/collection/table/RowFirstTable.js +34 -0
  9. package/core/collection/table/RowFirstTable.spec.js +59 -1
  10. package/core/color/Color.js +83 -1
  11. package/core/color/YCbCr_to_rgb_uint24.js +3 -4
  12. package/core/color/hsv2rgb.js +4 -3
  13. package/core/color/linear_to_sRGB.js +4 -5
  14. package/core/color/rgb2hex.js +1 -1
  15. package/core/color/rgb2uint24.js +6 -4
  16. package/core/color/rgb_to_YCbCr_uint24.js +11 -13
  17. package/core/events/signal/Signal.d.ts +11 -9
  18. package/core/events/signal/Signal.js +8 -8
  19. package/core/events/signal/Signal.spec.js +16 -0
  20. package/core/geom/2d/quad-tree/qt_collect_by_circle.js +67 -0
  21. package/core/geom/Quaternion.d.ts +21 -1
  22. package/core/geom/Quaternion.js +279 -200
  23. package/core/geom/Quaternion.spec.js +71 -2
  24. package/core/geom/Vector2.js +3 -3
  25. package/core/geom/Vector3.d.ts +2 -0
  26. package/core/geom/Vector3.js +31 -7
  27. package/core/geom/Vector3.schema.json +16 -0
  28. package/core/geom/Vector4.js +16 -0
  29. package/core/json/JsonUtils.js +2 -20
  30. package/core/math/bell_membership_function.js +19 -0
  31. package/core/math/exp2.js +8 -0
  32. package/core/math/interval/NumericInterval.js +17 -0
  33. package/core/math/physics/brdf/brdf_burley.js +25 -0
  34. package/core/math/physics/bsdf/bsdf_schlick.js +22 -0
  35. package/core/math/physics/irradiance/interpolate_irradiance_linear.js +18 -0
  36. package/{engine/sound/ecs/emitter/attenuate/attenuateSoundLogarithmic.js → core/math/physics/irradiance/interpolate_irradiance_lograrithmic.js} +2 -2
  37. package/{engine/sound/ecs/emitter/attenuate/attenuateSoundSmith.js → core/math/physics/irradiance/interpolate_irradiance_smith.js} +1 -1
  38. package/core/model/ObservedEnum.js +8 -0
  39. package/editor/Editor.js +97 -1
  40. package/editor/actions/concrete/ModifyPatchSampler2DAction.js +118 -0
  41. package/editor/actions/concrete/ModifyPatchSampler2DAction.spec.js +30 -0
  42. package/editor/actions/concrete/PatchTerrainHeightAction.js +13 -105
  43. package/editor/ecs/component/FieldDescriptor.js +34 -0
  44. package/editor/ecs/component/FieldValueAdapter.js +20 -0
  45. package/editor/ecs/component/TypeEditor.js +33 -0
  46. package/editor/ecs/component/TypeSchema.d.ts +38 -0
  47. package/editor/ecs/component/createFieldEditor.js +90 -0
  48. package/editor/ecs/component/createObjectEditor.js +266 -60
  49. package/editor/ecs/component/editors/ColorEditor.js +39 -0
  50. package/editor/ecs/component/editors/HTMLElementEditor.js +17 -0
  51. package/editor/ecs/component/editors/ImagePathEditor.js +50 -0
  52. package/editor/ecs/component/editors/NumericIntervalEditor.js +86 -0
  53. package/editor/ecs/component/editors/ObservedBooleanEditor.js +13 -0
  54. package/editor/ecs/component/editors/ObservedEnumEditor.js +32 -0
  55. package/editor/ecs/component/editors/ObservedIntegerEditor.js +43 -0
  56. package/editor/ecs/component/editors/ObservedStringEditor.js +51 -0
  57. package/editor/ecs/component/editors/Sampler2DEditor.js +107 -0
  58. package/editor/ecs/component/editors/collection/ListEditor.js +83 -0
  59. package/editor/ecs/component/editors/common/BitFlagsEditor.js +80 -0
  60. package/editor/ecs/component/editors/common/EnumEditor.js +41 -0
  61. package/editor/ecs/component/editors/common/makeV3_editor.js +85 -0
  62. package/editor/ecs/component/editors/common/noEditor.js +9 -0
  63. package/editor/ecs/component/editors/ecs/GridObstacleEditor.js +17 -0
  64. package/editor/ecs/component/editors/ecs/MinimapMarkerEditor.js +16 -0
  65. package/editor/ecs/component/editors/ecs/ParameterLookupTableEditor.js +44 -0
  66. package/editor/ecs/component/editors/ecs/ParameterTrackEditor.js +17 -0
  67. package/editor/ecs/component/editors/ecs/ParticleEmitterEditor.js +58 -0
  68. package/editor/ecs/component/editors/ecs/ParticleEmitterLayerEditor.js +54 -0
  69. package/editor/ecs/component/editors/ecs/SimulationStepDefinitionEditor.js +21 -0
  70. package/editor/ecs/component/editors/ecs/Trail2DEditor.js +33 -0
  71. package/editor/ecs/component/editors/ecs/TransformEditor.js +23 -0
  72. package/editor/ecs/component/editors/ecs/terrain/SplatMappingEditor.js +21 -0
  73. package/editor/ecs/component/editors/ecs/terrain/TerrainEditor.js +89 -0
  74. package/editor/ecs/component/editors/ecs/terrain/TerrainLayerEditor.js +18 -0
  75. package/editor/ecs/component/editors/ecs/terrain/TerrainLayersEditor.js +22 -0
  76. package/editor/ecs/component/editors/ecs/terrain/TerrainOverlayEditor.js +20 -0
  77. package/editor/ecs/component/editors/geom/QuaternionEditor.js +56 -0
  78. package/editor/ecs/component/editors/geom/Vector1Editor.js +57 -0
  79. package/editor/ecs/component/editors/geom/Vector2Editor.js +11 -0
  80. package/editor/ecs/component/editors/geom/Vector3Editor.js +13 -0
  81. package/editor/ecs/component/editors/geom/Vector4Editor.js +12 -0
  82. package/editor/ecs/component/editors/primitive/ArrayEditor.js +46 -0
  83. package/editor/ecs/component/editors/primitive/BooleanEditor.js +27 -0
  84. package/editor/ecs/component/editors/primitive/FunctionEditor.js +29 -0
  85. package/editor/ecs/component/editors/primitive/NumberEditor.js +60 -0
  86. package/editor/ecs/component/editors/primitive/ObjectEditor.js +12 -0
  87. package/editor/ecs/component/editors/primitive/StringEditor.js +31 -0
  88. package/editor/ecs/component/editors/three/BufferGeometryEditor.js +28 -0
  89. package/editor/ecs/component/editors/three/MaterialEditor.js +27 -0
  90. package/editor/ecs/component/editors/three/MeshEditor.js +35 -0
  91. package/editor/ecs/component/editors/three/TextureEditor.js +32 -0
  92. package/editor/ecs/component/findNearestRegisteredType.js +59 -0
  93. package/editor/ecs/component/prototypeObjectEditor.js +379 -0
  94. package/editor/tools/SelectionTool.js +1 -1
  95. package/editor/tools/paint/TerrainHeightPaintTool.js +88 -68
  96. package/editor/tools/paint/TerrainPaintTool.js +2 -1
  97. package/editor/tools/paint/TerrainTexturePaintTool.js +8 -73
  98. package/editor/view/EditorView.js +1 -1
  99. package/editor/view/ecs/ComponentControlView.js +2 -30
  100. package/editor/view/ecs/EntityEditor.js +61 -139
  101. package/editor/view/ecs/components/GridObstacleController.js +4 -4
  102. package/editor/view/ecs/components/TerrainController.js +1 -1
  103. package/editor/view/ecs/components/common/NumberController.js +19 -7
  104. package/engine/animation/keyed2/AnimationTrack.js +1 -1
  105. package/engine/asset/AssetManager.d.ts +1 -1
  106. package/engine/asset/AssetManager.js +390 -388
  107. package/engine/asset/loaders/gltf/extensions/MSFT_texture_dds.js +14 -2
  108. package/engine/ecs/components/TagEditor.js +15 -0
  109. package/engine/ecs/fow/FogOfWarEditor.js +13 -0
  110. package/engine/ecs/terrain/ecs/OffsetScaleTransform2D.d.ts +6 -0
  111. package/engine/ecs/terrain/ecs/Terrain.js +44 -43
  112. package/engine/ecs/terrain/ecs/TerrainSystem.js +2 -2
  113. package/engine/ecs/terrain/ecs/layers/TerrainLayer.js +1 -1
  114. package/engine/ecs/terrain/ecs/splat/SplatMapping.js +26 -28
  115. package/engine/ecs/terrain/overlay/TerrainOverlay.js +71 -66
  116. package/engine/ecs/terrain/tiles/TerrainTileManager.js +23 -0
  117. package/engine/ecs/terrain/util/loadVisibleTerrainTiles.js +1 -1
  118. package/engine/ecs/terrain/util/paintTerrainOverlayViaLookupTable.js +13 -7
  119. package/engine/ecs/transform/Transform.d.ts +2 -0
  120. package/engine/ecs/transform/Transform.editor.schema.json +16 -0
  121. package/engine/ecs/transform/Transform.js +3 -0
  122. package/engine/graphics/ecs/highlight/HighlightEditor.js +17 -0
  123. package/engine/graphics/ecs/light/Light.js +0 -47
  124. package/engine/graphics/ecs/light/LightSerializationAdapter.js +50 -0
  125. package/engine/graphics/ecs/mesh/MeshEditor.js +28 -0
  126. package/engine/graphics/ecs/mesh-v2/DrawMode.js +2 -1
  127. package/engine/graphics/ecs/mesh-v2/aggregate/prototypeSGMesh.js +3 -3
  128. package/engine/graphics/ecs/mesh-v2/build_three_object.js +3 -1
  129. package/engine/graphics/ecs/sprite/Sprite.js +11 -0
  130. package/engine/graphics/ecs/sprite/SpriteSystemPE.js +133 -0
  131. package/engine/graphics/ecs/sprite/prototypeSpriteSystem.js +1566 -0
  132. package/engine/graphics/micron/prototypeVirtualGeometry.js +2 -2
  133. package/engine/graphics/micron/render/instanced/shader/shader_rewrite_standard.js +15 -15
  134. package/engine/graphics/particles/particular/engine/ParticularEngine.js +5 -0
  135. package/engine/graphics/particles/particular/engine/emitter/ParticleLayer.js +17 -9
  136. package/engine/graphics/particles/particular/engine/renderers/ParticleRenderer.js +12 -10
  137. package/engine/graphics/particles/particular/engine/renderers/billboard/ParticleBillboardMaterial.js +7 -2
  138. package/engine/graphics/particles/particular/engine/renderers/billboard/SoftBillboardParticlePool.js +27 -0
  139. package/engine/graphics/particles/particular/engine/renderers/billboard/SoftBillboardParticleRenderer.js +80 -0
  140. package/engine/graphics/particles/particular/engine/shader/ShaderManager.js +16 -4
  141. package/engine/graphics/shaders/TerrainShader.js +8 -8
  142. package/engine/graphics/texture/atlas/TextureAtlasDebugger.js +2 -1
  143. package/engine/graphics/texture/sampler/Sampler2D.js +206 -201
  144. package/engine/graphics/texture/sampler/Sampler2D.spec.js +34 -35
  145. package/engine/graphics/texture/sampler/bicubic.js +59 -0
  146. package/engine/graphics/texture/sampler/downsampleSample2D.spec.js +2 -2
  147. package/engine/graphics/texture/sampler/genericResampleSampler2D.js +0 -2
  148. package/engine/graphics/texture/sampler/prototypeSamplerFiltering.js +146 -0
  149. package/engine/graphics/texture/sampler/{downsampleSampler2D.js → sampler2D_scale_down_linear.js} +8 -4
  150. package/engine/graphics/texture/sampler/sampler2_d_scale_down_lanczos.js +140 -0
  151. package/engine/graphics/texture/sampler/scaleSampler2D.js +3 -3
  152. package/engine/graphics/texture/sampler/writeSampler2DDataToDataTexture.js +1 -1
  153. package/engine/graphics/util/ScaleObject3ToBox.js +14 -1
  154. package/engine/graphics/util/makeMeshPreviewScene.js +2 -1
  155. package/engine/grid/components/GridObstacle.js +0 -44
  156. package/engine/grid/components/GridObstacleSerializationAdapter.js +46 -0
  157. package/engine/input/ecs/util/TerrainCameraTargetSampler.js +2 -2
  158. package/engine/navigation/ecs/components/Path.d.ts +2 -0
  159. package/engine/navigation/ecs/components/Path.js +6 -1
  160. package/engine/navigation/ecs/components/computeNonuniformCatmullRomSplineSample.js +117 -0
  161. package/engine/platform/GetURLHash.js +27 -0
  162. package/engine/platform/WebEnginePlatform.js +1 -22
  163. package/engine/sound/ecs/emitter/SoundEmitter.js +10 -6
  164. package/generation/GridGenerator.js +7 -6
  165. package/generation/example/SampleGenerator0.js +39 -35
  166. package/generation/example/filters/SampleGroundMoistureFilter.js +58 -17
  167. package/generation/example/generators/interactive/mir_generator_place_buff_objects.js +7 -6
  168. package/generation/example/generators/mir_generator_place_bases.js +7 -3
  169. package/generation/example/generators/mir_generator_place_road_decorators.js +3 -3
  170. package/generation/example/generators/mir_generator_place_starting_point.js +3 -2
  171. package/generation/example/themes/SampleTheme0.js +11 -7
  172. package/generation/filtering/numeric/CellFilterLiteralFloat.js +5 -0
  173. package/generation/filtering/numeric/complex/CellFilterDilate.js +36 -0
  174. package/generation/filtering/numeric/complex/CellFilterGaussianBlur.js +15 -5
  175. package/generation/filtering/numeric/complex/CellFilterSimplexNoise.js +53 -1
  176. package/generation/filtering/numeric/math/CellFilterMax2.js +3 -0
  177. package/generation/filtering/numeric/math/CellFilterMembershipGeneralizedBell.js +55 -0
  178. package/generation/filtering/numeric/sampling/AbstractCellFilterSampleGridLayer.js +42 -0
  179. package/generation/filtering/numeric/sampling/CellFilterSampleLayerCubic.js +36 -0
  180. package/generation/filtering/numeric/sampling/CellFilterSampleLayerLinear.js +41 -0
  181. package/generation/grid/GridData.d.ts +5 -1
  182. package/generation/grid/GridData.js +35 -36
  183. package/generation/grid/MarkerMatchCounter.js +5 -3
  184. package/generation/markers/GridActionRuleSet.js +15 -32
  185. package/generation/markers/GridCellActionPlaceMarker.js +12 -8
  186. package/generation/markers/debug/visualizeMarkers.js +56 -36
  187. package/generation/markers/emitter/MarkerNodeEmitterFromAction.js +8 -8
  188. package/generation/markers/prototypeGridCellActionPlaceMarker.js +209 -0
  189. package/generation/markers/transform/MarkerNodeTransformerOffsetPosition.js +1 -5
  190. package/generation/markers/transform/MarkerNodeTransformerYRotateByFilterGradient.spec.js +2 -2
  191. package/generation/placement/GridCellPlacementRule.js +31 -25
  192. package/generation/theme/ThemeEngine.js +1 -1
  193. package/package.json +1 -1
  194. package/samples/terrain/from_image.js +7 -3
  195. package/samples/terrain/main.js +1 -1
  196. package/view/View.js +23 -1
  197. package/view/common/LabelView.js +1 -1
  198. package/view/compose3x3transform.js +32 -8
  199. package/view/controller/dat/DatGuiUtils.js +1 -1
  200. package/view/elements/DropDownSelectionView.js +11 -3
  201. package/view/elements/image/ImageView.js +3 -1
  202. package/core/model/ObservedReal.js +0 -55
  203. package/editor/ecs/component/ObjectEditor.js +0 -0
  204. package/engine/graphics/particles/particular/engine/renderers/SoftBillboardParticleRenderer.js +0 -7
  205. package/engine/sound/ecs/emitter/attenuate/attenuateSoundLinear.js +0 -11
  206. package/generation/filtering/numeric/CellFilterReadGridLayer.js +0 -73
@@ -10,131 +10,11 @@ import { mix } from "../../../../core/math/mix.js";
10
10
  import { BlendingType } from "./BlendingType.js";
11
11
  import { assert } from "../../../../core/assert.js";
12
12
  import { typedArrayConstructorByInstance } from "./typedArrayConstructorByInstance.js";
13
- import { fract } from "../../../../core/math/fract.js";
14
-
15
- function v2CrossMag(ax, ay, bx, by) {
16
- return ax * by - ay * bx;
17
- }
18
-
19
-
20
- function sampleTriangleM2(f2_x, f2_y, f3_x, f3_y, f1_x, f1_y, p1, p2, p3) {
21
- const a = 0.5; // main triangle cross product
22
- const a1 = v2CrossMag(f2_x, f2_y, f3_x, f3_y) / a;
23
- const a2 = v2CrossMag(f3_x, f3_y, f1_x, f1_y) / a;
24
- const a3 = v2CrossMag(f1_x, f1_y, f2_x, f2_y) / a;
25
- return p1 * a1 + p2 * a2 + p3 * a3;
26
- }
27
-
28
- function interpolateVectors1(v_0_0, v_1_0, v_0_1, v_1_1, xd, yd, result) {
29
- return filterFunctionBilinear(v_0_0, v_1_0, v_0_1, v_1_1, xd, yd);
30
- }
31
-
32
- //
33
- function interpolateVectors2(v_0_0, v_1_0, v_0_1, v_1_1, xd, yd, result) {
34
- result.x = filterFunctionBilinear(v_0_0.x, v_1_0.x, v_0_1.x, v_1_1.x, xd, yd);
35
- result.y = filterFunctionBilinear(v_0_0.y, v_1_0.y, v_0_1.y, v_1_1.y, xd, yd);
36
- return result;
37
- }
38
-
39
- function interpolateVectors3(v_0_0, v_1_0, v_0_1, v_1_1, xd, yd, result) {
40
- result.x = filterFunctionBilinear(v_0_0.x, v_1_0.x, v_0_1.x, v_1_1.x, xd, yd);
41
- result.y = filterFunctionBilinear(v_0_0.y, v_1_0.y, v_0_1.y, v_1_1.y, xd, yd);
42
- result.z = filterFunctionBilinear(v_0_0.z, v_1_0.z, v_0_1.z, v_1_1.z, xd, yd);
43
- return result;
44
- }
45
-
46
- function interpolateVectors4(v_0_0, v_1_0, v_0_1, v_1_1, xd, yd, result) {
47
- result.x = filterFunctionBilinear(v_0_0.x, v_1_0.x, v_0_1.x, v_1_1.x, xd, yd);
48
- result.y = filterFunctionBilinear(v_0_0.y, v_1_0.y, v_0_1.y, v_1_1.y, xd, yd);
49
- result.z = filterFunctionBilinear(v_0_0.z, v_1_0.z, v_0_1.z, v_1_1.z, xd, yd);
50
- result.w = filterFunctionBilinear(v_0_0.w, v_1_0.w, v_0_1.w, v_1_1.w, xd, yd);
51
- return result;
52
- }
53
13
 
54
14
 
55
- /**
56
- * Quad interpolation
57
- * @param {number} q0
58
- * @param {number} q1
59
- * @param {number} p0
60
- * @param {number} p1
61
- * @param {number} xd
62
- * @param {number} yd
63
- * @returns {number}
64
- */
65
- function filterFunction_(q0, q1, p0, p1, xd, yd) {
66
- //
67
- const s0 = mix(q0, q1, xd);
68
- const s1 = mix(p0, p1, xd);
69
- const t0 = mix(q0, p0, yd);
70
- const t1 = mix(q1, p1, yd);
71
- //
72
- const u = mix(s0, s1, yd);
73
- const v = mix(t0, t1, xd);
74
- //
75
- const total = u + v;
76
- return total / 2;
77
- }
78
-
79
- /**
80
- * Bi-Linear interpolation
81
- * @param q0
82
- * @param q1
83
- * @param p0
84
- * @param p1
85
- * @param xd
86
- * @param yd
87
- * @returns {*}
88
- */
89
- function filterFunctionBilinear(q0, q1, p0, p1, xd, yd) {
90
-
91
- const s0 = mix(q0, q1, xd);
92
- const s1 = mix(p0, p1, xd);
93
-
94
- return mix(s0, s1, yd);
95
- }
96
-
97
- function filterFunctionSQRT(q0, q1, p0, p1, xd, yd) {
98
- function sd(v, x, y) {
99
- return v * Math.sqrt(x * x + y * y);
100
- }
101
-
102
- return sd(q0, 1 - xd, 1 - yd) + sd(q1, xd, 1 - yd) + sd(p0, 1 - xd, yd) + sd(p1, xd, yd);
103
- }
104
-
105
- function sampleTriangleTopLeft(p1, p2, p3, dx, dy) {
106
-
107
- // calculate vectors from point f to vertices p1, p2 and p3:
108
- const f1_x = -dx;
109
- const f1_y = -dy;
110
-
111
- const f2_x = 1 - dx;
112
- const f2_y = -dy;
113
-
114
- const f3_x = -dx;
115
- const f3_y = 1 - dy;
116
- // calculate the areas (parameters order is essential in this case):
117
- return sampleTriangleM2(f2_x, f2_y, f3_x, f3_y, f1_x, f1_y, p1, p2, p3);
118
- }
119
-
120
- function sampleTriangleBottomRight(p1, p2, p3, dx, dy) {
121
-
122
- // calculate vectors from point f to vertices p1, p2 and p3:
123
- const f1_x = 1 - dx;
124
- const f1_y = -dy;
125
-
126
- const f2_x = 1 - dx;
127
- const f2_y = 1 - dy;
128
-
129
- const f3_x = -dx;
130
- const f3_y = 1 - dy;
131
- // calculate the areas (parameters order is essential in this case):
132
- return sampleTriangleM2(f2_x, f2_y, f3_x, f3_y, f1_x, f1_y, p1, p2, p3);
133
- }
134
-
135
15
  /**
136
16
  *
137
- * @param {ArrayLike<number>|number[]|Uint8ClampedArray|Uint8Array|Uint16Array|Int8Array|Int16Array|Int32Array|Float32Array|Float64Array} data
17
+ * @param {ArrayLike<number>|number[]|Uint8ClampedArray|Uint8Array|Uint16Array|Uint32Array|Int8Array|Int16Array|Int32Array|Float32Array|Float64Array} data
138
18
  * @param {int} itemSize
139
19
  * @param {int} width
140
20
  * @param {int} height
@@ -160,6 +40,7 @@ export function Sampler2D(data = [], itemSize = 1, width = 0, height = 0) {
160
40
  * @type {Number}
161
41
  */
162
42
  this.width = width;
43
+
163
44
  /**
164
45
  *
165
46
  * @type {Number}
@@ -174,9 +55,15 @@ export function Sampler2D(data = [], itemSize = 1, width = 0, height = 0) {
174
55
 
175
56
  /**
176
57
  *
177
- * @type {Array<number>|Uint8Array|Uint16Array|Int8Array|Float32Array|Float64Array}
58
+ * @type {number[]|Uint8ClampedArray|Uint8Array|Uint16Array|Uint32Array|Int8Array|Int16Array|Int32Array|Float32Array|Float64Array}
178
59
  */
179
60
  this.data = data;
61
+
62
+ /**
63
+ * Used to tracking changes
64
+ * @type {number}
65
+ */
66
+ this.version = 0;
180
67
  }
181
68
 
182
69
  /**
@@ -355,6 +242,8 @@ Sampler2D.combine = function (input0, input1, result, operation) {
355
242
  }
356
243
 
357
244
  }
245
+
246
+ result.version++;
358
247
  };
359
248
 
360
249
 
@@ -429,7 +318,6 @@ Sampler2D.prototype.computeMinIndices = function (result, channel = 0) {
429
318
  }
430
319
 
431
320
  let bestValue = data[channel];
432
- let bestIndex = channel;
433
321
 
434
322
  let resultCount = 0;
435
323
 
@@ -504,9 +392,6 @@ Sampler2D.prototype.computeMin = function (channel = 0) {
504
392
  };
505
393
  };
506
394
 
507
- Sampler2D.prototype.initialize = function () {
508
- };
509
-
510
395
  /**
511
396
  *
512
397
  * @deprecated
@@ -552,75 +437,81 @@ Sampler2D.prototype.sampleCatmullRomUV = function (u, v, result) {
552
437
  * @returns {number}
553
438
  */
554
439
  Sampler2D.prototype.sampleChannelCatmullRomUV = function (u, v, channel) {
555
- const x = u * (this.width - 1);
556
- const y = v * (this.height - 1);
440
+ const x = u * (this.width);
441
+ const y = v * (this.height);
557
442
 
558
- return this.sampleChannelCatmullRom(x, y, channel);
443
+ return this.sampleChannelCatmullRom(x - 0.5, y - 0.5, channel);
559
444
  };
560
445
 
561
446
  /**
562
447
  *
563
- * @see https://www.shadertoy.com/view/NsBfRG
564
- * @see https://www.decarpentier.nl/2d-catmull-rom-in-4-samples
448
+ * @see https://gist.github.com/TheRealMJP/c83b8c0f46b63f3a88a5986f4fa982b1
565
449
  * @param {number} x
566
450
  * @param {number} y
567
451
  * @param {number} channel
568
452
  * @returns {number}
569
453
  */
570
454
  Sampler2D.prototype.sampleChannelCatmullRom = function (x, y, channel) {
571
- // Based on the standard Catmull-Rom spline: w1*C1+w2*C2+w3*C3+w4*C4, where
572
- // w1 = ((-0.5*f + 1.0)*f - 0.5)*f, w2 = (1.5*f - 2.5)*f*f + 1.0,
573
- // w3 = ((-1.5*f + 2.0)*f + 0.5)*f and w4 = (0.5*f - 0.5)*f*f with f as the
574
- // normalized interpolation position between C2 (at f=0) and C3 (at f=1).
575
-
576
- // half_f is a sort of sub-pixelquad fraction, -1 <= half_f < 1.
577
- const half_f_x = 2.0 * fract(0.5 * x - 0.25) - 1.0;
578
- const half_f_y = 2.0 * fract(0.5 * y - 0.25) - 1.0;
579
-
580
- // f is the regular sub-pixel fraction, 0 <= f < 1. This is equivalent to
581
- // fract(uv * texSize - 0.5), but based on half_f to prevent rounding issues.
582
- const f_x = fract(half_f_x);
583
- const f_y = fract(half_f_y);
584
-
585
- const s1_x = (0.5 * f_x - 0.5) * f_x; // = w1 / (1 - f)
586
- const s1_y = (0.5 * f_y - 0.5) * f_y; // = w1 / (1 - f)
587
-
588
- const s12_x = (-2.0 * f_x + 1.5) * f_x + 1.0; // = (w2 - w1) / (1 - f)
589
- const s12_y = (-2.0 * f_y + 1.5) * f_y + 1.0; // = (w2 - w1) / (1 - f)
590
-
591
- const s34_x = (2.0 * f_x - 2.5) * f_x - 0.5; // = (w4 - w3) / f
592
- const s34_y = (2.0 * f_y - 2.5) * f_y - 0.5; // = (w4 - w3) / f
593
-
594
- // positions is equivalent to: (floor(uv * texSize - 0.5).xyxy + 0.5 +
595
- // vec4(-1.0 + w2 / (w2 - w1), 1.0 + w4 / (w4 - w3))) / texSize.xyxy.
596
- const positions_x = (-f_x * s12_x + s1_x) / (s12_x) + x;
597
- const positions_y = (-f_y * s12_y + s1_y) / (s12_y) + y;
598
- const positions_z = (-f_x * s34_x + s1_x + s34_x) / (s34_x) + x;
599
- const positions_w = (-f_y * s34_y + s1_y + s34_y) / (s34_y) + y;
600
-
601
- // Determine if the output needs to be sign-flipped. Equivalent to .x*.y of
602
- // (1.0 - 2.0 * floor(t - 2.0 * floor(0.5 * t))), where t is uv * texSize - 0.5.
603
- const sign_flip = half_f_x * half_f_y > 0.0 ? 1.0 : -1.0;
604
-
605
- // = (w2 - w1, w4 - w3)
606
- const w_x = -f_x * s12_x + s12_x;
607
- const w_y = -f_y * s12_y + s12_y;
608
- const w_z = s34_x * f_x
609
- const w_w = s34_y * f_y
610
-
611
- const weights_x = w_x * w_y * sign_flip;
612
- const weights_y = w_z * w_y * sign_flip;
613
- const weights_z = w_x * w_w * sign_flip;
614
- const weights_w = w_z * w_w * sign_flip;
615
-
616
- return this.sampleChannelBilinear(positions_x, positions_y, channel) * weights_x +
617
- this.sampleChannelBilinear(positions_z, positions_y, channel) * weights_y +
618
- this.sampleChannelBilinear(positions_x, positions_w, channel) * weights_z +
619
- this.sampleChannelBilinear(positions_z, positions_w, channel) * weights_w;
455
+ // We're going to sample a a 4x4 grid of texels surrounding the target UV coordinate. We'll do this by rounding
456
+ // down the sample location to get the exact center of our "starting" texel. The starting texel will be at
457
+ // location [1, 1] in the grid, where [0, 0] is the top-left corner.
458
+ const texPos1_x = Math.floor(x - 0.5) + 0.5;
459
+ const texPos1_y = Math.floor(y - 0.5) + 0.5;
460
+
461
+ // Compute the fractional offset from our starting texel to our original sample location, which we'll
462
+ // feed into the Catmull-Rom spline function to get our filter weights.
463
+ const f_x = x - texPos1_x;
464
+ const f_y = y - texPos1_y;
465
+
466
+ // Compute the Catmull-Rom weights using the fractional offset that we calculated earlier.
467
+ // These equations are pre-expanded based on our knowledge of where the texels will be located,
468
+ // which lets us avoid having to evaluate a piece-wise function.
469
+ const w0_x = f_x * (-0.5 + f_x * (1.0 - 0.5 * f_x));
470
+ const w0_y = f_y * (-0.5 + f_y * (1.0 - 0.5 * f_y));
471
+
472
+ const w1_x = 1.0 + f_x * f_x * (-2.5 + 1.5 * f_x);
473
+ const w1_y = 1.0 + f_y * f_y * (-2.5 + 1.5 * f_y);
474
+
475
+ const w2_x = f_x * (0.5 + f_x * (2.0 - 1.5 * f_x));
476
+ const w2_y = f_y * (0.5 + f_y * (2.0 - 1.5 * f_y));
477
+
478
+ const w3_x = f_x * f_x * (-0.5 + 0.5 * f_x);
479
+ const w3_y = f_y * f_y * (-0.5 + 0.5 * f_y);
480
+
481
+ // Work out weighting factors and sampling offsets that will let us use bilinear filtering to
482
+ // simultaneously evaluate the middle 2 samples from the 4x4 grid.
483
+ const w12_x = w1_x + w2_x;
484
+ const w12_y = w1_y + w2_y;
485
+ const offset12_x = w2_x / w12_x;
486
+ const offset12_y = w2_y / w12_y;
487
+
488
+ // Compute the final coordinates we'll use for sampling the texture
489
+ const texPos0_x = texPos1_x - 1;
490
+ const texPos0_y = texPos1_y - 1;
491
+ const texPos3_x = texPos1_x + 2;
492
+ const texPos3_y = texPos1_y + 2;
493
+ const texPos12_x = texPos1_x + offset12_x;
494
+ const texPos12_y = texPos1_y + offset12_y;
495
+
496
+
497
+ let result = 0.0;
498
+ result += this.sampleChannelBilinear(texPos0_x, texPos0_y, channel) * w0_x * w0_y;
499
+ result += this.sampleChannelBilinear(texPos12_x, texPos0_y, channel) * w12_x * w0_y;
500
+ result += this.sampleChannelBilinear(texPos3_x, texPos0_y, channel) * w3_x * w0_y;
501
+
502
+ result += this.sampleChannelBilinear(texPos0_x, texPos12_y, channel) * w0_x * w12_y;
503
+ result += this.sampleChannelBilinear(texPos12_x, texPos12_y, channel) * w12_x * w12_y;
504
+ result += this.sampleChannelBilinear(texPos3_x, texPos12_y, channel) * w3_x * w12_y;
505
+
506
+ result += this.sampleChannelBilinear(texPos0_x, texPos3_y, channel) * w0_x * w3_y;
507
+ result += this.sampleChannelBilinear(texPos12_x, texPos3_y, channel) * w12_x * w3_y;
508
+ result += this.sampleChannelBilinear(texPos3_x, texPos3_y, channel) * w3_x * w3_y;
509
+
510
+ return result;
620
511
  }
621
512
 
622
513
  /**
623
- * Based on code from From reddit https://www.reddit.com/r/javascript/comments/jxa8x/bicubic_interpolation/
514
+ * Based on code from reddit https://www.reddit.com/r/javascript/comments/jxa8x/bicubic_interpolation/
624
515
  * @param {number} t
625
516
  * @param {number} a
626
517
  * @param {number} b
@@ -654,10 +545,10 @@ Sampler2D.prototype.sampleBicubicUV = function (u, v, result) {
654
545
  * @returns {number}
655
546
  */
656
547
  Sampler2D.prototype.sampleChannelBicubicUV = function (u, v, channel) {
657
- const x = u * (this.width - 1);
658
- const y = v * (this.height - 1);
548
+ const x = u * (this.width);
549
+ const y = v * (this.height);
659
550
 
660
- return this.sampleChannelBicubic(x, y, channel);
551
+ return this.sampleChannelBicubic(x - 0.5, y - 0.5, channel);
661
552
  };
662
553
 
663
554
  /**
@@ -681,12 +572,15 @@ Sampler2D.prototype.sampleChannelBicubic = function (x, y, channel) {
681
572
  const x_max = width - 1;
682
573
  const y_max = height - 1;
683
574
 
684
- const x1 = clamp(x, 0, x_max) | 0;
685
- const y1 = clamp(y, 0, y_max) | 0;
575
+ const clamped_x = clamp(x, 0, x_max)
576
+ const clamped_y = clamp(y, 0, y_max)
686
577
 
687
578
  // fractional texel position (from the nearest low texel)
688
- const xd = x - x1;
689
- const yd = y - y1;
579
+ const x1 = clamped_x | 0;
580
+ const y1 = clamped_y | 0;
581
+
582
+ const xd = clamped_x - x1;
583
+ const yd = clamped_y - y1;
690
584
 
691
585
  const x0 = max2(0, x1 - 1);
692
586
  const y0 = max2(0, y1 - 1);
@@ -735,6 +629,14 @@ Sampler2D.prototype.sampleChannelBicubic = function (x, y, channel) {
735
629
  const vl3 = data[row3_address + col3_offset];
736
630
 
737
631
 
632
+ // return bicubic(xd, yd,
633
+ // vi0, vi1, vi2, vi3,
634
+ // vj0, vj1, vj2, vj3,
635
+ // vk0, vk1, vk2, vk3,
636
+ // vl0, vl1, vl2, vl3,
637
+ // );
638
+
639
+
738
640
  // perform filtering in X (rows)
739
641
  const s0 = bicubic_terp(xd, vi0, vi1, vi2, vi3);
740
642
  const s1 = bicubic_terp(xd, vj0, vj1, vj2, vj3);
@@ -745,6 +647,23 @@ Sampler2D.prototype.sampleChannelBicubic = function (x, y, channel) {
745
647
  return bicubic_terp(yd, s0, s1, s2, s3);
746
648
  };
747
649
 
650
+ /**
651
+ *
652
+ * @param {number} u
653
+ * @param {number} v
654
+ * @param {number[]} result
655
+ * @param {number} result_offset
656
+ */
657
+ Sampler2D.prototype.sampleBilinearUV = function (u, v, result, result_offset = 0) {
658
+
659
+ const itemSize = this.itemSize;
660
+
661
+ for (let i = 0; i < itemSize; i++) {
662
+ result[i + result_offset] = this.sampleChannelBilinearUV(u, v, i);
663
+
664
+ }
665
+ }
666
+
748
667
  /**
749
668
  *
750
669
  * @param {number} x
@@ -752,7 +671,7 @@ Sampler2D.prototype.sampleChannelBicubic = function (x, y, channel) {
752
671
  * @param {number[]} result
753
672
  * @param {number} result_offset
754
673
  */
755
- Sampler2D.prototype.sampleBilinear = function (x, y, result, result_offset) {
674
+ Sampler2D.prototype.sampleBilinear = function (x, y, result, result_offset = 0) {
756
675
 
757
676
  const itemSize = this.itemSize;
758
677
 
@@ -771,10 +690,10 @@ Sampler2D.prototype.sampleBilinear = function (x, y, result, result_offset) {
771
690
  * @return {number}
772
691
  */
773
692
  Sampler2D.prototype.sampleChannelBilinearUV = function (u, v, channel) {
774
- const x = u * (this.width - 1);
775
- const y = v * (this.height - 1);
693
+ const x = u * (this.width);
694
+ const y = v * (this.height);
776
695
 
777
- return this.sampleChannelBilinear(x, y, channel);
696
+ return this.sampleChannelBilinear(x - 0.5, y - 0.5, channel);
778
697
  };
779
698
 
780
699
  /**
@@ -850,9 +769,20 @@ Sampler2D.prototype.sampleChannelBilinear = function (x, y, channel) {
850
769
  const p0 = data[j0];
851
770
  const p1 = data[j1];
852
771
 
853
- return filterFunctionBilinear(q0, q1, p0, p1, xd, yd);
772
+ // perform Bi-Linear interpolation
773
+ const s0 = mix(q0, q1, xd);
774
+ const s1 = mix(p0, p1, xd);
775
+
776
+ return mix(s0, s1, yd);
854
777
  };
855
778
 
779
+ Sampler2D.prototype.sampleNearestUV = function (u, v, result) {
780
+ const x = Math.round(u * (this.width) - 0.5);
781
+ const y = Math.round(v * (this.height) - 0.5);
782
+
783
+ this.read(min2(x, this.width - 1), min2(y, this.height - 1), result);
784
+ }
785
+
856
786
  /**
857
787
  *
858
788
  * @param {number} x
@@ -865,6 +795,8 @@ Sampler2D.prototype.readChannel = function (x, y, channel) {
865
795
  assert.isNumber(y, "y");
866
796
  assert.isNumber(channel, "channel");
867
797
 
798
+ assert.isNonNegativeInteger(channel, 'channel');
799
+
868
800
  const index = (y * this.width + x) * this.itemSize + channel;
869
801
 
870
802
  return this.data[index];
@@ -1180,6 +1112,8 @@ Sampler2D.prototype.copyWithMargin = function (source, sourceX, sourceY, destina
1180
1112
  }
1181
1113
  }
1182
1114
  }
1115
+
1116
+ this.version++;
1183
1117
  };
1184
1118
 
1185
1119
  /**
@@ -1192,7 +1126,19 @@ Sampler2D.prototype.copyWithMargin = function (source, sourceX, sourceY, destina
1192
1126
  * @param {Number} width size of the patch that is to be copied
1193
1127
  * @param {Number} height size of the patch that is to be copied
1194
1128
  */
1195
- Sampler2D.prototype.copy = function (source, sourceX, sourceY, destinationX, destinationY, width, height) {
1129
+ Sampler2D.prototype.copy = function (
1130
+ source, sourceX, sourceY,
1131
+ destinationX, destinationY, width, height
1132
+ ) {
1133
+
1134
+ assert.isNumber(sourceX, 'sourceX');
1135
+ assert.isNumber(sourceY, 'sourceY');
1136
+
1137
+ assert.isNumber(destinationX, 'destinationX');
1138
+ assert.isNumber(destinationY, 'destinationY');
1139
+
1140
+ assert.isNumber(width, 'width');
1141
+ assert.isNumber(height, 'height');
1196
1142
 
1197
1143
  const _w = Math.min(width, source.width - sourceX, this.width - destinationX);
1198
1144
  const _h = Math.min(height, source.height - sourceY, this.height - destinationY);
@@ -1222,6 +1168,8 @@ Sampler2D.prototype.copy = function (source, sourceX, sourceY, destinationX, des
1222
1168
  }
1223
1169
  }
1224
1170
  }
1171
+
1172
+ this.version++;
1225
1173
  };
1226
1174
 
1227
1175
 
@@ -1268,6 +1216,8 @@ Sampler2D.prototype.copy_sameItemSize = function (source, sourceX, sourceY, dest
1268
1216
 
1269
1217
  }
1270
1218
  }
1219
+
1220
+ this.version++;
1271
1221
  };
1272
1222
 
1273
1223
 
@@ -1297,9 +1247,9 @@ function blendFunctionNormal(source, destination, result) {
1297
1247
  * @param destinationY
1298
1248
  * @param width
1299
1249
  * @param height
1300
- * @param {BlendingType} blendMode
1250
+ * @param {BlendingType} [blendMode]
1301
1251
  */
1302
- Sampler2D.prototype.paint = function (source, sourceX, sourceY, destinationX, destinationY, width, height, blendMode) {
1252
+ Sampler2D.prototype.paint = function (source, sourceX, sourceY, destinationX, destinationY, width, height, blendMode = BlendingType.Normal) {
1303
1253
  let blendFunction;
1304
1254
  if (blendMode === BlendingType.Normal) {
1305
1255
  blendFunction = blendFunctionNormal;
@@ -1310,6 +1260,8 @@ Sampler2D.prototype.paint = function (source, sourceX, sourceY, destinationX, de
1310
1260
  const _w = Math.min(width, source.width - sourceX, this.width - destinationX);
1311
1261
  const _h = Math.min(height, source.height - sourceY, this.height - destinationY);
1312
1262
 
1263
+ const _x0 = Math.max(0, -destinationX);
1264
+ const _y0 = Math.max(0, -destinationY);
1313
1265
 
1314
1266
  const c0 = [0, 0, 0, 255];
1315
1267
  const c1 = [0, 0, 0, 255];
@@ -1318,14 +1270,21 @@ Sampler2D.prototype.paint = function (source, sourceX, sourceY, destinationX, de
1318
1270
 
1319
1271
  let x, y;
1320
1272
 
1321
- for (y = 0; y < _h; y++) {
1322
- for (x = 0; x < _w; x++) {
1323
- this.read(x + destinationX, y + destinationY, c0);
1324
- source.read(x + sourceY, y + sourceY, c1);
1273
+ for (y = _y0; y < _h; y++) {
1274
+ for (x = _x0; x < _w; x++) {
1275
+ const d_x = Math.round(x + destinationX);
1276
+ const d_y = Math.round(y + destinationY);
1277
+
1278
+ this.read(d_x, d_y, c0);
1279
+
1280
+ const s_x = Math.round(x + sourceY);
1281
+ const s_y = Math.round(y + sourceY);
1282
+
1283
+ source.read(s_x, s_y, c1);
1325
1284
 
1326
1285
  blendFunction(c1, c0, c3);
1327
1286
 
1328
- this.set(x, y, c3);
1287
+ this.set(d_x, d_y, c3);
1329
1288
 
1330
1289
  }
1331
1290
  }
@@ -1364,6 +1323,25 @@ Sampler2D.prototype.zeroFill = function (x, y, width, height) {
1364
1323
  data.fill(0, a + clearRowOffset0, a + clearRowOffset1);
1365
1324
 
1366
1325
  }
1326
+
1327
+ this.version++;
1328
+ };
1329
+
1330
+ /**
1331
+ *
1332
+ * @param {number} channel_index
1333
+ * @param {number} value
1334
+ */
1335
+ Sampler2D.prototype.fill_channel = function (channel_index, value) {
1336
+ const itemSize = this.itemSize;
1337
+ const data = this.data;
1338
+ const length = data.length;
1339
+
1340
+ for (let i = channel_index; i < length; i += itemSize) {
1341
+ data[i] = value;
1342
+ }
1343
+
1344
+ this.version++;
1367
1345
  };
1368
1346
 
1369
1347
  /**
@@ -1407,6 +1385,8 @@ Sampler2D.prototype.fill = function (x, y, width, height, value) {
1407
1385
 
1408
1386
  }
1409
1387
  }
1388
+
1389
+ this.version++;
1410
1390
  };
1411
1391
 
1412
1392
  /**
@@ -1430,6 +1410,8 @@ Sampler2D.prototype.writeChannel = function (x, y, channel, value) {
1430
1410
  const channelAddress = pointAddress + channel;
1431
1411
 
1432
1412
  this.data[channelAddress] = value;
1413
+
1414
+ this.version++;
1433
1415
  };
1434
1416
 
1435
1417
  /**
@@ -1449,6 +1431,8 @@ Sampler2D.prototype.set = function (x, y, value) {
1449
1431
  for (let i = 0; i < itemSize; i++) {
1450
1432
  data[offset + i] = value[i];
1451
1433
  }
1434
+
1435
+ this.version++;
1452
1436
  };
1453
1437
 
1454
1438
  /**
@@ -1542,6 +1526,8 @@ Sampler2D.prototype.resize = function (x, y, preserveData = true) {
1542
1526
  this.height = y;
1543
1527
 
1544
1528
  this.data = newData;
1529
+
1530
+ this.version++;
1545
1531
  };
1546
1532
 
1547
1533
  /**
@@ -1609,6 +1595,7 @@ Sampler2D.prototype.fromBinaryBuffer = function (buffer) {
1609
1595
 
1610
1596
  buffer.readBytes(this.data, 0, numBytes);
1611
1597
 
1598
+ this.version++;
1612
1599
  } else {
1613
1600
  throw new TypeError(`Unsupported data type (${dataType})`);
1614
1601
  }
@@ -1647,6 +1634,24 @@ Sampler2D.prototype.traverseOrthogonalNeighbours = function (x, y, visitor, this
1647
1634
  }
1648
1635
  };
1649
1636
 
1637
+ /**
1638
+ * @returns {Sampler2D}
1639
+ */
1640
+ Sampler2D.prototype.clone = function () {
1641
+ let data_clone;
1642
+
1643
+ if (Array.isArray(this.data)) {
1644
+ data_clone = this.data.slice();
1645
+ } else {
1646
+ // storage is a typed array
1647
+ const T = this.data.constructor;
1648
+
1649
+ data_clone = new T(this.data);
1650
+ }
1651
+
1652
+ return new Sampler2D(data_clone, this.itemSize, this.width, this.height);
1653
+ };
1654
+
1650
1655
  /**
1651
1656
  * @readonly
1652
1657
  * @type {boolean}