@woosh/meep-engine 2.40.1 → 2.42.0
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/collection/HashMap.d.ts +2 -0
- package/core/collection/HashMap.js +22 -0
- package/core/geom/3d/apply_mat4_transform_to_v3_array.js +2 -4
- package/core/geom/3d/normal/hemioct/encode_unit3_hemioct.js +5 -0
- package/core/geom/3d/normal/octahedron/decode_octahedron_to_unit.js +31 -0
- package/core/geom/3d/normal/octahedron/encode_unit_to_octahedron.js +33 -0
- package/core/geom/3d/normal/octahedron/encoding.spec.js +29 -0
- package/core/geom/3d/sphere/sphere_radius_sqr_from_v3_array_transformed.js +28 -0
- package/core/geom/3d/topology/struct/BinaryTopology.js +112 -0
- package/core/geom/Quaternion.js +14 -0
- package/core/math/sign_not_zero.js +8 -0
- package/core/parser/simple/SimpleParser.js +3 -86
- package/core/parser/simple/readUnsignedInteger.js +66 -0
- package/core/parser/simple/skipWhitespace.js +21 -0
- package/engine/EngineHarness.js +13 -3
- package/engine/asset/AssetDescription.spec.js +27 -0
- package/engine/asset/loaders/GLTFAssetLoader.js +5 -3
- package/engine/ecs/foliage/ImpostorFoliage.js +4 -0
- package/engine/ecs/transform/Transform.js +23 -3
- package/engine/graphics/ecs/decal/v2/Decal.d.ts +11 -0
- package/engine/graphics/ecs/decal/v2/Decal.js +50 -0
- package/engine/graphics/ecs/decal/v2/FPDecalSystem.d.ts +8 -0
- package/engine/graphics/ecs/decal/v2/FPDecalSystem.js +213 -0
- package/engine/graphics/ecs/decal/v2/prototypeDecalSystem.js +237 -0
- package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +8 -1
- package/engine/graphics/ecs/mesh-v2/build_three_object.js +4 -0
- package/engine/graphics/ecs/mesh-v2/three_object_to_entity_composition.js +22 -7
- package/engine/graphics/filter/ImageFilter.js +2 -1
- package/engine/graphics/geometry/MikkT/MikkTSpace.js +466 -305
- package/engine/graphics/geometry/MikkT/MikkTSpace.spec.js +7 -1
- package/engine/{asset/loaders/geometry/geometry → graphics/geometry/buffered}/computeBufferAttributeHash.js +1 -1
- package/engine/{asset/loaders/geometry/geometry → graphics/geometry/buffered}/computeGeometryEquality.js +2 -2
- package/engine/{asset/loaders/geometry/geometry → graphics/geometry/buffered}/computeGeometryHash.js +1 -1
- package/engine/graphics/geometry/optimization/merge/merge_geometry_hierarchy.js +2 -2
- package/engine/graphics/impostors/card_cluster/FacePlaneAssignment.js +30 -0
- package/engine/graphics/impostors/card_cluster/README.md +13 -0
- package/engine/graphics/impostors/octahedral/ImpostorBaker.js +345 -0
- package/engine/graphics/impostors/octahedral/ImpostorCaptureType.js +10 -0
- package/engine/graphics/impostors/octahedral/ImpostorDescription.js +69 -0
- package/engine/graphics/impostors/octahedral/README.md +30 -0
- package/engine/graphics/impostors/octahedral/bake/compute_bounding_sphere.js +45 -0
- package/engine/graphics/impostors/octahedral/bake/compute_bounding_sphere_radius_only.js +37 -0
- package/engine/graphics/impostors/octahedral/bake/prepare_bake_material.js +117 -0
- package/engine/graphics/impostors/octahedral/grid/HemiOctahedralUvEncoder.js +20 -0
- package/engine/graphics/impostors/octahedral/grid/OctahedralUvEncoder.js +25 -0
- package/engine/graphics/impostors/octahedral/grid/UvEncoder.js +21 -0
- package/engine/graphics/impostors/octahedral/prototypeBaker.js +237 -0
- package/engine/graphics/impostors/octahedral/shader/BakeShaderStandard.js +196 -0
- package/engine/graphics/impostors/octahedral/shader/ImpostorShaderStandard.js +306 -0
- package/engine/graphics/impostors/octahedral/shader/ImpostorShaderV0.js +349 -0
- package/engine/graphics/impostors/octahedral/shader/ImpostorShaderV1.js +74 -0
- package/engine/graphics/impostors/octahedral/shader/glsl/common.glsl +206 -0
- package/engine/graphics/impostors/octahedral/shader/glsl/v1/common.glsl +209 -0
- package/engine/graphics/impostors/octahedral/shader/glsl/v1/flagment.glsl +80 -0
- package/engine/graphics/impostors/octahedral/shader/glsl/v1/vertex.glsl +350 -0
- package/engine/graphics/micron/convert_three_object_to_micron.js +2 -2
- package/engine/graphics/micron/plugin/MicronRenderPlugin.js +2 -2
- package/engine/graphics/micron/render/v1/getTransformedPositionsCached.js +1 -1
- package/engine/graphics/particles/node-based/codegen/CodeGenerator.js +1 -1
- package/engine/graphics/particles/node-based/nodes/noise/CurlNoiseNode.js +1 -1
- package/engine/graphics/render/forward_plus/LightManager.js +1 -1
- package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_ACCUMULATION.js +1 -3
- package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_PREAMBLE.js +2 -1
- package/engine/graphics/render/forward_plus/model/Decal.js +19 -2
- package/engine/graphics/render/visibility/hiz/buildCanvasViewFromTexture.js +32 -10
- package/engine/graphics/shaders/ScreenSpaceQuadShader.js +4 -14
- package/engine/graphics/shaders/glsl_gen_swizzled_read.js +39 -0
- package/engine/graphics/texture/sampler/Sampler2D.js +10 -10
- package/engine/graphics/texture/sampler/prototypeSamplerFiltering.js +117 -11
- package/engine/graphics/texture/sampler/resize/sampler2d_downsample_mipmap.js +66 -0
- package/engine/graphics/texture/sampler/sampler2_d_scale_down_lanczos.js +2 -2
- package/engine/ui/GUIEngine.js +8 -1
- package/package.json +1 -1
- package/view/tooltip/gml/parser/readReferenceToken.js +1 -1
- package/engine/asset/GameAssetManager.js +0 -137
|
@@ -273,6 +273,28 @@ export class HashMap {
|
|
|
273
273
|
return undefined;
|
|
274
274
|
}
|
|
275
275
|
|
|
276
|
+
/**
|
|
277
|
+
*
|
|
278
|
+
* @param {Key} key
|
|
279
|
+
* @param {function(Key):V} compute
|
|
280
|
+
* @param {*} [compute_context]
|
|
281
|
+
* @return {V}
|
|
282
|
+
*/
|
|
283
|
+
getOrCompute(key, compute, compute_context) {
|
|
284
|
+
const existing = this.get(key);
|
|
285
|
+
|
|
286
|
+
if (existing !== undefined) {
|
|
287
|
+
return existing;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
const value = compute.call(compute_context, key);
|
|
291
|
+
|
|
292
|
+
this.set(key, value);
|
|
293
|
+
|
|
294
|
+
return value;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
|
|
276
298
|
/**
|
|
277
299
|
*
|
|
278
300
|
* @param {K} key
|
|
@@ -6,11 +6,9 @@
|
|
|
6
6
|
* @param {number[]|Float32Array|Float64Array} destination
|
|
7
7
|
* @param {number} destination_offset
|
|
8
8
|
* @param {number} count
|
|
9
|
-
* @param {
|
|
9
|
+
* @param {mat4|number[]|Float32Array} mat4
|
|
10
10
|
*/
|
|
11
|
-
export function apply_mat4_transform_to_v3_array(source, source_offset, destination, destination_offset, count,
|
|
12
|
-
|
|
13
|
-
const mat4 = matrix.elements;
|
|
11
|
+
export function apply_mat4_transform_to_v3_array(source, source_offset, destination, destination_offset, count, mat4) {
|
|
14
12
|
|
|
15
13
|
const a0 = mat4[0];
|
|
16
14
|
const a1 = mat4[1];
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* Assume normalized input on +Z hemisphere.
|
|
3
3
|
* Output is on [-1, 1].
|
|
4
4
|
*
|
|
5
|
+
* Uses hemi-octahedron for sphere approximation
|
|
6
|
+
*
|
|
5
7
|
* @see A Survey of Efficient Representations for Independent Unit Vectors (Journal of Computer Graphics Techniques Vol. 3, No. 2, 2014)
|
|
6
8
|
* @param {number[]} output
|
|
7
9
|
* @param {number} output_offset
|
|
@@ -27,6 +29,9 @@ export function encode_unit_to_hemioct(output, output_offset, x, y, z) {
|
|
|
27
29
|
|
|
28
30
|
/**
|
|
29
31
|
* @see A Survey of Efficient Representations for Independent Unit Vectors (Journal of Computer Graphics Techniques Vol. 3, No. 2, 2014)
|
|
32
|
+
*
|
|
33
|
+
* Uses hemi-octahedron for sphere approximation
|
|
34
|
+
*
|
|
30
35
|
* @param {number[]} output
|
|
31
36
|
* @param {number} output_offset
|
|
32
37
|
* @param {number} x range [-1,1]
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { sign_not_zero } from "../../../../math/sign_not_zero.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @see A Survey of Efficient Representations for Independent Unit Vectors (Journal of Computer Graphics Techniques Vol. 3, No. 2, 2014) - page 13
|
|
5
|
+
* @see https://gamedev.stackexchange.com/questions/169508/octahedral-impostors-octahedral-mapping
|
|
6
|
+
* @param {number[]} output
|
|
7
|
+
* @param {number} output_offset
|
|
8
|
+
* @param {number} x range [0,1]
|
|
9
|
+
* @param {number} y range [0,1]
|
|
10
|
+
*/
|
|
11
|
+
export function decode_octahedron_to_unit(output, output_offset, x, y) {
|
|
12
|
+
let v_x = x;
|
|
13
|
+
let v_y = y;
|
|
14
|
+
|
|
15
|
+
const abs_x = Math.abs(v_x);
|
|
16
|
+
const abs_y = Math.abs(v_y);
|
|
17
|
+
|
|
18
|
+
let v_z = 1 - abs_x - abs_y;
|
|
19
|
+
|
|
20
|
+
if (v_z < 0) {
|
|
21
|
+
v_x = (1 - abs_y) * sign_not_zero(v_x);
|
|
22
|
+
v_y = (1 - abs_x) * sign_not_zero(v_y);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// normalize
|
|
26
|
+
const m = 1 / Math.hypot(v_x, v_y, v_z);
|
|
27
|
+
|
|
28
|
+
output[output_offset] = v_x * m;
|
|
29
|
+
output[output_offset + 1] = v_y * m;
|
|
30
|
+
output[output_offset + 2] = v_z * m;
|
|
31
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { sign_not_zero } from "../../../../math/sign_not_zero.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Input vector is assumed to be normalized
|
|
5
|
+
*
|
|
6
|
+
* @see A Survey of Efficient Representations for Independent Unit Vectors (Journal of Computer Graphics Techniques Vol. 3, No. 2, 2014) - page 13
|
|
7
|
+
* @see https://gamedev.stackexchange.com/questions/169508/octahedral-impostors-octahedral-mapping
|
|
8
|
+
*
|
|
9
|
+
* @param {number[]} output
|
|
10
|
+
* @param {number} output_offset
|
|
11
|
+
* @param {number} x range [-1,1]
|
|
12
|
+
* @param {number} y range [-1,1]
|
|
13
|
+
* @param {number} z range [-1,1]
|
|
14
|
+
*/
|
|
15
|
+
export function encode_unit_to_octahedron(output, output_offset, x, y, z) {
|
|
16
|
+
// Project the sphere onto the octahedron, and then onto the xy plane
|
|
17
|
+
const l2 = 1 / (Math.abs(x) + Math.abs(y) + Math.abs(z));
|
|
18
|
+
|
|
19
|
+
let p_x = x * l2;
|
|
20
|
+
let p_y = y * l2;
|
|
21
|
+
|
|
22
|
+
// Reflect the folds of the lower hemisphere over the diagonals
|
|
23
|
+
if (z <= 0) {
|
|
24
|
+
const abs_x = Math.abs(p_x);
|
|
25
|
+
const abs_y = Math.abs(p_y);
|
|
26
|
+
|
|
27
|
+
p_x = sign_not_zero(p_x) * (1 - abs_y);
|
|
28
|
+
p_y = sign_not_zero(p_y) * (1 - abs_x);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
output[output_offset] = p_x;
|
|
32
|
+
output[output_offset + 1] = p_y;
|
|
33
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { encode_unit_to_octahedron } from "./encode_unit_to_octahedron.js";
|
|
2
|
+
import { decode_octahedron_to_unit } from "./decode_octahedron_to_unit.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @param {number} x
|
|
7
|
+
* @param {number} y
|
|
8
|
+
*/
|
|
9
|
+
function try_one(x, y) {
|
|
10
|
+
const output_v2 = [];
|
|
11
|
+
const output_v3 = [];
|
|
12
|
+
|
|
13
|
+
decode_octahedron_to_unit(output_v3, 0, x, y);
|
|
14
|
+
encode_unit_to_octahedron(output_v2, 0, output_v3[0], output_v3[1], output_v3[2]);
|
|
15
|
+
|
|
16
|
+
expect(output_v2[0]).toBeCloseTo(x);
|
|
17
|
+
expect(output_v2[1]).toBeCloseTo(y);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
test("encoding/decoding consistency", () => {
|
|
21
|
+
// corners
|
|
22
|
+
try_one(0, 0);
|
|
23
|
+
try_one(0, 1);
|
|
24
|
+
try_one(1, 0);
|
|
25
|
+
try_one(1, 1);
|
|
26
|
+
|
|
27
|
+
// center
|
|
28
|
+
try_one(0.5, 0.5);
|
|
29
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param {number[]|ArrayLike<number>} input
|
|
4
|
+
* @param {number} input_length
|
|
5
|
+
* @param {ArrayLike<number>|number[]|Float32Array} e 4x4 transformation matrix
|
|
6
|
+
* @returns {number}
|
|
7
|
+
*/
|
|
8
|
+
export function sphere_radius_sqr_from_v3_array_transformed(input, input_length, e) {
|
|
9
|
+
let result = 0;
|
|
10
|
+
|
|
11
|
+
for (let i = 0; i < input_length; i += 3) {
|
|
12
|
+
const x = input[i];
|
|
13
|
+
const y = input[i + 1];
|
|
14
|
+
const z = input[i + 2];
|
|
15
|
+
|
|
16
|
+
const _x = e[0] * x + e[4] * y + e[8] * z + e[12];
|
|
17
|
+
const _y = e[1] * x + e[5] * y + e[9] * z + e[13];
|
|
18
|
+
const _z = e[2] * x + e[6] * y + e[10] * z + e[14];
|
|
19
|
+
|
|
20
|
+
const l2 = _x * _x + _y * _y + _z * _z;
|
|
21
|
+
|
|
22
|
+
if (l2 > result) {
|
|
23
|
+
result = l2;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return result;
|
|
28
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { max2 } from "../../../../math/max2.js";
|
|
2
|
+
|
|
3
|
+
const INITIAL_CAPACITY = 128;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @readonly
|
|
7
|
+
* @type {number}
|
|
8
|
+
*/
|
|
9
|
+
const CAPACITY_GROW_MULTIPLIER = 1.2;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @readonly
|
|
13
|
+
* @type {number}
|
|
14
|
+
*/
|
|
15
|
+
const CAPACITY_GROW_MIN_STEP = 32;
|
|
16
|
+
|
|
17
|
+
class BinaryPool {
|
|
18
|
+
|
|
19
|
+
constructor(item_size, initial_capacity = INITIAL_CAPACITY) {
|
|
20
|
+
/**
|
|
21
|
+
* Size of a single pool item in bytes
|
|
22
|
+
* @type {number}
|
|
23
|
+
* @private
|
|
24
|
+
*/
|
|
25
|
+
this.__item_size = item_size;
|
|
26
|
+
/**
|
|
27
|
+
* Unused slots
|
|
28
|
+
* @type {number[]}
|
|
29
|
+
* @private
|
|
30
|
+
*/
|
|
31
|
+
this.__free = [];
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
*
|
|
35
|
+
* @type {number}
|
|
36
|
+
* @private
|
|
37
|
+
*/
|
|
38
|
+
this.__free_pointer = 0;
|
|
39
|
+
|
|
40
|
+
this.__data_buffer = new ArrayBuffer(initial_capacity * item_size);
|
|
41
|
+
this.__data_uint8 = new Uint8Array(this.__data_buffer);
|
|
42
|
+
|
|
43
|
+
this.__capacity = initial_capacity;
|
|
44
|
+
|
|
45
|
+
this.__used_end = 0;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
__grow_capacity() {
|
|
49
|
+
const new_capacity = Math.ceil(max2(
|
|
50
|
+
this.__capacity * CAPACITY_GROW_MULTIPLIER,
|
|
51
|
+
this.__capacity + CAPACITY_GROW_MIN_STEP
|
|
52
|
+
));
|
|
53
|
+
|
|
54
|
+
const old_data_uint8 = this.__data_uint8;
|
|
55
|
+
|
|
56
|
+
const new_data_buffer = new ArrayBuffer(new_capacity * this.__item_size);
|
|
57
|
+
|
|
58
|
+
this.__data_buffer = new_data_buffer;
|
|
59
|
+
this.__data_uint8 = new Uint8Array(new_data_buffer);
|
|
60
|
+
|
|
61
|
+
// copy old data
|
|
62
|
+
this.__data_uint8.set(old_data_uint8);
|
|
63
|
+
|
|
64
|
+
this.__capacity = new_capacity;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
*
|
|
70
|
+
* @return {number}
|
|
71
|
+
*/
|
|
72
|
+
allocate() {
|
|
73
|
+
if (this.__free_pointer > 0) {
|
|
74
|
+
// get unused slot
|
|
75
|
+
this.__free_pointer--;
|
|
76
|
+
return this.__free[this.__free_pointer];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// allocate new
|
|
80
|
+
|
|
81
|
+
let result = this.__used_end;
|
|
82
|
+
|
|
83
|
+
if (result >= this.__capacity) {
|
|
84
|
+
this.__grow_capacity();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
this.__used_end++;
|
|
88
|
+
|
|
89
|
+
return result;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
*
|
|
94
|
+
* @param {number} id
|
|
95
|
+
*/
|
|
96
|
+
release(id) {
|
|
97
|
+
this.__free[this.__free_pointer++] = id;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Heavily influenced by blender's internal mesh structure
|
|
103
|
+
* @see https://github.com/blender/blender/blob/master/source/blender/bmesh/bmesh_class.h
|
|
104
|
+
*/
|
|
105
|
+
export class BinaryTopology {
|
|
106
|
+
__vertex_pool = new BinaryPool();
|
|
107
|
+
__edge_pool = new BinaryPool();
|
|
108
|
+
__loop_pool = new BinaryPool();
|
|
109
|
+
__face_pool = new BinaryPool();
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
}
|
package/core/geom/Quaternion.js
CHANGED
|
@@ -1705,6 +1705,20 @@ class Quaternion {
|
|
|
1705
1705
|
return result;
|
|
1706
1706
|
}
|
|
1707
1707
|
|
|
1708
|
+
/**
|
|
1709
|
+
*
|
|
1710
|
+
* @param {number} x
|
|
1711
|
+
* @param {number} y
|
|
1712
|
+
* @param {number} z
|
|
1713
|
+
* @returns {Quaternion}
|
|
1714
|
+
*/
|
|
1715
|
+
static fromEulerAngles(x, y, z) {
|
|
1716
|
+
const r = new Quaternion();
|
|
1717
|
+
|
|
1718
|
+
r.fromEulerAnglesXYZ(x, y, z);
|
|
1719
|
+
|
|
1720
|
+
return r;
|
|
1721
|
+
}
|
|
1708
1722
|
|
|
1709
1723
|
/**
|
|
1710
1724
|
* Behaves similarly to Unity's Quaternion `RotateToward` method
|
|
@@ -2,6 +2,8 @@ import DataType from "./DataType.js";
|
|
|
2
2
|
import ParserError from "./ParserError.js";
|
|
3
3
|
import Token from "./Token.js";
|
|
4
4
|
import TokenType from "./TokenType.js";
|
|
5
|
+
import { readUnsignedInteger } from "./readUnsignedInteger.js";
|
|
6
|
+
import { skipWhitespace } from "./skipWhitespace.js";
|
|
5
7
|
|
|
6
8
|
|
|
7
9
|
const RX_IDENTIFIER_CHAR = /^[a-zA-Z0-9_]/;
|
|
@@ -272,90 +274,6 @@ function readHex(text, cursor, length) {
|
|
|
272
274
|
return new Token(value, cursor, i, null, DataType.Number);
|
|
273
275
|
}
|
|
274
276
|
|
|
275
|
-
/**
|
|
276
|
-
*
|
|
277
|
-
* @param {string} text
|
|
278
|
-
* @param {number} cursor
|
|
279
|
-
* @param {number} length
|
|
280
|
-
* @returns {Token}
|
|
281
|
-
*/
|
|
282
|
-
function readUnsignedInteger(text, cursor, length) {
|
|
283
|
-
let i = cursor;
|
|
284
|
-
|
|
285
|
-
let value = 0;
|
|
286
|
-
|
|
287
|
-
main_loop: for (; i < length;) {
|
|
288
|
-
const char = text.charAt(i);
|
|
289
|
-
let digit;
|
|
290
|
-
switch (char) {
|
|
291
|
-
case '0':
|
|
292
|
-
digit = 0;
|
|
293
|
-
break;
|
|
294
|
-
case '1':
|
|
295
|
-
digit = 1;
|
|
296
|
-
break;
|
|
297
|
-
case '2':
|
|
298
|
-
digit = 2;
|
|
299
|
-
break;
|
|
300
|
-
case '3':
|
|
301
|
-
digit = 3;
|
|
302
|
-
break;
|
|
303
|
-
case '4':
|
|
304
|
-
digit = 4;
|
|
305
|
-
break;
|
|
306
|
-
case '5':
|
|
307
|
-
digit = 5;
|
|
308
|
-
break;
|
|
309
|
-
case '6':
|
|
310
|
-
digit = 6;
|
|
311
|
-
break;
|
|
312
|
-
case '7':
|
|
313
|
-
digit = 7;
|
|
314
|
-
break;
|
|
315
|
-
case '8':
|
|
316
|
-
digit = 8;
|
|
317
|
-
break;
|
|
318
|
-
case '9':
|
|
319
|
-
digit = 9;
|
|
320
|
-
break;
|
|
321
|
-
default:
|
|
322
|
-
if (i === cursor) {
|
|
323
|
-
//first character is not a digit
|
|
324
|
-
throw new ParserError(i, `Expected a digit [0,1,2,3,4,5,6,7,8,9] but got '${char}' instead`, text);
|
|
325
|
-
}
|
|
326
|
-
//not a digit
|
|
327
|
-
break main_loop;
|
|
328
|
-
}
|
|
329
|
-
i++;
|
|
330
|
-
value = value * 10 + digit;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
return new Token(value, cursor, i, null, DataType.Number);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
/**
|
|
339
|
-
*
|
|
340
|
-
* @param {string} text
|
|
341
|
-
* @param {number} cursor
|
|
342
|
-
* @param {number} length
|
|
343
|
-
* @returns {number}
|
|
344
|
-
*/
|
|
345
|
-
export function skipWhitespace(text, cursor, length) {
|
|
346
|
-
let i = cursor;
|
|
347
|
-
let char;
|
|
348
|
-
while (i < length) {
|
|
349
|
-
char = text.charAt(i);
|
|
350
|
-
|
|
351
|
-
if (char === ' ' || char === '\n' || char === '\t') {
|
|
352
|
-
i++;
|
|
353
|
-
} else {
|
|
354
|
-
break;
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
return i;
|
|
358
|
-
}
|
|
359
277
|
|
|
360
278
|
/**
|
|
361
279
|
*
|
|
@@ -542,6 +460,5 @@ export {
|
|
|
542
460
|
readLiteral,
|
|
543
461
|
readNumber,
|
|
544
462
|
readStringToken,
|
|
545
|
-
readBoolean
|
|
546
|
-
readUnsignedInteger
|
|
463
|
+
readBoolean
|
|
547
464
|
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import ParserError from "./ParserError.js";
|
|
2
|
+
import Token from "./Token.js";
|
|
3
|
+
import DataType from "./DataType.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @param {string} text
|
|
8
|
+
* @param {number} cursor
|
|
9
|
+
* @param {number} length
|
|
10
|
+
* @returns {Token}
|
|
11
|
+
*/
|
|
12
|
+
export function readUnsignedInteger(text, cursor, length) {
|
|
13
|
+
let i = cursor;
|
|
14
|
+
|
|
15
|
+
let value = 0;
|
|
16
|
+
|
|
17
|
+
main_loop: for (; i < length;) {
|
|
18
|
+
const char = text.charAt(i);
|
|
19
|
+
let digit;
|
|
20
|
+
switch (char) {
|
|
21
|
+
case '0':
|
|
22
|
+
digit = 0;
|
|
23
|
+
break;
|
|
24
|
+
case '1':
|
|
25
|
+
digit = 1;
|
|
26
|
+
break;
|
|
27
|
+
case '2':
|
|
28
|
+
digit = 2;
|
|
29
|
+
break;
|
|
30
|
+
case '3':
|
|
31
|
+
digit = 3;
|
|
32
|
+
break;
|
|
33
|
+
case '4':
|
|
34
|
+
digit = 4;
|
|
35
|
+
break;
|
|
36
|
+
case '5':
|
|
37
|
+
digit = 5;
|
|
38
|
+
break;
|
|
39
|
+
case '6':
|
|
40
|
+
digit = 6;
|
|
41
|
+
break;
|
|
42
|
+
case '7':
|
|
43
|
+
digit = 7;
|
|
44
|
+
break;
|
|
45
|
+
case '8':
|
|
46
|
+
digit = 8;
|
|
47
|
+
break;
|
|
48
|
+
case '9':
|
|
49
|
+
digit = 9;
|
|
50
|
+
break;
|
|
51
|
+
default:
|
|
52
|
+
if (i === cursor) {
|
|
53
|
+
//first character is not a digit
|
|
54
|
+
throw new ParserError(i, `Expected a digit [0,1,2,3,4,5,6,7,8,9] but got '${char}' instead`, text);
|
|
55
|
+
}
|
|
56
|
+
//not a digit
|
|
57
|
+
break main_loop;
|
|
58
|
+
}
|
|
59
|
+
i++;
|
|
60
|
+
value = value * 10 + digit;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
return new Token(value, cursor, i, null, DataType.Number);
|
|
65
|
+
}
|
|
66
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param {string} text
|
|
4
|
+
* @param {number} cursor
|
|
5
|
+
* @param {number} length
|
|
6
|
+
* @returns {number}
|
|
7
|
+
*/
|
|
8
|
+
export function skipWhitespace(text, cursor, length) {
|
|
9
|
+
let i = cursor;
|
|
10
|
+
let char;
|
|
11
|
+
while (i < length) {
|
|
12
|
+
char = text.charAt(i);
|
|
13
|
+
|
|
14
|
+
if (char === ' ' || char === '\n' || char === '\t') {
|
|
15
|
+
i++;
|
|
16
|
+
} else {
|
|
17
|
+
break;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return i;
|
|
21
|
+
}
|
package/engine/EngineHarness.js
CHANGED
|
@@ -122,6 +122,10 @@ export class EngineHarness {
|
|
|
122
122
|
document.body.appendChild(engine.viewStack.el);
|
|
123
123
|
engine.viewStack.link();
|
|
124
124
|
|
|
125
|
+
// set css
|
|
126
|
+
document.body.style.margin = "0";
|
|
127
|
+
document.body.style.overflow = "hidden";
|
|
128
|
+
|
|
125
129
|
function handleInput() {
|
|
126
130
|
window.removeEventListener(MouseEvents.Down, handleInput);
|
|
127
131
|
|
|
@@ -149,6 +153,7 @@ export class EngineHarness {
|
|
|
149
153
|
* @param {boolean} [autoClip]
|
|
150
154
|
* @param {number} [distanceMin]
|
|
151
155
|
* @param {number} [distanceMax]
|
|
156
|
+
* @param {number} [fieldOfView] in degrees
|
|
152
157
|
* @returns {EntityBuilder}
|
|
153
158
|
*/
|
|
154
159
|
static buildCamera(
|
|
@@ -159,9 +164,10 @@ export class EngineHarness {
|
|
|
159
164
|
distance = 10,
|
|
160
165
|
pitch = 1.4,
|
|
161
166
|
yaw = 0,
|
|
162
|
-
autoClip =
|
|
167
|
+
autoClip = false,
|
|
163
168
|
distanceMin = 0,
|
|
164
|
-
distanceMax = 1000
|
|
169
|
+
distanceMax = 1000,
|
|
170
|
+
fieldOfView = 45
|
|
165
171
|
}
|
|
166
172
|
) {
|
|
167
173
|
const em = engine.entityManager;
|
|
@@ -195,6 +201,7 @@ export class EngineHarness {
|
|
|
195
201
|
|
|
196
202
|
camera.active.set(true);
|
|
197
203
|
camera.autoClip = autoClip;
|
|
204
|
+
camera.fov.set(fieldOfView);
|
|
198
205
|
|
|
199
206
|
const entityBuilder = new EntityBuilder();
|
|
200
207
|
|
|
@@ -225,6 +232,7 @@ export class EngineHarness {
|
|
|
225
232
|
* @param {boolean} [enableWater]
|
|
226
233
|
* @param {boolean} [enableTerrain]
|
|
227
234
|
* @param {boolean} [enableLights=true]
|
|
235
|
+
* @param {number} [cameraFieldOfView]
|
|
228
236
|
* @param {boolean} [cameraController=true]
|
|
229
237
|
*/
|
|
230
238
|
static async buildBasics({
|
|
@@ -240,6 +248,7 @@ export class EngineHarness {
|
|
|
240
248
|
enableWater = true,
|
|
241
249
|
enableTerrain = true,
|
|
242
250
|
enableLights = true,
|
|
251
|
+
cameraFieldOfView,
|
|
243
252
|
cameraController = true
|
|
244
253
|
}) {
|
|
245
254
|
|
|
@@ -252,7 +261,8 @@ export class EngineHarness {
|
|
|
252
261
|
target: focus,
|
|
253
262
|
pitch,
|
|
254
263
|
yaw,
|
|
255
|
-
distance
|
|
264
|
+
distance,
|
|
265
|
+
fieldOfView: cameraFieldOfView
|
|
256
266
|
});
|
|
257
267
|
|
|
258
268
|
const cameraEntity = camera.entity;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { AssetDescription } from "./AssetDescription.js";
|
|
2
|
+
|
|
3
|
+
test('equality', () => {
|
|
4
|
+
const a = new AssetDescription('a', 'b');
|
|
5
|
+
const b = new AssetDescription('a', 'b');
|
|
6
|
+
const c = new AssetDescription('b', 'a');
|
|
7
|
+
const d = new AssetDescription('b', 'b');
|
|
8
|
+
const e = new AssetDescription('a', 'a');
|
|
9
|
+
const f = new AssetDescription('x', 'y');
|
|
10
|
+
|
|
11
|
+
expect(b.equals(a)).toBe(true);
|
|
12
|
+
expect(b.equals(c)).toBe(false);
|
|
13
|
+
expect(b.equals(d)).toBe(false);
|
|
14
|
+
expect(b.equals(e)).toBe(false);
|
|
15
|
+
expect(b.equals(f)).toBe(false);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
test('hash stability', () => {
|
|
20
|
+
const a = new AssetDescription('a', 'b');
|
|
21
|
+
|
|
22
|
+
expect(a.hash()).toEqual(a.hash());
|
|
23
|
+
|
|
24
|
+
const b = new AssetDescription('a', 'b');
|
|
25
|
+
|
|
26
|
+
expect(a.hash()).toEqual(b.hash());
|
|
27
|
+
});
|
|
@@ -11,7 +11,9 @@ import { MeshDepthMaterial, RGBADepthPacking } from "three";
|
|
|
11
11
|
import { TextureAttachmentsByMaterialType } from "./material/TextureAttachmensByMaterialType.js";
|
|
12
12
|
import { AssetLoader } from "./AssetLoader.js";
|
|
13
13
|
import { ensureGeometryBoundingSphere } from "../../graphics/geometry/buffered/ensureGeometryBoundingSphere.js";
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
computeSkinnedMeshBoundingVolumes
|
|
16
|
+
} from "../../graphics/geometry/skining/computeSkinnedMeshBoundingVolumes.js";
|
|
15
17
|
import { ensureGeometryBoundingBox } from "../../graphics/util/ensureGeometryBoundingBox.js";
|
|
16
18
|
import { cloneObject3D } from "../../graphics/three/cloneObject3D.js";
|
|
17
19
|
import GLTFTextureDDSExtension from "./gltf/extensions/MSFT_texture_dds.js";
|
|
@@ -20,8 +22,8 @@ import { computeObjectBoundingSphere } from "./gltf/computeObjectBoundingSphere.
|
|
|
20
22
|
import { isMesh } from "./gltf/isMesh.js";
|
|
21
23
|
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader.js";
|
|
22
24
|
import { HashSet } from "../../../core/collection/HashSet.js";
|
|
23
|
-
import { computeGeometryHash } from "
|
|
24
|
-
import { computeGeometryEquality } from "
|
|
25
|
+
import { computeGeometryHash } from "../../graphics/geometry/buffered/computeGeometryHash.js";
|
|
26
|
+
import { computeGeometryEquality } from "../../graphics/geometry/buffered/computeGeometryEquality.js";
|
|
25
27
|
import { traverseThreeObject } from "../../graphics/ecs/highlight/renderer/traverseThreeObject.js";
|
|
26
28
|
import { computeTextureHash } from "./material/computeTextureHash.js";
|
|
27
29
|
import { computeTextureEquality } from "./material/computeTextureEquality.js";
|
|
@@ -19,6 +19,10 @@ import {
|
|
|
19
19
|
import Vector2 from "../../../core/geom/Vector2.js";
|
|
20
20
|
import Vector4 from "../../../core/geom/Vector4.js";
|
|
21
21
|
|
|
22
|
+
/**
|
|
23
|
+
* @deprecated use other options, such as ShadedMesh with INSTANCED draw mode or dedicated instanced mesh system such as Foliage2System
|
|
24
|
+
* @constructor
|
|
25
|
+
*/
|
|
22
26
|
const Foliage = function (options) {
|
|
23
27
|
const size = options.size || 1;
|
|
24
28
|
const lightMap = options.lightMap;
|