@woosh/meep-engine 2.46.36 → 2.47.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/meep.cjs +302 -369
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +302 -369
- package/package.json +3 -2
- package/src/core/collection/list/List.js +8 -0
- package/src/core/geom/Rectangle.js +178 -168
- package/src/core/model/node-graph/NodeGraph.js +10 -1
- package/src/core/model/node-graph/node/NodeInstance.js +83 -15
- package/src/engine/ecs/fow/serialization/FogOfWarSerializationAdapter.js +7 -2
- package/src/engine/ecs/terrain/ecs/makeTerrainWorkerProxy.js +4 -2
- package/src/engine/graphics/micron/prototypeVirtualGeometry.js +2 -2
- package/src/engine/graphics/texture/sampler/Sampler2D.js +12 -198
- package/src/engine/graphics/texture/sampler/Sampler2D.spec.js +0 -37
- package/src/engine/graphics/texture/sampler/Sampler2D2Canvas.js +3 -3
- package/src/engine/graphics/texture/sampler/resize/sampler2d_downsample_mipmap.js +2 -2
- package/src/engine/graphics/texture/sampler/sampler2d_channel_compute_max.js +51 -0
- package/src/engine/graphics/texture/sampler/sampler2d_channel_compute_max.spec.js +40 -0
- package/src/engine/graphics/texture/sampler/sampler2d_channel_compute_min.js +51 -0
- package/src/engine/graphics/texture/sampler/sampler2d_compute_texel_value_conversion_scale_to_uint8.js +4 -2
- package/src/engine/graphics/texture/sampler/sampler2d_make_array_filler_function.js +65 -0
- package/src/engine/graphics/texture/sampler/{sampler2D_scale_down_linear.js → sampler2d_scale_down_linear.js} +1 -1
- package/src/engine/graphics/texture/sampler/{downsampleSample2D.spec.js → sampler2d_scale_down_linear.spec.js} +2 -2
- package/src/engine/graphics/texture/sampler/{sample2d_write_to_canvas_raw.js → sampler2d_write_to_canvas_raw.js} +5 -1
- package/src/engine/graphics/texture/sampler/scaleSampler2D.js +2 -2
- package/src/engine/input/ecs/util/TerrainCameraTargetSampler.js +2 -2
- package/src/engine/ui/tiles2d/computeTileGridMove.js +2 -2
|
@@ -78,59 +78,15 @@ export class Sampler2D {
|
|
|
78
78
|
* @type {number}
|
|
79
79
|
*/
|
|
80
80
|
this.version = 0;
|
|
81
|
-
/**
|
|
82
|
-
* @readonly
|
|
83
|
-
* @type {boolean}
|
|
84
|
-
*/
|
|
85
|
-
this.isSampler2D = true;
|
|
86
81
|
}
|
|
87
82
|
|
|
88
83
|
/**
|
|
84
|
+
* @deprecated
|
|
89
85
|
* @param {number} [channel=0]
|
|
90
86
|
* @returns {{x: number, index: number, y: number, value: number}}
|
|
91
87
|
*/
|
|
92
88
|
computeMax(channel = 0) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
assert.isNumber(channel, "channel");
|
|
96
|
-
assert.isNonNegativeInteger(channel , 'channel');
|
|
97
|
-
assert.lessThan(channel, itemSize, `channel must be less than itemSize(=${itemSize}), was ${channel}`);
|
|
98
|
-
|
|
99
|
-
const data = this.data;
|
|
100
|
-
|
|
101
|
-
const l = data.length;
|
|
102
|
-
|
|
103
|
-
if (l === 0) {
|
|
104
|
-
//no data
|
|
105
|
-
return undefined;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
let bestValue = data[channel];
|
|
109
|
-
let bestIndex = channel;
|
|
110
|
-
|
|
111
|
-
for (let i = channel + itemSize; i < l; i += itemSize) {
|
|
112
|
-
const value = data[i];
|
|
113
|
-
|
|
114
|
-
if (bestValue < value) {
|
|
115
|
-
bestValue = value;
|
|
116
|
-
bestIndex = i;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const width = this.width;
|
|
122
|
-
|
|
123
|
-
const itemIndex = (bestIndex / this.itemSize) | 0;
|
|
124
|
-
|
|
125
|
-
const x = itemIndex % width;
|
|
126
|
-
const y = (itemIndex / width) | 0;
|
|
127
|
-
|
|
128
|
-
return {
|
|
129
|
-
index: bestIndex,
|
|
130
|
-
value: bestValue,
|
|
131
|
-
x,
|
|
132
|
-
y
|
|
133
|
-
};
|
|
89
|
+
throw new Error("deprecated, use sampler2d_channel_compute_max");
|
|
134
90
|
}
|
|
135
91
|
|
|
136
92
|
/**
|
|
@@ -152,7 +108,7 @@ export class Sampler2D {
|
|
|
152
108
|
|
|
153
109
|
if (l === 0) {
|
|
154
110
|
//no data
|
|
155
|
-
return
|
|
111
|
+
return;
|
|
156
112
|
}
|
|
157
113
|
|
|
158
114
|
let bestValue = data[channel];
|
|
@@ -178,56 +134,15 @@ export class Sampler2D {
|
|
|
178
134
|
if (resultCount < result.length) {
|
|
179
135
|
result.splice(resultCount, result.length - resultCount);
|
|
180
136
|
}
|
|
181
|
-
|
|
182
|
-
return;
|
|
183
137
|
}
|
|
184
138
|
|
|
185
139
|
/**
|
|
140
|
+
* @deprecated
|
|
186
141
|
* @param {number} [channel=0]
|
|
187
142
|
* @returns {{x: number, index: number, y: number, value: number}}
|
|
188
143
|
*/
|
|
189
144
|
computeMin(channel = 0) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
assert.typeOf(channel, "number", "channel");
|
|
193
|
-
assert.ok(channel >= 0, `channel must be >= 0, was ${channel}`);
|
|
194
|
-
assert.ok(channel < itemSize, `channel must be less than itemSize(=${itemSize}), was ${channel}`);
|
|
195
|
-
|
|
196
|
-
const data = this.data;
|
|
197
|
-
|
|
198
|
-
const l = data.length;
|
|
199
|
-
|
|
200
|
-
if (l === 0) {
|
|
201
|
-
//no data
|
|
202
|
-
return undefined;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
let bestValue = data[channel];
|
|
206
|
-
let bestIndex = channel;
|
|
207
|
-
|
|
208
|
-
for (let i = channel + itemSize; i < l; i += itemSize) {
|
|
209
|
-
const value = data[i];
|
|
210
|
-
|
|
211
|
-
if (bestValue > value) {
|
|
212
|
-
bestValue = value;
|
|
213
|
-
bestIndex = i;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
const width = this.width;
|
|
219
|
-
|
|
220
|
-
const itemIndex = (bestIndex / this.itemSize) | 0;
|
|
221
|
-
|
|
222
|
-
const x = itemIndex % width;
|
|
223
|
-
const y = (itemIndex / width) | 0;
|
|
224
|
-
|
|
225
|
-
return {
|
|
226
|
-
index: bestIndex,
|
|
227
|
-
value: bestValue,
|
|
228
|
-
x,
|
|
229
|
-
y
|
|
230
|
-
};
|
|
145
|
+
throw new Error("deprecated, use sampler2d_channel_compute_min");
|
|
231
146
|
}
|
|
232
147
|
|
|
233
148
|
/**
|
|
@@ -717,74 +632,6 @@ export class Sampler2D {
|
|
|
717
632
|
result.set(x, y);
|
|
718
633
|
}
|
|
719
634
|
|
|
720
|
-
/**
|
|
721
|
-
*
|
|
722
|
-
* @param {number} scale
|
|
723
|
-
* @param {number} offset
|
|
724
|
-
* @return {function(index:int, array:ArrayLike, x:int, y:int)}
|
|
725
|
-
*/
|
|
726
|
-
makeArrayFiller(scale, offset) {
|
|
727
|
-
scale = scale || 255;
|
|
728
|
-
offset = offset || 0;
|
|
729
|
-
|
|
730
|
-
const sampler = this;
|
|
731
|
-
const v4 = [1 / scale, 1 / scale, 1 / scale, 1 / scale];
|
|
732
|
-
|
|
733
|
-
//
|
|
734
|
-
function fillDD1(index, array, x, y) {
|
|
735
|
-
const val = (sampler.sampleChannelBilinear(x, y, 0) + offset) * scale | 0;
|
|
736
|
-
array[index] = val;
|
|
737
|
-
array[index + 1] = val;
|
|
738
|
-
array[index + 2] = val;
|
|
739
|
-
array[index + 3] = 255;
|
|
740
|
-
}
|
|
741
|
-
|
|
742
|
-
function fillDD2(index, array, x, y) {
|
|
743
|
-
sampler.sampleBilinear(x, y, v4, 0);
|
|
744
|
-
const val = (v4[0] + offset) * scale | 0;
|
|
745
|
-
array.fill(val, index, index + 3);
|
|
746
|
-
array[index + 3] = (v4[1] + offset) * scale | 0;
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
function fillDD3(index, array, x, y) {
|
|
750
|
-
|
|
751
|
-
sampler.sampleBilinear(x, y, v4, 0);
|
|
752
|
-
|
|
753
|
-
array[index] = (v4[0] + offset) * scale | 0;
|
|
754
|
-
array[index + 1] = (v4[1] + offset) * scale | 0;
|
|
755
|
-
array[index + 2] = (v4[2] + offset) * scale | 0;
|
|
756
|
-
array[index + 3] = 255;
|
|
757
|
-
}
|
|
758
|
-
|
|
759
|
-
function fillDD4(index, array, x, y) {
|
|
760
|
-
sampler.sampleBilinear(x, y, v4, 0);
|
|
761
|
-
array[index] = (v4[0] + offset) * scale | 0;
|
|
762
|
-
array[index + 1] = (v4[1] + offset) * scale | 0;
|
|
763
|
-
array[index + 2] = (v4[2] + offset) * scale | 0;
|
|
764
|
-
array[index + 3] = (v4[3] + offset) * scale | 0;
|
|
765
|
-
}
|
|
766
|
-
|
|
767
|
-
let fillDD;
|
|
768
|
-
switch (sampler.itemSize) {
|
|
769
|
-
case 1:
|
|
770
|
-
fillDD = fillDD1;
|
|
771
|
-
break;
|
|
772
|
-
case 2:
|
|
773
|
-
fillDD = fillDD2;
|
|
774
|
-
break;
|
|
775
|
-
case 3:
|
|
776
|
-
fillDD = fillDD3;
|
|
777
|
-
break;
|
|
778
|
-
case 4:
|
|
779
|
-
fillDD = fillDD4;
|
|
780
|
-
break;
|
|
781
|
-
default :
|
|
782
|
-
throw new Error("unsupported item size");
|
|
783
|
-
break;
|
|
784
|
-
}
|
|
785
|
-
return fillDD;
|
|
786
|
-
}
|
|
787
|
-
|
|
788
635
|
/**
|
|
789
636
|
* Copy a patch from another sampler with a margin.
|
|
790
637
|
* This is useful for texture rendering where filtering can cause bleeding along the edges of the patch.
|
|
@@ -1361,28 +1208,7 @@ export class Sampler2D {
|
|
|
1361
1208
|
* @param {BinaryBuffer} buffer
|
|
1362
1209
|
*/
|
|
1363
1210
|
toBinaryBuffer(buffer) {
|
|
1364
|
-
|
|
1365
|
-
const height = this.height;
|
|
1366
|
-
|
|
1367
|
-
const itemSize = this.itemSize;
|
|
1368
|
-
|
|
1369
|
-
buffer.writeUint16(width);
|
|
1370
|
-
buffer.writeUint16(height);
|
|
1371
|
-
|
|
1372
|
-
buffer.writeUint8(itemSize);
|
|
1373
|
-
|
|
1374
|
-
if (this.data instanceof Uint8Array) {
|
|
1375
|
-
//data type
|
|
1376
|
-
buffer.writeUint8(0);
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
const byteSize = width * height * itemSize;
|
|
1380
|
-
|
|
1381
|
-
buffer.writeBytes(this.data, 0, byteSize);
|
|
1382
|
-
|
|
1383
|
-
} else {
|
|
1384
|
-
throw new TypeError(`Unsupported data type`);
|
|
1385
|
-
}
|
|
1211
|
+
throw new Error('Deprecated, use Sampler2DSerializationAdapter instead');
|
|
1386
1212
|
}
|
|
1387
1213
|
|
|
1388
1214
|
/**
|
|
@@ -1390,24 +1216,7 @@ export class Sampler2D {
|
|
|
1390
1216
|
* @param {BinaryBuffer} buffer
|
|
1391
1217
|
*/
|
|
1392
1218
|
fromBinaryBuffer(buffer) {
|
|
1393
|
-
|
|
1394
|
-
this.height = buffer.readUint16();
|
|
1395
|
-
|
|
1396
|
-
this.itemSize = buffer.readUint8();
|
|
1397
|
-
|
|
1398
|
-
const dataType = buffer.readUint8();
|
|
1399
|
-
|
|
1400
|
-
if (dataType === 0) {
|
|
1401
|
-
|
|
1402
|
-
const numBytes = this.height * this.width * this.itemSize;
|
|
1403
|
-
this.data = new Uint8Array(numBytes);
|
|
1404
|
-
|
|
1405
|
-
buffer.readBytes(this.data, 0, numBytes);
|
|
1406
|
-
|
|
1407
|
-
this.version++;
|
|
1408
|
-
} else {
|
|
1409
|
-
throw new TypeError(`Unsupported data type (${dataType})`);
|
|
1410
|
-
}
|
|
1219
|
+
throw new Error('Deprecated, use Sampler2DSerializationAdapter instead');
|
|
1411
1220
|
}
|
|
1412
1221
|
|
|
1413
1222
|
/**
|
|
@@ -1652,6 +1461,11 @@ export class Sampler2D {
|
|
|
1652
1461
|
|
|
1653
1462
|
}
|
|
1654
1463
|
|
|
1464
|
+
/**
|
|
1465
|
+
* @readonly
|
|
1466
|
+
* @type {boolean}
|
|
1467
|
+
*/
|
|
1468
|
+
Sampler2D.prototype.isSampler2D = true;
|
|
1655
1469
|
|
|
1656
1470
|
/**
|
|
1657
1471
|
* Based on code from reddit https://www.reddit.com/r/javascript/comments/jxa8x/bicubic_interpolation/
|
|
@@ -119,43 +119,6 @@ test('set and get consistency itemSize=4, 2x2', () => {
|
|
|
119
119
|
expect(sample).toEqual([13, 14, 15, 16]);
|
|
120
120
|
});
|
|
121
121
|
|
|
122
|
-
test('computeMax itemSize=1, 0x0', () => {
|
|
123
|
-
const ut = Sampler2D.int8(1, 0, 0);
|
|
124
|
-
|
|
125
|
-
expect(ut.computeMax(0)).toEqual(undefined);
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
test('computeMax itemSize=1, 1x1', () => {
|
|
129
|
-
const ut = Sampler2D.int8(1, 1, 1);
|
|
130
|
-
|
|
131
|
-
ut.set(0, 0, [7]);
|
|
132
|
-
|
|
133
|
-
expect(ut.computeMax(0)).toEqual({ value: 7, x: 0, y: 0, index: 0 });
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
test('computeMax itemSize=1, 2x2', () => {
|
|
137
|
-
const ut = Sampler2D.int8(1, 2, 2);
|
|
138
|
-
|
|
139
|
-
ut.set(0, 0, [3]);
|
|
140
|
-
ut.set(1, 0, [-7]);
|
|
141
|
-
ut.set(0, 1, [7]);
|
|
142
|
-
ut.set(1, 1, [4]);
|
|
143
|
-
|
|
144
|
-
expect(ut.computeMax(0)).toEqual({ value: 7, x: 0, y: 1, index: 2 });
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
test('computeMax itemSize=2, 2x2', () => {
|
|
148
|
-
const ut = Sampler2D.int8(2, 2, 2);
|
|
149
|
-
|
|
150
|
-
ut.set(0, 0, [3, 8]);
|
|
151
|
-
ut.set(1, 0, [-7, 13]);
|
|
152
|
-
ut.set(0, 1, [7, 1]);
|
|
153
|
-
ut.set(1, 1, [4, -3]);
|
|
154
|
-
|
|
155
|
-
expect(ut.computeMax(0)).toEqual({ value: 7, x: 0, y: 1, index: 4 });
|
|
156
|
-
|
|
157
|
-
expect(ut.computeMax(1)).toEqual({ value: 13, x: 1, y: 0, index: 3 });
|
|
158
|
-
});
|
|
159
122
|
|
|
160
123
|
test('sampleChannelBilinear 1x1 exact', () => {
|
|
161
124
|
const s = Sampler2D.uint8(1, 1, 1);
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
import { Sampler2D } from "./Sampler2D.js";
|
|
7
|
-
import {
|
|
7
|
+
import { sampler2d_write_to_canvas_raw } from "./sampler2d_write_to_canvas_raw.js";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
*
|
|
@@ -12,7 +12,7 @@ import { sample2d_write_to_canvas_raw } from "./sample2d_write_to_canvas_raw.js"
|
|
|
12
12
|
* @param {Number} [scale]
|
|
13
13
|
* @param {Number} [offset]
|
|
14
14
|
* @param {HTMLCanvasElement} [canvas] if no canvas is supplied, a new one will be created
|
|
15
|
-
* @param {function(index:int, array:ArrayLike<number>, x:int, y:int)} [fillDD] allows you to supply mapping function, if none is given - one will be created from sampler
|
|
15
|
+
* @param {function(index:int, array:ArrayLike<number>, x:int, y:int)} [fillDD] allows you to supply mapping function, if none is given - one will be created from sampler
|
|
16
16
|
* @returns {HTMLCanvasElement} canvas
|
|
17
17
|
*/
|
|
18
18
|
function convertSampler2D2Canvas(sampler, scale = 255, offset = 0, canvas, fillDD) {
|
|
@@ -85,7 +85,7 @@ function convertSampler2D2Canvas(sampler, scale = 255, offset = 0, canvas, fillD
|
|
|
85
85
|
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
sampler2d_write_to_canvas_raw(converted_sampler, canvas);
|
|
89
89
|
|
|
90
90
|
return canvas;
|
|
91
91
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Sampler2D } from "../Sampler2D.js";
|
|
2
|
-
import {
|
|
2
|
+
import { sampler2d_scale_down_linear } from "../sampler2d_scale_down_linear.js";
|
|
3
3
|
import { inverseLerp } from "../../../../../core/math/inverseLerp.js";
|
|
4
4
|
import { lerp } from "../../../../../core/math/lerp.js";
|
|
5
5
|
|
|
@@ -24,7 +24,7 @@ export function sampler2d_downsample_mipmap(source, destination) {
|
|
|
24
24
|
|
|
25
25
|
const out = new Sampler2D(new current_mip.data.constructor(new_w * new_h * itemSize), itemSize, new_w, new_h);
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
sampler2d_scale_down_linear(current_mip, out);
|
|
28
28
|
|
|
29
29
|
previous_mip = current_mip;
|
|
30
30
|
current_mip = out;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { assert } from "../../../../core/assert.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {Sampler2D} sampler
|
|
6
|
+
* @param {number} [channel=0]
|
|
7
|
+
* @returns {undefined|{x: number, index:number, y: number, value: number}}
|
|
8
|
+
*/
|
|
9
|
+
export function sampler2d_channel_compute_max(sampler, channel=0){
|
|
10
|
+
const itemSize = sampler.itemSize;
|
|
11
|
+
|
|
12
|
+
assert.isNumber(channel, "channel");
|
|
13
|
+
assert.isNonNegativeInteger(channel , 'channel');
|
|
14
|
+
assert.lessThan(channel, itemSize, `channel must be less than itemSize(=${itemSize}), was ${channel}`);
|
|
15
|
+
|
|
16
|
+
const data = sampler.data;
|
|
17
|
+
|
|
18
|
+
const l = data.length;
|
|
19
|
+
|
|
20
|
+
if (l === 0) {
|
|
21
|
+
//no data
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let bestValue = data[channel];
|
|
26
|
+
let bestIndex = channel;
|
|
27
|
+
|
|
28
|
+
for (let i = channel + itemSize; i < l; i += itemSize) {
|
|
29
|
+
const value = data[i];
|
|
30
|
+
|
|
31
|
+
if (bestValue < value) {
|
|
32
|
+
bestValue = value;
|
|
33
|
+
bestIndex = i;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const width = this.width;
|
|
39
|
+
|
|
40
|
+
const itemIndex = (bestIndex / itemSize) | 0;
|
|
41
|
+
|
|
42
|
+
const x = itemIndex % width;
|
|
43
|
+
const y = (itemIndex / width) | 0;
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
index: bestIndex,
|
|
47
|
+
value: bestValue,
|
|
48
|
+
x,
|
|
49
|
+
y
|
|
50
|
+
};
|
|
51
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Sampler2D } from "./Sampler2D.js";
|
|
2
|
+
import { sampler2d_channel_compute_max } from "./sampler2d_channel_compute_max.js";
|
|
3
|
+
|
|
4
|
+
test('computeMax itemSize=1, 0x0', () => {
|
|
5
|
+
const ut = Sampler2D.int8(1, 0, 0);
|
|
6
|
+
|
|
7
|
+
expect(sampler2d_channel_compute_max(ut,0)).toEqual(undefined);
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
test('computeMax itemSize=1, 1x1', () => {
|
|
11
|
+
const ut = Sampler2D.int8(1, 1, 1);
|
|
12
|
+
|
|
13
|
+
ut.set(0, 0, [7]);
|
|
14
|
+
|
|
15
|
+
expect(sampler2d_channel_compute_max(ut,0)).toEqual({ value: 7, x: 0, y: 0, index: 0 });
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test('computeMax itemSize=1, 2x2', () => {
|
|
19
|
+
const ut = Sampler2D.int8(1, 2, 2);
|
|
20
|
+
|
|
21
|
+
ut.set(0, 0, [3]);
|
|
22
|
+
ut.set(1, 0, [-7]);
|
|
23
|
+
ut.set(0, 1, [7]);
|
|
24
|
+
ut.set(1, 1, [4]);
|
|
25
|
+
|
|
26
|
+
expect(sampler2d_channel_compute_max(ut,0)).toEqual({ value: 7, x: 0, y: 1, index: 2 });
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test('computeMax itemSize=2, 2x2', () => {
|
|
30
|
+
const ut = Sampler2D.int8(2, 2, 2);
|
|
31
|
+
|
|
32
|
+
ut.set(0, 0, [3, 8]);
|
|
33
|
+
ut.set(1, 0, [-7, 13]);
|
|
34
|
+
ut.set(0, 1, [7, 1]);
|
|
35
|
+
ut.set(1, 1, [4, -3]);
|
|
36
|
+
|
|
37
|
+
expect(sampler2d_channel_compute_max(ut,0)).toEqual({ value: 7, x: 0, y: 1, index: 4 });
|
|
38
|
+
|
|
39
|
+
expect(sampler2d_channel_compute_max(ut,1)).toEqual({ value: 13, x: 1, y: 0, index: 3 });
|
|
40
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { assert } from "../../../../core/assert.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {Sampler2D} sampler
|
|
6
|
+
* @param {number} [channel=0]
|
|
7
|
+
* @returns {undefined|{x: number, index:number, y: number, value: number}}
|
|
8
|
+
*/
|
|
9
|
+
export function sampler2d_channel_compute_min(sampler, channel=0){
|
|
10
|
+
const itemSize = sampler.itemSize;
|
|
11
|
+
|
|
12
|
+
assert.isNumber(channel, "channel");
|
|
13
|
+
assert.isNonNegativeInteger(channel , 'channel');
|
|
14
|
+
assert.lessThan(channel, itemSize, `channel must be less than itemSize(=${itemSize}), was ${channel}`);
|
|
15
|
+
|
|
16
|
+
const data = sampler.data;
|
|
17
|
+
|
|
18
|
+
const l = data.length;
|
|
19
|
+
|
|
20
|
+
if (l === 0) {
|
|
21
|
+
//no data
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let bestValue = data[channel];
|
|
26
|
+
let bestIndex = channel;
|
|
27
|
+
|
|
28
|
+
for (let i = channel + itemSize; i < l; i += itemSize) {
|
|
29
|
+
const value = data[i];
|
|
30
|
+
|
|
31
|
+
if (bestValue > value) {
|
|
32
|
+
bestValue = value;
|
|
33
|
+
bestIndex = i;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const width = this.width;
|
|
39
|
+
|
|
40
|
+
const itemIndex = (bestIndex / itemSize) | 0;
|
|
41
|
+
|
|
42
|
+
const x = itemIndex % width;
|
|
43
|
+
const y = (itemIndex / width) | 0;
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
index: bestIndex,
|
|
47
|
+
value: bestValue,
|
|
48
|
+
x,
|
|
49
|
+
y
|
|
50
|
+
};
|
|
51
|
+
}
|
|
@@ -3,6 +3,8 @@ import { min2 } from "../../../../core/math/min2.js";
|
|
|
3
3
|
import { max2 } from "../../../../core/math/max2.js";
|
|
4
4
|
import { isTypedArray } from "../../../../core/collection/array/typed/isTypedArray.js";
|
|
5
5
|
import { typedArrayToDataType } from "../../../../core/collection/array/typedArrayToDataType.js";
|
|
6
|
+
import { sampler2d_channel_compute_max } from "./sampler2d_channel_compute_max.js";
|
|
7
|
+
import { sampler2d_channel_compute_min } from "./sampler2d_channel_compute_min.js";
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
10
|
*
|
|
@@ -31,8 +33,8 @@ export function sampler2d_compute_texel_value_conversion_scale_to_uint8(sampler)
|
|
|
31
33
|
max = -Infinity;
|
|
32
34
|
for (let i = 0; i < sampler.itemSize; i++) {
|
|
33
35
|
|
|
34
|
-
min = min2(min,
|
|
35
|
-
max = max2(min, sampler
|
|
36
|
+
min = min2(min,sampler2d_channel_compute_min(sampler,i).value)
|
|
37
|
+
max = max2(min, sampler2d_channel_compute_max(sampler,i).value)
|
|
36
38
|
}
|
|
37
39
|
}
|
|
38
40
|
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param {Sampler2D} sampler
|
|
4
|
+
* @param {number} scale
|
|
5
|
+
* @param {number} offset
|
|
6
|
+
* @return {function(index:int, array:ArrayLike, x:int, y:int)}
|
|
7
|
+
*/
|
|
8
|
+
export function sampler2d_make_array_filler_function(sampler, scale=255, offset=0){
|
|
9
|
+
|
|
10
|
+
const v4 = [1 / scale, 1 / scale, 1 / scale, 1 / scale];
|
|
11
|
+
|
|
12
|
+
//
|
|
13
|
+
function fillDD1(index, array, x, y) {
|
|
14
|
+
const val = (sampler.sampleChannelBilinear(x, y, 0) + offset) * scale | 0;
|
|
15
|
+
array[index] = val;
|
|
16
|
+
array[index + 1] = val;
|
|
17
|
+
array[index + 2] = val;
|
|
18
|
+
array[index + 3] = 255;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function fillDD2(index, array, x, y) {
|
|
22
|
+
sampler.sampleBilinear(x, y, v4, 0);
|
|
23
|
+
const val = (v4[0] + offset) * scale | 0;
|
|
24
|
+
array.fill(val, index, index + 3);
|
|
25
|
+
array[index + 3] = (v4[1] + offset) * scale | 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function fillDD3(index, array, x, y) {
|
|
29
|
+
|
|
30
|
+
sampler.sampleBilinear(x, y, v4, 0);
|
|
31
|
+
|
|
32
|
+
array[index] = (v4[0] + offset) * scale | 0;
|
|
33
|
+
array[index + 1] = (v4[1] + offset) * scale | 0;
|
|
34
|
+
array[index + 2] = (v4[2] + offset) * scale | 0;
|
|
35
|
+
array[index + 3] = 255;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function fillDD4(index, array, x, y) {
|
|
39
|
+
sampler.sampleBilinear(x, y, v4, 0);
|
|
40
|
+
array[index] = (v4[0] + offset) * scale | 0;
|
|
41
|
+
array[index + 1] = (v4[1] + offset) * scale | 0;
|
|
42
|
+
array[index + 2] = (v4[2] + offset) * scale | 0;
|
|
43
|
+
array[index + 3] = (v4[3] + offset) * scale | 0;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
let fillDD;
|
|
47
|
+
switch (sampler.itemSize) {
|
|
48
|
+
case 1:
|
|
49
|
+
fillDD = fillDD1;
|
|
50
|
+
break;
|
|
51
|
+
case 2:
|
|
52
|
+
fillDD = fillDD2;
|
|
53
|
+
break;
|
|
54
|
+
case 3:
|
|
55
|
+
fillDD = fillDD3;
|
|
56
|
+
break;
|
|
57
|
+
case 4:
|
|
58
|
+
fillDD = fillDD4;
|
|
59
|
+
break;
|
|
60
|
+
default :
|
|
61
|
+
throw new Error("unsupported item size");
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
return fillDD;
|
|
65
|
+
}
|
|
@@ -5,7 +5,7 @@ import { assert } from "../../../../core/assert.js";
|
|
|
5
5
|
* @param {Sampler2D} input
|
|
6
6
|
* @param {Sampler2D} output
|
|
7
7
|
*/
|
|
8
|
-
export function
|
|
8
|
+
export function sampler2d_scale_down_linear(input, output) {
|
|
9
9
|
assert.notEqual(input, undefined, 'input is undefined');
|
|
10
10
|
assert.notEqual(output, undefined, 'output is undefined');
|
|
11
11
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Sampler2D } from "./Sampler2D.js";
|
|
2
|
-
import {
|
|
2
|
+
import { sampler2d_scale_down_linear } from "./sampler2d_scale_down_linear.js";
|
|
3
3
|
|
|
4
4
|
test('2x2 -> 1x1 2x channel', () => {
|
|
5
5
|
const input = Sampler2D.float32(2, 2, 2);
|
|
@@ -10,7 +10,7 @@ test('2x2 -> 1x1 2x channel', () => {
|
|
|
10
10
|
input.set(0, 1, [11, 13]);
|
|
11
11
|
input.set(1, 1, [17, 19]);
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
sampler2d_scale_down_linear(input, output);
|
|
14
14
|
|
|
15
15
|
expect(output.data[0]).toEqual(8.5);
|
|
16
16
|
expect(output.data[1]).toEqual(10.5);
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { Sampler2D } from "./Sampler2D.js";
|
|
2
2
|
import { sampler2d_to_uint8_RGBA } from "./sampler2d_to_uint8_RGBA.js";
|
|
3
|
+
import { assert } from "../../../../core/assert.js";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
*
|
|
6
7
|
* @param {Sampler2D} sampler
|
|
7
8
|
* @param {HTMLCanvasElement} canvas
|
|
8
9
|
*/
|
|
9
|
-
export function
|
|
10
|
+
export function sampler2d_write_to_canvas_raw(sampler, canvas) {
|
|
11
|
+
|
|
12
|
+
assert.defined(sampler, 'sampler');
|
|
13
|
+
assert.defined(canvas, 'canvas');
|
|
10
14
|
|
|
11
15
|
const width = sampler.width;
|
|
12
16
|
const height = sampler.height;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { assert } from "../../../../core/assert.js";
|
|
2
|
-
import {
|
|
2
|
+
import { sampler2d_scale_down_linear } from "./sampler2d_scale_down_linear.js";
|
|
3
3
|
import { Sampler2D } from "./Sampler2D.js";
|
|
4
4
|
import { upsampleSampler2D } from "./upsampleSampler2D.js";
|
|
5
5
|
import { genericResampleSampler2D } from "./genericResampleSampler2D.js";
|
|
@@ -29,7 +29,7 @@ export function scaleSampler2D(input, output) {
|
|
|
29
29
|
// downscaling
|
|
30
30
|
if (Number.isInteger(sourceWidth / targetWidth) && Number.isInteger(sourceHeight / targetHeight)) {
|
|
31
31
|
// dimensions are multiples of source/target
|
|
32
|
-
|
|
32
|
+
sampler2d_scale_down_linear(input, output);
|
|
33
33
|
} else {
|
|
34
34
|
// generic downsample
|
|
35
35
|
genericResampleSampler2D(input, output, 3);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Sampler2D } from "../../../graphics/texture/sampler/Sampler2D.js";
|
|
2
|
-
import {
|
|
2
|
+
import { sampler2d_scale_down_linear } from "../../../graphics/texture/sampler/sampler2d_scale_down_linear.js";
|
|
3
3
|
import { computeWholeDivisorLow } from "../../../../core/math/computeWholeDivisorLow.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -20,7 +20,7 @@ export function buildCameraTargetSampler({ heightSampler }) {
|
|
|
20
20
|
|
|
21
21
|
const result = Sampler2D.float32(1, s(heightSampler.width), s(heightSampler.height));
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
sampler2d_scale_down_linear(heightSampler, result);
|
|
24
24
|
|
|
25
25
|
return result;
|
|
26
26
|
}
|
|
@@ -16,8 +16,8 @@ import { aabb2_contains, aabb2_overlapExists } from "../../../core/geom/AABB2.js
|
|
|
16
16
|
* @returns {TileMoveProgram}
|
|
17
17
|
*/
|
|
18
18
|
export function computeTileGridMove(tile, targetX, targetY, source, target) {
|
|
19
|
-
assert.
|
|
20
|
-
assert.
|
|
19
|
+
assert.isNumber(targetX, 'targetX');
|
|
20
|
+
assert.isNumber(targetY, 'targetY');
|
|
21
21
|
|
|
22
22
|
assert.defined(tile, 'tile');
|
|
23
23
|
assert.defined(source, 'source');
|