@woosh/meep-engine 2.43.22 → 2.43.24
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/geom/3d/tetrahedra/delaunay/compute_delaunay_tetrahedral_mesh.js +2 -2
- package/core/geom/3d/topology/struct/{BinaryElementPool.js → binary/BinaryElementPool.js} +7 -11
- package/core/geom/3d/topology/struct/{BinaryElementPool.spec.js → binary/BinaryElementPool.spec.js} +0 -0
- package/core/geom/3d/topology/struct/{BinaryTopology.js → binary/BinaryTopology.js} +123 -6
- package/core/geom/3d/topology/struct/{BinaryTopology.spec.js → binary/BinaryTopology.spec.js} +0 -0
- package/core/geom/3d/topology/struct/binary/io/OrderedEdge.js +66 -0
- package/core/geom/3d/topology/struct/binary/io/bt_index_geometry_to_topology.js +188 -0
- package/core/geom/3d/topology/struct/binary/io/bt_index_geometry_to_topology.spec.js +84 -0
- package/core/geom/3d/topology/struct/binary/io/bt_mesh_calc_edges.js +51 -0
- package/core/geom/3d/topology/struct/binary/io/create_edge.js +106 -0
- package/core/geom/3d/topology/struct/binary/io/get_or_create_edge_map.js +26 -0
- package/core/geom/3d/topology/struct/binary/query/bt_mesh_edge_has_vertex.js +16 -0
- package/core/geom/3d/topology/struct/binary/query/bt_mesh_edge_has_vertex.spec.js +15 -0
- package/core/geom/3d/topology/struct/binary/query/bt_mesh_edge_other_vertex.js +21 -0
- package/core/geom/3d/topology/struct/binary/query/bt_mesh_edge_other_vertex.spec.js +16 -0
- package/core/geom/3d/topology/struct/prototypeBinaryTopology.js +14 -14
- package/core/path/PATH_SEPARATOR.js +1 -0
- package/core/path/computeFileExtension.js +24 -0
- package/core/path/computeFileExtension.spec.js +13 -0
- package/core/path/computePathBase.js +21 -0
- package/core/path/computePathBase.spec.js +13 -0
- package/core/path/computePathDirectory.js +25 -0
- package/editor/Editor.js +3 -2
- package/editor/view/library/MeshLibraryView.js +1 -1
- package/engine/EngineHarness.js +25 -1
- package/engine/asset/guessAssetType.js +1 -1
- package/engine/asset/loaders/image/ImageRGBADataLoader.js +1 -1
- package/engine/asset/loaders/texture/TextureAssetLoader.js +1 -1
- package/engine/ecs/storage/BinaryBufferSerializer.js +7 -0
- package/engine/graphics/camera/camera_compute_distance_to_fit_length.js +5 -1
- package/engine/graphics/ecs/mesh-v2/render/adapters/AbstractRenderAdapter.js +33 -0
- package/engine/graphics/ecs/mesh-v2/sample/prototypeShadedGeometry.js +1 -0
- package/engine/graphics/material/composeCompile.js +3 -5
- package/engine/graphics/micron/plugin/GLTFAssetTransformer.js +1 -1
- package/engine/graphics/sh3/README.md +2 -0
- package/engine/graphics/sh3/path_tracer/PathTracer.js +0 -14
- package/engine/graphics/sh3/path_tracer/prototypePathTracer.js +11 -7
- package/engine/graphics/texture/cubemap/load_environment_map.js +1 -1
- package/engine/graphics/util/makeMeshPreviewScene.js +38 -26
- package/engine/network/RemoteController.js +138 -0
- package/engine/network/remoteEditor.js +36 -0
- package/package.json +1 -1
- package/view/elements/MeshPreview.js +5 -1
- package/core/FilePath.js +0 -73
- package/core/FilePath.spec.js +0 -25
- package/core/geom/3d/topology/struct/bt_index_geometry_to_topology.js +0 -329
- package/core/geom/3d/topology/struct/bt_index_geometry_to_topology.spec.js +0 -26
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { NULL_POINTER } from "../BinaryTopology.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {BinaryTopology} mesh
|
|
6
|
+
* @param {number} edge_from
|
|
7
|
+
* @param {number} edge_to
|
|
8
|
+
* @param {number} vertex
|
|
9
|
+
*/
|
|
10
|
+
function edge_link_disk_forward(mesh, edge_from, edge_to, vertex) {
|
|
11
|
+
const from_v1 = mesh.edge_read_vertex1(edge_from);
|
|
12
|
+
|
|
13
|
+
let displaced_edge;
|
|
14
|
+
|
|
15
|
+
if (from_v1 === vertex) {
|
|
16
|
+
displaced_edge = mesh.edge_read_v1_disk_next(edge_from);
|
|
17
|
+
|
|
18
|
+
mesh.edge_write_v1_disk_next(edge_from, edge_to);
|
|
19
|
+
|
|
20
|
+
} else {
|
|
21
|
+
displaced_edge = mesh.edge_read_v2_disk_next(edge_from);
|
|
22
|
+
|
|
23
|
+
mesh.edge_write_v2_disk_next(edge_from, edge_to);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return displaced_edge;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function edge_link_disk_back(mesh, edge_from, edge_to, vertex) {
|
|
30
|
+
const from_v1 = mesh.edge_read_vertex1(edge_from);
|
|
31
|
+
|
|
32
|
+
let displaced_edge;
|
|
33
|
+
|
|
34
|
+
if (from_v1 === vertex) {
|
|
35
|
+
displaced_edge = mesh.edge_read_v1_disk_prev(edge_from);
|
|
36
|
+
|
|
37
|
+
mesh.edge_write_v1_disk_prev(edge_from, edge_to);
|
|
38
|
+
|
|
39
|
+
} else {
|
|
40
|
+
displaced_edge = mesh.edge_read_v2_disk_prev(edge_from);
|
|
41
|
+
|
|
42
|
+
mesh.edge_write_v2_disk_prev(edge_from, edge_to);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return displaced_edge;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
*
|
|
50
|
+
* @param {BinaryTopology} mesh
|
|
51
|
+
* @param {number} edge_source anchor edge, new edge is inserted after this one
|
|
52
|
+
* @param {number} edge_new edge that is being introduced
|
|
53
|
+
* @param {number} vertex
|
|
54
|
+
*/
|
|
55
|
+
function edge_link_disk(mesh, edge_source, edge_new, vertex) {
|
|
56
|
+
const forward_link = edge_link_disk_forward(mesh, edge_source, edge_new, vertex);
|
|
57
|
+
edge_link_disk_forward(mesh, edge_new, forward_link, vertex);
|
|
58
|
+
|
|
59
|
+
edge_link_disk_back(mesh, forward_link, edge_new, vertex);
|
|
60
|
+
edge_link_disk_back(mesh, edge_new, edge_source, vertex);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
*
|
|
65
|
+
* @param {BinaryTopology} mesh
|
|
66
|
+
* @param {number} v0
|
|
67
|
+
* @param {number} v1
|
|
68
|
+
* @return {number}
|
|
69
|
+
*/
|
|
70
|
+
export function create_edge(mesh, v0, v1) {
|
|
71
|
+
const edge_id = mesh.edges.allocate();
|
|
72
|
+
|
|
73
|
+
mesh.edge_write_vertex1(edge_id, v0);
|
|
74
|
+
mesh.edge_write_vertex2(edge_id, v1);
|
|
75
|
+
|
|
76
|
+
// initialize rest of the edge
|
|
77
|
+
mesh.edge_write_loop(edge_id, NULL_POINTER);
|
|
78
|
+
|
|
79
|
+
// process disk links
|
|
80
|
+
const first_v0_edge = mesh.vertex_read_edge(v0);
|
|
81
|
+
|
|
82
|
+
if (first_v0_edge !== NULL_POINTER) {
|
|
83
|
+
edge_link_disk(mesh, first_v0_edge, edge_id, v0);
|
|
84
|
+
} else {
|
|
85
|
+
// no edges attached yet, attach this one as the first
|
|
86
|
+
mesh.vertex_write_edge(v0, edge_id);
|
|
87
|
+
// link to self
|
|
88
|
+
mesh.edge_write_v1_disk_next(edge_id, edge_id);
|
|
89
|
+
mesh.edge_write_v1_disk_prev(edge_id, edge_id);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const first_v1_edge = mesh.vertex_read_edge(v1);
|
|
93
|
+
|
|
94
|
+
if (first_v1_edge !== NULL_POINTER) {
|
|
95
|
+
|
|
96
|
+
edge_link_disk(mesh, first_v1_edge, edge_id, v1);
|
|
97
|
+
|
|
98
|
+
} else {
|
|
99
|
+
// no edges attached yet, attach this one as the first
|
|
100
|
+
mesh.vertex_write_edge(v1, edge_id);
|
|
101
|
+
// link to self
|
|
102
|
+
mesh.edge_write_v2_disk_next(edge_id, edge_id);
|
|
103
|
+
mesh.edge_write_v2_disk_prev(edge_id, edge_id);
|
|
104
|
+
}
|
|
105
|
+
return edge_id;
|
|
106
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { OrderedEdge } from "./OrderedEdge.js";
|
|
2
|
+
import { create_edge } from "./create_edge.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @param {number} v0
|
|
7
|
+
* @param {number} v1
|
|
8
|
+
* @param {HashMap<OrderedEdge,number>} map
|
|
9
|
+
* @param {BinaryTopology} mesh
|
|
10
|
+
*/
|
|
11
|
+
function get_or_create_edge_map(v0, v1, map, mesh) {
|
|
12
|
+
const scratch_ordered_edge = new OrderedEdge(v0, v1);
|
|
13
|
+
|
|
14
|
+
const existing = map.get(scratch_ordered_edge);
|
|
15
|
+
|
|
16
|
+
if (existing !== undefined) {
|
|
17
|
+
return existing;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// doesn't exist - create
|
|
21
|
+
const edge_id = create_edge(mesh, v0, v1);
|
|
22
|
+
|
|
23
|
+
map.set(scratch_ordered_edge, edge_id);
|
|
24
|
+
|
|
25
|
+
return edge_id;
|
|
26
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param {BinaryTopology} mesh
|
|
4
|
+
* @param {number} edge_id
|
|
5
|
+
* @param {number} vertex_id
|
|
6
|
+
* @returns {boolean}
|
|
7
|
+
*/
|
|
8
|
+
export function bt_mesh_edge_has_vertex(mesh, edge_id, vertex_id) {
|
|
9
|
+
const v1 = mesh.edge_read_vertex1(edge_id);
|
|
10
|
+
|
|
11
|
+
if (v1 === vertex_id) {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return mesh.edge_read_vertex2(edge_id) === vertex_id;
|
|
16
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BinaryTopology } from "../BinaryTopology.js";
|
|
2
|
+
import { bt_mesh_edge_has_vertex } from "./bt_mesh_edge_has_vertex.js";
|
|
3
|
+
|
|
4
|
+
test('main', () => {
|
|
5
|
+
const mesh = new BinaryTopology();
|
|
6
|
+
|
|
7
|
+
const edge = mesh.edges.allocate();
|
|
8
|
+
|
|
9
|
+
mesh.edge_write_vertex1(edge, 7);
|
|
10
|
+
mesh.edge_write_vertex2(edge, 3);
|
|
11
|
+
|
|
12
|
+
expect(bt_mesh_edge_has_vertex(mesh, edge, 7)).toBe(true);
|
|
13
|
+
expect(bt_mesh_edge_has_vertex(mesh, edge, 3)).toBe(true);
|
|
14
|
+
expect(bt_mesh_edge_has_vertex(mesh, edge, 1)).toBe(false);
|
|
15
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns other vertex ID
|
|
3
|
+
* Assumes that given vertex belongs to this edge
|
|
4
|
+
* Assumes that given edge exists
|
|
5
|
+
* @param {BinaryTopology} mesh
|
|
6
|
+
* @param {number} edge_id edge ID
|
|
7
|
+
* @param {number} vertex_id
|
|
8
|
+
* @returns {number}
|
|
9
|
+
*/
|
|
10
|
+
export function bt_mesh_edge_other_vertex(mesh, edge_id, vertex_id) {
|
|
11
|
+
|
|
12
|
+
const v1 = mesh.edge_read_vertex1(edge_id);
|
|
13
|
+
const v2 = mesh.edge_read_vertex2(edge_id);
|
|
14
|
+
|
|
15
|
+
if (v1 === vertex_id) {
|
|
16
|
+
return v2;
|
|
17
|
+
} else {
|
|
18
|
+
return v1;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { BinaryTopology } from "../BinaryTopology.js";
|
|
2
|
+
import { bt_mesh_edge_other_vertex } from "./bt_mesh_edge_other_vertex.js";
|
|
3
|
+
|
|
4
|
+
test('main', () => {
|
|
5
|
+
|
|
6
|
+
const mesh = new BinaryTopology();
|
|
7
|
+
|
|
8
|
+
const edge = mesh.edges.allocate();
|
|
9
|
+
|
|
10
|
+
mesh.edge_write_vertex1(edge, 7);
|
|
11
|
+
mesh.edge_write_vertex2(edge, 3);
|
|
12
|
+
|
|
13
|
+
expect(bt_mesh_edge_other_vertex(mesh, edge, 7)).toBe(3);
|
|
14
|
+
expect(bt_mesh_edge_other_vertex(mesh, edge, 3)).toBe(7);
|
|
15
|
+
|
|
16
|
+
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PLYLoader } from "three/examples/jsm/loaders/PLYLoader.js";
|
|
2
2
|
import { noop } from "../../../../function/Functions.js";
|
|
3
|
-
import { bt_index_geometry_to_topology } from "./bt_index_geometry_to_topology.js";
|
|
4
|
-
import { BinaryTopology } from "./BinaryTopology.js";
|
|
3
|
+
import { bt_index_geometry_to_topology } from "./binary/io/bt_index_geometry_to_topology.js";
|
|
4
|
+
import { BinaryTopology } from "./binary/BinaryTopology.js";
|
|
5
5
|
import {
|
|
6
6
|
compute_buffer_geometry_byte_size
|
|
7
7
|
} from "../../../../../engine/graphics/geometry/buffered/compute_buffer_geometry_byte_size.js";
|
|
@@ -18,27 +18,27 @@ function promise_ply(url) {
|
|
|
18
18
|
|
|
19
19
|
async function main() {
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
const url = "data/models/stanford/dragon_recon/dragon_vrip.ply";
|
|
21
|
+
const url = "data/models/stanford/Lucy100k.ply";
|
|
22
|
+
// const url = "data/models/stanford/dragon_recon/dragon_vrip.ply";
|
|
23
23
|
const lucy_geom = await promise_ply(url);
|
|
24
24
|
|
|
25
25
|
const mesh = new BinaryTopology();
|
|
26
|
+
const topoMesh = new TopoMesh();
|
|
26
27
|
|
|
27
28
|
const positions_array = lucy_geom.getAttribute('position').array;
|
|
28
29
|
const index_array = lucy_geom.getIndex().array;
|
|
29
30
|
|
|
30
31
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
console.time('topo build - obj');
|
|
34
|
-
topoMesh.build(positions_array, index_array);
|
|
35
|
-
console.timeEnd('topo build - obj');
|
|
36
|
-
|
|
37
|
-
// console.time('topo build - bin');
|
|
38
|
-
console.profile('topo build - bin');
|
|
32
|
+
console.time('topo build - bin');
|
|
33
|
+
// console.profile('topo build - bin');
|
|
39
34
|
bt_index_geometry_to_topology(mesh, index_array, positions_array);
|
|
40
|
-
console.profileEnd('topo build - bin');
|
|
41
|
-
|
|
35
|
+
// console.profileEnd('topo build - bin');
|
|
36
|
+
console.timeEnd('topo build - bin');
|
|
37
|
+
|
|
38
|
+
//
|
|
39
|
+
// console.time('topo build - obj');
|
|
40
|
+
// topoMesh.build(positions_array, index_array);
|
|
41
|
+
// console.timeEnd('topo build - obj');
|
|
42
42
|
|
|
43
43
|
mesh.trim();
|
|
44
44
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const PATH_SEPARATOR = '/';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { computePathBase } from "./computePathBase.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {string} path
|
|
6
|
+
* @returns {String|null}
|
|
7
|
+
*/
|
|
8
|
+
export function computeFileExtension(path) {
|
|
9
|
+
if (typeof path !== "string") {
|
|
10
|
+
throw new Error('path is not a string');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
//get base
|
|
14
|
+
const pathBase = computePathBase(path);
|
|
15
|
+
|
|
16
|
+
const lastDotIndex = pathBase.lastIndexOf('.');
|
|
17
|
+
|
|
18
|
+
if (lastDotIndex !== -1) {
|
|
19
|
+
return pathBase.substring(lastDotIndex + 1);
|
|
20
|
+
} else {
|
|
21
|
+
//no extension
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { computeFileExtension } from "./computeFileExtension.js";
|
|
2
|
+
|
|
3
|
+
test('extract extension of cat.txt', () => {
|
|
4
|
+
expect(computeFileExtension('cat.txt')).toEqual('txt');
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
test('extract extension of ../hmm/cat.txt', () => {
|
|
8
|
+
expect(computeFileExtension('../hmm/cat.txt')).toEqual('txt');
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test('extract extension of empty string', () => {
|
|
12
|
+
expect(computeFileExtension('')).toBeNull();
|
|
13
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { PATH_SEPARATOR } from "./PATH_SEPARATOR.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Strips all directories from the path.
|
|
5
|
+
* @example 'a/b/c' -> 'c'
|
|
6
|
+
* @param {string} path
|
|
7
|
+
* @returns {string}
|
|
8
|
+
*/
|
|
9
|
+
export function computePathBase(path) {
|
|
10
|
+
if (typeof path !== "string") {
|
|
11
|
+
throw new Error('path is not a string');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const lastSlashIndex = path.lastIndexOf(PATH_SEPARATOR);
|
|
15
|
+
|
|
16
|
+
if (lastSlashIndex !== -1) {
|
|
17
|
+
return path.substring(lastSlashIndex + 1);
|
|
18
|
+
} else {
|
|
19
|
+
return path;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { computePathBase } from "./computePathBase.js";
|
|
2
|
+
|
|
3
|
+
test('extract base path of empty string', () => {
|
|
4
|
+
expect(computePathBase('')).toBe('');
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
test('extract base path of hello', () => {
|
|
8
|
+
expect(computePathBase('hello')).toBe('hello');
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test('extract base path of hello/there/world', () => {
|
|
12
|
+
expect(computePathBase('hello/there/world')).toBe('world');
|
|
13
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { PATH_SEPARATOR } from "./PATH_SEPARATOR.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Returns the directory name of a path, similar to the Unix dirname command.
|
|
5
|
+
* @param {string} path
|
|
6
|
+
* @return {string}
|
|
7
|
+
*/
|
|
8
|
+
export function computePathDirectory(path) {
|
|
9
|
+
if (typeof path !== "string") {
|
|
10
|
+
throw new Error('path is not a string');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
let lastSlashIndex = path.lastIndexOf(PATH_SEPARATOR);
|
|
14
|
+
|
|
15
|
+
//rewind in case of trailing slashes
|
|
16
|
+
while (lastSlashIndex > 0 && path.charAt(lastSlashIndex - 1) === PATH_SEPARATOR) {
|
|
17
|
+
lastSlashIndex--;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (lastSlashIndex !== -1) {
|
|
21
|
+
return path.substring(0, lastSlashIndex);
|
|
22
|
+
} else {
|
|
23
|
+
return path;
|
|
24
|
+
}
|
|
25
|
+
}
|
package/editor/Editor.js
CHANGED
|
@@ -71,8 +71,8 @@ import { ObservedIntegerEditor } from "./ecs/component/editors/ObservedIntegerEd
|
|
|
71
71
|
|
|
72
72
|
import '../../../../css/editor/EntityEditorView.scss';
|
|
73
73
|
import '../../../../css/editor/EditorView.scss';
|
|
74
|
-
import {ParameterTrackSet} from "../engine/graphics/particles/particular/engine/parameter/ParameterTrackSet.js";
|
|
75
|
-
import {ParameterTrackSetEditor} from "./ecs/component/editors/ecs/ParameterTrackSetEditor.js";
|
|
74
|
+
import { ParameterTrackSet } from "../engine/graphics/particles/particular/engine/parameter/ParameterTrackSet.js";
|
|
75
|
+
import { ParameterTrackSetEditor } from "./ecs/component/editors/ecs/ParameterTrackSetEditor.js";
|
|
76
76
|
|
|
77
77
|
/**
|
|
78
78
|
* @template T
|
|
@@ -485,6 +485,7 @@ function Editor() {
|
|
|
485
485
|
resetSoundEmitterTracks(dataset);
|
|
486
486
|
|
|
487
487
|
const serializer = new BinaryBufferSerializer();
|
|
488
|
+
serializer.engine = self.engine;
|
|
488
489
|
serializer.registry = engine.binarySerializationRegistry;
|
|
489
490
|
|
|
490
491
|
const state = new EncodingBinaryBuffer();
|
|
@@ -2,13 +2,13 @@ import View from "../../../view/View.js";
|
|
|
2
2
|
import { makeModelView } from "../../../view/renderModel.js";
|
|
3
3
|
import Vector2 from "../../../core/geom/Vector2.js";
|
|
4
4
|
import domify from "../../../view/DOM.js";
|
|
5
|
-
import { computePathBase } from "../../../core/FilePath.js";
|
|
6
5
|
import LabelView from "../../../view/common/LabelView.js";
|
|
7
6
|
import List from "../../../core/collection/list/List.js";
|
|
8
7
|
import AABB2 from "../../../core/geom/AABB2.js";
|
|
9
8
|
import { DragEvents } from "../../../engine/input/devices/events/DragEvents.js";
|
|
10
9
|
import { MouseEvents } from "../../../engine/input/devices/events/MouseEvents.js";
|
|
11
10
|
import { TouchEvents } from "../../../engine/input/devices/events/TouchEvents.js";
|
|
11
|
+
import { computePathBase } from "../../../core/path/computePathBase.js";
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
const ICON_SIZE = 50;
|
package/engine/EngineHarness.js
CHANGED
|
@@ -29,6 +29,8 @@ import { noop } from "../core/function/Functions.js";
|
|
|
29
29
|
import SoundListenerSystem from "./sound/ecs/SoundListenerSystem.js";
|
|
30
30
|
import SoundListener from "./sound/ecs/SoundListener.js";
|
|
31
31
|
import { getURLHash } from "./platform/GetURLHash.js";
|
|
32
|
+
import Stats from "three/examples/jsm/libs/stats.module.js";
|
|
33
|
+
import EmptyView from "../view/elements/EmptyView.js";
|
|
32
34
|
|
|
33
35
|
/**
|
|
34
36
|
*
|
|
@@ -68,6 +70,22 @@ export class EngineHarness {
|
|
|
68
70
|
this.p = null;
|
|
69
71
|
}
|
|
70
72
|
|
|
73
|
+
/**
|
|
74
|
+
*
|
|
75
|
+
* @param {Engine} engine
|
|
76
|
+
*/
|
|
77
|
+
static addFpsCounter(engine) {
|
|
78
|
+
const stats = new Stats();
|
|
79
|
+
|
|
80
|
+
engine.graphics.on.postRender.add(stats.update, stats);
|
|
81
|
+
|
|
82
|
+
const view = new EmptyView({
|
|
83
|
+
el: stats.domElement
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
engine.viewStack.addChild(view);
|
|
87
|
+
}
|
|
88
|
+
|
|
71
89
|
/**
|
|
72
90
|
* @param {(config:EngineConfiguration,engine:Engine)=>*} configuration
|
|
73
91
|
* @param {boolean} [enable_localization] Whether or not to load localization data
|
|
@@ -228,6 +246,7 @@ export class EngineHarness {
|
|
|
228
246
|
* @param {boolean} [cameraController=true]
|
|
229
247
|
* @param {boolean} [cameraAutoClip]
|
|
230
248
|
* @param shadowmapResolution
|
|
249
|
+
* @param showFps
|
|
231
250
|
*/
|
|
232
251
|
static async buildBasics({
|
|
233
252
|
engine,
|
|
@@ -246,9 +265,14 @@ export class EngineHarness {
|
|
|
246
265
|
cameraFarDistance,
|
|
247
266
|
cameraController = true,
|
|
248
267
|
cameraAutoClip = false,
|
|
249
|
-
shadowmapResolution
|
|
268
|
+
shadowmapResolution,
|
|
269
|
+
showFps = true
|
|
250
270
|
}) {
|
|
251
271
|
|
|
272
|
+
if (showFps) {
|
|
273
|
+
EngineHarness.addFpsCounter(engine);
|
|
274
|
+
}
|
|
275
|
+
|
|
252
276
|
if (enableLights) {
|
|
253
277
|
await EngineHarness.buildLights({ engine: engine, shadowmapResolution });
|
|
254
278
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { AssetLoader } from "../AssetLoader.js";
|
|
2
|
-
import { computeFileExtension } from "../../../../core/FilePath.js";
|
|
3
2
|
import { GameAssetType } from "../../GameAssetType.js";
|
|
4
3
|
import { convertTexture2Sampler2D } from "../../../graphics/texture/sampler/convertTexture2Sampler2D.js";
|
|
5
4
|
import { ImageRGBADataAsset } from "./ImageRGBADataAsset.js";
|
|
@@ -7,6 +6,7 @@ import { ArrayBufferLoader } from "../ArrayBufferLoader.js";
|
|
|
7
6
|
import { CodecWithFallback } from "./codec/CodecWithFallback.js";
|
|
8
7
|
import { ThreadedImageDecoder } from "./codec/ThreadedImageDecoder.js";
|
|
9
8
|
import { NativeImageDecoder } from "./codec/NativeImageDecoder.js";
|
|
9
|
+
import { computeFileExtension } from "../../../../core/path/computeFileExtension.js";
|
|
10
10
|
|
|
11
11
|
const ASSET_TYPE_ARRAY_BUFFER = "arraybuffer";
|
|
12
12
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AssetLoader } from "../AssetLoader.js";
|
|
2
|
-
import { computeFileExtension } from "../../../../core/FilePath.js";
|
|
3
2
|
import { loadDDSTexture } from "./loadDDSTexture.js";
|
|
4
3
|
import { loadStandardImageTexture } from "./loadStandardImageTexture.js";
|
|
4
|
+
import { computeFileExtension } from "../../../../core/path/computeFileExtension.js";
|
|
5
5
|
|
|
6
6
|
export class TextureAssetLoader extends AssetLoader {
|
|
7
7
|
load(path, success, failure, progress) {
|
|
@@ -55,6 +55,11 @@ class BinaryBufferSerializer {
|
|
|
55
55
|
* @type {BinarySerializationRegistry}
|
|
56
56
|
*/
|
|
57
57
|
this.registry = null;
|
|
58
|
+
/**
|
|
59
|
+
*
|
|
60
|
+
* @type {Engine|null}
|
|
61
|
+
*/
|
|
62
|
+
this.engine = null;
|
|
58
63
|
}
|
|
59
64
|
|
|
60
65
|
/**
|
|
@@ -92,6 +97,8 @@ class BinaryBufferSerializer {
|
|
|
92
97
|
|
|
93
98
|
let i;
|
|
94
99
|
|
|
100
|
+
const engine = this.engine;
|
|
101
|
+
|
|
95
102
|
for (i = 0; i < numSerializableTypes; i++) {
|
|
96
103
|
|
|
97
104
|
const componentType = serializableComponentTypes[i];
|
|
@@ -8,9 +8,13 @@ import { assert } from "../../../core/assert.js";
|
|
|
8
8
|
*/
|
|
9
9
|
export function camera_compute_distance_to_fit_length(length, fov) {
|
|
10
10
|
assert.isNumber(length, 'length');
|
|
11
|
+
assert.greaterThanOrEqual(length, 0, 'length < 0');
|
|
12
|
+
|
|
11
13
|
assert.isNumber(fov, 'fov');
|
|
12
14
|
assert.greaterThan(fov, 0, 'fov <= 0');
|
|
13
15
|
assert.lessThan(fov, Math.PI, 'fov >= pi');
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
const signed_distance = (length * 0.5) / Math.tan(fov * 0.5);
|
|
18
|
+
|
|
19
|
+
return Math.abs(signed_distance);
|
|
16
20
|
}
|
|
@@ -1,3 +1,29 @@
|
|
|
1
|
+
import { array_quick_sort_by_comparator } from "../../../../../../core/collection/array/arrayQuickSort.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {THREE.Object3D} a
|
|
6
|
+
* @param {THREE.Object3D} b
|
|
7
|
+
* @returns {number}
|
|
8
|
+
*/
|
|
9
|
+
function compare_by_material(a, b) {
|
|
10
|
+
|
|
11
|
+
const a_mat = a.material;
|
|
12
|
+
const b_mat = b.material;
|
|
13
|
+
|
|
14
|
+
if (a_mat === b_mat) {
|
|
15
|
+
return 0;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (a_mat === undefined) {
|
|
19
|
+
return 1;
|
|
20
|
+
} else if (b_mat === undefined) {
|
|
21
|
+
return -1;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return a_mat.id - b_mat.id;
|
|
25
|
+
}
|
|
26
|
+
|
|
1
27
|
export class AbstractRenderAdapter {
|
|
2
28
|
constructor() {
|
|
3
29
|
|
|
@@ -16,6 +42,13 @@ export class AbstractRenderAdapter {
|
|
|
16
42
|
this.__objects = [];
|
|
17
43
|
}
|
|
18
44
|
|
|
45
|
+
/**
|
|
46
|
+
* Sorting objects by material will help reduce context switching and number of graphics API calls
|
|
47
|
+
*/
|
|
48
|
+
sort_by_material() {
|
|
49
|
+
array_quick_sort_by_comparator(this.__objects, compare_by_material, null, 0, this.__object_count - 1);
|
|
50
|
+
}
|
|
51
|
+
|
|
19
52
|
/**
|
|
20
53
|
*
|
|
21
54
|
* @param {THREE.BufferGeometry} geometry
|
|
@@ -110,6 +110,7 @@ async function main(engine) {
|
|
|
110
110
|
// sg.draw_method = 2;
|
|
111
111
|
// sg.draw_method = DRAW_METHOD_INSTANCED;
|
|
112
112
|
// sg.draw_method = random() > 0.5 ? DRAW_METHOD_INSTANCED : 2;
|
|
113
|
+
sg.setFlag(ShadedGeometryFlags.DrawMethodLocked);
|
|
113
114
|
sg.clearFlag(ShadedGeometryFlags.CastShadow | ShadedGeometryFlags.ReceiveShadow);
|
|
114
115
|
|
|
115
116
|
new EntityBuilder()
|
|
@@ -13,6 +13,7 @@ export function composeCompile(previous, next) {
|
|
|
13
13
|
let t1_cache = cache.get(previous);
|
|
14
14
|
|
|
15
15
|
if (t1_cache === undefined) {
|
|
16
|
+
// no caches starting from previous
|
|
16
17
|
t1_cache = new WeakMap();
|
|
17
18
|
|
|
18
19
|
cache.set(previous, t1_cache);
|
|
@@ -21,14 +22,11 @@ export function composeCompile(previous, next) {
|
|
|
21
22
|
let result_function = t1_cache.get(next);
|
|
22
23
|
|
|
23
24
|
if (result_function === undefined) {
|
|
25
|
+
// no matching function found for pair, let's create it
|
|
26
|
+
|
|
24
27
|
// we create a custom function just to be able to name our function, this is because of how three.js caches onBeforeCompile by just turning it into the string, so changing the function name will result in altered cache key
|
|
25
28
|
const f = new Function('previous, next', `return function f${id_counter++}(a,b,c,d){ previous(a,b,c,d); next(a,b,c,d); };`);
|
|
26
29
|
|
|
27
|
-
// result_function = function (a, b, c, d) {
|
|
28
|
-
// previous(a, b, c, d);
|
|
29
|
-
// next(a, b, c, d);
|
|
30
|
-
// };
|
|
31
|
-
//
|
|
32
30
|
|
|
33
31
|
result_function = f(previous, next);
|
|
34
32
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { AssetTransformer } from "../../../asset/AssetTransformer.js";
|
|
2
|
-
import { computePathDirectory } from "../../../../core/FilePath.js";
|
|
3
2
|
import { BinaryBuffer } from "../../../../core/binary/BinaryBuffer.js";
|
|
4
3
|
import { MicronGeometry } from "../format/MicronGeometry.js";
|
|
5
4
|
import { MICRON_GEOMETRY_FIELD } from "../MICRON_GEOMETRY_FIELD.js";
|
|
@@ -12,6 +11,7 @@ import {
|
|
|
12
11
|
deserialize_geometry_collection
|
|
13
12
|
} from "../format/serialization/collection/geometry_collection_serialization.js";
|
|
14
13
|
import { GLTF_MICRON_ID_FIELD } from "./GLTF_MICRON_ID_FIELD.js";
|
|
14
|
+
import { computePathDirectory } from "../../../../core/path/computePathDirectory.js";
|
|
15
15
|
|
|
16
16
|
export const ASSET_TYPE_ARRAY_BUFFER = "arraybuffer";
|
|
17
17
|
|
|
@@ -3,3 +3,5 @@ Path tracing ideas:
|
|
|
3
3
|
* [smallpt](https://www.kevinbeason.com/smallpt/) (100 line c implementation of path tracer)
|
|
4
4
|
* [three path tracer](https://github.com/gkjohnson/three-gpu-pathtracer)
|
|
5
5
|
* http://blog.hvidtfeldts.net/index.php/2015/01/path-tracing-3d-fractals/
|
|
6
|
+
* [Global Illumination and Path Tracing](https://www.scratchapixel.com/lessons/3d-basic-rendering/global-illumination-path-tracing/global-illumination-path-tracing-practical-implementation)
|
|
7
|
+
* [Path Tracing, by Steve Rotenberg](https://cseweb.ucsd.edu/classes/sp17/cse168-a/CSE168_08_PathTracing.pdf)
|
|
@@ -20,7 +20,6 @@ import {
|
|
|
20
20
|
UnsignedByteType
|
|
21
21
|
} from "three";
|
|
22
22
|
import { linear_to_sRGB } from "../../../../core/color/linear_to_sRGB.js";
|
|
23
|
-
import { random_in_hemisphere } from "./random_in_hemisphere.js";
|
|
24
23
|
import { sample_triangle_attribute } from "./sample_triangle_attribute.js";
|
|
25
24
|
import { vec3_uint8_to_float } from "./vec3_uint8_to_float.js";
|
|
26
25
|
import { apply_texture_clamping_to_coordinate } from "./apply_texture_clamping_to_coordinate.js";
|
|
@@ -527,10 +526,6 @@ export class PathTracer {
|
|
|
527
526
|
break;
|
|
528
527
|
}
|
|
529
528
|
|
|
530
|
-
|
|
531
|
-
// irradiance[0] += m;
|
|
532
|
-
// irradiance[1] += m;
|
|
533
|
-
// irradiance[2] += m;
|
|
534
529
|
this.sample_material(tmp_0, trace_result);
|
|
535
530
|
|
|
536
531
|
// adjust normal on the hit
|
|
@@ -541,7 +536,6 @@ export class PathTracer {
|
|
|
541
536
|
array_copy(trace_result, 0, _ray_0, 0, 3);
|
|
542
537
|
|
|
543
538
|
getBiasedNormalSample(_ray_0, 3, tmp_0, 3, 1, random);
|
|
544
|
-
// random_in_hemisphere(random, _ray_0, 3, tmp_0, 3);
|
|
545
539
|
|
|
546
540
|
// accumulate
|
|
547
541
|
vec3.multiply(irradiance, irradiance, tmp_0);
|
|
@@ -556,14 +550,6 @@ export class PathTracer {
|
|
|
556
550
|
vec3.multiply(irradiance, irradiance, tmp_1);
|
|
557
551
|
}
|
|
558
552
|
|
|
559
|
-
//
|
|
560
|
-
// if (got_emission === false) {
|
|
561
|
-
// // no light source was hit, propagate shadow(darkness) along the ray
|
|
562
|
-
// irradiance[0] = 0;
|
|
563
|
-
// irradiance[1] = 0;
|
|
564
|
-
// irradiance[2] = 0;
|
|
565
|
-
// }
|
|
566
|
-
|
|
567
553
|
array_copy(irradiance, 0, out, 0, 3);
|
|
568
554
|
}
|
|
569
555
|
}
|