@woosh/meep-engine 2.43.22 → 2.43.23
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/view/library/MeshLibraryView.js +1 -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/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 +98 -0
- package/engine/network/remoteEditor.js +33 -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
|
+
}
|
|
@@ -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;
|
|
@@ -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];
|
|
@@ -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
|
}
|
|
@@ -7,8 +7,7 @@ import {
|
|
|
7
7
|
OctahedronBufferGeometry,
|
|
8
8
|
PerspectiveCamera,
|
|
9
9
|
PlaneBufferGeometry,
|
|
10
|
-
Sphere
|
|
11
|
-
SphereBufferGeometry
|
|
10
|
+
Sphere
|
|
12
11
|
} from "three";
|
|
13
12
|
import { Sampler2D } from "../../texture/sampler/Sampler2D.js";
|
|
14
13
|
import sampler2D2Canvas from "../../texture/sampler/Sampler2D2Canvas.js";
|
|
@@ -134,8 +133,13 @@ function make_sun({
|
|
|
134
133
|
function prepare_scene_sphere_01(pt, camera) {
|
|
135
134
|
camera.position.set(0, 0, -2.1);
|
|
136
135
|
camera.lookAt(0, 0, 0);
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
const sphere_geo = new OctahedronBufferGeometry(1, 9);
|
|
139
|
+
makeGeometryIndexed(sphere_geo);
|
|
140
|
+
|
|
137
141
|
pt.addMesh(
|
|
138
|
-
|
|
142
|
+
sphere_geo,
|
|
139
143
|
// new MeshStandardMaterial({ color: '#FF0000' }),
|
|
140
144
|
new MeshStandardMaterial({ color: '#FFFFFF' }),
|
|
141
145
|
Transform.fromJSON({
|
|
@@ -460,7 +464,7 @@ function* render(target, pt, camera, progress = { current: 0, total: 0 }) {
|
|
|
460
464
|
ray_direction.x, ray_direction.y, ray_direction.z
|
|
461
465
|
);
|
|
462
466
|
|
|
463
|
-
pt.path_trace(out, ray, Infinity,
|
|
467
|
+
pt.path_trace(out, ray, Infinity, 4, random);
|
|
464
468
|
|
|
465
469
|
out2[0] += out[0];
|
|
466
470
|
out2[1] += out[1];
|
|
@@ -510,13 +514,13 @@ const camera = new PerspectiveCamera();
|
|
|
510
514
|
async function start_renderer(camera) {
|
|
511
515
|
camera.aspect = vCanvas.size.x / vCanvas.size.y;
|
|
512
516
|
|
|
513
|
-
const path = 'data/models/LowPolyTownshipSet/Small_house/Small_house.gltf';
|
|
517
|
+
// const path = 'data/models/LowPolyTownshipSet/Small_house/Small_house.gltf';
|
|
514
518
|
// const path = 'data/models/road_bike/road_bike.gltf'; //large CAD-type model
|
|
515
519
|
|
|
516
520
|
// await prepare_scene_lucy(pt, camera);
|
|
517
521
|
// await prepare_scene_rtiow(pt, camera);
|
|
518
|
-
|
|
519
|
-
await prepare_scene_gltf(pt, camera, path);
|
|
522
|
+
await prepare_scene_sphere_01(pt, camera);
|
|
523
|
+
// await prepare_scene_gltf(pt, camera, path);
|
|
520
524
|
|
|
521
525
|
pt.build();
|
|
522
526
|
pt.optimize();
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { EXRLoader } from "three/examples/jsm/loaders/EXRLoader.js";
|
|
2
2
|
import { CubeTextureLoader, LinearFilter, PMREMGenerator, sRGBEncoding, TextureLoader, UnsignedByteType } from "three";
|
|
3
3
|
import { noop } from "../../../../core/function/Functions.js";
|
|
4
|
-
import { computeFileExtension } from "../../../../core/FilePath.js";
|
|
5
4
|
import { HDRCubeTextureLoader } from "three/examples/jsm/loaders/HDRCubeTextureLoader.js";
|
|
5
|
+
import { computeFileExtension } from "../../../../core/path/computeFileExtension.js";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
*
|
|
@@ -15,39 +15,51 @@ import AABB2 from "../../../core/geom/AABB2.js";
|
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
*
|
|
18
|
-
* @param {
|
|
19
|
-
* @param {Vector2} size
|
|
20
|
-
* @param {AABB2} focus
|
|
21
|
-
* @returns {{scene: Scene, camera: PerspectiveCamera}}
|
|
18
|
+
* @param {THREE.OrthographicCamera} camera
|
|
22
19
|
*/
|
|
23
|
-
|
|
24
|
-
const
|
|
20
|
+
function setShadowCamera(camera) {
|
|
21
|
+
const sqrt2 = Math.sqrt(2);
|
|
22
|
+
let sqrt2_2 = sqrt2 / 2;
|
|
23
|
+
camera.left = -sqrt2_2;
|
|
24
|
+
camera.right = sqrt2_2;
|
|
25
|
+
|
|
26
|
+
camera.bottom = -sqrt2_2;
|
|
27
|
+
camera.top = sqrt2_2;
|
|
28
|
+
}
|
|
25
29
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
/**
|
|
31
|
+
*
|
|
32
|
+
* @param {THREE.Scene} scene
|
|
33
|
+
*/
|
|
34
|
+
function setupLights(scene) {
|
|
35
|
+
const lightKey = new ThreeDirectionalLight(0xffffff, 1);
|
|
36
|
+
lightKey.position.set(-1, 1, 1);
|
|
37
|
+
lightKey.castShadow = true;
|
|
38
|
+
lightKey.shadow.mapSize.set(1024, 1024);
|
|
31
39
|
|
|
32
|
-
function setShadowCamera(camera) {
|
|
33
|
-
const sqrt2 = Math.sqrt(2);
|
|
34
|
-
let sqrt2_2 = sqrt2 / 2;
|
|
35
|
-
camera.left = -sqrt2_2;
|
|
36
|
-
camera.right = sqrt2_2;
|
|
37
40
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
+
setShadowCamera(lightKey.shadow.camera);
|
|
42
|
+
scene.add(lightKey);
|
|
41
43
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
+
const lightHighlight = new ThreeDirectionalLight(0xffffff, 0.50);
|
|
45
|
+
lightHighlight.position.set(0, 0, 1);
|
|
46
|
+
scene.add(lightHighlight);
|
|
44
47
|
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
+
const lightFill = new ThreeAmbientLight(0xFFFFFF, 0.5);
|
|
49
|
+
scene.add(lightFill);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
*
|
|
54
|
+
* @param {Mesh} mesh trhee.js mesh
|
|
55
|
+
* @param {Vector2} size
|
|
56
|
+
* @param {AABB2} focus
|
|
57
|
+
* @returns {{scene: Scene, camera: THREE.PerspectiveCamera}}
|
|
58
|
+
*/
|
|
59
|
+
export function makeMeshPreviewScene(mesh, size, focus = new AABB2(0, 0, size.x, size.y)) {
|
|
60
|
+
const scene = new ThreeScene();
|
|
48
61
|
|
|
49
|
-
|
|
50
|
-
scene.add(l2);
|
|
62
|
+
setupLights(scene);
|
|
51
63
|
|
|
52
64
|
scaleObject3ToBox(mesh, new Vector3(1, 1, 1), mesh.scale);
|
|
53
65
|
scene.add(mesh);
|