@woosh/meep-engine 2.33.25 → 2.33.29
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/binary/BitSet.js +151 -167
- package/core/binary/BitSet.spec.js +99 -1
- package/core/binary/ValidatingBitSetWrapper.js +81 -0
- package/core/bvh2/aabb3/AABB3.js +3 -10
- package/core/cache/Cache.d.ts +4 -2
- package/core/cache/Cache.js +5 -2
- package/core/collection/HashMap.d.ts +9 -2
- package/core/collection/HashSet.d.ts +7 -2
- package/core/collection/HashSet.js +7 -2
- package/core/collection/array/typed/typed_array_copy.js +1 -1
- package/core/geom/3d/frustum/array_setFromProjectionMatrix.js +3 -3
- package/core/geom/3d/shape/AbstractShape3D.js +28 -1
- package/core/geom/3d/shape/TransformedShape3D.js +65 -10
- package/core/geom/3d/shape/TransformedShape3D.spec.js +33 -0
- package/core/geom/3d/shape/{CompositeShape.js → UnionShape3D.js} +27 -12
- package/core/geom/3d/shape/UnitCubeShape3D.js +77 -0
- package/core/geom/3d/shape/UnitCubeShape3D.spec.js +42 -0
- package/core/geom/3d/shape/UnitSphereShape3D.js +32 -1
- package/core/geom/3d/shape/util/compute_signed_distance_gradient_by_sampling.js +48 -0
- package/core/geom/3d/shape/util/shape_to_visual_entity.js +3 -3
- package/core/model/ObservedBoolean.d.ts +2 -0
- package/core/parser/simple/Token.d.ts +13 -0
- package/core/parser/simple/Token.js +61 -27
- package/editor/tools/FoliagePaintTool.js +4 -4
- package/engine/asset/loaders/GLTFAssetLoader.js +52 -1
- package/engine/asset/loaders/image/ImageDecoderWorker.js +4 -3
- package/engine/asset/loaders/image/ImageRGBADataAsset.js +3 -2
- package/engine/asset/loaders/image/ImageRGBADataLoader.js +3 -3
- package/engine/asset/loaders/image/codec/NativeImageDecoder.js +2 -1
- package/engine/asset/loaders/image/png/PNG.js +113 -6
- package/engine/asset/loaders/image/png/PNGReader.js +5 -0
- package/engine/asset/loaders/material/bitmap2sampler_gl.js +1 -1
- package/engine/asset/loaders/material/computeImageBitmapEquality.js +6 -1
- package/engine/asset/loaders/material/computeTextureEquality.js +40 -49
- package/engine/ecs/EntityComponentDataset.js +1 -1
- package/engine/ecs/foliage/InstancedFoliage.js +277 -266
- package/engine/ecs/foliage/ecs/Foliage2System.js +7 -7
- package/engine/ecs/foliage/ecs/InstancedMeshComponent.js +37 -0
- package/engine/ecs/foliage/ecs/{Foliage2.js → InstancedMeshLayer.js} +3 -45
- package/engine/ecs/foliage/ecs/InstancedMeshSerializationAdapter.js +6 -5
- package/engine/ecs/foliage/ecs/InstancedMeshUtils.js +7 -6
- package/engine/ecs/storage/binary/BinarySerializationRegistry.js +1 -1
- package/engine/ecs/terrain/ecs/layers/TerrainLayer.js +12 -16
- package/engine/graphics/ecs/highlight/plugin/OutlineRenderPlugin.js +2 -2
- package/engine/graphics/geometry/instancing/InstancedMeshGroup.js +14 -72
- package/engine/graphics/geometry/instancing/rewriteMaterial.js +70 -0
- package/engine/graphics/material/manager/MaterialManager.js +2 -1
- package/engine/graphics/micron/render/instanced/AttributeDataTexture.js +6 -4
- package/engine/graphics/micron/render/instanced/ThreeInstancedAdapter.js +0 -2
- package/engine/graphics/particles/particular/engine/shader/ShaderManager.js +1 -2
- package/engine/graphics/particles/particular/engine/shader/debugAtlas.js +1 -1
- package/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +12 -9
- package/engine/graphics/render/buffer/simple-fx/ao/AmbientOcclusionPostProcessEffect.js +3 -4
- package/engine/graphics/render/forward_plus/materials/FPlusDebugMaterial.js +3 -3
- package/engine/graphics/render/forward_plus/materials/ForwardPlusThreeMaterial.js +1 -1
- package/engine/graphics/render/forward_plus/prototypeLightManager.js +4 -4
- package/engine/graphics/render/forward_plus/query/point_light_inside_volume.js +10 -9
- package/engine/graphics/shadows/ShadowMapRenderer.js +8 -2
- package/engine/graphics/texture/atlas/ManagedTextureAtlas.js +12 -1
- package/engine/graphics/texture/sampler/Sampler2D.js +3 -1
- package/engine/graphics/texture/sampler/convertTexture2Sampler2D.js +1 -1
- package/engine/graphics/texture/sampler/copy_Sampler2D_channel_data.js +66 -0
- package/engine/input/devices/KeyCodes.d.ts +1 -0
- package/package.json +1 -1
- package/view/minimap/gl/MinimapWorldGL.js +12 -5
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const scratch_v = [];
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {number[]} result
|
|
6
|
+
* @param {AbstractShape3D} shape
|
|
7
|
+
* @param {number[]} point
|
|
8
|
+
* @returns {number}
|
|
9
|
+
*/
|
|
10
|
+
export function compute_signed_distance_gradient_by_sampling(result, shape, point) {
|
|
11
|
+
const v0 = shape.signed_distance_at_point(point);
|
|
12
|
+
|
|
13
|
+
scratch_v[0] = point[0] + 1e-5;
|
|
14
|
+
scratch_v[1] = point[1];
|
|
15
|
+
scratch_v[2] = point[2];
|
|
16
|
+
|
|
17
|
+
const vx = shape.signed_distance_at_point(scratch_v);
|
|
18
|
+
|
|
19
|
+
scratch_v[0] = point[0];
|
|
20
|
+
scratch_v[1] = point[1] + 1e-5;
|
|
21
|
+
scratch_v[2] = point[2];
|
|
22
|
+
|
|
23
|
+
const vy = shape.signed_distance_at_point(point);
|
|
24
|
+
|
|
25
|
+
scratch_v[0] = point[0];
|
|
26
|
+
scratch_v[1] = point[1];
|
|
27
|
+
scratch_v[2] = point[2] + 1e-5;
|
|
28
|
+
|
|
29
|
+
const vz = shape.signed_distance_at_point(point);
|
|
30
|
+
|
|
31
|
+
// convert absolute sample values to relative
|
|
32
|
+
const rx = vx - v0;
|
|
33
|
+
const ry = vy - v0;
|
|
34
|
+
const rz = vz - v0;
|
|
35
|
+
|
|
36
|
+
// normalize by sampling distance
|
|
37
|
+
const d = 1e-5 / 1.73205080757;
|
|
38
|
+
|
|
39
|
+
const nx = rx * d;
|
|
40
|
+
const ny = ry * d;
|
|
41
|
+
const nz = rz * d;
|
|
42
|
+
|
|
43
|
+
result[0] = nx;
|
|
44
|
+
result[1] = ny;
|
|
45
|
+
result[2] = nz;
|
|
46
|
+
|
|
47
|
+
return v0;
|
|
48
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { UnionShape3D } from "../UnionShape3D.js";
|
|
2
2
|
import { UnitCubeShape3D } from "../UnitCubeShape3D.js";
|
|
3
3
|
import { UnitSphereShape3D } from "../UnitSphereShape3D.js";
|
|
4
4
|
import { TransformedShape3D } from "../TransformedShape3D.js";
|
|
@@ -30,7 +30,7 @@ export const SHAPE_VISUAL_ENTITY_TAG = 'util/vis/Shape3D';
|
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
32
|
*
|
|
33
|
-
* @param {
|
|
33
|
+
* @param {UnionShape3D} shape
|
|
34
34
|
* @param {EntityComponentDataset} ecd
|
|
35
35
|
* @returns {EntityBuilder}
|
|
36
36
|
*/
|
|
@@ -145,7 +145,7 @@ function transformed_shape_to_entity(shape, ecd) {
|
|
|
145
145
|
* @returns {EntityBuilder}
|
|
146
146
|
*/
|
|
147
147
|
export function shape_to_visual_entity(shape, ecd) {
|
|
148
|
-
if (shape instanceof
|
|
148
|
+
if (shape instanceof UnionShape3D) {
|
|
149
149
|
return composite_shape_to_entity(shape, ecd);
|
|
150
150
|
} else if (shape instanceof UnitCubeShape3D) {
|
|
151
151
|
return cube_shape_to_entity(shape, ecd);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export class Token<V = string, T = string> {
|
|
2
|
+
readonly value: V
|
|
3
|
+
readonly start: number
|
|
4
|
+
readonly end: number
|
|
5
|
+
readonly name: string
|
|
6
|
+
readonly type: T
|
|
7
|
+
|
|
8
|
+
constructor(value: V, start: number, end: number, name: string, type: T)
|
|
9
|
+
|
|
10
|
+
equals(other: Token<V, T>): boolean
|
|
11
|
+
|
|
12
|
+
hash(): number
|
|
13
|
+
}
|
|
@@ -1,31 +1,65 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
1
|
+
class Token {
|
|
2
|
+
/**
|
|
3
|
+
* @template V,T
|
|
4
|
+
* @param {V} value
|
|
5
|
+
* @param {number} start
|
|
6
|
+
* @param {number} end
|
|
7
|
+
* @param {string} name
|
|
8
|
+
* @param {T} type
|
|
9
|
+
*/
|
|
10
|
+
constructor(value, start, end, name, type) {
|
|
11
|
+
/**
|
|
12
|
+
* @readonly
|
|
13
|
+
* @type {V}
|
|
14
|
+
*/
|
|
15
|
+
this.value = value;
|
|
16
|
+
/**
|
|
17
|
+
* Starting position in the input
|
|
18
|
+
* @readonly
|
|
19
|
+
* @type {number}
|
|
20
|
+
*/
|
|
21
|
+
this.start = start;
|
|
22
|
+
/**
|
|
23
|
+
* End position in the input
|
|
24
|
+
* @readonly
|
|
25
|
+
* @type {number}
|
|
26
|
+
*/
|
|
27
|
+
this.end = end;
|
|
28
|
+
/**
|
|
29
|
+
* @readonly
|
|
30
|
+
* @type {string}
|
|
31
|
+
*/
|
|
32
|
+
this.name = name;
|
|
33
|
+
/**
|
|
34
|
+
* Token type
|
|
35
|
+
* @readonly
|
|
36
|
+
* @type {T}
|
|
37
|
+
*/
|
|
38
|
+
this.type = type;
|
|
39
|
+
}
|
|
8
40
|
|
|
9
|
-
/**
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
41
|
+
/**
|
|
42
|
+
*
|
|
43
|
+
* @param {Token} other
|
|
44
|
+
* @returns {boolean}
|
|
45
|
+
*/
|
|
46
|
+
equals(other) {
|
|
47
|
+
return this.value === other.value &&
|
|
48
|
+
this.start === other.start &&
|
|
49
|
+
this.end === other.end &&
|
|
50
|
+
this.name === other.name &&
|
|
51
|
+
this.type === other.type
|
|
52
|
+
;
|
|
53
|
+
}
|
|
22
54
|
|
|
23
|
-
/**
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
55
|
+
/**
|
|
56
|
+
*
|
|
57
|
+
* @return {number}
|
|
58
|
+
*/
|
|
59
|
+
hash() {
|
|
60
|
+
// TODO make an actual hash
|
|
61
|
+
return 0;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
30
64
|
|
|
31
65
|
export default Token;
|
|
@@ -6,7 +6,7 @@ import { parseHex } from "../../core/color/ColorUtils.js";
|
|
|
6
6
|
import Vector4 from "../../core/geom/Vector4.js";
|
|
7
7
|
import loadSampler2D from "../../engine/graphics/texture/sampler/loadSampler2D.js";
|
|
8
8
|
import convertSampler2D2Canvas from "../../engine/graphics/texture/sampler/Sampler2D2Canvas.js";
|
|
9
|
-
import {
|
|
9
|
+
import { InstancedMeshComponent } from "../../engine/ecs/foliage/ecs/InstancedMeshComponent.js";
|
|
10
10
|
|
|
11
11
|
class FoliagePaintTool extends Tool {
|
|
12
12
|
constructor() {
|
|
@@ -100,7 +100,7 @@ class FoliagePaintTool extends Tool {
|
|
|
100
100
|
|
|
101
101
|
/**
|
|
102
102
|
*
|
|
103
|
-
* @param {
|
|
103
|
+
* @param {InstancedMeshComponent} foliage
|
|
104
104
|
* @param {Number} entity
|
|
105
105
|
*/
|
|
106
106
|
function visit(foliage, entity) {
|
|
@@ -149,9 +149,9 @@ class FoliagePaintTool extends Tool {
|
|
|
149
149
|
|
|
150
150
|
/**
|
|
151
151
|
*
|
|
152
|
-
* @type {
|
|
152
|
+
* @type {InstancedMeshComponent}
|
|
153
153
|
*/
|
|
154
|
-
const foliage = entityManger.getComponent(entity,
|
|
154
|
+
const foliage = entityManger.getComponent(entity, InstancedMeshComponent);
|
|
155
155
|
|
|
156
156
|
|
|
157
157
|
if (foliage === null) {
|
|
@@ -24,10 +24,42 @@ import { HashSet } from "../../../core/collection/HashSet.js";
|
|
|
24
24
|
import { computeGeometryHash } from "./geometry/geometry/computeGeometryHash.js";
|
|
25
25
|
import { computeGeometryEquality } from "./geometry/geometry/computeGeometryEquality.js";
|
|
26
26
|
import { traverseThreeObject } from "../../graphics/ecs/highlight/renderer/traverseThreeObject.js";
|
|
27
|
+
import { computeTextureHash } from "./material/computeTextureHash.js";
|
|
28
|
+
import { computeTextureEquality } from "./material/computeTextureEquality.js";
|
|
27
29
|
|
|
28
30
|
const animationOptimizer = new AnimationOptimizer();
|
|
29
31
|
const materialCache = StaticMaterialCache.Global;
|
|
30
32
|
|
|
33
|
+
/**
|
|
34
|
+
*
|
|
35
|
+
* @param {THREE.Material} material
|
|
36
|
+
* @param {HashSet<Texture>} texture_cache
|
|
37
|
+
*/
|
|
38
|
+
function replace_material_textures_from_cache(material, texture_cache) {
|
|
39
|
+
const attachments = TextureAttachmentsByMaterialType[material.type];
|
|
40
|
+
|
|
41
|
+
if (attachments === undefined) {
|
|
42
|
+
// unsupported material
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const attachment_count = attachments.length;
|
|
47
|
+
|
|
48
|
+
for (let i = 0; i < attachment_count; i++) {
|
|
49
|
+
const attachment = attachments[i];
|
|
50
|
+
|
|
51
|
+
const texture = attachment.read(material);
|
|
52
|
+
if (texture !== undefined && texture !== null) {
|
|
53
|
+
const cached = texture_cache.ensure(texture);
|
|
54
|
+
|
|
55
|
+
if (cached !== texture) {
|
|
56
|
+
// got an existing cached texture, write that instead
|
|
57
|
+
attachment.write(material, cached);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
31
63
|
/**
|
|
32
64
|
* Transfer any transform on the root down to the children instead
|
|
33
65
|
* @param {Object3D} root
|
|
@@ -154,7 +186,20 @@ export class GLTFAssetLoader extends AssetLoader {
|
|
|
154
186
|
*/
|
|
155
187
|
this.__geometry_cache = new HashSet({
|
|
156
188
|
keyHashFunction: computeGeometryHash,
|
|
157
|
-
keyEqualityFunction: computeGeometryEquality
|
|
189
|
+
keyEqualityFunction: computeGeometryEquality,
|
|
190
|
+
capacity: 1024
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
*
|
|
196
|
+
* @type {HashSet<Texture>}
|
|
197
|
+
* @private
|
|
198
|
+
*/
|
|
199
|
+
this.__texture_cache = new HashSet({
|
|
200
|
+
keyHashFunction: computeTextureHash,
|
|
201
|
+
keyEqualityFunction: computeTextureEquality,
|
|
202
|
+
capacity: 2048
|
|
158
203
|
});
|
|
159
204
|
}
|
|
160
205
|
|
|
@@ -234,9 +279,12 @@ export class GLTFAssetLoader extends AssetLoader {
|
|
|
234
279
|
}
|
|
235
280
|
}
|
|
236
281
|
|
|
282
|
+
|
|
237
283
|
load(path, success, failure, progress) {
|
|
238
284
|
const loader = this.loader;
|
|
239
285
|
const geometry_cache = this.__geometry_cache;
|
|
286
|
+
const texture_cache = this.__texture_cache;
|
|
287
|
+
|
|
240
288
|
|
|
241
289
|
/**
|
|
242
290
|
*
|
|
@@ -253,6 +301,9 @@ export class GLTFAssetLoader extends AssetLoader {
|
|
|
253
301
|
geometry = geometry_cache.ensure(geometry);
|
|
254
302
|
mesh.geometry = geometry;
|
|
255
303
|
|
|
304
|
+
// replace textures from cache
|
|
305
|
+
replace_material_textures_from_cache(mesh.material, texture_cache);
|
|
306
|
+
|
|
256
307
|
const isSkinned = mesh.isSkinnedMesh === true;
|
|
257
308
|
|
|
258
309
|
|
|
@@ -10,7 +10,7 @@ async function decode_png(png_bytes) {
|
|
|
10
10
|
|
|
11
11
|
const png = reader.parse();
|
|
12
12
|
|
|
13
|
-
const
|
|
13
|
+
const uint_channels = png.getUint8Data();
|
|
14
14
|
|
|
15
15
|
const width = png.getWidth();
|
|
16
16
|
const height = png.getHeight();
|
|
@@ -19,9 +19,10 @@ async function decode_png(png_bytes) {
|
|
|
19
19
|
// console.profileEnd('decode');
|
|
20
20
|
|
|
21
21
|
resolve({
|
|
22
|
-
data,
|
|
22
|
+
data: uint_channels.data,
|
|
23
23
|
width,
|
|
24
|
-
height
|
|
24
|
+
height,
|
|
25
|
+
itemSize: uint_channels.itemSize
|
|
25
26
|
});
|
|
26
27
|
});
|
|
27
28
|
}
|
|
@@ -6,8 +6,9 @@ export class ImageRGBADataAsset extends Asset {
|
|
|
6
6
|
* @param {number[]|Uint8Array} data
|
|
7
7
|
* @param {number} width
|
|
8
8
|
* @param {number} height
|
|
9
|
+
* @param {number} [itemSize]
|
|
9
10
|
*/
|
|
10
|
-
constructor(data, width, height) {
|
|
11
|
+
constructor(data, width, height, itemSize = 4) {
|
|
11
12
|
super();
|
|
12
13
|
|
|
13
14
|
/**
|
|
@@ -32,7 +33,7 @@ export class ImageRGBADataAsset extends Asset {
|
|
|
32
33
|
* Number of channels
|
|
33
34
|
* @type {number}
|
|
34
35
|
*/
|
|
35
|
-
this.itemSize =
|
|
36
|
+
this.itemSize = itemSize;
|
|
36
37
|
|
|
37
38
|
this.byteSize = data.length;
|
|
38
39
|
}
|
|
@@ -23,7 +23,7 @@ export class ImageRGBADataLoader extends AssetLoader {
|
|
|
23
23
|
/**
|
|
24
24
|
*
|
|
25
25
|
* @param {string} path
|
|
26
|
-
* @returns {Promise<{data:ArrayBuffer, width: number, height:number}>}
|
|
26
|
+
* @returns {Promise<{data:ArrayBuffer, width: number, height:number, itemSize: number}>}
|
|
27
27
|
* @private
|
|
28
28
|
*/
|
|
29
29
|
async __decode_via_worker(path) {
|
|
@@ -45,7 +45,7 @@ export class ImageRGBADataLoader extends AssetLoader {
|
|
|
45
45
|
|
|
46
46
|
const bitmap = await this.__decode_via_worker(path);
|
|
47
47
|
|
|
48
|
-
return new ImageRGBADataAsset(new Uint8Array(bitmap.data), bitmap.width, bitmap.height);
|
|
48
|
+
return new ImageRGBADataAsset(new Uint8Array(bitmap.data), bitmap.width, bitmap.height, bitmap.itemSize);
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
load(path, success, failure, progress) {
|
|
@@ -65,7 +65,7 @@ export class ImageRGBADataLoader extends AssetLoader {
|
|
|
65
65
|
|
|
66
66
|
texture.dispose();
|
|
67
67
|
|
|
68
|
-
const f = new ImageRGBADataAsset(sampler2D.data, sampler2D.width, sampler2D.height);
|
|
68
|
+
const f = new ImageRGBADataAsset(sampler2D.data, sampler2D.width, sampler2D.height, sampler2D.itemSize);
|
|
69
69
|
|
|
70
70
|
success(f);
|
|
71
71
|
|
|
@@ -5,12 +5,23 @@ export function PNG() {
|
|
|
5
5
|
// initialize all members to keep the same hidden class
|
|
6
6
|
this.width = 0;
|
|
7
7
|
this.height = 0;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Number of bits per channel?
|
|
11
|
+
* @type {number}
|
|
12
|
+
*/
|
|
8
13
|
this.bitDepth = 0;
|
|
14
|
+
|
|
9
15
|
this.colorType = 0;
|
|
10
16
|
this.compressionMethod = 0;
|
|
11
17
|
this.filterMethod = 0;
|
|
12
18
|
this.interlaceMethod = 0;
|
|
13
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Number of channels in the image
|
|
22
|
+
* @example RGB = 3, RGBA = 4, etc.
|
|
23
|
+
* @type {number}
|
|
24
|
+
*/
|
|
14
25
|
this.colors = 0;
|
|
15
26
|
this.alpha = false;
|
|
16
27
|
this.pixelBits = 0;
|
|
@@ -23,6 +34,10 @@ export function PNG() {
|
|
|
23
34
|
*/
|
|
24
35
|
this.pixels = null;
|
|
25
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Transparency palette
|
|
39
|
+
* @type {Uint8Array|null}
|
|
40
|
+
*/
|
|
26
41
|
this.trns = null;
|
|
27
42
|
|
|
28
43
|
}
|
|
@@ -138,6 +153,10 @@ PNG.prototype.setInterlaceMethod = function (interlaceMethod) {
|
|
|
138
153
|
this.interlaceMethod = interlaceMethod;
|
|
139
154
|
};
|
|
140
155
|
|
|
156
|
+
/**
|
|
157
|
+
*
|
|
158
|
+
* @param {Uint8Array} trns
|
|
159
|
+
*/
|
|
141
160
|
PNG.prototype.setTRNS = function (trns) {
|
|
142
161
|
this.trns = trns;
|
|
143
162
|
};
|
|
@@ -161,7 +180,9 @@ PNG.prototype.getPalette = function () {
|
|
|
161
180
|
* result is an array: [red, green, blue, alpha]
|
|
162
181
|
*/
|
|
163
182
|
PNG.prototype.getPixel = function (result, result_offset, x, y) {
|
|
164
|
-
|
|
183
|
+
var pixels = this.pixels;
|
|
184
|
+
|
|
185
|
+
if (!pixels) {
|
|
165
186
|
throw new Error("pixel data is empty");
|
|
166
187
|
}
|
|
167
188
|
|
|
@@ -170,7 +191,6 @@ PNG.prototype.getPixel = function (result, result_offset, x, y) {
|
|
|
170
191
|
}
|
|
171
192
|
|
|
172
193
|
var i = this.colors * this.bitDepth / 8 * (y * this.width + x);
|
|
173
|
-
var pixels = this.pixels;
|
|
174
194
|
|
|
175
195
|
let r, g, b, a;
|
|
176
196
|
|
|
@@ -189,14 +209,17 @@ PNG.prototype.getPixel = function (result, result_offset, x, y) {
|
|
|
189
209
|
break;
|
|
190
210
|
case 3:
|
|
191
211
|
a = 255;
|
|
192
|
-
|
|
212
|
+
|
|
213
|
+
if (this.trns != null) {
|
|
193
214
|
a = this.trns[pixels[i]];
|
|
194
215
|
}
|
|
216
|
+
|
|
195
217
|
const offset = pixels[i] * 3;
|
|
196
218
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
219
|
+
const palette = this.palette;
|
|
220
|
+
r = palette[offset];
|
|
221
|
+
g = palette[offset + 1];
|
|
222
|
+
b = palette[offset + 2];
|
|
200
223
|
|
|
201
224
|
break;
|
|
202
225
|
case 4:
|
|
@@ -293,3 +316,87 @@ PNG.prototype.getRGBA8Array = function () {
|
|
|
293
316
|
|
|
294
317
|
return data;
|
|
295
318
|
};
|
|
319
|
+
|
|
320
|
+
PNG.prototype.getUint8Data_case3 = function () {
|
|
321
|
+
const w = this.width;
|
|
322
|
+
const h = this.height;
|
|
323
|
+
|
|
324
|
+
const pixel_count = w * h;
|
|
325
|
+
|
|
326
|
+
let itemSize;
|
|
327
|
+
|
|
328
|
+
const transparency_lookup = this.trns;
|
|
329
|
+
if (transparency_lookup !== null) {
|
|
330
|
+
// has transparency
|
|
331
|
+
itemSize = 4;
|
|
332
|
+
} else {
|
|
333
|
+
itemSize = 3;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const result_data = new Uint8Array(pixel_count * itemSize);
|
|
337
|
+
|
|
338
|
+
const pixels = this.pixels;
|
|
339
|
+
const palette = this.palette;
|
|
340
|
+
|
|
341
|
+
const d = this.colors * this.bitDepth / 8;
|
|
342
|
+
|
|
343
|
+
for (let i = 0; i < pixel_count; i++) {
|
|
344
|
+
const destination_address = i * itemSize;
|
|
345
|
+
|
|
346
|
+
const lookup_value = pixels[i * d];
|
|
347
|
+
|
|
348
|
+
result_data[destination_address] = palette[lookup_value];
|
|
349
|
+
result_data[destination_address + 1] = palette[lookup_value + 1];
|
|
350
|
+
result_data[destination_address + 2] = palette[lookup_value + 2];
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
//transparency
|
|
354
|
+
if (transparency_lookup !== null) {
|
|
355
|
+
for (let i = 0; i < pixel_count; i++) {
|
|
356
|
+
result_data[i * 4 + 3] = transparency_lookup[pixels[i * d]];
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
return {
|
|
361
|
+
data: result_data,
|
|
362
|
+
itemSize: itemSize
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* @returns {{itemSize:number, data:Uint8Array}}
|
|
368
|
+
*/
|
|
369
|
+
PNG.prototype.getUint8Data = function () {
|
|
370
|
+
let data;
|
|
371
|
+
let itemSize = 0; // note, can take this from this.colors
|
|
372
|
+
|
|
373
|
+
switch (this.colorType) {
|
|
374
|
+
case 0:
|
|
375
|
+
data = this.pixels;
|
|
376
|
+
itemSize = 1;
|
|
377
|
+
break;
|
|
378
|
+
case 2:
|
|
379
|
+
data = this.pixels;
|
|
380
|
+
itemSize = 3;
|
|
381
|
+
break;
|
|
382
|
+
case 3:
|
|
383
|
+
// palette
|
|
384
|
+
return this.getUint8Data_case3();
|
|
385
|
+
case 4:
|
|
386
|
+
// grayscale with alpha
|
|
387
|
+
data = this.pixels;
|
|
388
|
+
itemSize = 2;
|
|
389
|
+
break;
|
|
390
|
+
case 6:
|
|
391
|
+
data = this.pixels;
|
|
392
|
+
itemSize = 4;
|
|
393
|
+
break;
|
|
394
|
+
default:
|
|
395
|
+
throw new Error('Unsupported color type');
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
return {
|
|
399
|
+
data,
|
|
400
|
+
itemSize
|
|
401
|
+
};
|
|
402
|
+
};
|
|
@@ -91,6 +91,10 @@ PNGReader.prototype.decodeChunk = function () {
|
|
|
91
91
|
|
|
92
92
|
const type = buffer.readASCIICharacters(4);
|
|
93
93
|
|
|
94
|
+
/**
|
|
95
|
+
*
|
|
96
|
+
* @type {Uint8Array}
|
|
97
|
+
*/
|
|
94
98
|
var chunk = this.readBytes(length);
|
|
95
99
|
|
|
96
100
|
// checksum
|
|
@@ -161,6 +165,7 @@ PNGReader.prototype.decodeIDAT = function (chunk) {
|
|
|
161
165
|
|
|
162
166
|
/**
|
|
163
167
|
* https://www.w3.org/TR/PNG/#11tRNS
|
|
168
|
+
* @param {Uint8Array} chunk
|
|
164
169
|
*/
|
|
165
170
|
PNGReader.prototype.decodeTRNS = function (chunk) {
|
|
166
171
|
this.png.setTRNS(chunk);
|
|
@@ -40,7 +40,7 @@ function obtainSampler(bitmap, ctx) {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
|
-
*
|
|
43
|
+
* Ref holding webgl context, being weak-ref, allows context to be removed when not in use
|
|
44
44
|
* @type {WeakRef<WebGL2RenderingContext>|null}
|
|
45
45
|
*/
|
|
46
46
|
let ctx_ref = null;
|
|
@@ -97,8 +97,13 @@ export function sampler_from_bitmap(bitmap) {
|
|
|
97
97
|
* @returns {boolean}
|
|
98
98
|
*/
|
|
99
99
|
export function computeImageBitmapEquality(a, b) {
|
|
100
|
+
if (a === b) {
|
|
101
|
+
// strict equality check, special case
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
100
104
|
|
|
101
105
|
if (a.width !== b.width || a.height !== b.height) {
|
|
106
|
+
// check dimensions
|
|
102
107
|
return false;
|
|
103
108
|
}
|
|
104
109
|
|