@woosh/meep-engine 2.48.12 → 2.48.14
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/package.json +1 -1
- package/src/core/collection/queue/Deque.d.ts +9 -0
- package/src/core/collection/queue/Deque.js +3 -0
- package/src/core/collection/queue/Deque.spec.js +51 -0
- package/src/core/font/FontAssetLoader.js +2 -2
- package/src/core/math/bessel_3.js +3 -1
- package/src/core/math/noise/create_noise_2d.js +193 -0
- package/src/core/path/computeFileExtension.js +3 -2
- package/src/engine/Engine.js +14 -8
- package/src/engine/achievements/AchievementManager.js +16 -16
- package/src/engine/asset/AssetManager.d.ts +10 -5
- package/src/engine/asset/AssetManager.js +79 -24
- package/src/engine/asset/AssetManager.spec.js +1 -1
- package/src/engine/asset/AssetRequest.js +19 -1
- package/src/engine/asset/AssetRequestScope.d.ts +3 -0
- package/src/engine/asset/AssetRequestScope.js +64 -0
- package/src/engine/asset/PendingAsset.js +7 -7
- package/src/engine/asset/loaders/ArrayBufferLoader.js +1 -1
- package/src/engine/asset/loaders/AssetLoader.d.ts +9 -2
- package/src/engine/asset/loaders/AssetLoader.js +19 -16
- package/src/engine/asset/loaders/GLTFAssetLoader.d.ts +1 -1
- package/src/engine/asset/loaders/GLTFAssetLoader.js +2 -2
- package/src/engine/asset/loaders/JavascriptAssetLoader.js +17 -12
- package/src/engine/asset/loaders/JsonAssetLoader.js +1 -1
- package/src/engine/asset/loaders/LegacyThreeJSONAssetLoader.js +4 -1
- package/src/engine/asset/loaders/SVGAssetLoader.js +1 -1
- package/src/engine/asset/loaders/SoundAssetLoader.js +4 -6
- package/src/engine/asset/loaders/TextAssetLoader.js +1 -1
- package/src/engine/asset/loaders/image/ImageRGBADataLoader.js +24 -17
- package/src/engine/asset/loaders/texture/TextureAssetLoader.d.ts +1 -1
- package/src/engine/asset/loaders/texture/TextureAssetLoader.js +1 -1
- package/src/engine/asset/preloader/Preloader.js +1 -1
- package/src/engine/development/performance/MetricStatistics.js +7 -5
- package/src/engine/development/performance/RingBufferMetric.js +2 -2
- package/src/engine/ecs/foliage/ecs/Foliage2System.js +7 -5
- package/src/engine/ecs/foliage/ecs/InstancedMeshUtils.js +14 -1
- package/src/engine/ecs/gui/GUIElementSystem.d.ts +1 -1
- package/src/engine/ecs/sockets/serialization/AttachmentSocketsAssetLoader.js +2 -2
- package/src/engine/ecs/terrain/ecs/PromiseSamplerHeight.js +16 -9
- package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.js +3 -21
- package/src/engine/ecs/terrain/ecs/splat/SplatMapping.js +16 -11
- package/src/engine/ecs/terrain/serialization/TerrainSerializationAdapter.js +1 -1
- package/src/engine/graphics/ecs/animation/animator/graph/definition/serialization/AnimationGraphDefinitionAssetLoader.js +18 -15
- package/src/engine/graphics/ecs/camera/pp/PerfectPanner.js +4 -2
- package/src/engine/graphics/ecs/mesh/MeshSystem.js +1 -1
- package/src/engine/graphics/ecs/path/tube/build/TubePathBuilder.js +6 -4
- package/src/engine/graphics/material/getTextureImmediate.js +5 -3
- package/src/engine/graphics/texture/3d/SingleChannelSampler3D.js +146 -0
- package/src/engine/graphics/texture/3d/scs3d_read_2d_slice.js +26 -0
- package/src/engine/graphics/texture/atlas/ManagedTextureAtlas.js +1 -1
- package/src/engine/graphics/texture/sampler/Sampler2D.js +22 -13
- package/src/engine/graphics/texture/sampler/filter/box.js +3 -3
- package/src/engine/graphics/texture/sampler/filter/kaiser_bessel_window.js +2 -1
- package/src/engine/graphics/texture/sampler/genericResampleSampler2D.js +9 -8
- package/src/engine/graphics/texture/sampler/loadSampler2D.js +18 -16
- package/src/engine/graphics/texture/sampler/sampler2d_scale_down_linear.js +8 -11
- package/src/engine/graphics/texture/virtual/tile/TileLoader.js +1 -1
- package/src/engine/graphics/trail/x/RibbonXPlugin.js +5 -3
- package/src/engine/knowledge/database/StaticKnowledgeDataTable.js +1 -1
- package/src/engine/physics/fluid/FluidField.js +153 -1
- package/src/engine/physics/fluid/prototype.js +201 -0
- package/src/engine/physics/fluid/solver/v3_grid_apply_diffusion.js +67 -0
- package/src/engine/sound/ecs/emitter/loadSoundTrackAsset.js +1 -1
- package/src/generation/filtering/numeric/complex/CellFilterGaussianBlur.js +17 -12
- package/src/generation/filtering/numeric/complex/CellFilterSimplexNoise.js +14 -10
- package/src/view/elements/MeshPreview.js +66 -64
- package/src/view/elements/image/SvgImageView.js +8 -6
- package/src/view/renderModel.js +1 -1
|
@@ -99,13 +99,10 @@ class ClingToTerrainSystem extends System {
|
|
|
99
99
|
* @param {int} entityId
|
|
100
100
|
*/
|
|
101
101
|
link(cling, transform, entityId) {
|
|
102
|
-
const self = this;
|
|
103
102
|
|
|
104
|
-
|
|
105
|
-
self.requestUpdate(entityId);
|
|
106
|
-
}
|
|
103
|
+
const update = () => this.requestUpdate(entityId);
|
|
107
104
|
|
|
108
|
-
|
|
105
|
+
this.data[entityId] = {
|
|
109
106
|
update,
|
|
110
107
|
transform,
|
|
111
108
|
component: cling
|
|
@@ -139,21 +136,6 @@ class ClingToTerrainSystem extends System {
|
|
|
139
136
|
this.updateQueue.remove(entityId);
|
|
140
137
|
}
|
|
141
138
|
|
|
142
|
-
reset() {
|
|
143
|
-
this.updateQueue.clear();
|
|
144
|
-
|
|
145
|
-
const data = this.data;
|
|
146
|
-
for (let entity in data) {
|
|
147
|
-
if (!data.hasOwnProperty(entity)) {
|
|
148
|
-
continue;
|
|
149
|
-
}
|
|
150
|
-
const datum = data[entity];
|
|
151
|
-
deregister(datum);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
this.data = [];
|
|
155
|
-
}
|
|
156
|
-
|
|
157
139
|
update(timeDelta) {
|
|
158
140
|
const em = this.entityManager;
|
|
159
141
|
|
|
@@ -192,7 +174,7 @@ class ClingToTerrainSystem extends System {
|
|
|
192
174
|
the entity is gone
|
|
193
175
|
*/
|
|
194
176
|
|
|
195
|
-
console.warn("ClingToTerrain component was in the update queue, but no data found. Skipping");
|
|
177
|
+
//console.warn("ClingToTerrain component was in the update queue, but no data found. Skipping");
|
|
196
178
|
continue;
|
|
197
179
|
}
|
|
198
180
|
|
|
@@ -20,7 +20,7 @@ export class SplatMapping {
|
|
|
20
20
|
* How large is the map
|
|
21
21
|
* @type {Vector2}
|
|
22
22
|
*/
|
|
23
|
-
this.size = new Vector2(
|
|
23
|
+
this.size = new Vector2(1, 1);
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
*
|
|
@@ -475,8 +475,9 @@ export class SplatMapping {
|
|
|
475
475
|
* @param {number} width
|
|
476
476
|
* @param {number} height
|
|
477
477
|
* @param {number} depth
|
|
478
|
+
* @param {boolean} [keep_data]
|
|
478
479
|
*/
|
|
479
|
-
resize(width, height, depth) {
|
|
480
|
+
resize(width, height, depth, keep_data = true) {
|
|
480
481
|
const oldWidth = this.size.x;
|
|
481
482
|
const oldHeight = this.size.y;
|
|
482
483
|
const oldDepth = this.depth;
|
|
@@ -506,19 +507,23 @@ export class SplatMapping {
|
|
|
506
507
|
weightImage.depth = depth;
|
|
507
508
|
weightImage.data = new Uint8Array(newLayerSize * depth);
|
|
508
509
|
|
|
509
|
-
if (
|
|
510
|
-
// dimensions haven't changed, we can copy data directly
|
|
511
|
-
typed_array_copy(oldWeightData, weightImage.data);
|
|
512
|
-
} else {
|
|
510
|
+
if (keep_data) {
|
|
513
511
|
|
|
514
|
-
|
|
515
|
-
|
|
512
|
+
if (oldWidth === width && oldHeight === height) {
|
|
513
|
+
// dimensions haven't changed, we can copy data directly
|
|
514
|
+
typed_array_copy(oldWeightData, weightImage.data);
|
|
515
|
+
} else {
|
|
516
516
|
|
|
517
|
-
|
|
518
|
-
|
|
517
|
+
// different dimensions, copy layer-by-layer
|
|
518
|
+
for (let d = 0; d < min2(depth, oldDepth); d++) {
|
|
519
519
|
|
|
520
|
-
|
|
520
|
+
const source = new Sampler2D(oldWeightData.subarray(d * oldLayerSize, (d + 1) * oldLayerSize), 1, oldWidth, oldHeight);
|
|
521
|
+
const target = new Sampler2D(weightImage.data.subarray(d * newLayerSize, (d + 1) * newLayerSize), 1, width, height);
|
|
522
|
+
|
|
523
|
+
scaleSampler2D(source, target);
|
|
524
|
+
}
|
|
521
525
|
}
|
|
526
|
+
|
|
522
527
|
}
|
|
523
528
|
|
|
524
529
|
weightTexture.needsUpdate = true;
|
|
@@ -164,7 +164,7 @@ export class TerrainSerializationAdapter extends BinaryClassSerializationAdapter
|
|
|
164
164
|
const splat_size_x = buffer.readUintVar();
|
|
165
165
|
const splat_size_y = buffer.readUintVar();
|
|
166
166
|
|
|
167
|
-
value.splat.resize(splat_size_x, splat_size_y, layer_count);
|
|
167
|
+
value.splat.resize(splat_size_x, splat_size_y, layer_count, false);
|
|
168
168
|
|
|
169
169
|
const weightData = value.splat.weightData;
|
|
170
170
|
|
|
@@ -4,25 +4,28 @@ import { Asset } from "../../../../../../../asset/Asset.js";
|
|
|
4
4
|
import { readAnimationGraphDefinitionFromJSON } from "./readAnimationGraphDefinitionFromJSON.js";
|
|
5
5
|
|
|
6
6
|
export class AnimationGraphDefinitionAssetLoader extends AssetLoader {
|
|
7
|
-
load(path, success, failure, progress) {
|
|
7
|
+
load(scope, path, success, failure, progress) {
|
|
8
8
|
|
|
9
9
|
this.assetManager.get(
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
{
|
|
11
|
+
scope: scope,
|
|
12
|
+
path: path,
|
|
13
|
+
type: GameAssetType.JSON,
|
|
14
|
+
callback: jsonAsset => {
|
|
15
|
+
const json = jsonAsset.create();
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
const asset = new Asset(
|
|
18
|
+
() => {
|
|
19
|
+
return readAnimationGraphDefinitionFromJSON(json);
|
|
20
|
+
},
|
|
21
|
+
1
|
|
22
|
+
);
|
|
21
23
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
success(asset);
|
|
25
|
+
},
|
|
26
|
+
failure: failure,
|
|
27
|
+
progress: progress
|
|
28
|
+
}
|
|
26
29
|
);
|
|
27
30
|
|
|
28
31
|
}
|
|
@@ -80,6 +80,8 @@ export class PerfectPanner {
|
|
|
80
80
|
|
|
81
81
|
const ray = make_ray_from_viewport_position(engine, new Vector2(viewport_x, viewport_y));
|
|
82
82
|
|
|
83
|
+
// console.log(`Ray origin:${ray.origin}, direction:${ray.direction}`);
|
|
84
|
+
|
|
83
85
|
this.#camera.rayPlaneIntersection(
|
|
84
86
|
out,
|
|
85
87
|
ray.origin.x, ray.origin.y, ray.origin.z,
|
|
@@ -93,7 +95,7 @@ export class PerfectPanner {
|
|
|
93
95
|
* @param {Vector2} screen_position
|
|
94
96
|
*/
|
|
95
97
|
update(screen_position) {
|
|
96
|
-
//console.log(`PerfectPanner/update: ${screen_position}`)
|
|
98
|
+
// console.log(`PerfectPanner/update: ${screen_position}`)
|
|
97
99
|
|
|
98
100
|
const C = this.#grab_world_reference;
|
|
99
101
|
const A = this.#grab_eye_position;
|
|
@@ -121,7 +123,7 @@ export class PerfectPanner {
|
|
|
121
123
|
}
|
|
122
124
|
|
|
123
125
|
start(screen_position) {
|
|
124
|
-
//console.log(`PerfectPanner/start: ${screen_position}`)
|
|
126
|
+
// console.log(`PerfectPanner/start: ${screen_position}`)
|
|
125
127
|
|
|
126
128
|
// obtain reference point
|
|
127
129
|
|
|
@@ -427,7 +427,7 @@ export class MeshSystem extends System {
|
|
|
427
427
|
|
|
428
428
|
} else {
|
|
429
429
|
// load the asset
|
|
430
|
-
am.get(component.url, assetType, assetLoaded, assetFailure);
|
|
430
|
+
am.get({ path: component.url, type: assetType, callback: assetLoaded, failure: assetFailure });
|
|
431
431
|
}
|
|
432
432
|
}
|
|
433
433
|
|
|
@@ -67,11 +67,13 @@ function make_material(style, am) {
|
|
|
67
67
|
|
|
68
68
|
material_def = new MeshMatcapMaterial();
|
|
69
69
|
|
|
70
|
-
am.get(
|
|
71
|
-
|
|
70
|
+
am.get({
|
|
71
|
+
path: style.material.texture, type: GameAssetType.Texture, callback: asset => {
|
|
72
|
+
material_def.matcap = asset.create();
|
|
72
73
|
|
|
73
|
-
|
|
74
|
-
|
|
74
|
+
material_def.needsUpdate = true;
|
|
75
|
+
}, failure: console.error
|
|
76
|
+
});
|
|
75
77
|
|
|
76
78
|
} else {
|
|
77
79
|
throw new Error(`Unsupported material type '${material_type}'`);
|
|
@@ -11,9 +11,11 @@ export function getTextureImmediate(url, assetManager) {
|
|
|
11
11
|
|
|
12
12
|
let t;
|
|
13
13
|
|
|
14
|
-
assetManager.get(
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
assetManager.get({
|
|
15
|
+
path: url, type: GameAssetType.DeferredTexture, callback: function (asset) {
|
|
16
|
+
t = asset.create();
|
|
17
|
+
}, failure: noop
|
|
18
|
+
});
|
|
17
19
|
|
|
18
20
|
return t;
|
|
19
21
|
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { clamp } from "../../../../core/math/clamp.js";
|
|
2
|
+
import { lerp } from "../../../../core/math/lerp.js";
|
|
3
|
+
|
|
4
|
+
export class SingleChannelSampler3D {
|
|
5
|
+
|
|
6
|
+
data = new Float32Array(0)
|
|
7
|
+
#resolution = [0, 0, 0]
|
|
8
|
+
|
|
9
|
+
set resolution(v) {
|
|
10
|
+
const width = v[0];
|
|
11
|
+
const height = v[1];
|
|
12
|
+
const depth = v[2];
|
|
13
|
+
|
|
14
|
+
const old_width = this.#resolution[0];
|
|
15
|
+
const old_height = this.#resolution[1];
|
|
16
|
+
const old_depth = this.#resolution[2];
|
|
17
|
+
|
|
18
|
+
if (old_width === width && old_height === height && old_depth === depth) {
|
|
19
|
+
// no change
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
this.#resolution[0] = width;
|
|
24
|
+
this.#resolution[1] = height;
|
|
25
|
+
this.#resolution[2] = depth
|
|
26
|
+
|
|
27
|
+
const new_data_size = width * height * depth;
|
|
28
|
+
|
|
29
|
+
if (new_data_size !== old_width * old_height * old_depth) {
|
|
30
|
+
|
|
31
|
+
this.data = new Float32Array(new_data_size);
|
|
32
|
+
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
get resolution() {
|
|
37
|
+
return this.#resolution;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
*
|
|
42
|
+
* @param {number} x
|
|
43
|
+
* @param {number} y
|
|
44
|
+
* @param {number} z
|
|
45
|
+
* @param {number} value
|
|
46
|
+
*/
|
|
47
|
+
write(x, y, z, value) {
|
|
48
|
+
const resolution = this.#resolution;
|
|
49
|
+
|
|
50
|
+
const res_x = resolution[0];
|
|
51
|
+
const res_y = resolution[1];
|
|
52
|
+
|
|
53
|
+
this.data[z * res_y * res_x + y * res_x + x] = value;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
*
|
|
58
|
+
* @param {number} x
|
|
59
|
+
* @param {number} y
|
|
60
|
+
* @param {number} z
|
|
61
|
+
* @returns {number}
|
|
62
|
+
*/
|
|
63
|
+
sample_channel_linear(x, y, z) {
|
|
64
|
+
const resolution = this.#resolution;
|
|
65
|
+
|
|
66
|
+
const res_x = resolution[0];
|
|
67
|
+
const res_y = resolution[1];
|
|
68
|
+
const res_z = resolution[2];
|
|
69
|
+
|
|
70
|
+
const x_max = res_x - 1;
|
|
71
|
+
const y_max = res_y - 1;
|
|
72
|
+
const z_max = res_z - 1;
|
|
73
|
+
|
|
74
|
+
const x_clamped = clamp(x, 0, x_max);
|
|
75
|
+
const y_clamped = clamp(y, 0, y_max);
|
|
76
|
+
const z_clamped = clamp(z, 0, z_max);
|
|
77
|
+
|
|
78
|
+
const x0 = x_clamped | 0;
|
|
79
|
+
const y0 = y_clamped | 0;
|
|
80
|
+
const z0 = z_clamped | 0;
|
|
81
|
+
|
|
82
|
+
const f_x = x_clamped - x0;
|
|
83
|
+
const f_y = y_clamped - y0;
|
|
84
|
+
const f_z = z_clamped - z0;
|
|
85
|
+
|
|
86
|
+
const x1 = x_clamped === x0 ? x0 : x0 + 1;
|
|
87
|
+
const y1 = y_clamped === y0 ? y0 : y0 + 1;
|
|
88
|
+
const z1 = z_clamped === z0 ? z0 : z0 + 1;
|
|
89
|
+
|
|
90
|
+
// get 8 points
|
|
91
|
+
const data = this.data;
|
|
92
|
+
|
|
93
|
+
const z0_offset = z0 * (res_x * res_y);
|
|
94
|
+
|
|
95
|
+
const y0_offset = y0 * res_x;
|
|
96
|
+
|
|
97
|
+
const x0_offset = x0;
|
|
98
|
+
const x1_offset = x1;
|
|
99
|
+
|
|
100
|
+
const x0y0z0 = data[z0_offset + y0_offset + x0_offset];
|
|
101
|
+
const x1y0z0 = data[z0_offset + y0_offset + x1_offset];
|
|
102
|
+
|
|
103
|
+
const y1_offset = y1 * res_x;
|
|
104
|
+
|
|
105
|
+
const x0y1z0 = data[z0_offset + y1_offset + x0_offset];
|
|
106
|
+
const x1y1z0 = data[z0_offset + y1_offset + x1_offset];
|
|
107
|
+
|
|
108
|
+
const z1_offset = z1 * (res_x * res_y);
|
|
109
|
+
|
|
110
|
+
const x0y0z1 = data[z1_offset + y0_offset + x0_offset];
|
|
111
|
+
const x1y0z1 = data[z1_offset + y0_offset + x1_offset];
|
|
112
|
+
|
|
113
|
+
const x0y1z1 = data[z1_offset + y1_offset + x0_offset];
|
|
114
|
+
const x1y1z1 = data[z1_offset + y1_offset + x1_offset];
|
|
115
|
+
|
|
116
|
+
// filter on z0
|
|
117
|
+
const lerp_z0_y0 = lerp(x0y0z0, x1y0z0, f_x);
|
|
118
|
+
const lerp_z0_y1 = lerp(x0y1z0, x1y1z0, f_x);
|
|
119
|
+
const lerp_z0 = lerp(lerp_z0_y0, lerp_z0_y1, f_y);
|
|
120
|
+
|
|
121
|
+
// filter on z1
|
|
122
|
+
const lerp_z1_y0 = lerp(x0y0z1, x1y0z1, f_x);
|
|
123
|
+
const lerp_z1_y1 = lerp(x0y1z1, x1y1z1, f_x);
|
|
124
|
+
const lerp_z1 = lerp(lerp_z1_y0, lerp_z1_y1, f_y);
|
|
125
|
+
|
|
126
|
+
return lerp(lerp_z0, lerp_z1, f_z);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
*
|
|
131
|
+
* @param {SingleChannelSampler3D} other
|
|
132
|
+
*/
|
|
133
|
+
copy(other) {
|
|
134
|
+
this.resolution = other.#resolution;
|
|
135
|
+
|
|
136
|
+
this.data.set(other.data);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
clone() {
|
|
140
|
+
const r = new SingleChannelSampler3D();
|
|
141
|
+
|
|
142
|
+
r.copy(this);
|
|
143
|
+
|
|
144
|
+
return r;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { array_copy } from "../../../../core/collection/array/copyArray.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {SingleChannelSampler3D} source
|
|
6
|
+
* @param {Sampler2D} output
|
|
7
|
+
* @param {number} z_index
|
|
8
|
+
*/
|
|
9
|
+
export function scs3d_read_2d_slice(source, output, z_index) {
|
|
10
|
+
const source_resolution = source.resolution;
|
|
11
|
+
|
|
12
|
+
const source_width = source_resolution[0];
|
|
13
|
+
const source_height = source_resolution[1];
|
|
14
|
+
|
|
15
|
+
if (source_width !== output.width || source_height !== output.height) {
|
|
16
|
+
throw new Error('Incompatible resolutions');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (output.itemSize !== 1) {
|
|
20
|
+
throw new Error(`Expected output to have 1 channel, instead got ${output.itemSize}`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const slice_size = source_width * source_height;
|
|
24
|
+
|
|
25
|
+
array_copy(source.data, slice_size * z_index, output.data, 0, slice_size);
|
|
26
|
+
}
|
|
@@ -192,8 +192,8 @@ export class Sampler2D {
|
|
|
192
192
|
* @returns {number}
|
|
193
193
|
*/
|
|
194
194
|
sampleChannelCatmullRomUV(u, v, channel) {
|
|
195
|
-
const x = u * (this.width -
|
|
196
|
-
const y = v * (this.height -
|
|
195
|
+
const x = u * (this.width) - 0.5;
|
|
196
|
+
const y = v * (this.height) - 0.5;
|
|
197
197
|
|
|
198
198
|
return this.sampleChannelCatmullRom(x, y, channel);
|
|
199
199
|
}
|
|
@@ -210,8 +210,8 @@ export class Sampler2D {
|
|
|
210
210
|
// We're going to sample a 4x4 grid of texels surrounding the target UV coordinate. We'll do this by rounding
|
|
211
211
|
// down the sample location to get the exact center of our "starting" texel. The starting texel will be at
|
|
212
212
|
// location [1, 1] in the grid, where [0, 0] is the top-left corner.
|
|
213
|
-
const texPos1_x = Math.floor(x
|
|
214
|
-
const texPos1_y = Math.floor(y
|
|
213
|
+
const texPos1_x = Math.floor(x);
|
|
214
|
+
const texPos1_y = Math.floor(y);
|
|
215
215
|
|
|
216
216
|
// Compute the fractional offset from our starting texel to our original sample location, which we'll
|
|
217
217
|
// feed into the Catmull-Rom spline function to get our filter weights.
|
|
@@ -287,8 +287,8 @@ export class Sampler2D {
|
|
|
287
287
|
* @returns {number}
|
|
288
288
|
*/
|
|
289
289
|
sampleChannelBicubicUV(u, v, channel) {
|
|
290
|
-
const x = u * (this.width
|
|
291
|
-
const y = v * (this.height
|
|
290
|
+
const x = u * (this.width);
|
|
291
|
+
const y = v * (this.height);
|
|
292
292
|
|
|
293
293
|
return this.sampleChannelBicubic(x - 0.5, y - 0.5, channel);
|
|
294
294
|
}
|
|
@@ -432,8 +432,8 @@ export class Sampler2D {
|
|
|
432
432
|
* @return {number}
|
|
433
433
|
*/
|
|
434
434
|
sampleChannelBilinearUV(u, v, channel) {
|
|
435
|
-
const x = u *
|
|
436
|
-
const y = v *
|
|
435
|
+
const x = u * this.width - 0.5;
|
|
436
|
+
const y = v * this.height - 0.5;
|
|
437
437
|
|
|
438
438
|
return this.sampleChannelBilinear(x, y, channel);
|
|
439
439
|
}
|
|
@@ -474,14 +474,14 @@ export class Sampler2D {
|
|
|
474
474
|
//
|
|
475
475
|
let x1, y1;
|
|
476
476
|
|
|
477
|
-
if (clamped_x === x0
|
|
477
|
+
if (clamped_x === x0) {
|
|
478
478
|
x1 = x0;
|
|
479
479
|
} else {
|
|
480
480
|
x1 = x0 + 1;
|
|
481
481
|
}
|
|
482
482
|
|
|
483
483
|
|
|
484
|
-
if (clamped_y === y0
|
|
484
|
+
if (clamped_y === y0) {
|
|
485
485
|
y1 = y0;
|
|
486
486
|
} else {
|
|
487
487
|
y1 = y0 + 1;
|
|
@@ -519,11 +519,20 @@ export class Sampler2D {
|
|
|
519
519
|
return mix(s0, s1, yd);
|
|
520
520
|
}
|
|
521
521
|
|
|
522
|
+
/**
|
|
523
|
+
*
|
|
524
|
+
* @param {number} u
|
|
525
|
+
* @param {number} v
|
|
526
|
+
* @param {ArrayLike<number>} result
|
|
527
|
+
*/
|
|
522
528
|
sampleNearestUV(u, v, result) {
|
|
523
|
-
const
|
|
524
|
-
const
|
|
529
|
+
const w = this.width;
|
|
530
|
+
const h = this.height;
|
|
531
|
+
|
|
532
|
+
const x = Math.round(u * w - 0.5);
|
|
533
|
+
const y = Math.round(v * h - 0.5);
|
|
525
534
|
|
|
526
|
-
this.read(
|
|
535
|
+
this.read(clamp(x, 0, w - 1), clamp(y, 0, h - 1), result);
|
|
527
536
|
}
|
|
528
537
|
|
|
529
538
|
/**
|
|
@@ -3,6 +3,7 @@ import { clamp } from "../../../../../core/math/clamp.js";
|
|
|
3
3
|
|
|
4
4
|
const PI3 = 3.0 * Math.PI;
|
|
5
5
|
const BESSEL_3_PI_3 = bessel_3(PI3);
|
|
6
|
+
const INV_BESSEL_3_PI_3 = 1 / BESSEL_3_PI_3;
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
*
|
|
@@ -13,7 +14,7 @@ const BESSEL_3_PI_3 = bessel_3(PI3);
|
|
|
13
14
|
export function kaiser_bessel_window(x) {
|
|
14
15
|
const i = clamp(x * 0.6666666666666666, -1.0, 1.0);
|
|
15
16
|
const t = Math.sqrt(1.0 - i * i);
|
|
16
|
-
return bessel_3(PI3 * t)
|
|
17
|
+
return bessel_3(PI3 * t) * INV_BESSEL_3_PI_3;
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
kaiser_bessel_window.support = 2;
|
|
@@ -18,6 +18,7 @@ export function genericResampleSampler2D(source, target) {
|
|
|
18
18
|
const kernel_height = max2(1, Math.ceil(v_scale));
|
|
19
19
|
|
|
20
20
|
const kernel_size = kernel_width * kernel_height;
|
|
21
|
+
const kernel_size_inv = 1 / kernel_size;
|
|
21
22
|
|
|
22
23
|
const itemSize = source.itemSize;
|
|
23
24
|
|
|
@@ -30,16 +31,15 @@ export function genericResampleSampler2D(source, target) {
|
|
|
30
31
|
let i;
|
|
31
32
|
|
|
32
33
|
for (column_index = 0; column_index < target_height; column_index++) {
|
|
34
|
+
|
|
35
|
+
const source_y = column_index * v_scale;
|
|
36
|
+
|
|
33
37
|
for (row_index = 0; row_index < target_width; row_index++) {
|
|
34
38
|
|
|
35
39
|
// figure out source offset
|
|
36
40
|
const source_x = row_index * u_scale;
|
|
37
|
-
const source_y = column_index * v_scale;
|
|
38
41
|
|
|
39
|
-
|
|
40
|
-
for (i = 0; i < itemSize; i++) {
|
|
41
|
-
sample[i] = 0;
|
|
42
|
-
}
|
|
42
|
+
const output_texel_address = (column_index * target_width + row_index) * itemSize;
|
|
43
43
|
|
|
44
44
|
// accumulate kernel samples
|
|
45
45
|
for (k_y = 0; k_y < kernel_height; k_y++) {
|
|
@@ -55,9 +55,10 @@ export function genericResampleSampler2D(source, target) {
|
|
|
55
55
|
|
|
56
56
|
for (i = 0; i < itemSize; i++) {
|
|
57
57
|
// dilute sample
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
target.data[output_texel_address + i] = sample[i] * kernel_size_inv;
|
|
59
|
+
|
|
60
|
+
//reset sample
|
|
61
|
+
sample[i] = 0;
|
|
61
62
|
}
|
|
62
63
|
|
|
63
64
|
}
|
|
@@ -13,24 +13,26 @@ import { GameAssetType } from "../../../asset/GameAssetType.js";
|
|
|
13
13
|
*/
|
|
14
14
|
export default function loadSampler2D(url, assetManager) {
|
|
15
15
|
return new Promise(function (resolve, reject) {
|
|
16
|
-
assetManager.get(
|
|
17
|
-
|
|
16
|
+
assetManager.get({
|
|
17
|
+
path: url, type: GameAssetType.Image, callback: (asset) => {
|
|
18
|
+
const imageData = asset.create();
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
const width = imageData.width;
|
|
21
|
+
const height = imageData.height;
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
const data = imageData.data;
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
25
|
+
//
|
|
26
|
+
const bufferSize = width * height;
|
|
27
|
+
const buffer = new Float32Array(bufferSize);
|
|
28
|
+
//
|
|
29
|
+
for (let i = 0; i < bufferSize; i++) {
|
|
30
|
+
const j = (i * 4);
|
|
31
|
+
buffer[i] = (data[j] + data[j + 1] + data[j + 2]) / 765;
|
|
32
|
+
}
|
|
33
|
+
const sampler2D = new Sampler2D(buffer, 1, width, height);
|
|
34
|
+
resolve(sampler2D);
|
|
35
|
+
}, failure: reject
|
|
36
|
+
});
|
|
35
37
|
});
|
|
36
38
|
};
|
|
@@ -29,13 +29,13 @@ export function sampler2d_scale_down_linear(input, output) {
|
|
|
29
29
|
|
|
30
30
|
const itemSize = input.itemSize;
|
|
31
31
|
|
|
32
|
-
const sample = new
|
|
32
|
+
const sample = new Float64Array(itemSize);
|
|
33
33
|
|
|
34
34
|
const sampleSize = sW * sH;
|
|
35
35
|
const sampleSizeInv = 1 / sampleSize;
|
|
36
36
|
|
|
37
|
-
const
|
|
38
|
-
const
|
|
37
|
+
const input_data = input.data;
|
|
38
|
+
const output_data = output.data;
|
|
39
39
|
|
|
40
40
|
let i, j, k;
|
|
41
41
|
let x, y;
|
|
@@ -50,11 +50,6 @@ export function sampler2d_scale_down_linear(input, output) {
|
|
|
50
50
|
|
|
51
51
|
const output_texel_address = row_address + x * itemSize;
|
|
52
52
|
|
|
53
|
-
for (i = 0; i < itemSize; i++) {
|
|
54
|
-
// reset sample
|
|
55
|
-
sample[i] = 0;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
53
|
const sampleOffsetX = x * sW;
|
|
59
54
|
|
|
60
55
|
// accumulate sample
|
|
@@ -67,15 +62,17 @@ export function sampler2d_scale_down_linear(input, output) {
|
|
|
67
62
|
const iAddress = (texel_offset + i) * itemSize;
|
|
68
63
|
|
|
69
64
|
for (k = 0; k < itemSize; k++) {
|
|
70
|
-
sample[k] +=
|
|
65
|
+
sample[k] += input_data[k + iAddress];
|
|
71
66
|
}
|
|
72
67
|
|
|
73
68
|
}
|
|
74
69
|
}
|
|
75
70
|
|
|
76
|
-
// dilute the sample
|
|
77
71
|
for (i = 0; i < itemSize; i++) {
|
|
78
|
-
|
|
72
|
+
// dilute the sample
|
|
73
|
+
output_data[output_texel_address + i] = sample[i] * sampleSizeInv;
|
|
74
|
+
//reset sample
|
|
75
|
+
sample[i] = 0;
|
|
79
76
|
}
|
|
80
77
|
|
|
81
78
|
|