@woosh/meep-engine 2.39.40 → 2.39.43
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/aabb3/AABB3.js +6 -6
- 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/cache/Cache.js +6 -0
- 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 +33 -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/buffered/query/GeometrySpatialQueryAccelerator.d.ts +7 -0
- package/engine/graphics/geometry/buffered/query/GeometrySpatialQueryAccelerator.js +17 -1
- 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/samples/terrain/from_image_2.js +8 -2
- 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
|
+
});
|
package/core/bvh2/aabb3/AABB3.js
CHANGED
|
@@ -553,12 +553,12 @@ export class AABB3 {
|
|
|
553
553
|
|
|
554
554
|
/**
|
|
555
555
|
* @source http://stackoverflow.com/questions/3106666/intersection-of-line-segment-with-axis-aligned-box-in-c-sharp
|
|
556
|
-
* @param startX
|
|
557
|
-
* @param startY
|
|
558
|
-
* @param startZ
|
|
559
|
-
* @param endX
|
|
560
|
-
* @param endY
|
|
561
|
-
* @param endZ
|
|
556
|
+
* @param {number} startX
|
|
557
|
+
* @param {number} startY
|
|
558
|
+
* @param {number} startZ
|
|
559
|
+
* @param {number} endX
|
|
560
|
+
* @param {number} endY
|
|
561
|
+
* @param {number} endZ
|
|
562
562
|
* @returns {boolean}
|
|
563
563
|
*/
|
|
564
564
|
intersectSegment2(startX, startY, startZ, endX, endY, endZ) {
|
|
@@ -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();
|
package/core/cache/Cache.js
CHANGED
|
@@ -264,6 +264,12 @@ export class Cache {
|
|
|
264
264
|
*/
|
|
265
265
|
const weightTarget = this.maxWeight - elementWeight;
|
|
266
266
|
|
|
267
|
+
if (weightTarget < 0) {
|
|
268
|
+
// Special case
|
|
269
|
+
// element does not fit into cache, attempting to insert it forcibly would result in a full flush and overflow
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
|
|
267
273
|
//evict elements until there is enough space for the element
|
|
268
274
|
this.evictUntilWeight(weightTarget);
|
|
269
275
|
|
|
@@ -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,24 @@ 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();
|
|
274
|
+
|
|
263
275
|
readPositionFromMouseEvent(v2, evt);
|
|
264
276
|
|
|
265
|
-
this.
|
|
277
|
+
const position_changed = (this.input_pointer_position === null || this.input_pointer_position.x !== v2.x || this.input_pointer_position.y !== v2.y);
|
|
278
|
+
|
|
279
|
+
this.input_pointer_position = new Vector3(v2.x, v2.y, 0);
|
|
280
|
+
|
|
281
|
+
return position_changed;
|
|
266
282
|
}
|
|
267
283
|
|
|
268
284
|
/**
|
|
@@ -270,7 +286,7 @@ export class BlenderCameraOrientationGizmo extends CanvasView {
|
|
|
270
286
|
* @param {MouseEvent} evt
|
|
271
287
|
*/
|
|
272
288
|
onMouseOut(evt) {
|
|
273
|
-
this.
|
|
289
|
+
this.input_pointer_position = null;
|
|
274
290
|
}
|
|
275
291
|
|
|
276
292
|
/**
|
|
@@ -278,6 +294,12 @@ export class BlenderCameraOrientationGizmo extends CanvasView {
|
|
|
278
294
|
* @param {MouseEvent} evt
|
|
279
295
|
*/
|
|
280
296
|
onMouseClick(evt) {
|
|
297
|
+
|
|
298
|
+
if (this._setPointerPositionFromEvent(evt)) {
|
|
299
|
+
// positions do not match, force update
|
|
300
|
+
this.update();
|
|
301
|
+
}
|
|
302
|
+
|
|
281
303
|
if (this.selectedAxis !== null) {
|
|
282
304
|
this.on.axisSelected.send2(
|
|
283
305
|
this.selectedAxis.axis,
|
|
@@ -362,13 +384,13 @@ export class BlenderCameraOrientationGizmo extends CanvasView {
|
|
|
362
384
|
// If the mouse is over the gizmo, find the closest axis and highlight it
|
|
363
385
|
this.selectedAxis = null;
|
|
364
386
|
|
|
365
|
-
if (this.
|
|
387
|
+
if (this.input_pointer_position) {
|
|
366
388
|
let closestDist = Infinity;
|
|
367
389
|
let closestZ = -Infinity;
|
|
368
390
|
|
|
369
391
|
// Loop through each layer
|
|
370
392
|
for (let bubble of layers) {
|
|
371
|
-
const distance = v2_distance(this.
|
|
393
|
+
const distance = v2_distance(this.input_pointer_position.x, this.input_pointer_position.y, bubble.position.x, bubble.position.y);
|
|
372
394
|
|
|
373
395
|
// Only select the axis if its closer to the mouse than the previous or if its within its bubble circle
|
|
374
396
|
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
|
}
|