@woosh/meep-engine 2.43.50 → 2.43.52
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/core/collection/array/typed/typed_array_is_integer.js +17 -0
- package/core/model/node-graph/NodeGraph.spec.js +19 -0
- package/engine/graphics/ecs/decal/v2/FPDecalSystem.js +21 -1
- package/engine/graphics/ecs/decal/v2/prototypeDecalSystem.js +7 -2
- package/engine/graphics/render/forward_plus/LightManager.js +7 -0
- package/engine/graphics/render/forward_plus/model/AbstractLight.js +4 -0
- package/engine/graphics/texture/sampler/Sampler2D2Canvas.js +10 -18
- package/engine/graphics/texture/sampler/copy_Sampler2D_channel_data.js +6 -2
- package/engine/graphics/texture/sampler/sample2d_write_to_canvas_raw.js +38 -0
- package/engine/graphics/texture/sampler/sampler2d_channel_linear_transform.js +68 -0
- package/engine/graphics/texture/sampler/sampler2d_to_uint8_RGBA.js +97 -0
- package/engine/graphics/texture/sampler/sampler2d_to_uint8_RGBA.spec.js +52 -0
- package/engine/graphics/texture/sampler/saturated_value_by_constructor.js +28 -0
- package/package.json +1 -1
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param {Uint8Array|Uint16Array|Uint32Array|Int8Array|Int16Array|Int32Array} array
|
|
4
|
+
* @return {boolean}
|
|
5
|
+
*/
|
|
6
|
+
export function typed_array_is_integer(array) {
|
|
7
|
+
const ctor = array.constructor;
|
|
8
|
+
|
|
9
|
+
return ctor === Uint8ClampedArray
|
|
10
|
+
|| ctor === Uint8Array
|
|
11
|
+
|| ctor === Uint16Array
|
|
12
|
+
|| ctor === Uint32Array
|
|
13
|
+
|| ctor === Int8Array
|
|
14
|
+
|| ctor === Int16Array
|
|
15
|
+
|| ctor === Int32Array
|
|
16
|
+
;
|
|
17
|
+
}
|
|
@@ -32,6 +32,25 @@ test("createConnection returns a number", () => {
|
|
|
32
32
|
expect(typeof g.createConnection(i0, pOut, i1, pInt)).toBe('number');
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
+
test("createConnection populates NodeInstance.connections", () => {
|
|
36
|
+
const node = new NodeDescription();
|
|
37
|
+
|
|
38
|
+
const dt = new DataType();
|
|
39
|
+
|
|
40
|
+
const pInt = node.createPort(dt, "in", PortDirection.In);
|
|
41
|
+
const pOut = node.createPort(dt, "out", PortDirection.Out);
|
|
42
|
+
|
|
43
|
+
const g = new NodeGraph();
|
|
44
|
+
|
|
45
|
+
const i0 = g.createNode(node);
|
|
46
|
+
const i1 = g.createNode(node);
|
|
47
|
+
|
|
48
|
+
g.createConnection(i0, pOut, i1, pInt);
|
|
49
|
+
|
|
50
|
+
expect(g.getNode(i0).connections.length).toBe(1);
|
|
51
|
+
expect(g.getNode(i1).connections.length).toBe(1);
|
|
52
|
+
});
|
|
53
|
+
|
|
35
54
|
test('getNode produces correct result', () => {
|
|
36
55
|
const graph = new NodeGraph();
|
|
37
56
|
|
|
@@ -10,6 +10,7 @@ import { Sampler2D } from "../../../texture/sampler/Sampler2D.js";
|
|
|
10
10
|
import { GameAssetType } from "../../../../asset/GameAssetType.js";
|
|
11
11
|
import { assert } from "../../../../../core/assert.js";
|
|
12
12
|
import { AsyncLoadingCache } from "../../../../../core/collection/map/AsyncLoadingCache.js";
|
|
13
|
+
import { sampler2d_to_uint8_RGBA } from "../../../texture/sampler/sampler2d_to_uint8_RGBA.js";
|
|
13
14
|
|
|
14
15
|
const placeholder_texture = Sampler2D.uint8(4, 1, 1);
|
|
15
16
|
placeholder_texture.data.fill(255);
|
|
@@ -107,6 +108,13 @@ class Context extends SystemEntityContext {
|
|
|
107
108
|
*/
|
|
108
109
|
const decal_spec = this.components[0];
|
|
109
110
|
|
|
111
|
+
// propagate draw priority onto decal
|
|
112
|
+
Object.defineProperty(fpDecal, 'draw_priority', {
|
|
113
|
+
get() {
|
|
114
|
+
return decal_spec.priority;
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
|
|
110
118
|
this.__load_texture().then(() => {
|
|
111
119
|
|
|
112
120
|
if (!this.__is_linked) {
|
|
@@ -167,7 +175,19 @@ export class FPDecalSystem extends AbstractContextSystem {
|
|
|
167
175
|
* @private
|
|
168
176
|
*/
|
|
169
177
|
this.__texture_cache = new AsyncLoadingCache(new Map(), (key) => {
|
|
170
|
-
return this.__assets.promise(key, GameAssetType.Image).then(asset =>
|
|
178
|
+
return this.__assets.promise(key, GameAssetType.Image).then(asset => {
|
|
179
|
+
const asset_sampler = asset.create();
|
|
180
|
+
|
|
181
|
+
if (asset_sampler.itemSize === 4) {
|
|
182
|
+
return asset_sampler;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const resampled = Sampler2D.uint8(4, asset_sampler.width, asset_sampler.height);
|
|
186
|
+
|
|
187
|
+
sampler2d_to_uint8_RGBA(resampled, asset_sampler);
|
|
188
|
+
|
|
189
|
+
return resampled;
|
|
190
|
+
});
|
|
171
191
|
});
|
|
172
192
|
|
|
173
193
|
/**
|
|
@@ -287,7 +287,8 @@ function makeNormalTestGridDecal(ecd, root_transform = new Transform()) {
|
|
|
287
287
|
|
|
288
288
|
const decal = new Decal();
|
|
289
289
|
|
|
290
|
-
decal.uri = decal_urls[1];
|
|
290
|
+
// decal.uri = decal_urls[1];
|
|
291
|
+
decal.uri ='moicon/ISO 7010 - Safety Signs (3)/ISO 7010 - Safety Signs/Emergency/400px/E001 – Emergency exit (left hand).png';
|
|
291
292
|
|
|
292
293
|
const entity = new EntityBuilder();
|
|
293
294
|
|
|
@@ -299,7 +300,7 @@ function makeNormalTestGridDecal(ecd, root_transform = new Transform()) {
|
|
|
299
300
|
SPACING * j,
|
|
300
301
|
0,
|
|
301
302
|
);
|
|
302
|
-
transform.scale.setScalar(
|
|
303
|
+
transform.scale.setScalar(3);
|
|
303
304
|
transform.rotation._lookRotation(direction[0],direction[2], direction[1] , 0, 1, 0);
|
|
304
305
|
|
|
305
306
|
transform.multiplyTransforms(root_transform, transform);
|
|
@@ -311,6 +312,10 @@ function makeNormalTestGridDecal(ecd, root_transform = new Transform()) {
|
|
|
311
312
|
.add(decal)
|
|
312
313
|
.build(ecd);
|
|
313
314
|
|
|
315
|
+
setInterval(()=>{
|
|
316
|
+
decal.priority = Math.random();
|
|
317
|
+
},7000);
|
|
318
|
+
|
|
314
319
|
|
|
315
320
|
// make an arrow helper
|
|
316
321
|
const arrow_transform = Transform.fromJSON({
|
|
@@ -503,6 +503,13 @@ export class LightManager {
|
|
|
503
503
|
if (light instanceof Decal) {
|
|
504
504
|
const ref = this.__decal_references.get(light);
|
|
505
505
|
|
|
506
|
+
if (ref === undefined) {
|
|
507
|
+
// This can occur when decal changes while being in the visible list, messing with the IncrementalDeltaSet's compare order
|
|
508
|
+
console.warn(`Decal reference not found: ${light}, likely live decal changed`);
|
|
509
|
+
// TODO address this case properly
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
|
|
506
513
|
const patch = ref.getValue();
|
|
507
514
|
const patch_uv = patch.uv;
|
|
508
515
|
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
|
|
6
|
+
import { Sampler2D } from "./Sampler2D.js";
|
|
7
|
+
import { sample2d_write_to_canvas_raw } from "./sample2d_write_to_canvas_raw.js";
|
|
8
|
+
|
|
6
9
|
/**
|
|
7
10
|
*
|
|
8
11
|
* @param {Sampler2D} sampler
|
|
@@ -12,32 +15,20 @@
|
|
|
12
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 using {@link Sampler2D#makeArrayFiller}
|
|
13
16
|
* @returns {HTMLCanvasElement} canvas
|
|
14
17
|
*/
|
|
15
|
-
function convertSampler2D2Canvas(sampler, scale=255, offset=0, canvas, fillDD) {
|
|
18
|
+
function convertSampler2D2Canvas(sampler, scale = 255, offset = 0, canvas, fillDD) {
|
|
16
19
|
const source_data = sampler.data;
|
|
17
20
|
|
|
18
21
|
//generate canvas
|
|
19
22
|
if (canvas === undefined) {
|
|
20
23
|
canvas = document.createElement("canvas");
|
|
21
24
|
}
|
|
22
|
-
const width = sampler.width;
|
|
23
|
-
const height = sampler.height;
|
|
24
|
-
|
|
25
|
-
if (canvas.width !== width) {
|
|
26
|
-
canvas.width = width;
|
|
27
|
-
}
|
|
28
25
|
|
|
29
|
-
|
|
30
|
-
canvas.height = height;
|
|
31
|
-
}
|
|
26
|
+
const converted_sampler = Sampler2D.uint8(4, sampler.width, sampler.height);
|
|
32
27
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return canvas;
|
|
36
|
-
}
|
|
28
|
+
const width = sampler.width;
|
|
29
|
+
const height = sampler.height;
|
|
37
30
|
|
|
38
|
-
const
|
|
39
|
-
const imageData = context.createImageData(width, height);
|
|
40
|
-
const array = imageData.data;
|
|
31
|
+
const array = converted_sampler.data;
|
|
41
32
|
//
|
|
42
33
|
const source_channel_count = sampler.itemSize;
|
|
43
34
|
if (source_channel_count === 4 && offset === 0 && scale === 1) {
|
|
@@ -94,7 +85,8 @@ function convertSampler2D2Canvas(sampler, scale=255, offset=0, canvas, fillDD) {
|
|
|
94
85
|
|
|
95
86
|
}
|
|
96
87
|
|
|
97
|
-
|
|
88
|
+
sample2d_write_to_canvas_raw(converted_sampler, canvas);
|
|
89
|
+
|
|
98
90
|
return canvas;
|
|
99
91
|
}
|
|
100
92
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { saturated_value_by_constructor } from "./saturated_value_by_constructor.js";
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Allows copying data from one sampler to another with unequal number of channels (a.itemSize !== b.itemSize)
|
|
3
5
|
* @example convert RGBA to RGB or R to RGB
|
|
@@ -19,12 +21,14 @@ export function copy_Sampler2D_channel_data(source, destination) {
|
|
|
19
21
|
|
|
20
22
|
let i, j;
|
|
21
23
|
|
|
24
|
+
const saturated_channel_value = saturated_value_by_constructor(destination_data.constructor);
|
|
25
|
+
|
|
22
26
|
if (source_item_size === destination_item_size) {
|
|
23
27
|
// just copy data chunk
|
|
24
28
|
destination_data.set(source_data);
|
|
25
29
|
|
|
26
30
|
} else if (source_item_size > destination_item_size) {
|
|
27
|
-
|
|
31
|
+
// more channels in source than in destination
|
|
28
32
|
for (i = 0; i < pixel_count; i++) {
|
|
29
33
|
const source_sample_offset = i * source_item_size;
|
|
30
34
|
const destination_sample_offset = i * destination_item_size;
|
|
@@ -44,7 +48,7 @@ export function copy_Sampler2D_channel_data(source, destination) {
|
|
|
44
48
|
destination_data[i4 + 1] = source_data[i3 + 1];
|
|
45
49
|
destination_data[i4 + 2] = source_data[i3 + 2];
|
|
46
50
|
|
|
47
|
-
destination_data[i4] =
|
|
51
|
+
destination_data[i4 + 3] = saturated_channel_value; // fill alpha
|
|
48
52
|
}
|
|
49
53
|
} else if (source_item_size === 2 && destination_item_size === 4) {
|
|
50
54
|
//RA -> RGBA
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Sampler2D } from "./Sampler2D.js";
|
|
2
|
+
import { sampler2d_to_uint8_RGBA } from "./sampler2d_to_uint8_RGBA.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @param {Sampler2D} sampler
|
|
7
|
+
* @param {HTMLCanvasElement} canvas
|
|
8
|
+
*/
|
|
9
|
+
export function sample2d_write_to_canvas_raw(sampler, canvas) {
|
|
10
|
+
|
|
11
|
+
const width = sampler.width;
|
|
12
|
+
const height = sampler.height;
|
|
13
|
+
|
|
14
|
+
if (canvas.width !== width) {
|
|
15
|
+
canvas.width = width;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (canvas.height !== height) {
|
|
19
|
+
canvas.height = height;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (height === 0 || width === 0) {
|
|
23
|
+
//there is no data, just return
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const context = canvas.getContext("2d");
|
|
28
|
+
|
|
29
|
+
const imageData = context.createImageData(width, height);
|
|
30
|
+
const array = imageData.data;
|
|
31
|
+
|
|
32
|
+
const destination_sampler = new Sampler2D(array, 4, width, height);
|
|
33
|
+
|
|
34
|
+
sampler2d_to_uint8_RGBA(destination_sampler, sampler);
|
|
35
|
+
|
|
36
|
+
context.putImageData(imageData, 0, 0);
|
|
37
|
+
|
|
38
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { typed_array_is_integer } from "../../../../core/collection/array/typed/typed_array_is_integer.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Applies a linear polynomial transform to each value of a given channel
|
|
5
|
+
* @param {Sampler2D} output
|
|
6
|
+
* @param {Sampler2D} input
|
|
7
|
+
* @param {number} output_channel_index
|
|
8
|
+
* @param {number} input_channel_index
|
|
9
|
+
* @param {number} gradient
|
|
10
|
+
* @param {number} intercept
|
|
11
|
+
*/
|
|
12
|
+
export function sampler2d_channel_linear_transform(
|
|
13
|
+
output, input,
|
|
14
|
+
output_channel_index, input_channel_index,
|
|
15
|
+
gradient, intercept
|
|
16
|
+
) {
|
|
17
|
+
|
|
18
|
+
const input_width = input.width;
|
|
19
|
+
const input_height = input.height;
|
|
20
|
+
|
|
21
|
+
const output_width = output.width;
|
|
22
|
+
const output_height = output.height;
|
|
23
|
+
|
|
24
|
+
if (
|
|
25
|
+
input_width !== output_width
|
|
26
|
+
|| input_height !== output_height
|
|
27
|
+
) {
|
|
28
|
+
throw new Error('Dimensions of input and output are incompatible');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const input_item_size = input.itemSize;
|
|
32
|
+
const output_item_size = output.itemSize;
|
|
33
|
+
|
|
34
|
+
const input_data = input.data;
|
|
35
|
+
const output_data = output.data;
|
|
36
|
+
|
|
37
|
+
const pixel_count = input_width * input_height;
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
if (typed_array_is_integer(output_data)) {
|
|
41
|
+
|
|
42
|
+
for (let i = 0; i < pixel_count; i++) {
|
|
43
|
+
|
|
44
|
+
const input_address = i * input_item_size + input_channel_index;
|
|
45
|
+
const output_address = i * output_item_size + output_channel_index;
|
|
46
|
+
|
|
47
|
+
const input_value = input_data[input_address];
|
|
48
|
+
|
|
49
|
+
output_data[output_address] = Math.round(input_value * gradient + intercept);
|
|
50
|
+
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
} else {
|
|
54
|
+
|
|
55
|
+
for (let i = 0; i < pixel_count; i++) {
|
|
56
|
+
|
|
57
|
+
const input_address = i * input_item_size + input_channel_index;
|
|
58
|
+
const output_address = i * output_item_size + output_channel_index;
|
|
59
|
+
|
|
60
|
+
const input_value = input_data[input_address];
|
|
61
|
+
|
|
62
|
+
output_data[output_address] = input_value * gradient + intercept;
|
|
63
|
+
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { sampler2d_channel_linear_transform } from "./sampler2d_channel_linear_transform.js";
|
|
2
|
+
|
|
3
|
+
function compute_gradient_and_intercept_uint8(ctor) {
|
|
4
|
+
let gradient = 1;
|
|
5
|
+
let intercept = 0;
|
|
6
|
+
|
|
7
|
+
switch (ctor) {
|
|
8
|
+
case Uint16Array:
|
|
9
|
+
gradient = 0.0038910505836575876;
|
|
10
|
+
break;
|
|
11
|
+
case Uint32Array:
|
|
12
|
+
gradient = 5.937181414556033e-8;
|
|
13
|
+
break;
|
|
14
|
+
case Int8Array:
|
|
15
|
+
gradient = 1;
|
|
16
|
+
intercept = 127;
|
|
17
|
+
break
|
|
18
|
+
case Int16Array:
|
|
19
|
+
gradient = 0.0038910505836575876;
|
|
20
|
+
intercept = 127;
|
|
21
|
+
break;
|
|
22
|
+
case Int32Array:
|
|
23
|
+
gradient = 5.937181414556033e-8;
|
|
24
|
+
intercept = 127;
|
|
25
|
+
break
|
|
26
|
+
case Float32Array:
|
|
27
|
+
case Float64Array:
|
|
28
|
+
gradient = 255;
|
|
29
|
+
break;
|
|
30
|
+
default:
|
|
31
|
+
// do nothing;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
gradient, intercept
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Many applications work with 8bit RGBA images, this utility function converts a given input to that format
|
|
41
|
+
* @param {Sampler2D} input
|
|
42
|
+
* @param {Sampler2D} output
|
|
43
|
+
*/
|
|
44
|
+
export function sampler2d_to_uint8_RGBA(output, input) {
|
|
45
|
+
if (
|
|
46
|
+
input.width !== output.width
|
|
47
|
+
|| input.height !== output.height
|
|
48
|
+
) {
|
|
49
|
+
throw new Error('Dimensions of source and destination are incompatible');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (output.itemSize !== 4) {
|
|
53
|
+
throw new Error(`Destination must have 4 channels exactly, instead got '${output.itemSize}'`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const { gradient, intercept } = compute_gradient_and_intercept_uint8(input.data.constructor);
|
|
57
|
+
|
|
58
|
+
const source_item_size = input.itemSize;
|
|
59
|
+
|
|
60
|
+
if (intercept === 0 && gradient === 1 && source_item_size === 4) {
|
|
61
|
+
// already in the right format, use shortcut
|
|
62
|
+
output.data.set(input.data);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (source_item_size === 1) {
|
|
67
|
+
|
|
68
|
+
sampler2d_channel_linear_transform(output, input, 0, 0, gradient, intercept);
|
|
69
|
+
sampler2d_channel_linear_transform(output, input, 1, 0, gradient, intercept);
|
|
70
|
+
sampler2d_channel_linear_transform(output, input, 2, 0, gradient, intercept);
|
|
71
|
+
|
|
72
|
+
output.fill_channel(3, 255);
|
|
73
|
+
|
|
74
|
+
} else if (source_item_size === 2) {
|
|
75
|
+
|
|
76
|
+
sampler2d_channel_linear_transform(output, input, 0, 0, gradient, intercept);
|
|
77
|
+
sampler2d_channel_linear_transform(output, input, 1, 0, gradient, intercept);
|
|
78
|
+
sampler2d_channel_linear_transform(output, input, 2, 0, gradient, intercept);
|
|
79
|
+
sampler2d_channel_linear_transform(output, input, 3, 1, gradient, intercept);
|
|
80
|
+
|
|
81
|
+
} else if (source_item_size === 3) {
|
|
82
|
+
|
|
83
|
+
sampler2d_channel_linear_transform(output, input, 0, 0, gradient, intercept);
|
|
84
|
+
sampler2d_channel_linear_transform(output, input, 1, 1, gradient, intercept);
|
|
85
|
+
sampler2d_channel_linear_transform(output, input, 2, 2, gradient, intercept);
|
|
86
|
+
|
|
87
|
+
output.fill_channel(3, 255);
|
|
88
|
+
|
|
89
|
+
} else if (source_item_size === 4) {
|
|
90
|
+
|
|
91
|
+
sampler2d_channel_linear_transform(output, input, 0, 0, gradient, intercept);
|
|
92
|
+
sampler2d_channel_linear_transform(output, input, 1, 1, gradient, intercept);
|
|
93
|
+
sampler2d_channel_linear_transform(output, input, 2, 2, gradient, intercept);
|
|
94
|
+
sampler2d_channel_linear_transform(output, input, 3, 3, gradient, intercept);
|
|
95
|
+
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { sampler2d_to_uint8_RGBA } from "./sampler2d_to_uint8_RGBA.js";
|
|
2
|
+
import { Sampler2D } from "./Sampler2D.js";
|
|
3
|
+
|
|
4
|
+
test('uint8 RGBA input', () => {
|
|
5
|
+
|
|
6
|
+
const source = new Sampler2D(new Uint8Array([1,3,7,11]), 4, 1, 1);
|
|
7
|
+
const destination = Sampler2D.uint8(4, 1, 1);
|
|
8
|
+
|
|
9
|
+
sampler2d_to_uint8_RGBA(destination, source);
|
|
10
|
+
|
|
11
|
+
expect(Array.from(destination.data)).toEqual([1,3,7,11]);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('uint8 RGB input', () => {
|
|
15
|
+
|
|
16
|
+
const source = new Sampler2D(new Uint8Array([1,3,7]), 3, 1, 1);
|
|
17
|
+
const destination = Sampler2D.uint8(4, 1, 1);
|
|
18
|
+
|
|
19
|
+
sampler2d_to_uint8_RGBA(destination, source);
|
|
20
|
+
|
|
21
|
+
expect(Array.from(destination.data)).toEqual([1,3,7,255]);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('uint8 RG input', () => {
|
|
25
|
+
|
|
26
|
+
const source = new Sampler2D(new Uint8Array([1,3]), 2, 1, 1);
|
|
27
|
+
const destination = Sampler2D.uint8(4, 1, 1);
|
|
28
|
+
|
|
29
|
+
sampler2d_to_uint8_RGBA(destination, source);
|
|
30
|
+
|
|
31
|
+
expect(Array.from(destination.data)).toEqual([1,1,1,3]);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test('uint8 R input', () => {
|
|
35
|
+
|
|
36
|
+
const source = new Sampler2D(new Uint8Array([1]), 1, 1, 1);
|
|
37
|
+
const destination = Sampler2D.uint8(4, 1, 1);
|
|
38
|
+
|
|
39
|
+
sampler2d_to_uint8_RGBA(destination, source);
|
|
40
|
+
|
|
41
|
+
expect(Array.from(destination.data)).toEqual([1,1,1,255]);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test('float32 RGBA input', () => {
|
|
45
|
+
|
|
46
|
+
const source = new Sampler2D(new Float32Array([0.1,0.3,0.7,0.11]), 4, 1, 1);
|
|
47
|
+
const destination = Sampler2D.uint8(4, 1, 1);
|
|
48
|
+
|
|
49
|
+
sampler2d_to_uint8_RGBA(destination, source);
|
|
50
|
+
|
|
51
|
+
expect(Array.from(destination.data)).toEqual([26, 77, 178, 28]);
|
|
52
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param {*} ctor
|
|
4
|
+
* @returns {number}
|
|
5
|
+
*/
|
|
6
|
+
export function saturated_value_by_constructor(ctor) {
|
|
7
|
+
|
|
8
|
+
switch (ctor) {
|
|
9
|
+
case Uint8Array:
|
|
10
|
+
return 255;
|
|
11
|
+
case Uint16Array:
|
|
12
|
+
return 65535;
|
|
13
|
+
case Uint32Array:
|
|
14
|
+
return 4294967295;
|
|
15
|
+
case Int8Array:
|
|
16
|
+
return 127;
|
|
17
|
+
case Int16Array:
|
|
18
|
+
return 32767;
|
|
19
|
+
case Int32Array:
|
|
20
|
+
return 2147483647;
|
|
21
|
+
case Float32Array:
|
|
22
|
+
case Float64Array:
|
|
23
|
+
return 1;
|
|
24
|
+
default:
|
|
25
|
+
return 1;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
}
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"productName": "Meep",
|
|
6
6
|
"description": "production-ready JavaScript game engine based on Entity Component System Architecture",
|
|
7
7
|
"author": "Alexander Goldring",
|
|
8
|
-
"version": "2.43.
|
|
8
|
+
"version": "2.43.52",
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"gl-matrix": "3.4.3",
|
|
11
11
|
"fast-levenshtein": "2.0.6",
|