@woosh/meep-engine 2.33.75 → 2.34.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/core/collection/Set.js +0 -61
- package/core/collection/array/arrayIndexByEquality.js +20 -0
- package/core/collection/array/arraySetDiff.js +42 -0
- package/core/collection/array/arraySetSortingDiff.js +67 -0
- package/core/collection/array/arraySetSortingDiff.spec.js +74 -0
- package/core/collection/array/array_filter_by_multiple.js +36 -0
- package/core/collection/array/weightedRandomFromArray.js +9 -5
- package/core/collection/list/FilteredListProjection.js +1 -1
- package/core/collection/list/List.js +2 -1
- package/core/geom/3d/topology/compareEdges.js +16 -0
- package/core/geom/3d/topology/compareFaces.js +9 -0
- package/core/geom/3d/topology/compareVertices.js +9 -0
- package/core/geom/3d/topology/computeTopoMeshVertexDuplicates.js +25 -6
- package/core/geom/3d/topology/expandConnectivityByLocality.js +35 -19
- package/core/geom/Vector2.js +7 -2
- package/core/geom/Vector3.js +2 -2
- package/core/geom/v3_angle_between.js +3 -1
- package/editor/view/ecs/components/items/ItemContainerController.stories.js +1 -1
- package/engine/asset/loaders/image/ImageDecoderWorker.js +3 -2
- package/engine/asset/loaders/image/ImageRGBADataAsset.js +2 -6
- package/engine/asset/loaders/image/ImageRGBADataLoader.js +18 -2
- package/engine/asset/loaders/image/codec/NativeImageDecoder.js +2 -1
- package/engine/asset/loaders/image/png/PNG.js +3 -2
- package/engine/asset/loaders/image/png/PNGReader.js +1 -0
- package/engine/ecs/EntityComponentDataset.js +1 -1
- package/engine/ecs/terrain/ecs/splat/SplatMapping.js +39 -26
- package/engine/graphics/ecs/camera/topdown/TopDownCameraController.js +3 -4
- package/engine/graphics/ecs/highlight/system/MeshHighlightSystem.d.ts +3 -2
- package/engine/graphics/ecs/highlight/system/RenderableHighlightSystem.d.ts +3 -1
- package/engine/graphics/ecs/highlight/system/ShadedGeometryHighlightSystem.d.ts +8 -0
- package/engine/graphics/ecs/highlight/system/ShadedGeometryHighlightSystem.js +180 -0
- package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +74 -16
- package/engine/graphics/ecs/mesh-v2/ShadedGeometryFlags.js +7 -0
- package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +9 -0
- package/engine/graphics/ecs/mesh-v2/prototypeShadedGeometry.js +4 -2
- package/engine/graphics/geometry/VertexDataSpec.js +20 -0
- package/engine/graphics/micron/build/buildMicronGeometryFromBufferGeometry.js +41 -1
- package/engine/graphics/micron/format/MicronGeometry.d.ts +6 -0
- package/engine/graphics/micron/format/MicronGeometry.js +125 -0
- package/engine/graphics/micron/plugin/MicronRenderPlugin.js +10 -1
- package/engine/graphics/particles/particular/engine/parameter/ParticleParameter.js +7 -2
- package/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +3 -2
- package/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_texture.js +7 -3
- package/engine/graphics/texture/sampler/Sampler2D.js +2 -0
- package/engine/graphics/texture/sampler/downsampleSampler2D.js +3 -1
- package/engine/graphics/texture/sampler/genericResampleSampler2D.js +67 -0
- package/engine/graphics/texture/sampler/scaleSampler2D.js +29 -35
- package/engine/graphics/texture/sampler/upsampleSampler2D.js +47 -0
- package/generation/filtering/numeric/CellFilterReadGridLayer.js +2 -2
- package/generation/filtering/numeric/math/CellFilterSaturate.js +24 -0
- package/package.json +1 -1
- package/samples/terrain/from_image.js +289 -0
- package/samples/terrain/from_image_2.js +219 -0
- package/view/elements/radial/RadialMenu.js +1 -1
- package/generation/theme/TerrainThemeApplicator.js +0 -6
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { VertexDataSpec } from "../../geometry/VertexDataSpec.js";
|
|
2
2
|
import { assert } from "../../../../core/assert.js";
|
|
3
|
+
import { intersectRay } from "../../../../core/bvh2/aabb3/AABB3Math.js";
|
|
4
|
+
import { computeTriangleRayIntersection } from "../../../../core/geom/3d/triangle/computeTriangleRayIntersection.js";
|
|
5
|
+
import { SurfacePoint3 } from "../../../../core/geom/3d/SurfacePoint3.js";
|
|
3
6
|
|
|
4
7
|
let id_counter = 0;
|
|
5
8
|
|
|
@@ -55,6 +58,128 @@ export class MicronGeometry {
|
|
|
55
58
|
this.__proxy = null;
|
|
56
59
|
}
|
|
57
60
|
|
|
61
|
+
/**
|
|
62
|
+
*
|
|
63
|
+
* @param {number} origin_x
|
|
64
|
+
* @param {number} origin_y
|
|
65
|
+
* @param {number} origin_z
|
|
66
|
+
* @param {number} direction_x
|
|
67
|
+
* @param {number} direction_y
|
|
68
|
+
* @param {number} direction_z
|
|
69
|
+
* @returns {SurfacePoint3[]}
|
|
70
|
+
*/
|
|
71
|
+
raycast(
|
|
72
|
+
origin_x, origin_y, origin_z,
|
|
73
|
+
direction_x, direction_y, direction_z
|
|
74
|
+
) {
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
*
|
|
78
|
+
* @type {SurfacePoint3[]}
|
|
79
|
+
*/
|
|
80
|
+
const hits = [];
|
|
81
|
+
|
|
82
|
+
let stack_cursor = 1;
|
|
83
|
+
const stack = [this.root];
|
|
84
|
+
|
|
85
|
+
const spec = this.vertex_spec;
|
|
86
|
+
|
|
87
|
+
const position_attribute_index = spec.getAttributeIndexByName('position');
|
|
88
|
+
|
|
89
|
+
// check that position attribute actually exists
|
|
90
|
+
assert.isNonNegativeInteger(position_attribute_index, 'position_attribute_index');
|
|
91
|
+
|
|
92
|
+
const temp_hit = new SurfacePoint3();
|
|
93
|
+
|
|
94
|
+
while (stack_cursor > 0) {
|
|
95
|
+
stack_cursor--;
|
|
96
|
+
|
|
97
|
+
const patch = stack[stack_cursor];
|
|
98
|
+
|
|
99
|
+
// using group bounding box because it's conservative, as we want to be able to hit LOD_0
|
|
100
|
+
const bb = patch.group_bounding_box;
|
|
101
|
+
|
|
102
|
+
const bb_intersection_exists = intersectRay(
|
|
103
|
+
bb[0], bb[1], bb[2], bb[3], bb[4], bb[5],
|
|
104
|
+
origin_x, origin_y, origin_z,
|
|
105
|
+
direction_x, direction_y, direction_z
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
if (!bb_intersection_exists) {
|
|
109
|
+
// no intersection
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (patch.lod === 0) {
|
|
114
|
+
// LOD 0 - source geometry
|
|
115
|
+
|
|
116
|
+
// raycast against geometry
|
|
117
|
+
const indices = patch.face_indices;
|
|
118
|
+
const index_count = indices.length;
|
|
119
|
+
|
|
120
|
+
const vertices = patch.vertex_attribute_arrays[position_attribute_index];
|
|
121
|
+
|
|
122
|
+
for (let i = 0; i < index_count;) {
|
|
123
|
+
const a = indices[i++];
|
|
124
|
+
const b = indices[i++];
|
|
125
|
+
const c = indices[i++];
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
const a_address = a * 3;
|
|
129
|
+
const b_address = b * 3;
|
|
130
|
+
const c_address = c * 3;
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
const ax = vertices[a_address];
|
|
134
|
+
const ay = vertices[a_address + 1];
|
|
135
|
+
const az = vertices[a_address + 2];
|
|
136
|
+
|
|
137
|
+
const bx = vertices[b_address];
|
|
138
|
+
const by = vertices[b_address + 1];
|
|
139
|
+
const bz = vertices[b_address + 2];
|
|
140
|
+
|
|
141
|
+
const cx = vertices[c_address];
|
|
142
|
+
const cy = vertices[c_address + 1];
|
|
143
|
+
const cz = vertices[c_address + 2];
|
|
144
|
+
|
|
145
|
+
if (computeTriangleRayIntersection(
|
|
146
|
+
temp_hit,
|
|
147
|
+
origin_x, origin_y, origin_z,
|
|
148
|
+
direction_x, direction_y, direction_z,
|
|
149
|
+
ax, ay, az,
|
|
150
|
+
bx, by, bz,
|
|
151
|
+
cx, cy, cz
|
|
152
|
+
)) {
|
|
153
|
+
|
|
154
|
+
const contact = new SurfacePoint3();
|
|
155
|
+
|
|
156
|
+
contact.copy(temp_hit);
|
|
157
|
+
|
|
158
|
+
hits.push(contact);
|
|
159
|
+
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
} else {
|
|
164
|
+
// refine more
|
|
165
|
+
const children = patch.children;
|
|
166
|
+
|
|
167
|
+
const child_count = children.length;
|
|
168
|
+
|
|
169
|
+
for (let i = 0; i < child_count; i++) {
|
|
170
|
+
const child = children[i];
|
|
171
|
+
|
|
172
|
+
// push to stack
|
|
173
|
+
stack[stack_cursor] = child;
|
|
174
|
+
|
|
175
|
+
stack_cursor++;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return hits;
|
|
181
|
+
}
|
|
182
|
+
|
|
58
183
|
get patches() {
|
|
59
184
|
return this.__patches;
|
|
60
185
|
}
|
|
@@ -98,7 +98,16 @@ class GLTFAssetTransformer extends AssetTransformer {
|
|
|
98
98
|
|
|
99
99
|
const base = computePathDirectory(ad.path);
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
let micron_data;
|
|
102
|
+
|
|
103
|
+
const micron_path = `${base}/${micron_uri}`;
|
|
104
|
+
|
|
105
|
+
try {
|
|
106
|
+
micron_data = await this.__am.promise(micron_path, ASSET_TYPE_ARRAY_BUFFER);
|
|
107
|
+
} catch (e) {
|
|
108
|
+
console.error(`Failed to load micron geometry '${micron_path}' referenced in GLTF (will skip): ${e}`);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
102
111
|
|
|
103
112
|
// deserialize micron data
|
|
104
113
|
const buffer = BinaryBuffer.fromArrayBuffer(micron_data.create());
|
|
@@ -173,8 +173,12 @@ export class ParticleParameter {
|
|
|
173
173
|
//lock default track
|
|
174
174
|
this.defaultTrackValue.disableWriteMode();
|
|
175
175
|
|
|
176
|
-
|
|
177
|
-
|
|
176
|
+
const track_count = this.trackCount;
|
|
177
|
+
const tracks = this.tracks;
|
|
178
|
+
|
|
179
|
+
for (i = 0; i < track_count; i++) {
|
|
180
|
+
|
|
181
|
+
track = tracks.get(i);
|
|
178
182
|
|
|
179
183
|
if (track === undefined) {
|
|
180
184
|
//write the default track into the parameter
|
|
@@ -183,6 +187,7 @@ export class ParticleParameter {
|
|
|
183
187
|
//lock track
|
|
184
188
|
track.disableWriteMode();
|
|
185
189
|
}
|
|
190
|
+
|
|
186
191
|
}
|
|
187
192
|
|
|
188
193
|
this.computeStatistics();
|
|
@@ -433,9 +433,10 @@ async function sample_scene_nam(engine) {
|
|
|
433
433
|
"distanceMax": 1000
|
|
434
434
|
});
|
|
435
435
|
|
|
436
|
-
|
|
437
|
-
load_model('moicon/20_Dec_2021_Nammo/with_assets_micron_conveted/model.gltf', ecd)
|
|
436
|
+
load_model('moicon/20_Dec_2021_Nammo/with_assets(for_alex)/model.gltf', ecd)
|
|
437
|
+
// load_model('moicon/20_Dec_2021_Nammo/with_assets_micron_conveted/model.gltf', ecd)
|
|
438
438
|
// load_model('moicon/micron_container/model.gltf', ecd)
|
|
439
|
+
// load_model('moicon/test_philippe_jan_2022/test/model.gltf', ecd)
|
|
439
440
|
|
|
440
441
|
const P_SIZE_SMALL = 0.15;
|
|
441
442
|
const P_SIZE_MEDIUM = 0.6;
|
|
@@ -30,13 +30,19 @@ export function query_bvh_frustum_from_texture(
|
|
|
30
30
|
let result = 0;
|
|
31
31
|
let plane_address;
|
|
32
32
|
|
|
33
|
+
const binary_node_count = root.getBinaryNodeCount();
|
|
34
|
+
|
|
35
|
+
if (binary_node_count <= 0) {
|
|
36
|
+
// this should not happen
|
|
37
|
+
return 0;
|
|
38
|
+
}
|
|
39
|
+
|
|
33
40
|
/**
|
|
34
41
|
* After performing empirical tests, stack-based depth-first traversal turns out faster than using a queue
|
|
35
42
|
* @type {number}
|
|
36
43
|
*/
|
|
37
44
|
stack[0] = 0;
|
|
38
45
|
|
|
39
|
-
const binary_node_count = root.getBinaryNodeCount();
|
|
40
46
|
const last_valid_index = binary_node_count + root.getLeafNodeCount();
|
|
41
47
|
const data_view = root.getDataView();
|
|
42
48
|
|
|
@@ -122,8 +128,6 @@ export function query_bvh_frustum_from_texture(
|
|
|
122
128
|
|
|
123
129
|
} else if (light_type === 3) {
|
|
124
130
|
// decal
|
|
125
|
-
debugger;
|
|
126
|
-
|
|
127
131
|
} else {
|
|
128
132
|
throw new Error(`Unsupported light type ${light_type}`);
|
|
129
133
|
}
|
|
@@ -1374,6 +1374,8 @@ Sampler2D.prototype.traverseCircle = function (centerX, centerY, radius, visitor
|
|
|
1374
1374
|
* @param {boolean} [preserveData=true]
|
|
1375
1375
|
*/
|
|
1376
1376
|
Sampler2D.prototype.resize = function (x, y, preserveData = true) {
|
|
1377
|
+
assert.isNonNegativeInteger(x, 'x');
|
|
1378
|
+
assert.isNonNegativeInteger(y, 'y');
|
|
1377
1379
|
|
|
1378
1380
|
const _w = this.width;
|
|
1379
1381
|
const _h = this.height;
|
|
@@ -56,9 +56,11 @@ export function downsampleSampler2D(input, output) {
|
|
|
56
56
|
|
|
57
57
|
// accumulate sample
|
|
58
58
|
for (j = 0; j < sH; j++) {
|
|
59
|
+
const row_index = (sampleOffsetY + j) * iW;
|
|
60
|
+
|
|
59
61
|
for (i = 0; i < sW; i++) {
|
|
60
62
|
|
|
61
|
-
const iAddress = ((sampleOffsetX + i) +
|
|
63
|
+
const iAddress = ((sampleOffsetX + i) + row_index) * itemSize;
|
|
62
64
|
|
|
63
65
|
for (k = 0; k < itemSize; k++) {
|
|
64
66
|
sample[k] += iData[k + iAddress];
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { max2 } from "../../../../core/math/max2.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {Sampler2D} source
|
|
6
|
+
* @param {Sampler2D} target
|
|
7
|
+
*/
|
|
8
|
+
export function genericResampleSampler2D(source, target) {
|
|
9
|
+
const target_width = target.width;
|
|
10
|
+
const target_height = target.height;
|
|
11
|
+
|
|
12
|
+
// build kernel
|
|
13
|
+
|
|
14
|
+
// TODO add gaussian weights kernel for samples
|
|
15
|
+
|
|
16
|
+
const u_scale = source.width / target_width;
|
|
17
|
+
const v_scale = source.height / target_height;
|
|
18
|
+
|
|
19
|
+
const kernel_width = max2(1, Math.ceil(u_scale));
|
|
20
|
+
const kernel_height = max2(1, Math.ceil(v_scale));
|
|
21
|
+
|
|
22
|
+
const kernel_size = kernel_width * kernel_height;
|
|
23
|
+
|
|
24
|
+
const itemSize = source.itemSize;
|
|
25
|
+
|
|
26
|
+
const sample = new Float32Array(itemSize);
|
|
27
|
+
|
|
28
|
+
let column_index;
|
|
29
|
+
let row_index;
|
|
30
|
+
let k_y;
|
|
31
|
+
let k_x;
|
|
32
|
+
let i;
|
|
33
|
+
|
|
34
|
+
for (column_index = 0; column_index < target_height; column_index++) {
|
|
35
|
+
for (row_index = 0; row_index < target_width; row_index++) {
|
|
36
|
+
|
|
37
|
+
// figure out source offset
|
|
38
|
+
const source_x = row_index * u_scale;
|
|
39
|
+
const source_y = column_index * v_scale;
|
|
40
|
+
|
|
41
|
+
// reset sample
|
|
42
|
+
for (i = 0; i < itemSize; i++) {
|
|
43
|
+
sample[i] = 0;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// accumulate kernel samples
|
|
47
|
+
for (k_y = 0; k_y < kernel_height; k_y++) {
|
|
48
|
+
|
|
49
|
+
for (k_x = 0; k_x < kernel_width; k_x++) {
|
|
50
|
+
|
|
51
|
+
for (i = 0; i < itemSize; i++) {
|
|
52
|
+
sample[i] += source.sampleChannelBilinear(source_x + k_x, source_y + k_y, i);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
for (i = 0; i < itemSize; i++) {
|
|
59
|
+
// dilute sample
|
|
60
|
+
const channel_value = sample[i] / kernel_size;
|
|
61
|
+
// write out
|
|
62
|
+
target.data[(column_index * target_width + row_index) * itemSize + i] = channel_value;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -1,47 +1,41 @@
|
|
|
1
1
|
import { assert } from "../../../../core/assert.js";
|
|
2
|
+
import { downsampleSampler2D } from "./downsampleSampler2D.js";
|
|
3
|
+
import { Sampler2D } from "./Sampler2D.js";
|
|
4
|
+
import { upsampleSampler2D } from "./upsampleSampler2D.js";
|
|
5
|
+
import { genericResampleSampler2D } from "./genericResampleSampler2D.js";
|
|
2
6
|
|
|
3
7
|
/**
|
|
4
8
|
*
|
|
5
|
-
* @param {Sampler2D}
|
|
6
|
-
* @param {Sampler2D}
|
|
9
|
+
* @param {Sampler2D} input
|
|
10
|
+
* @param {Sampler2D} output
|
|
7
11
|
*/
|
|
8
|
-
export function scaleSampler2D(
|
|
9
|
-
const targetItemSize =
|
|
12
|
+
export function scaleSampler2D(input, output) {
|
|
13
|
+
const targetItemSize = output.itemSize;
|
|
10
14
|
|
|
11
|
-
assert.equal(
|
|
15
|
+
assert.equal(input.itemSize, targetItemSize, 'both source and target must have the same number of channels');
|
|
12
16
|
|
|
13
|
-
const targetWidth =
|
|
14
|
-
const targetHeight =
|
|
15
|
-
const sourceWidth =
|
|
16
|
-
const sourceHeight =
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const target_data = target.data;
|
|
17
|
+
const targetWidth = output.width;
|
|
18
|
+
const targetHeight = output.height;
|
|
19
|
+
const sourceWidth = input.width;
|
|
20
|
+
const sourceHeight = input.height;
|
|
20
21
|
|
|
21
22
|
if (sourceWidth === targetWidth && sourceHeight === targetHeight) {
|
|
22
|
-
//
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
for (let y = 0; y < targetHeight; y++) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const sample_y = y * source_scale_y;
|
|
36
|
-
const target_row_address = y * targetRowSize;
|
|
37
|
-
|
|
38
|
-
for (let x = 0; x < targetWidth; x++) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const target_offset = target_row_address + x * targetItemSize;
|
|
42
|
-
|
|
43
|
-
source.sampleBilinear(x * source_scale_x, sample_y, target_data, target_offset);
|
|
44
|
-
|
|
23
|
+
// same dimensions, copy directly
|
|
24
|
+
output.data.set(input.data);
|
|
25
|
+
} else if (sourceWidth > targetWidth && sourceHeight > targetHeight) {
|
|
26
|
+
// downscaling
|
|
27
|
+
if (Number.isInteger(sourceWidth / targetWidth) && Number.isInteger(sourceHeight / targetHeight)) {
|
|
28
|
+
// dimensions are multiples of source/target
|
|
29
|
+
downsampleSampler2D(input, output);
|
|
30
|
+
} else {
|
|
31
|
+
// generic downsample
|
|
32
|
+
genericResampleSampler2D(input, output);
|
|
45
33
|
}
|
|
34
|
+
} else if (sourceWidth < targetWidth && sourceHeight < targetHeight) {
|
|
35
|
+
// upscaling
|
|
36
|
+
upsampleSampler2D(input, output);
|
|
37
|
+
} else {
|
|
38
|
+
// mixed resampling
|
|
39
|
+
genericResampleSampler2D(input, output);
|
|
46
40
|
}
|
|
47
41
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { assert } from "../../../../core/assert.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {Sampler2D} input
|
|
6
|
+
* @param {Sampler2D} output
|
|
7
|
+
*/
|
|
8
|
+
export function upsampleSampler2D(input, output) {
|
|
9
|
+
const targetItemSize = output.itemSize;
|
|
10
|
+
|
|
11
|
+
assert.equal(input.itemSize, targetItemSize, 'both source and target must have the same number of channels');
|
|
12
|
+
|
|
13
|
+
const targetWidth = output.width;
|
|
14
|
+
const targetHeight = output.height;
|
|
15
|
+
const sourceWidth = input.width;
|
|
16
|
+
const sourceHeight = input.height;
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
const target_data = output.data;
|
|
20
|
+
|
|
21
|
+
if (sourceWidth === targetWidth && sourceHeight === targetHeight) {
|
|
22
|
+
// exact size match, nothing to do
|
|
23
|
+
target_data.set(input.data);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const targetRowSize = targetItemSize * targetWidth;
|
|
28
|
+
|
|
29
|
+
const source_scale_x = sourceWidth / targetWidth;
|
|
30
|
+
const source_scale_y = sourceHeight / targetHeight;
|
|
31
|
+
|
|
32
|
+
for (let y = 0; y < targetHeight; y++) {
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
const sample_y = y * source_scale_y;
|
|
36
|
+
const target_row_address = y * targetRowSize;
|
|
37
|
+
|
|
38
|
+
for (let x = 0; x < targetWidth; x++) {
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
const target_offset = target_row_address + x * targetItemSize;
|
|
42
|
+
|
|
43
|
+
input.sampleBilinear(x * source_scale_x, sample_y, target_data, target_offset);
|
|
44
|
+
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -36,8 +36,8 @@ export class CellFilterReadGridLayer extends CellFilter {
|
|
|
36
36
|
// cache required values
|
|
37
37
|
this.__sampler = this.__layer.sampler;
|
|
38
38
|
|
|
39
|
-
this.__u_scale =
|
|
40
|
-
this.__v_scale =
|
|
39
|
+
this.__u_scale = this.__sampler.width / grid.width;
|
|
40
|
+
this.__v_scale = this.__sampler.height / grid.height;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
/**
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { CellFilterUnaryOperation } from "../../core/CellFilterUnaryOperation.js";
|
|
2
|
+
import { clamp } from "../../../../core/math/clamp.js";
|
|
3
|
+
import { assert } from "../../../../core/assert.js";
|
|
4
|
+
|
|
5
|
+
export class CellFilterSaturate extends CellFilterUnaryOperation {
|
|
6
|
+
operation(v) {
|
|
7
|
+
return clamp(v, 0, 1);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
*
|
|
12
|
+
* @param {CellFilter} v
|
|
13
|
+
* @return {CellFilterUnaryOperation}
|
|
14
|
+
*/
|
|
15
|
+
static from(v) {
|
|
16
|
+
assert.equal(v.isCellFilter, true, "v.isCellFilter !== true");
|
|
17
|
+
|
|
18
|
+
const r = new CellFilterSaturate();
|
|
19
|
+
|
|
20
|
+
r.source = v;
|
|
21
|
+
|
|
22
|
+
return r;
|
|
23
|
+
}
|
|
24
|
+
}
|
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.
|
|
8
|
+
"version": "2.34.2",
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"gl-matrix": "3.4.3",
|
|
11
11
|
"fast-levenshtein": "2.0.6",
|