@woosh/meep-engine 2.39.40 → 2.39.41
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/operations/ceilPowerOfTwo.spec.js +17 -0
- package/core/bvh2/binary/2/BinaryUint32BVH.js +7 -1
- package/core/bvh2/binary/2/BinaryUint32BVH.spec.js +31 -1
- package/core/bvh2/bvh3/query/compute_tight_near_far_clipping_planes.spec.js +2 -2
- package/core/collection/IteratorUtils.js +1 -0
- package/core/collection/queue/Deque.js +5 -2
- package/core/color/Color.js +22 -4
- package/core/color/hsluv/HSLuv.js +187 -0
- package/core/geom/3d/aabb/aabb3_matrix4_project.js +1 -0
- package/core/geom/3d/topology/simplify/simplifyTopoMesh2.js +1 -1
- package/core/primitives/strings/compareStrings.js +22 -0
- package/editor/Editor.js +2 -0
- package/editor/tools/v2/BlenderCameraOrientationGizmo.js +22 -11
- package/engine/EngineHarness.js +7 -0
- package/engine/asset/loaders/geometry/geometry/computeBufferAttributeHash.js +5 -6
- package/engine/asset/loaders/image/codec/Codec.js +9 -0
- package/engine/asset/loaders/image/codec/CodecWithFallback.js +52 -11
- package/engine/asset/loaders/image/codec/ThreadedImageDecoder.js +12 -0
- package/engine/asset/loaders/image/png/PNGReader.js +2 -1
- package/engine/asset/loaders/image/png/PNG_HEADER_BYTES.js +1 -0
- package/engine/computeStridedIntegerArrayHash.js +19 -0
- package/engine/ecs/EntityBuilder.d.ts +2 -0
- package/engine/ecs/gui/GUIElement.d.ts +3 -1
- package/engine/graphics/ecs/light/binding/fp/FPLightBinding.js +11 -2
- package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +2 -8
- package/engine/graphics/geometry/optimization/merge/merge_geometry_hierarchy.js +336 -0
- package/engine/graphics/geometry/optimization/merge/prototypeGeometryMerge.js +176 -0
- package/engine/graphics/micron/build/hierarchy/buildAbstractPatchHierarchy.js +7 -3
- package/engine/graphics/micron/build/hierarchy/merge_patches.js +0 -1
- package/engine/graphics/micron/prototypeVirtualGeometry.js +3 -3
- package/engine/graphics/particles/particular/engine/parameter/ParameterLookupTable.js +32 -1
- package/engine/graphics/render/forward_plus/LightManager.js +58 -13
- package/engine/graphics/render/forward_plus/debug/createScreenGrid.js +192 -9
- package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_ACCUMULATION.js +42 -1
- package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_PREAMBLE.js +1 -0
- package/engine/graphics/render/forward_plus/materials/ForwardPlusThreeMaterial.js +5 -0
- package/engine/graphics/render/forward_plus/materials/fp_build_fragment_shader.js +1 -4
- package/engine/graphics/render/forward_plus/model/Decal.js +33 -5
- package/engine/graphics/render/forward_plus/model/PointLight.js +1 -1
- package/engine/graphics/render/forward_plus/plugin/MaterialTransformer.js +4 -0
- package/engine/graphics/render/forward_plus/prototype/prototypeLightManager.js +480 -12
- package/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_texture.js +49 -29
- package/engine/graphics/texture/atlas/AbstractTextureAtlas.js +11 -0
- package/engine/graphics/texture/atlas/CachingTextureAtlas.js +34 -0
- package/engine/graphics/texture/atlas/ReferencedTextureAtlas.js +9 -1
- package/engine/graphics/texture/atlas/TextureAtlas.js +29 -16
- package/engine/graphics/texture/atlas/TextureAtlasDebugger.js +75 -19
- package/engine/graphics/texture/sampler/Sampler2D.d.ts +2 -0
- package/engine/graphics/texture/sampler/Sampler2D.js +49 -9
- package/engine/sound/ecs/SoundListenerSystem.js +5 -0
- package/engine/sound/ecs/emitter/SoundEmitter.js +12 -1
- package/package.json +1 -1
- package/view/tooltip/TooltipManager.js +0 -95
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ceilPowerOfTwo } from "./ceilPowerOfTwo.js";
|
|
2
|
+
|
|
3
|
+
test('test', () => {
|
|
4
|
+
expect(ceilPowerOfTwo(1)).toBe(1);
|
|
5
|
+
|
|
6
|
+
expect(ceilPowerOfTwo(2)).toBe(2);
|
|
7
|
+
|
|
8
|
+
expect(ceilPowerOfTwo(3)).toBe(4);
|
|
9
|
+
expect(ceilPowerOfTwo(4)).toBe(4);
|
|
10
|
+
|
|
11
|
+
expect(ceilPowerOfTwo(5)).toBe(8);
|
|
12
|
+
expect(ceilPowerOfTwo(7)).toBe(8);
|
|
13
|
+
expect(ceilPowerOfTwo(8)).toBe(8);
|
|
14
|
+
|
|
15
|
+
expect(ceilPowerOfTwo(9)).toBe(16);
|
|
16
|
+
expect(ceilPowerOfTwo(15)).toBe(16);
|
|
17
|
+
});
|
|
@@ -201,7 +201,13 @@ export class BinaryUint32BVH {
|
|
|
201
201
|
|
|
202
202
|
const twoLeafLimit = ceilPowerOfTwo(count);
|
|
203
203
|
|
|
204
|
-
|
|
204
|
+
if (count <= 1) {
|
|
205
|
+
// special case
|
|
206
|
+
this.__node_count_binary = twoLeafLimit;
|
|
207
|
+
} else {
|
|
208
|
+
this.__node_count_binary = twoLeafLimit - 1;
|
|
209
|
+
}
|
|
210
|
+
|
|
205
211
|
}
|
|
206
212
|
|
|
207
213
|
/**
|
|
@@ -12,6 +12,36 @@ test('1 leaf build does not throw', () => {
|
|
|
12
12
|
bvh.build();
|
|
13
13
|
});
|
|
14
14
|
|
|
15
|
+
test('0 leaf tree must have a no binary nodes', () => {
|
|
16
|
+
const bvh = new BinaryUint32BVH();
|
|
17
|
+
|
|
18
|
+
bvh.setLeafCount(0);
|
|
19
|
+
bvh.initialize_structure();
|
|
20
|
+
bvh.build();
|
|
21
|
+
|
|
22
|
+
expect(bvh.getBinaryNodeCount()).toBe(0);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test('1 leaf tree must have a single binary node', () => {
|
|
26
|
+
const bvh = new BinaryUint32BVH();
|
|
27
|
+
|
|
28
|
+
bvh.setLeafCount(1);
|
|
29
|
+
bvh.initialize_structure();
|
|
30
|
+
bvh.build();
|
|
31
|
+
|
|
32
|
+
expect(bvh.getBinaryNodeCount()).toBe(1);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test('4 leaf tree must have a 3 binary nodes', () => {
|
|
36
|
+
const bvh = new BinaryUint32BVH();
|
|
37
|
+
|
|
38
|
+
bvh.setLeafCount(4);
|
|
39
|
+
bvh.initialize_structure();
|
|
40
|
+
bvh.build();
|
|
41
|
+
|
|
42
|
+
expect(bvh.getBinaryNodeCount()).toBe(3);
|
|
43
|
+
});
|
|
44
|
+
|
|
15
45
|
test('read/write 1 leaf', () => {
|
|
16
46
|
const bvh = new BinaryUint32BVH();
|
|
17
47
|
|
|
@@ -23,7 +53,7 @@ test('read/write 1 leaf', () => {
|
|
|
23
53
|
expect(bvh.readLeafPayload(0)).toBe(7);
|
|
24
54
|
|
|
25
55
|
const bounds = [];
|
|
26
|
-
bvh.readBounds(
|
|
56
|
+
bvh.readBounds(bvh.getLeafBlockAddress(), bounds, 0);
|
|
27
57
|
|
|
28
58
|
expect(bounds[0]).toBeCloseTo(-3);
|
|
29
59
|
expect(bounds[1]).toBeCloseTo(-7);
|
|
@@ -13,7 +13,7 @@ function orthographic_frustum(left, right, up, down, near, far) {
|
|
|
13
13
|
]);
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
test('Empty', () => {
|
|
16
|
+
test('Empty does not throw', () => {
|
|
17
17
|
const bvh = new ExplicitBinaryBoundingVolumeHierarchy();
|
|
18
18
|
|
|
19
19
|
const res = [];
|
|
@@ -23,7 +23,7 @@ test('Empty', () => {
|
|
|
23
23
|
compute_tight_near_far_clipping_planes(res, 0, 0b000011, bvh, frustum);
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
-
test('Axis-aligned, orthographic tight fit around a single small node', () => {
|
|
26
|
+
test.skip('Axis-aligned, orthographic tight fit around a single small node', () => {
|
|
27
27
|
const frustum = orthographic_frustum(-1, 1, -1, 1, -1, 1);
|
|
28
28
|
|
|
29
29
|
const bvh = new ExplicitBinaryBoundingVolumeHierarchy();
|
|
@@ -200,11 +200,14 @@ export class Deque {
|
|
|
200
200
|
*/
|
|
201
201
|
__index_of(e) {
|
|
202
202
|
const size = this.size();
|
|
203
|
-
|
|
203
|
+
|
|
204
|
+
const data = this.__data;
|
|
205
|
+
const capacity = data.length;
|
|
206
|
+
|
|
204
207
|
for (let i = 0; i < size; i++) {
|
|
205
208
|
const index = (this.__head + i) % capacity;
|
|
206
209
|
|
|
207
|
-
const el =
|
|
210
|
+
const el = data[index];
|
|
208
211
|
|
|
209
212
|
if (el === e) {
|
|
210
213
|
return i;
|
package/core/color/Color.js
CHANGED
|
@@ -157,7 +157,8 @@ export class Color {
|
|
|
157
157
|
let _h = h % 1;
|
|
158
158
|
|
|
159
159
|
if (_h < 0) {
|
|
160
|
-
|
|
160
|
+
// move into positive range
|
|
161
|
+
_h = _h + Math.ceil(Math.abs(_h));
|
|
161
162
|
}
|
|
162
163
|
|
|
163
164
|
const k_r = (_h * 12) % 12;
|
|
@@ -184,7 +185,8 @@ export class Color {
|
|
|
184
185
|
let _h = h % 1;
|
|
185
186
|
|
|
186
187
|
if (_h < 0) {
|
|
187
|
-
|
|
188
|
+
// move into positive range
|
|
189
|
+
_h = _h + Math.ceil(Math.abs(_h));
|
|
188
190
|
}
|
|
189
191
|
|
|
190
192
|
const h_face = _h * 6;
|
|
@@ -244,7 +246,8 @@ export class Color {
|
|
|
244
246
|
let _h = h % 1;
|
|
245
247
|
|
|
246
248
|
if (_h < 0) {
|
|
247
|
-
|
|
249
|
+
// move into positive range
|
|
250
|
+
_h = _h + Math.ceil(Math.abs(_h));
|
|
248
251
|
}
|
|
249
252
|
|
|
250
253
|
const h_face = _h * 6;
|
|
@@ -315,7 +318,7 @@ export class Color {
|
|
|
315
318
|
|
|
316
319
|
let r, g, b;
|
|
317
320
|
|
|
318
|
-
const i = Math.floor(
|
|
321
|
+
const i = Math.floor(_h * 6);
|
|
319
322
|
const f = _h * 6 - i;
|
|
320
323
|
const p = _v * (1 - _s);
|
|
321
324
|
const q = _v * (1 - f * _s);
|
|
@@ -534,6 +537,21 @@ export class Color {
|
|
|
534
537
|
return new Color(r, g, b);
|
|
535
538
|
}
|
|
536
539
|
|
|
540
|
+
/**
|
|
541
|
+
*
|
|
542
|
+
* @param {number} h
|
|
543
|
+
* @param {number} s
|
|
544
|
+
* @param {number} v
|
|
545
|
+
* @return {Color}
|
|
546
|
+
*/
|
|
547
|
+
static fromHSV(h, s, v) {
|
|
548
|
+
const color = new Color();
|
|
549
|
+
|
|
550
|
+
color.setHSV(h, s, v);
|
|
551
|
+
|
|
552
|
+
return color;
|
|
553
|
+
}
|
|
554
|
+
|
|
537
555
|
|
|
538
556
|
/**
|
|
539
557
|
*
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @see https://github.com/hsluv/hsluv-c/blob/master/src/hsluv.c
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const temp_0 = new Float32Array(3);
|
|
6
|
+
const temp_1 = new Float32Array(3);
|
|
7
|
+
/* for RGB */
|
|
8
|
+
const m = new Float32Array([
|
|
9
|
+
3.24096994190452134377, -1.53738317757009345794, -0.49861076029300328366,
|
|
10
|
+
-0.96924363628087982613, 1.87596750150772066772, 0.04155505740717561247,
|
|
11
|
+
0.05563007969699360846, -0.20397695888897656435, 1.05697151424287856072
|
|
12
|
+
]);
|
|
13
|
+
|
|
14
|
+
/* for XYZ */
|
|
15
|
+
const m_inv = new Float32Array([
|
|
16
|
+
0.41239079926595948129, 0.35758433938387796373, 0.18048078840183428751,
|
|
17
|
+
0.21263900587151035754, 0.71516867876775592746, 0.07219231536073371500,
|
|
18
|
+
0.01933081871559185069, 0.11919477979462598791, 0.95053215224966058086
|
|
19
|
+
]);
|
|
20
|
+
|
|
21
|
+
function dot_product(t1, offset_1, t2, offset_2) {
|
|
22
|
+
return t1[offset_1] * t2[offset_2] + t1[offset_1 + 1] * t2[offset_2 + 1] + t1[offset_1 + 2] * t2[offset_2 + 2];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* Used for rgb conversions */
|
|
26
|
+
|
|
27
|
+
function from_linear(c) {
|
|
28
|
+
if (c <= 0.0031308)
|
|
29
|
+
return 12.92 * c;
|
|
30
|
+
else
|
|
31
|
+
return 1.055 * Math.pow(c, 1.0 / 2.4) - 0.055;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function to_linear(c) {
|
|
35
|
+
if (c > 0.04045)
|
|
36
|
+
return Math.pow((c + 0.055) / 1.055, 2.4);
|
|
37
|
+
else
|
|
38
|
+
return c / 12.92;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const ref_u = 0.19783000664283680764;
|
|
42
|
+
const ref_v = 0.46831999493879100370;
|
|
43
|
+
|
|
44
|
+
const kappa = 903.29629629629629629630;
|
|
45
|
+
const epsilon = 0.00885645167903563082;
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
*
|
|
50
|
+
* @param {number} theta
|
|
51
|
+
* @param {number[]|Float32Array} line
|
|
52
|
+
* @param {number} line_address
|
|
53
|
+
* @return {number}
|
|
54
|
+
*/
|
|
55
|
+
function ray_length_until_intersect(theta, line, line_address) {
|
|
56
|
+
return line[line_address + 1] / (Math.sin(theta) - line[line_address] * Math.cos(theta));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function get_bounds( l, bounds)
|
|
60
|
+
{
|
|
61
|
+
const tl = l + 16.0;
|
|
62
|
+
const sub1 = (tl * tl * tl) / 1560896.0;
|
|
63
|
+
const sub2 = (sub1 > epsilon ? sub1 : (l / kappa));
|
|
64
|
+
let channel;
|
|
65
|
+
let t;
|
|
66
|
+
|
|
67
|
+
for(channel = 0; channel < 3; channel++) {
|
|
68
|
+
const ch3 = channel*3;
|
|
69
|
+
let m1 = m[ch3];
|
|
70
|
+
let m2 = m[ch3+1];
|
|
71
|
+
let m3 = m[ch3+2];
|
|
72
|
+
|
|
73
|
+
for (t = 0; t < 2; t++) {
|
|
74
|
+
const top1 = (284517.0 * m1 - 94839.0 * m3) * sub2;
|
|
75
|
+
const top2 = (838422.0 * m3 + 769860.0 * m2 + 731718.0 * m1) * l * sub2 - 769860.0 * t * l;
|
|
76
|
+
const bottom = (632260.0 * m3 - 126452.0 * m2) * sub2 + 126452.0 * t;
|
|
77
|
+
|
|
78
|
+
const bounds_index = channel * 2 + t;
|
|
79
|
+
const bounds_address = bounds_index*2;
|
|
80
|
+
|
|
81
|
+
bounds[bounds_address] = top1 / bottom;
|
|
82
|
+
bounds[bounds_address] = top2 / bottom;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function max_chroma_for_lh(l, h) {
|
|
88
|
+
let min_len = Infinity;
|
|
89
|
+
const hrad = h * 0.01745329251994329577; /* (2 * pi / 360) */
|
|
90
|
+
const bounds = new Float32Array(12);
|
|
91
|
+
let i;
|
|
92
|
+
|
|
93
|
+
get_bounds(l, bounds);
|
|
94
|
+
|
|
95
|
+
for (i = 0; i < 6; i++) {
|
|
96
|
+
const len = ray_length_until_intersect(hrad, bounds, i * 2);
|
|
97
|
+
|
|
98
|
+
if (len >= 0 && len < min_len)
|
|
99
|
+
min_len = len;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return min_len;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function hsluv2lch(input, output) {
|
|
106
|
+
let h = input[0];
|
|
107
|
+
const s = input[1];
|
|
108
|
+
const l = input[2];
|
|
109
|
+
let c;
|
|
110
|
+
|
|
111
|
+
/* White and black: disambiguate chroma */
|
|
112
|
+
if (l > 99.9999999 || l < 0.00000001)
|
|
113
|
+
c = 0.0;
|
|
114
|
+
else
|
|
115
|
+
c = max_chroma_for_lh(l, h) / 100.0 * s;
|
|
116
|
+
|
|
117
|
+
/* Grays: disambiguate hue */
|
|
118
|
+
if (s < 0.00000001)
|
|
119
|
+
h = 0.0;
|
|
120
|
+
|
|
121
|
+
output[0] = l;
|
|
122
|
+
output[1] = c;
|
|
123
|
+
output[2] = h;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function lch2luv(input, output) {
|
|
127
|
+
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function luv2xyz(input, output) {
|
|
131
|
+
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function xyz2rgb(input, output) {
|
|
135
|
+
const r = from_linear(dot_product(m, 0, input, 0));
|
|
136
|
+
|
|
137
|
+
const g = from_linear(dot_product(m, 3, input, 0));
|
|
138
|
+
|
|
139
|
+
const b = from_linear(dot_product(m, 6, input, 0));
|
|
140
|
+
|
|
141
|
+
output[0] = r;
|
|
142
|
+
output[1] = g;
|
|
143
|
+
output[2] = b;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function rgb2xyz(input, output) {
|
|
147
|
+
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function xyz2luv(input, output) {
|
|
151
|
+
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function luv2lch(input, output) {
|
|
155
|
+
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function lch2hsluv(input, output) {
|
|
159
|
+
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
*
|
|
165
|
+
* @param {number[]} input
|
|
166
|
+
* @param {number[]} output
|
|
167
|
+
*/
|
|
168
|
+
export function rgb2hsluv(input, output) {
|
|
169
|
+
rgb2xyz(input, temp_0);
|
|
170
|
+
xyz2luv(temp_0, temp_1);
|
|
171
|
+
luv2lch(temp_1, temp_0);
|
|
172
|
+
lch2hsluv(temp_0, output);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
*
|
|
177
|
+
* @param {number[]} input
|
|
178
|
+
* @param {number[]} output
|
|
179
|
+
*/
|
|
180
|
+
export function hsluv2rgb(input, output) {
|
|
181
|
+
hsluv2lch(input, temp_0);
|
|
182
|
+
lch2luv(temp_0, temp_1);
|
|
183
|
+
luv2xyz(temp_1, temp_0);
|
|
184
|
+
xyz2rgb(temp_0, output);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* NOTE: Based on Transforming Axis-Aligned Bounding Boxes by Jim Arvo from "Graphics Gems", Academic Press, 1990
|
|
3
|
+
* NOTE: {@link result} and {@link aabb} must be different objects
|
|
3
4
|
* @param {ArrayLike<number>|number[]|Float32Array} result
|
|
4
5
|
* @param {ArrayLike<number>|number[]|Float32Array} aabb
|
|
5
6
|
* @param {number[]} matrix 4x4 matrix
|
|
@@ -52,7 +52,7 @@ export function edge_collapse_reduce_face_count(mesh, num_faces_to_remove, heap,
|
|
|
52
52
|
const target_face_count = max2(0, mesh_faces.size - num_faces_to_remove);
|
|
53
53
|
|
|
54
54
|
let cycle_count = 0;
|
|
55
|
-
let cycle_limit = max2(heap.size, num_faces_to_remove *
|
|
55
|
+
let cycle_limit = max2(heap.size, num_faces_to_remove * 10) + 10;
|
|
56
56
|
|
|
57
57
|
while (
|
|
58
58
|
!heap.is_empty()
|
|
@@ -5,6 +5,28 @@
|
|
|
5
5
|
* @returns {number}
|
|
6
6
|
*/
|
|
7
7
|
export function compareStrings(a, b) {
|
|
8
|
+
// null check
|
|
9
|
+
if (a === null) {
|
|
10
|
+
if (b === null) {
|
|
11
|
+
return 0;
|
|
12
|
+
} else {
|
|
13
|
+
return 1;
|
|
14
|
+
}
|
|
15
|
+
} else if (b === null) {
|
|
16
|
+
return -1;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// undefined check
|
|
20
|
+
if (a === undefined) {
|
|
21
|
+
if (b === undefined) {
|
|
22
|
+
return 0;
|
|
23
|
+
} else {
|
|
24
|
+
return 1;
|
|
25
|
+
}
|
|
26
|
+
} else if (b === undefined) {
|
|
27
|
+
return -1;
|
|
28
|
+
}
|
|
29
|
+
|
|
8
30
|
const n = a.length;
|
|
9
31
|
|
|
10
32
|
const m = b.length;
|
package/editor/Editor.js
CHANGED
|
@@ -69,6 +69,8 @@ import Signal from "../core/events/signal/Signal.js";
|
|
|
69
69
|
import ObservedInteger from "../core/model/ObservedInteger.js";
|
|
70
70
|
import { ObservedIntegerEditor } from "./ecs/component/editors/ObservedIntegerEditor.js";
|
|
71
71
|
|
|
72
|
+
import '../../../../css/editor/EntityEditorView.scss';
|
|
73
|
+
import '../../../../css/editor/EditorView.scss';
|
|
72
74
|
|
|
73
75
|
/**
|
|
74
76
|
* @template T
|
|
@@ -217,7 +217,7 @@ export class BlenderCameraOrientationGizmo extends CanvasView {
|
|
|
217
217
|
*
|
|
218
218
|
* @type {Vector3|null}
|
|
219
219
|
*/
|
|
220
|
-
this.
|
|
220
|
+
this.input_pointer_position = null;
|
|
221
221
|
|
|
222
222
|
this.center = new Vector3(this.options.size / 2, this.options.size / 2, 0);
|
|
223
223
|
this.selectedAxis = null;
|
|
@@ -240,16 +240,18 @@ export class BlenderCameraOrientationGizmo extends CanvasView {
|
|
|
240
240
|
super.link();
|
|
241
241
|
|
|
242
242
|
const el = this.el;
|
|
243
|
-
|
|
244
|
-
el.addEventListener('
|
|
245
|
-
el.addEventListener('
|
|
243
|
+
|
|
244
|
+
el.addEventListener('mousemove', this.onMouseMove);
|
|
245
|
+
el.addEventListener('mouseout', this.onMouseOut);
|
|
246
|
+
el.addEventListener('click', this.onMouseClick);
|
|
246
247
|
}
|
|
247
248
|
|
|
248
249
|
unlink() {
|
|
249
250
|
const el = this.el;
|
|
250
|
-
|
|
251
|
-
el.removeEventListener('
|
|
252
|
-
el.removeEventListener('
|
|
251
|
+
|
|
252
|
+
el.removeEventListener('mousemove', this.onMouseMove);
|
|
253
|
+
el.removeEventListener('mouseout', this.onMouseOut);
|
|
254
|
+
el.removeEventListener('click', this.onMouseClick);
|
|
253
255
|
|
|
254
256
|
super.unlink();
|
|
255
257
|
}
|
|
@@ -259,10 +261,19 @@ export class BlenderCameraOrientationGizmo extends CanvasView {
|
|
|
259
261
|
* @param {MouseEvent} evt
|
|
260
262
|
*/
|
|
261
263
|
onMouseMove(evt) {
|
|
264
|
+
this._setPointerPositionFromEvent(evt);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
*
|
|
269
|
+
* @param {MouseEvent} evt
|
|
270
|
+
* @private
|
|
271
|
+
*/
|
|
272
|
+
_setPointerPositionFromEvent(evt) {
|
|
262
273
|
const v2 = new Vector2();
|
|
263
274
|
readPositionFromMouseEvent(v2, evt);
|
|
264
275
|
|
|
265
|
-
this.
|
|
276
|
+
this.input_pointer_position = new Vector3(v2.x, v2.y, 0);
|
|
266
277
|
}
|
|
267
278
|
|
|
268
279
|
/**
|
|
@@ -270,7 +281,7 @@ export class BlenderCameraOrientationGizmo extends CanvasView {
|
|
|
270
281
|
* @param {MouseEvent} evt
|
|
271
282
|
*/
|
|
272
283
|
onMouseOut(evt) {
|
|
273
|
-
this.
|
|
284
|
+
this.input_pointer_position = null;
|
|
274
285
|
}
|
|
275
286
|
|
|
276
287
|
/**
|
|
@@ -362,13 +373,13 @@ export class BlenderCameraOrientationGizmo extends CanvasView {
|
|
|
362
373
|
// If the mouse is over the gizmo, find the closest axis and highlight it
|
|
363
374
|
this.selectedAxis = null;
|
|
364
375
|
|
|
365
|
-
if (this.
|
|
376
|
+
if (this.input_pointer_position) {
|
|
366
377
|
let closestDist = Infinity;
|
|
367
378
|
let closestZ = -Infinity;
|
|
368
379
|
|
|
369
380
|
// Loop through each layer
|
|
370
381
|
for (let bubble of layers) {
|
|
371
|
-
const distance = v2_distance(this.
|
|
382
|
+
const distance = v2_distance(this.input_pointer_position.x, this.input_pointer_position.y, bubble.position.x, bubble.position.y);
|
|
372
383
|
|
|
373
384
|
// Only select the axis if its closer to the mouse than the previous or if its within its bubble circle
|
|
374
385
|
if (
|
package/engine/EngineHarness.js
CHANGED
|
@@ -27,6 +27,8 @@ import { JsonAssetLoader } from "./asset/loaders/JsonAssetLoader.js";
|
|
|
27
27
|
import { logger } from "./logging/GlobalLogger.js";
|
|
28
28
|
import { ConsoleLoggerBackend } from "./logging/ConsoleLoggerBackend.js";
|
|
29
29
|
import { noop } from "../core/function/Functions.js";
|
|
30
|
+
import SoundListenerSystem from "./sound/ecs/SoundListenerSystem.js";
|
|
31
|
+
import SoundListener from "./sound/ecs/SoundListener.js";
|
|
30
32
|
|
|
31
33
|
/**
|
|
32
34
|
*
|
|
@@ -174,6 +176,10 @@ export class EngineHarness {
|
|
|
174
176
|
em.addSystem(new CameraSystem(engine.graphics.scene, engine.graphics))
|
|
175
177
|
}
|
|
176
178
|
|
|
179
|
+
if (em.getSystem(SoundListenerSystem) === null) {
|
|
180
|
+
em.addSystem(new SoundListenerSystem(engine.sound.context));
|
|
181
|
+
}
|
|
182
|
+
|
|
177
183
|
if (!ecd.isComponentTypeRegistered(Tag)) {
|
|
178
184
|
ecd.registerComponentType(Tag);
|
|
179
185
|
}
|
|
@@ -199,6 +205,7 @@ export class EngineHarness {
|
|
|
199
205
|
.add(transform)
|
|
200
206
|
.add(cameraController)
|
|
201
207
|
.add(camera)
|
|
208
|
+
.add(new SoundListener())
|
|
202
209
|
.add(Tag.fromJSON(["Camera"]))
|
|
203
210
|
.build(ecd);
|
|
204
211
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { computeStridedIntegerArrayHash } from "../../../../computeStridedIntegerArrayHash.js";
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
*
|
|
3
5
|
* @param {THREE.BufferAttribute} attribute
|
|
@@ -15,14 +17,11 @@ export function computeBufferAttributeHash(attribute) {
|
|
|
15
17
|
// compute stride so that we don't have to iterate over the entire buffer, instead picking at most X(509) values to consider
|
|
16
18
|
const stride = Math.max(1, Math.ceil(index_data_size / 509));
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
const value = index_data[i];
|
|
20
|
-
|
|
21
|
-
result = ((result * 31) + value) | 0;
|
|
22
|
-
|
|
23
|
-
}
|
|
20
|
+
result ^= computeStridedIntegerArrayHash(index_data, 0, index_data_size, stride);
|
|
24
21
|
|
|
25
22
|
}
|
|
26
23
|
|
|
27
24
|
return result;
|
|
28
25
|
}
|
|
26
|
+
|
|
27
|
+
|
|
@@ -7,4 +7,13 @@ export class Codec {
|
|
|
7
7
|
async decode(data) {
|
|
8
8
|
throw new Error('Unsupported Operation');
|
|
9
9
|
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Whether codec is able to decode this data, typically checks headers in the data
|
|
13
|
+
* @param {Uint8Array} data
|
|
14
|
+
* @return {Promise<boolean>} true if able, false otherwise
|
|
15
|
+
*/
|
|
16
|
+
async test(data) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
10
19
|
}
|
|
@@ -1,28 +1,69 @@
|
|
|
1
1
|
import { Codec } from "./Codec.js";
|
|
2
|
-
import { logger } from "../../../../logging/GlobalLogger.js";
|
|
3
2
|
|
|
4
3
|
export class CodecWithFallback extends Codec {
|
|
5
4
|
/**
|
|
6
5
|
*
|
|
7
|
-
* @param {Codec}
|
|
8
|
-
* @param {Codec} fallback
|
|
6
|
+
* @param {Codec} codecs
|
|
9
7
|
*/
|
|
10
|
-
constructor(
|
|
8
|
+
constructor(...codecs) {
|
|
11
9
|
super();
|
|
12
10
|
|
|
13
|
-
this.
|
|
14
|
-
|
|
11
|
+
this.children = codecs.slice();
|
|
12
|
+
|
|
13
|
+
if (this.children.length < 1) {
|
|
14
|
+
throw new Error('At least one codec must be provided');
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async test(data) {
|
|
19
|
+
const codecs = this.children;
|
|
20
|
+
const codec_count = codecs.length;
|
|
21
|
+
|
|
22
|
+
for (let i = 0; i < codec_count; i++) {
|
|
23
|
+
const codec = codecs[i];
|
|
24
|
+
|
|
25
|
+
if (codec.test(data)) {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return false;
|
|
15
31
|
}
|
|
16
32
|
|
|
17
33
|
async decode(data) {
|
|
18
34
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
} catch (e) {
|
|
22
|
-
logger.warn(`Main codec failed, will attempt fallback. Error: ${e}`);
|
|
35
|
+
const codecs = this.children;
|
|
36
|
+
const codec_count = codecs.length;
|
|
23
37
|
|
|
24
|
-
|
|
38
|
+
const errors = [];
|
|
39
|
+
|
|
40
|
+
let result;
|
|
41
|
+
|
|
42
|
+
for (let i = 0; i < codec_count; i++) {
|
|
43
|
+
const codec = codecs[i];
|
|
44
|
+
|
|
45
|
+
if (!codec.test(data)) {
|
|
46
|
+
errors.push({
|
|
47
|
+
index: i, error: "Codec doesn't support this data"
|
|
48
|
+
});
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
result = await codec.decode(data);
|
|
54
|
+
} catch (e) {
|
|
55
|
+
|
|
56
|
+
errors.push({
|
|
57
|
+
index: i, error: e
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return result;
|
|
25
64
|
}
|
|
26
65
|
|
|
66
|
+
throw new Error(`All codecs failed, errors: ${errors.map(a => JSON.stringify(a)).join('\n')}`);
|
|
67
|
+
|
|
27
68
|
}
|
|
28
69
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Codec } from "./Codec.js";
|
|
2
2
|
import WorkerBuilder from "../../../../../core/process/worker/WorkerBuilder.js";
|
|
3
3
|
import { OnDemandWorkerManager } from "../../../../../core/process/worker/OnDemandWorkerManager.js";
|
|
4
|
+
import { PNG_HEADER_BYTES } from "../png/PNG_HEADER_BYTES.js";
|
|
4
5
|
|
|
5
6
|
export class ThreadedImageDecoder extends Codec {
|
|
6
7
|
constructor() {
|
|
@@ -23,6 +24,17 @@ export class ThreadedImageDecoder extends Codec {
|
|
|
23
24
|
this.worker.setTimeout(200);
|
|
24
25
|
}
|
|
25
26
|
|
|
27
|
+
async test(data) {
|
|
28
|
+
|
|
29
|
+
for (let i = 0; i < PNG_HEADER_BYTES.length; i++) {
|
|
30
|
+
if (data[i] !== PNG_HEADER_BYTES[i]) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
|
|
26
38
|
async decode(data) {
|
|
27
39
|
const result = await this.worker.request('decode', [data.buffer]);
|
|
28
40
|
return result;
|