@woosh/meep-engine 2.39.36 → 2.39.39
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/LICENSE +13 -0
- package/core/assert.js +14 -5
- package/core/binary/Base64.js +58 -31
- package/core/binary/Base64.spec.js +14 -0
- package/core/bvh2/aabb3/AABB3.js +2 -2
- package/core/bvh2/aabb3/aabb3_detailed_volume_intersection.js +3 -2
- package/core/bvh2/aabb3/aabb3_intersects_frustum_array.js +2 -2
- package/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js +7 -0
- package/core/bvh2/bvh3/query/compute_tight_near_far_clipping_planes.js +149 -6
- package/core/bvh2/bvh3/query/compute_tight_near_far_clipping_planes.spec.js +41 -0
- package/core/bvh2/traversal/ThreeClippingPlaneComputingBVHVisitor.js +2 -2
- package/core/bvh2/traversal/__process_point_if_within_planes.js +2 -2
- package/core/bvh2/traversal/aabb3_detailed_volume_intersection_callback_based.js +3 -0
- package/core/collection/array/computeHashArray.d.ts +1 -0
- package/core/color/Color.js +7 -3
- package/core/geom/3d/aabb/aabb3_computeDistanceAbovePlane_max.spec.js +8 -0
- package/core/geom/3d/aabb/{aabb3_computeDistanceAbovePlane.js → aabb3_compute_distance_above_plane_max.js} +3 -2
- package/core/geom/3d/aabb/computeAABB3PlaneSide.js +3 -3
- package/core/geom/3d/frustum/frustum3_computeNearestPointToPoint.js +3 -2
- package/core/geom/3d/plane/is_point_within_planes.js +2 -2
- package/core/geom/3d/plane/plane3_projectPoint.js +2 -2
- package/core/geom/3d/plane/plane3_projectPoint.spec.js +54 -0
- package/core/geom/Plane.js +0 -19
- package/core/geom/Quaternion.js +52 -38
- package/core/geom/v3_distance_above_plane.js +20 -0
- package/core/geom/v3_distance_above_plane.spec.js +40 -0
- package/core/math/statistics/halton_sequence.js +26 -0
- package/core/model/ModuleRegistry.js +1 -1
- package/core/model/reactive/model/terminal/ReactiveReference.js +1 -1
- package/core/model/reactive/trigger/ReactiveTrigger.js +14 -4
- package/editor/ecs/component/editors/ImagePathEditor.js +83 -0
- package/engine/asset/loaders/ArrayBufferLoader.js +76 -16
- package/engine/ecs/EntityComponentDataset.js +18 -28
- package/engine/ecs/terrain/ecs/splat/SplatMapping.js +27 -4
- package/engine/graphics/GraphicsEngine.d.ts +2 -2
- package/engine/graphics/GraphicsEngine.js +11 -15
- package/engine/graphics/composit/LayerCompositer.js +1 -0
- package/engine/graphics/ecs/camera/Camera.js +2 -2
- package/engine/graphics/ecs/camera/CameraSystem.js +6 -0
- package/engine/graphics/ecs/light/binding/three/ThreeLightBinding.js +1 -1
- package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +14 -6
- package/engine/graphics/ecs/mesh-v2/aggregate/SGMesh.js +2 -1
- package/engine/graphics/ecs/mesh-v2/aggregate/SGMeshSystem.js +17 -2
- package/engine/graphics/ecs/mesh-v2/aggregate/prototypeSGMesh.js +17 -20
- package/engine/graphics/filter/FlipArrayInPlace.js +11 -6
- package/engine/graphics/geometry/clipping/ClippedGeometry.js +4 -4
- package/engine/graphics/micron/prototypeVirtualGeometry.js +3 -1
- package/engine/graphics/render/buffer/simple-fx/ao/AmbientOcclusionPostProcessEffect.js +2 -0
- package/engine/graphics/render/buffer/simple-fx/taa/TemporalSupersamplingRenderPlugin.js +95 -0
- package/engine/graphics/render/buffer/simple-fx/taa/prototypeTAA.js +61 -0
- package/engine/graphics/render/forward_plus/LightManager.js +4 -4
- package/engine/graphics/render/forward_plus/plugin/ForwardPlusRenderingPlugin.js +6 -7
- package/engine/graphics/render/forward_plus/plugin/MaterialTransformer.js +6 -2
- package/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_objects.js +4 -2
- package/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_texture.js +4 -2
- package/engine/graphics/render/frame_graph/GraphNode.js +22 -0
- package/engine/graphics/render/frame_graph/RenderGraph.js +405 -0
- package/engine/graphics/render/frame_graph/RenderGraphBuilder.js +77 -0
- package/engine/graphics/render/frame_graph/RenderPass.js +30 -12
- package/engine/graphics/render/frame_graph/RenderPassNode.js +103 -0
- package/engine/graphics/render/frame_graph/RenderPassResources.js +54 -4
- package/engine/graphics/render/frame_graph/ResourceEntry.js +77 -0
- package/engine/graphics/render/frame_graph/ResourceNode.js +23 -0
- package/engine/graphics/render/frame_graph/TextureDescriptor.js +38 -4
- package/engine/graphics/render/frame_graph/sample/deferred/GBufferDrawPass.js +11 -5
- package/engine/graphics/render/frame_graph/sample/deferred/LightingPass.js +24 -0
- package/engine/graphics/render/frame_graph/sample/deferred/run.js +31 -0
- package/engine/graphics/render/frame_graph/sample/meep-v1/ColorDepthPass.js +38 -0
- package/engine/graphics/render/frame_graph/sample/meep-v1/OutlinePass.js +9 -0
- package/engine/graphics/render/frame_graph/sample/meep-v1/SSAOPass.js +5 -0
- package/engine/graphics/render/frame_graph/sample/meep-v1/render.js +7 -0
- package/engine/graphics/render/frame_graph/webgl/WebGLRenderContext.js +5 -0
- package/engine/graphics/render/layers/RenderLayerUtils.js +5 -3
- package/engine/graphics/render/view/CameraView.js +38 -0
- package/engine/graphics/texture/sampler/Sampler2D.js +22 -2
- package/engine/knowledge/database/DATABASE_SERIALIZATION_IGNORE_PROPERTY.js +1 -0
- package/engine/knowledge/database/StaticKnowledgeDataTable.js +5 -4
- package/package.json +1 -1
- package/view/elements/button/ButtonView.js +12 -1
- package/core/geom/Plane.spec.js +0 -12
- package/engine/graphics/render/frame_graph/FrameGraphBuilder.js +0 -36
- package/engine/graphics/render/frame_graph/Resource.js +0 -21
- package/engine/graphics/render/frame_graph/ResourceReference.js +0 -14
- package/engine/graphics/render/frame_graph/UsageModeType.js +0 -5
- package/engine/graphics/render/frame_graph/sample/deferred/PresentPass.js +0 -17
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { plane3_projectPoint } from "./plane3_projectPoint.js";
|
|
2
|
+
import Vector3 from "../../Vector3.js";
|
|
3
|
+
|
|
4
|
+
test("point above orthographic plane at origin", () => {
|
|
5
|
+
const p = new Vector3();
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
plane3_projectPoint(
|
|
9
|
+
p,
|
|
10
|
+
0, 1, 0,
|
|
11
|
+
0, 1, 0, 0
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
expect(p.toJSON()).toEqual({ x: 0, y: 0, z: 0 });
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test("point above orthographic plane", () => {
|
|
18
|
+
const p = new Vector3();
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
plane3_projectPoint(
|
|
22
|
+
p,
|
|
23
|
+
0, 2, 0,
|
|
24
|
+
0, 1, 0, -1
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
expect(p.toJSON()).toEqual({ x: 0, y: 1, z: 0 });
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test("point on orthographic plane", () => {
|
|
31
|
+
const p = new Vector3();
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
plane3_projectPoint(
|
|
35
|
+
p,
|
|
36
|
+
0, 1, 0,
|
|
37
|
+
0, 1, 0, -1
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
expect(p.toJSON()).toEqual({ x: 0, y: 1, z: 0 });
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test("point below orthographic plane", () => {
|
|
44
|
+
const p = new Vector3();
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
plane3_projectPoint(
|
|
48
|
+
p,
|
|
49
|
+
0, 0, 0,
|
|
50
|
+
0, 1, 0, -1
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
expect(p.toJSON()).toEqual({ x: 0, y: 1, z: 0 });
|
|
54
|
+
});
|
package/core/geom/Plane.js
CHANGED
|
@@ -121,25 +121,6 @@ export function computePlaneRayIntersection(out, originX, originY, originZ, dire
|
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
/**
|
|
125
|
-
* Orthogonal distance of a point to a plane, the distance is positive when the point lies above the plane and negative when the point is below
|
|
126
|
-
* @param {number} x
|
|
127
|
-
* @param {number} y
|
|
128
|
-
* @param {number} z
|
|
129
|
-
* @param {number} normalX
|
|
130
|
-
* @param {number} normalY
|
|
131
|
-
* @param {number} normalZ
|
|
132
|
-
* @param {number} planeConstant
|
|
133
|
-
* @returns {number}
|
|
134
|
-
*/
|
|
135
|
-
export function computePointDistanceToPlane(
|
|
136
|
-
x, y, z,
|
|
137
|
-
normalX, normalY, normalZ, planeConstant
|
|
138
|
-
) {
|
|
139
|
-
// this is is the same v4_dot(v4(x,y,z,1.0), v4(plane.normal, plane.constant));
|
|
140
|
-
return v3_dot(normalX, normalY, normalZ, x, y, z) + planeConstant;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
124
|
/**
|
|
144
125
|
*
|
|
145
126
|
* @param {Vector3} out Result will be written here
|
package/core/geom/Quaternion.js
CHANGED
|
@@ -8,7 +8,7 @@ import { assert } from "../assert.js";
|
|
|
8
8
|
import Signal from "../events/signal/Signal.js";
|
|
9
9
|
import { clamp } from "../math/clamp.js";
|
|
10
10
|
import { lerp } from "../math/lerp.js";
|
|
11
|
-
import { EPSILON, epsilonEquals
|
|
11
|
+
import { EPSILON, epsilonEquals } from "../math/MathUtils.js";
|
|
12
12
|
import Vector3 from "./Vector3.js";
|
|
13
13
|
import { v3_dot } from "./v3_dot.js";
|
|
14
14
|
import { min2 } from "../math/min2.js";
|
|
@@ -20,12 +20,6 @@ const forward = new Vector3();
|
|
|
20
20
|
const up = new Vector3();
|
|
21
21
|
const right = new Vector3();
|
|
22
22
|
|
|
23
|
-
const rotAxis = new Vector3();
|
|
24
|
-
|
|
25
|
-
function normalizeAngle(v) {
|
|
26
|
-
return v % PI2;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
23
|
/**
|
|
30
24
|
*
|
|
31
25
|
* @param {number[]|Float32Array} out
|
|
@@ -518,7 +512,12 @@ class Quaternion {
|
|
|
518
512
|
* @return {number}
|
|
519
513
|
*/
|
|
520
514
|
length() {
|
|
521
|
-
|
|
515
|
+
const x = this.x;
|
|
516
|
+
const y = this.y;
|
|
517
|
+
const z = this.z;
|
|
518
|
+
const w = this.w;
|
|
519
|
+
|
|
520
|
+
return Math.sqrt(x * x + y * y + z * z + w * w);
|
|
522
521
|
}
|
|
523
522
|
|
|
524
523
|
/**
|
|
@@ -827,13 +826,16 @@ class Quaternion {
|
|
|
827
826
|
const scaled_y = y * 0.5;
|
|
828
827
|
const scaled_z = z * 0.5;
|
|
829
828
|
|
|
830
|
-
const
|
|
831
|
-
const
|
|
832
|
-
|
|
829
|
+
const sin = Math.sin;
|
|
830
|
+
const cos = Math.cos;
|
|
831
|
+
|
|
832
|
+
const s1 = sin(scaled_x);
|
|
833
|
+
const s2 = sin(scaled_y);
|
|
834
|
+
const s3 = sin(scaled_z);
|
|
833
835
|
|
|
834
|
-
const c1 =
|
|
835
|
-
const c2 =
|
|
836
|
-
const c3 =
|
|
836
|
+
const c1 = cos(scaled_x);
|
|
837
|
+
const c2 = cos(scaled_y);
|
|
838
|
+
const c3 = cos(scaled_z);
|
|
837
839
|
|
|
838
840
|
const _x = s1 * c2 * c3 + c1 * s2 * s3;
|
|
839
841
|
const _y = c1 * s2 * c3 - s1 * c2 * s3;
|
|
@@ -857,13 +859,16 @@ class Quaternion {
|
|
|
857
859
|
const scaled_y = y * 0.5;
|
|
858
860
|
const scaled_z = z * 0.5;
|
|
859
861
|
|
|
860
|
-
const
|
|
861
|
-
const
|
|
862
|
-
|
|
862
|
+
const sin = Math.sin;
|
|
863
|
+
const cos = Math.cos;
|
|
864
|
+
|
|
865
|
+
const s1 = sin(scaled_x);
|
|
866
|
+
const s2 = sin(scaled_y);
|
|
867
|
+
const s3 = sin(scaled_z);
|
|
863
868
|
|
|
864
|
-
const c1 =
|
|
865
|
-
const c2 =
|
|
866
|
-
const c3 =
|
|
869
|
+
const c1 = cos(scaled_x);
|
|
870
|
+
const c2 = cos(scaled_y);
|
|
871
|
+
const c3 = cos(scaled_z);
|
|
867
872
|
|
|
868
873
|
const _x = s1 * c2 * c3 - c1 * s2 * s3;
|
|
869
874
|
const _y = c1 * s2 * c3 + s1 * c2 * s3;
|
|
@@ -887,13 +892,16 @@ class Quaternion {
|
|
|
887
892
|
const scaled_y = y * 0.5;
|
|
888
893
|
const scaled_z = z * 0.5;
|
|
889
894
|
|
|
890
|
-
const
|
|
891
|
-
const
|
|
892
|
-
|
|
895
|
+
const sin = Math.sin;
|
|
896
|
+
const cos = Math.cos;
|
|
897
|
+
|
|
898
|
+
const s1 = sin(scaled_x);
|
|
899
|
+
const s2 = sin(scaled_y);
|
|
900
|
+
const s3 = sin(scaled_z);
|
|
893
901
|
|
|
894
|
-
const c1 =
|
|
895
|
-
const c2 =
|
|
896
|
-
const c3 =
|
|
902
|
+
const c1 = cos(scaled_x);
|
|
903
|
+
const c2 = cos(scaled_y);
|
|
904
|
+
const c3 = cos(scaled_z);
|
|
897
905
|
|
|
898
906
|
const _x = s1 * c2 * c3 - c1 * s2 * s3;
|
|
899
907
|
const _y = c1 * s2 * c3 + s1 * c2 * s3;
|
|
@@ -917,13 +925,16 @@ class Quaternion {
|
|
|
917
925
|
const scaled_y = y * 0.5;
|
|
918
926
|
const scaled_z = z * 0.5;
|
|
919
927
|
|
|
920
|
-
const
|
|
921
|
-
const
|
|
922
|
-
|
|
928
|
+
const sin = Math.sin;
|
|
929
|
+
const cos = Math.cos;
|
|
930
|
+
|
|
931
|
+
const s1 = sin(scaled_x);
|
|
932
|
+
const s2 = sin(scaled_y);
|
|
933
|
+
const s3 = sin(scaled_z);
|
|
923
934
|
|
|
924
|
-
const c1 =
|
|
925
|
-
const c2 =
|
|
926
|
-
const c3 =
|
|
935
|
+
const c1 = cos(scaled_x);
|
|
936
|
+
const c2 = cos(scaled_y);
|
|
937
|
+
const c3 = cos(scaled_z);
|
|
927
938
|
|
|
928
939
|
const _x = s1 * c2 * c3 + c1 * s2 * s3;
|
|
929
940
|
const _y = c1 * s2 * c3 + s1 * c2 * s3;
|
|
@@ -947,13 +958,16 @@ class Quaternion {
|
|
|
947
958
|
const scaled_y = y * 0.5;
|
|
948
959
|
const scaled_z = z * 0.5;
|
|
949
960
|
|
|
950
|
-
const
|
|
951
|
-
const
|
|
952
|
-
|
|
961
|
+
const sin = Math.sin;
|
|
962
|
+
const cos = Math.cos;
|
|
963
|
+
|
|
964
|
+
const s1 = sin(scaled_x);
|
|
965
|
+
const s2 = sin(scaled_y);
|
|
966
|
+
const s3 = sin(scaled_z);
|
|
953
967
|
|
|
954
|
-
const c1 =
|
|
955
|
-
const c2 =
|
|
956
|
-
const c3 =
|
|
968
|
+
const c1 = cos(scaled_x);
|
|
969
|
+
const c2 = cos(scaled_y);
|
|
970
|
+
const c3 = cos(scaled_z);
|
|
957
971
|
|
|
958
972
|
const _x = s1 * c2 * c3 - c1 * s2 * s3;
|
|
959
973
|
const _y = c1 * s2 * c3 - s1 * c2 * s3;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { v3_dot } from "./v3_dot.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Orthogonal distance of a point to a plane, the distance is positive when the point lies above the plane and negative when the point is below
|
|
5
|
+
* @param {number} x
|
|
6
|
+
* @param {number} y
|
|
7
|
+
* @param {number} z
|
|
8
|
+
* @param {number} normalX
|
|
9
|
+
* @param {number} normalY
|
|
10
|
+
* @param {number} normalZ
|
|
11
|
+
* @param {number} planeConstant
|
|
12
|
+
* @returns {number}
|
|
13
|
+
*/
|
|
14
|
+
export function v3_distance_above_plane(
|
|
15
|
+
x, y, z,
|
|
16
|
+
normalX, normalY, normalZ, planeConstant
|
|
17
|
+
) {
|
|
18
|
+
// this is is the same v4_dot(v4(x,y,z,1.0), v4(plane.normal, plane.constant));
|
|
19
|
+
return v3_dot(normalX, normalY, normalZ, x, y, z) + planeConstant;
|
|
20
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { v3_distance_above_plane } from "./v3_distance_above_plane.js";
|
|
2
|
+
|
|
3
|
+
test('point above orthographic plane at origin', () => {
|
|
4
|
+
expect(v3_distance_above_plane(
|
|
5
|
+
0, 1, 0,
|
|
6
|
+
0, 1, 0, 0
|
|
7
|
+
)).toBe(1);
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
test('point below orthographic plane at origin', () => {
|
|
11
|
+
expect(v3_distance_above_plane(
|
|
12
|
+
0, -1, 0,
|
|
13
|
+
0, 1, 0, 0
|
|
14
|
+
)).toBe(-1);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('point above orthographic plane', () => {
|
|
18
|
+
expect(v3_distance_above_plane(
|
|
19
|
+
0, 2, 0,
|
|
20
|
+
0, 1, 0, -1
|
|
21
|
+
)).toBe(1);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('point below orthographic plane', () => {
|
|
25
|
+
expect(v3_distance_above_plane(
|
|
26
|
+
0, 0, 0,
|
|
27
|
+
0, 1, 0, -1
|
|
28
|
+
)).toBe(-1);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test('orthographic planes at origin', () => {
|
|
32
|
+
expect(v3_distance_above_plane(1, 0, 0, 1, 0, 0, 0)).toBe(1);
|
|
33
|
+
expect(v3_distance_above_plane(-1, 0, 0, 1, 0, 0, 0)).toBe(-1);
|
|
34
|
+
|
|
35
|
+
expect(v3_distance_above_plane(0, 1, 0, 0, 1, 0, 0)).toBe(1);
|
|
36
|
+
expect(v3_distance_above_plane(0, -1, 0, 0, 1, 0, 0)).toBe(-1);
|
|
37
|
+
|
|
38
|
+
expect(v3_distance_above_plane(0, 0, 1, 0, 0, 1, 0)).toBe(1);
|
|
39
|
+
expect(v3_distance_above_plane(0, 0, -1, 0, 0, 1, 0)).toBe(-1);
|
|
40
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { assert } from "../../assert.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Returns number from Halton Sequence identified by base and sequence index
|
|
5
|
+
* Halton sequence produces numbers that appear to have random distribution
|
|
6
|
+
* @see https://en.wikipedia.org/wiki/Halton_sequence
|
|
7
|
+
* @param {number} base
|
|
8
|
+
* @param {number} index sequence index
|
|
9
|
+
* @returns {number}
|
|
10
|
+
*/
|
|
11
|
+
export function halton_sequence(base, index) {
|
|
12
|
+
assert.isNonNegativeInteger(base, 'base');
|
|
13
|
+
assert.isNonNegativeInteger(index, 'index');
|
|
14
|
+
|
|
15
|
+
let result = 0;
|
|
16
|
+
let f = 1;
|
|
17
|
+
let i = index;
|
|
18
|
+
|
|
19
|
+
while (i > 0) {
|
|
20
|
+
f /= base;
|
|
21
|
+
result += f * (i % base);
|
|
22
|
+
i = Math.floor(i / base);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return result;
|
|
26
|
+
}
|
|
@@ -10,7 +10,7 @@ export class ReactiveTrigger {
|
|
|
10
10
|
*/
|
|
11
11
|
constructor(code) {
|
|
12
12
|
|
|
13
|
-
assert.
|
|
13
|
+
assert.isString(code, "code");
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
*
|
|
@@ -55,15 +55,25 @@ export class ReactiveTrigger {
|
|
|
55
55
|
* @param {Object} data
|
|
56
56
|
*/
|
|
57
57
|
connect(data) {
|
|
58
|
-
this.references
|
|
58
|
+
const references = this.references;
|
|
59
|
+
const ref_count = references.length;
|
|
60
|
+
|
|
61
|
+
for (let i = 0; i < ref_count; i++) {
|
|
62
|
+
const ref = references[i];
|
|
59
63
|
const refName = ref.name;
|
|
60
64
|
const datum = data[refName];
|
|
61
65
|
|
|
62
66
|
ref.connect(datum);
|
|
63
|
-
}
|
|
67
|
+
}
|
|
64
68
|
}
|
|
65
69
|
|
|
66
70
|
disconnect() {
|
|
67
|
-
|
|
71
|
+
const references = this.references;
|
|
72
|
+
const ref_count = references.length;
|
|
73
|
+
|
|
74
|
+
for (let i = 0; i < ref_count; i++) {
|
|
75
|
+
const ref = references[i];
|
|
76
|
+
ref.disconnect();
|
|
77
|
+
}
|
|
68
78
|
}
|
|
69
79
|
}
|
|
@@ -4,6 +4,49 @@ import EmptyView from "../../../../view/elements/EmptyView.js";
|
|
|
4
4
|
import ImageView from "../../../../view/elements/image/ImageView.js";
|
|
5
5
|
import ObservedString from "../../../../core/model/ObservedString.js";
|
|
6
6
|
import { ObservedStringEditor } from "./ObservedStringEditor.js";
|
|
7
|
+
import ButtonView from "../../../../view/elements/button/ButtonView.js";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
*
|
|
11
|
+
* @param {string} url
|
|
12
|
+
* @return {boolean}
|
|
13
|
+
*/
|
|
14
|
+
function is_data_url(url) {
|
|
15
|
+
if (typeof url !== "string") {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return url.startsWith('data:');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
*
|
|
24
|
+
* @param {string} url
|
|
25
|
+
* @returns {string}
|
|
26
|
+
*/
|
|
27
|
+
async function url_to_data_url(url) {
|
|
28
|
+
return fetch(url)
|
|
29
|
+
.then(response => {
|
|
30
|
+
return response.blob();
|
|
31
|
+
})
|
|
32
|
+
.then(blob => {
|
|
33
|
+
const fr = new FileReader();
|
|
34
|
+
|
|
35
|
+
return new Promise((resolve, reject) => {
|
|
36
|
+
|
|
37
|
+
fr.onload = () => {
|
|
38
|
+
resolve(fr.result);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
fr.onerror = reject;
|
|
42
|
+
fr.onabort = reject;
|
|
43
|
+
|
|
44
|
+
fr.readAsDataURL(blob);
|
|
45
|
+
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
});
|
|
49
|
+
}
|
|
7
50
|
|
|
8
51
|
export class ImagePathEditor extends TypeEditor {
|
|
9
52
|
inline = true;
|
|
@@ -36,8 +79,46 @@ export class ImagePathEditor extends TypeEditor {
|
|
|
36
79
|
|
|
37
80
|
vPreview.size.set(32, 32);
|
|
38
81
|
|
|
82
|
+
const b_toDataURL = new ButtonView({
|
|
83
|
+
classList: ['convert-to-data-url', 'embed'],
|
|
84
|
+
async action() {
|
|
85
|
+
const url = await url_to_data_url(field.adapter.read(parent, field.name));
|
|
86
|
+
|
|
87
|
+
field.adapter.write(parent, field.name, url);
|
|
88
|
+
|
|
89
|
+
// update editor value
|
|
90
|
+
vEditor.el.value = url;
|
|
91
|
+
|
|
92
|
+
update();
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
b_toDataURL.attr({
|
|
97
|
+
title:'Convert URL into DATA_URL, embedding the data. This allows to bypass CORRS restrictions if the URL points to a different origin from the one where the texture resides'
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
function update_data_url_status() {
|
|
101
|
+
const url = field.adapter.read(parent, field.name);
|
|
102
|
+
|
|
103
|
+
const can_convert = typeof url === "string"
|
|
104
|
+
&& field.adapter.writable
|
|
105
|
+
&& !is_data_url(url)
|
|
106
|
+
;
|
|
107
|
+
|
|
108
|
+
if (can_convert) {
|
|
109
|
+
// offer encoding option
|
|
110
|
+
r.addChild(b_toDataURL);
|
|
111
|
+
} else {
|
|
112
|
+
// nothing
|
|
113
|
+
if (r.hasChild(b_toDataURL)) {
|
|
114
|
+
r.removeChild(b_toDataURL);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
39
119
|
function update() {
|
|
40
120
|
vPreview.__setSource(vEditor.el.value);
|
|
121
|
+
update_data_url_status();
|
|
41
122
|
}
|
|
42
123
|
|
|
43
124
|
r.addChild(vPreview);
|
|
@@ -45,6 +126,8 @@ export class ImagePathEditor extends TypeEditor {
|
|
|
45
126
|
|
|
46
127
|
vEditor.el.addEventListener('input', update);
|
|
47
128
|
|
|
129
|
+
r.on.linked.add(update_data_url_status);
|
|
130
|
+
|
|
48
131
|
return r;
|
|
49
132
|
}
|
|
50
133
|
}
|
|
@@ -4,20 +4,84 @@ import { CrossOriginKind } from "../CORS/CrossOriginKind.js";
|
|
|
4
4
|
|
|
5
5
|
export class ArrayBufferLoader extends AssetLoader {
|
|
6
6
|
load(path, success, failure, progress) {
|
|
7
|
+
const coc = this.assetManager.crossOriginConfig;
|
|
7
8
|
|
|
8
|
-
const
|
|
9
|
-
xhr.open('GET', path, true);
|
|
10
|
-
xhr.responseType = "arraybuffer";
|
|
9
|
+
const headers = new Headers();
|
|
11
10
|
|
|
12
|
-
const
|
|
11
|
+
const request = new Request(path, {
|
|
12
|
+
credentials: coc.kind === CrossOriginKind.UseCredentials ? 'include' : 'same-origin',
|
|
13
|
+
headers: headers
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
fetch(request)
|
|
17
|
+
.then(response => {
|
|
18
|
+
if (response.status === 200 || response.status === 0) {
|
|
19
|
+
|
|
20
|
+
// Some browsers return HTTP Status 0 when using non-http protocol
|
|
21
|
+
// e.g. 'file://' or 'data://'. Handle as success.
|
|
22
|
+
|
|
23
|
+
if (response.status === 0) {
|
|
24
|
+
|
|
25
|
+
console.warn('HTTP Status 0 received.');
|
|
26
|
+
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (typeof ReadableStream === 'undefined' || response.body.getReader === undefined) {
|
|
30
|
+
|
|
31
|
+
return response;
|
|
32
|
+
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const reader = response.body.getReader();
|
|
36
|
+
const contentLength = response.headers.get('Content-Length');
|
|
37
|
+
const total = contentLength ? parseInt(contentLength) : 0;
|
|
38
|
+
const lengthComputable = total !== 0;
|
|
39
|
+
let loaded = 0;
|
|
40
|
+
|
|
41
|
+
// periodically read data into the new stream tracking while download progress
|
|
42
|
+
const stream = new ReadableStream({
|
|
43
|
+
start(controller) {
|
|
44
|
+
|
|
45
|
+
readData();
|
|
46
|
+
|
|
47
|
+
function readData() {
|
|
48
|
+
|
|
49
|
+
reader.read().then(({ done, value }) => {
|
|
50
|
+
|
|
51
|
+
if (done) {
|
|
52
|
+
|
|
53
|
+
controller.close();
|
|
54
|
+
|
|
55
|
+
} else {
|
|
56
|
+
|
|
57
|
+
loaded += value.byteLength;
|
|
58
|
+
|
|
59
|
+
progress(loaded, length);
|
|
60
|
+
|
|
61
|
+
controller.enqueue(value);
|
|
62
|
+
readData();
|
|
63
|
+
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
return new Response(stream);
|
|
75
|
+
|
|
76
|
+
} else {
|
|
77
|
+
|
|
78
|
+
throw Error(`fetch for "${response.url}" responded with ${response.status}: ${response.statusText}`);
|
|
13
79
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
.then(async response => {
|
|
83
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
17
84
|
|
|
18
|
-
xhr.addEventListener('load', function () {
|
|
19
|
-
if (xhr.readyState === xhr.DONE && xhr.status === 200) {
|
|
20
|
-
const arrayBuffer = xhr.response;
|
|
21
85
|
const asset = new Asset(
|
|
22
86
|
function () {
|
|
23
87
|
return arrayBuffer;
|
|
@@ -26,13 +90,9 @@ export class ArrayBufferLoader extends AssetLoader {
|
|
|
26
90
|
);
|
|
27
91
|
|
|
28
92
|
success(asset);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
}, false);
|
|
93
|
+
})
|
|
94
|
+
.catch(failure);
|
|
33
95
|
|
|
34
|
-
xhr.addEventListener('error', failure, false);
|
|
35
96
|
|
|
36
|
-
xhr.send();
|
|
37
97
|
}
|
|
38
98
|
}
|