@woosh/meep-engine 2.34.49 → 2.35.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/bvh2/BinaryNode.js +19 -35
- package/core/bvh2/aabb3/aabb3_intersects_frustum_array.js +5 -5
- package/core/bvh2/aabb3_combined_surface_area.js +21 -0
- package/core/bvh2/traversal/queryBinaryNode_FrustumIntersections.js +24 -12
- package/core/cache/Cache.d.ts +2 -0
- package/core/cache/Cache.js +27 -23
- package/core/geom/3d/frustum/frustum_from_projection_matrix_array.js +2 -0
- package/core/math/max2.js +2 -6
- package/core/math/min2.js +2 -6
- package/engine/asset/loaders/geometry/geometry/computeGeometryEquality.js +1 -1
- package/engine/asset/loaders/geometry/geometry/computeGeometryHash.js +9 -1
- package/engine/ecs/EntityComponentDataset.js +7 -2
- package/engine/ecs/foliage/ViewState.js +13 -3
- package/engine/ecs/parent/EntityNode.js +23 -11
- package/engine/ecs/transform/Transform.js +15 -13
- package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +63 -26
- package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +63 -3
- package/engine/graphics/ecs/mesh-v2/render/AbstractRenderAdapter.js +67 -0
- package/engine/graphics/ecs/mesh-v2/render/GenericRendererAdapter.js +48 -0
- package/engine/graphics/ecs/mesh-v2/render/InstancedRendererAdapter.js +110 -0
- package/engine/graphics/ecs/mesh-v2/render/ShadedGeometryRendererContext.js +98 -0
- package/engine/graphics/ecs/mesh-v2/sample/load_gltf.js +5 -0
- package/engine/graphics/ecs/mesh-v2/sample/prototypeShadedGeometry.js +23 -5
- package/engine/graphics/ecs/mesh-v2/three_object_to_entity_composition.js +8 -3
- package/engine/graphics/geometry/instancing/InstancedMeshGroup.js +23 -85
- package/engine/graphics/geometry/instancing/rewriteMaterial.js +9 -45
- package/engine/graphics/material/optimization/BUFFER_GEOMETRY_UVS.js +10 -0
- package/engine/graphics/material/optimization/MaterialDescriptor.js +46 -0
- package/engine/graphics/material/optimization/MaterialOptimizationContext.js +470 -201
- package/engine/graphics/material/optimization/UvContext.js +18 -0
- package/engine/graphics/material/optimization/is_compliant_mesh.js +71 -0
- package/engine/graphics/material/optimization/prepare_atlas_texture.js +23 -0
- package/engine/graphics/material/optimization/prototypeMaterialOptimizer.js +127 -0
- package/engine/graphics/micron/format/MicronGeometryPatch.js +1 -1
- package/engine/graphics/micron/format/VirtualGeometry.js +47 -11
- package/engine/graphics/micron/format/serialization/MicronGeometryBinarySerializationAdapter.js +16 -0
- package/engine/graphics/micron/prototypeVirtualGeometry.js +3 -2
- package/engine/graphics/micron/render/VirtualGeometryBuilder.js +5 -7
- package/engine/graphics/micron/render/instanced/AttributeDataTexture.js +1 -45
- package/engine/graphics/micron/render/instanced/ThreeInstancedAdapter.js +18 -7
- package/engine/graphics/micron/render/refinement/RefinementSpec.js +0 -1
- package/engine/graphics/micron/render/refinement/get_geometry_patch_cut.js +17 -24
- package/engine/graphics/micron/render/v1/MaterialContext.js +3 -2
- package/engine/graphics/micron/render/v1/VGThreeRenderer.js +19 -4
- package/engine/graphics/render/utils/ThreeBypassRenderer.js +3 -2
- package/engine/graphics/texture/normalized_internal_format.js +48 -0
- package/engine/graphics/texture/sampler/Sampler2D.js +6 -0
- package/engine/graphics/texture/sampler/sampler2d_copy_channel_data.js +25 -0
- package/engine/graphics/texture/sampler/scaleSampler2D.js +3 -0
- package/engine/graphics/texture/sampler/util/drawSamplerHTML.js +14 -1
- package/package.json +1 -1
|
@@ -12,6 +12,42 @@ const DEFAULT_FLAGS = ShadedGeometryFlags.CastShadow
|
|
|
12
12
|
| ShadedGeometryFlags.ReceiveShadow
|
|
13
13
|
;
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
*
|
|
17
|
+
* @param {ShadedGeometry} sg
|
|
18
|
+
* @returns {THREE.Object3D}
|
|
19
|
+
*/
|
|
20
|
+
export function build_three_object(sg) {
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @type {THREE.Object3D}
|
|
24
|
+
*/
|
|
25
|
+
let object;
|
|
26
|
+
|
|
27
|
+
const mode = sg.mode;
|
|
28
|
+
const shader = sg.material;
|
|
29
|
+
const geo = sg.geometry;
|
|
30
|
+
|
|
31
|
+
if (mode === DrawMode.Triangles) {
|
|
32
|
+
object = new Mesh(geo, shader);
|
|
33
|
+
} else if (mode === DrawMode.Lines) {
|
|
34
|
+
object = new Line(geo, shader);
|
|
35
|
+
} else if (mode === DrawMode.LineSegments) {
|
|
36
|
+
object = new LineSegments(geo, shader);
|
|
37
|
+
} else {
|
|
38
|
+
throw new Error(`Unsupported draw mode '${mode}'`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
object.matrixAutoUpdate = false;
|
|
42
|
+
object.frustumCulled = false;
|
|
43
|
+
object.matrixWorldNeedsUpdate = false;
|
|
44
|
+
|
|
45
|
+
object.castShadow = sg.getFlag(ShadedGeometryFlags.CastShadow);
|
|
46
|
+
object.receiveShadow = sg.getFlag(ShadedGeometryFlags.ReceiveShadow);
|
|
47
|
+
|
|
48
|
+
return object;
|
|
49
|
+
}
|
|
50
|
+
|
|
15
51
|
export class ShadedGeometry {
|
|
16
52
|
constructor() {
|
|
17
53
|
/**
|
|
@@ -51,6 +87,7 @@ export class ShadedGeometry {
|
|
|
51
87
|
* @private
|
|
52
88
|
*/
|
|
53
89
|
this.__entity = -1;
|
|
90
|
+
|
|
54
91
|
/**
|
|
55
92
|
* Transform matrix
|
|
56
93
|
* Transient, assigned in the system
|
|
@@ -59,6 +96,12 @@ export class ShadedGeometry {
|
|
|
59
96
|
*/
|
|
60
97
|
this.__transform = null;
|
|
61
98
|
|
|
99
|
+
/**
|
|
100
|
+
* Transient property signifying how to render object
|
|
101
|
+
* @type {number}
|
|
102
|
+
*/
|
|
103
|
+
this.draw_method = 0;
|
|
104
|
+
|
|
62
105
|
/**
|
|
63
106
|
*
|
|
64
107
|
* @type {number}
|
|
@@ -106,6 +149,25 @@ export class ShadedGeometry {
|
|
|
106
149
|
return (this.flags & flag) === flag;
|
|
107
150
|
}
|
|
108
151
|
|
|
152
|
+
/**
|
|
153
|
+
*
|
|
154
|
+
* @return {number}
|
|
155
|
+
*/
|
|
156
|
+
hash() {
|
|
157
|
+
return this.geometry.id ^ this.material.id;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
*
|
|
162
|
+
* @param {ShadedGeometry} other
|
|
163
|
+
* @returns {boolean}
|
|
164
|
+
*/
|
|
165
|
+
equals(other) {
|
|
166
|
+
return this.geometry.id === other.geometry.id
|
|
167
|
+
&& this.material.id === other.material.id
|
|
168
|
+
;
|
|
169
|
+
}
|
|
170
|
+
|
|
109
171
|
/**
|
|
110
172
|
* Current cached entity that this component is attached to
|
|
111
173
|
* @return {number}
|
|
@@ -130,32 +192,7 @@ export class ShadedGeometry {
|
|
|
130
192
|
}
|
|
131
193
|
|
|
132
194
|
__build_object() {
|
|
133
|
-
|
|
134
|
-
* @type {THREE.Object3D}
|
|
135
|
-
*/
|
|
136
|
-
let object;
|
|
137
|
-
|
|
138
|
-
const mode = this.mode;
|
|
139
|
-
const shader = this.material;
|
|
140
|
-
const geo = this.geometry;
|
|
141
|
-
|
|
142
|
-
if (mode === DrawMode.Triangles) {
|
|
143
|
-
object = new Mesh(geo, shader);
|
|
144
|
-
} else if (mode === DrawMode.Lines) {
|
|
145
|
-
object = new Line(geo, shader);
|
|
146
|
-
} else if (mode === DrawMode.LineSegments) {
|
|
147
|
-
object = new LineSegments(geo, shader);
|
|
148
|
-
} else {
|
|
149
|
-
throw new Error(`Unsupported draw mode '${mode}'`);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
object.matrixAutoUpdate = false;
|
|
153
|
-
object.frustumCulled = false;
|
|
154
|
-
|
|
155
|
-
object.castShadow = this.getFlag(ShadedGeometryFlags.CastShadow);
|
|
156
|
-
object.receiveShadow = this.getFlag(ShadedGeometryFlags.ReceiveShadow);
|
|
157
|
-
|
|
158
|
-
this.__cached_object = object;
|
|
195
|
+
this.__cached_object = build_three_object(this);
|
|
159
196
|
}
|
|
160
197
|
|
|
161
198
|
get bvh() {
|
|
@@ -7,6 +7,8 @@ import { v3_distance_sqr } from "../../../../core/geom/v3_distance_sqr.js";
|
|
|
7
7
|
import { mat4 } from "gl-matrix";
|
|
8
8
|
import { returnTrue } from "../../../../core/function/Functions.js";
|
|
9
9
|
import { aabb3_intersects_ray } from "../../../../core/bvh2/aabb3/aabb3_intersects_ray.js";
|
|
10
|
+
import { ShadedGeometryRendererContext } from "./render/ShadedGeometryRendererContext.js";
|
|
11
|
+
import { BinaryNode } from "../../../../core/bvh2/BinaryNode.js";
|
|
10
12
|
|
|
11
13
|
/**
|
|
12
14
|
*
|
|
@@ -54,14 +56,72 @@ export class ShadedGeometrySystem extends System {
|
|
|
54
56
|
* @private
|
|
55
57
|
*/
|
|
56
58
|
this.__render_layer = null;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
*
|
|
62
|
+
* @type {Map<CameraView, ShadedGeometryRendererContext>}
|
|
63
|
+
* @private
|
|
64
|
+
*/
|
|
65
|
+
this.__view_contexts = new Map();
|
|
66
|
+
|
|
67
|
+
this.__bvh = new BinaryNode();
|
|
68
|
+
this.__bvh.setNegativelyInfiniteBounds();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
*
|
|
73
|
+
* @param {CameraView} view
|
|
74
|
+
* @private
|
|
75
|
+
*/
|
|
76
|
+
__handle_view_added(view) {
|
|
77
|
+
this.__view_contexts.set(view, new ShadedGeometryRendererContext());
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
*
|
|
82
|
+
* @param {CameraView} view
|
|
83
|
+
* @private
|
|
84
|
+
*/
|
|
85
|
+
__handle_view_removed(view) {
|
|
86
|
+
const ctx = this.__view_contexts.get(view);
|
|
87
|
+
|
|
88
|
+
this.__view_contexts.delete(view);
|
|
89
|
+
|
|
90
|
+
ctx.dispose();
|
|
57
91
|
}
|
|
58
92
|
|
|
59
93
|
async startup(entityManager, readyCallback, errorCallback) {
|
|
60
94
|
|
|
61
95
|
const engine = this.__engine;
|
|
96
|
+
const graphics = engine.graphics;
|
|
97
|
+
|
|
98
|
+
const view_list = graphics.views.elements;
|
|
99
|
+
|
|
100
|
+
view_list.forEach(this.__handle_view_added, this);
|
|
101
|
+
view_list.on.added.add(this.__handle_view_added, this);
|
|
102
|
+
view_list.on.removed.add(this.__handle_view_removed, this);
|
|
103
|
+
|
|
104
|
+
this.__render_layer = graphics.layers.create('shaded-geometry');
|
|
105
|
+
|
|
106
|
+
this.__render_layer.buildVisibleSet = ((destination, destination_offset, view) => {
|
|
107
|
+
const ctx = this.__view_contexts.get(view);
|
|
108
|
+
|
|
109
|
+
return ctx.collect(destination, destination_offset, view, this.__bvh);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
readyCallback();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async shutdown(entityManager, readyCallback, errorCallback) {
|
|
116
|
+
|
|
117
|
+
const engine = this.__engine;
|
|
118
|
+
const graphics = engine.graphics;
|
|
119
|
+
|
|
120
|
+
const view_list = graphics.views.elements;
|
|
62
121
|
|
|
63
|
-
this.
|
|
64
|
-
this.
|
|
122
|
+
view_list.forEach(this.__handle_view_removed, this);
|
|
123
|
+
view_list.on.added.remove(this.__handle_view_added, this);
|
|
124
|
+
view_list.on.removed.remove(this.__handle_view_removed, this);
|
|
65
125
|
|
|
66
126
|
readyCallback();
|
|
67
127
|
}
|
|
@@ -87,7 +147,7 @@ export class ShadedGeometrySystem extends System {
|
|
|
87
147
|
// remember entity for lookups
|
|
88
148
|
sg.__entity = entity;
|
|
89
149
|
|
|
90
|
-
this.
|
|
150
|
+
this.__bvh.insertNode(leaf_node);
|
|
91
151
|
}
|
|
92
152
|
|
|
93
153
|
/**
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export class AbstractRenderAdapter {
|
|
2
|
+
constructor() {
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @type {number}
|
|
7
|
+
* @protected
|
|
8
|
+
*/
|
|
9
|
+
this.__object_count = 0;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
*
|
|
13
|
+
* @type {THREE.Object3D[]}
|
|
14
|
+
* @protected
|
|
15
|
+
*/
|
|
16
|
+
this.__objects = [];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
*
|
|
21
|
+
* @param {THREE.BufferGeometry} geometry
|
|
22
|
+
* @param {THREE.Material} material
|
|
23
|
+
* @returns {number}
|
|
24
|
+
*/
|
|
25
|
+
score(geometry, material) {
|
|
26
|
+
return 0;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
*
|
|
31
|
+
* @param {ShadedGeometry} sg
|
|
32
|
+
* @returns {void}
|
|
33
|
+
*/
|
|
34
|
+
add(sg) {
|
|
35
|
+
throw new Error('Not Implemented');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
build_start() {
|
|
39
|
+
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
build_end() {
|
|
43
|
+
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
clear() {
|
|
47
|
+
this.__object_count = 0;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @returns {THREE.Object3D[]}
|
|
52
|
+
*/
|
|
53
|
+
get objects() {
|
|
54
|
+
return this.__objects;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @returns {number}
|
|
59
|
+
*/
|
|
60
|
+
get object_count() {
|
|
61
|
+
return this.__object_count;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
dispose() {
|
|
65
|
+
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { AbstractRenderAdapter } from "./AbstractRenderAdapter.js";
|
|
2
|
+
import { build_three_object } from "../ShadedGeometry.js";
|
|
3
|
+
import { array_copy } from "../../../../../core/collection/array/copyArray.js";
|
|
4
|
+
|
|
5
|
+
export class GenericRendererAdapter extends AbstractRenderAdapter {
|
|
6
|
+
constructor() {
|
|
7
|
+
super();
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
*
|
|
11
|
+
* @type {Cache<ShadedGeometry, THREE.Object3D>}
|
|
12
|
+
* @private
|
|
13
|
+
*/
|
|
14
|
+
this.__cache = new WeakMap();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
score(geometry, material) {
|
|
19
|
+
return 0;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
build_start() {
|
|
23
|
+
this.clear();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
add(sg) {
|
|
27
|
+
const cache = this.__cache;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
*
|
|
31
|
+
* @type {THREE.Object3D}
|
|
32
|
+
*/
|
|
33
|
+
let object = cache.get(sg);
|
|
34
|
+
|
|
35
|
+
if (object === undefined) {
|
|
36
|
+
|
|
37
|
+
object = build_three_object(sg);
|
|
38
|
+
|
|
39
|
+
cache.set(sg, object);
|
|
40
|
+
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
array_copy(sg.__transform, 0, object.matrixWorld.elements, 0, 16);
|
|
44
|
+
|
|
45
|
+
this.__objects[this.__object_count++] = object;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { AbstractRenderAdapter } from "./AbstractRenderAdapter.js";
|
|
2
|
+
import { HashMap } from "../../../../../core/collection/HashMap.js";
|
|
3
|
+
import { InstancedMeshGroup } from "../../../geometry/instancing/InstancedMeshGroup.js";
|
|
4
|
+
import { ShadedGeometryFlags } from "../ShadedGeometryFlags.js";
|
|
5
|
+
|
|
6
|
+
const INSTANCED_EQUALITY_FLAGS = ShadedGeometryFlags.CastShadow
|
|
7
|
+
| ShadedGeometryFlags.ReceiveShadow
|
|
8
|
+
;
|
|
9
|
+
|
|
10
|
+
export class InstancedRendererAdapter extends AbstractRenderAdapter {
|
|
11
|
+
constructor() {
|
|
12
|
+
super();
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
*
|
|
16
|
+
* @type {HashMap<ShadedGeometry, InstancedMeshGroup>}
|
|
17
|
+
* @private
|
|
18
|
+
*/
|
|
19
|
+
this.__instanced_meshes = new HashMap({
|
|
20
|
+
keyHashFunction(sg) {
|
|
21
|
+
return sg.geometry.id ^ sg.material.id;
|
|
22
|
+
},
|
|
23
|
+
keyEqualityFunction(a, b) {
|
|
24
|
+
return a.material.id === b.material.id
|
|
25
|
+
&& a.geometry.id === b.geometry.id
|
|
26
|
+
&& (a.flags & INSTANCED_EQUALITY_FLAGS) === (b.flags & INSTANCED_EQUALITY_FLAGS)
|
|
27
|
+
;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
*
|
|
33
|
+
* @type {Set<InstancedMeshGroup>}
|
|
34
|
+
* @private
|
|
35
|
+
*/
|
|
36
|
+
this.__active_meshes = new Set();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
*
|
|
41
|
+
* @param {ShadedGeometry} sg
|
|
42
|
+
* @returns {InstancedMeshGroup}
|
|
43
|
+
* @private
|
|
44
|
+
*/
|
|
45
|
+
__get_instanced_mesh(sg) {
|
|
46
|
+
let im = this.__instanced_meshes.get(sg);
|
|
47
|
+
|
|
48
|
+
if (im === undefined) {
|
|
49
|
+
im = new InstancedMeshGroup();
|
|
50
|
+
im.shrinkFactor = 0; // prevent shrinking as we're essentially rebuilding this geometry frame
|
|
51
|
+
|
|
52
|
+
im.setMaterial(sg.material);
|
|
53
|
+
im.setGeometry(sg.geometry);
|
|
54
|
+
|
|
55
|
+
im.mesh.castShadow = sg.getFlag(ShadedGeometryFlags.CastShadow);
|
|
56
|
+
im.mesh.receiveShadow = sg.getFlag(ShadedGeometryFlags.ReceiveShadow);
|
|
57
|
+
|
|
58
|
+
this.__instanced_meshes.set(sg, im);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return im;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
add(sg) {
|
|
65
|
+
const mesh = this.__get_instanced_mesh(sg);
|
|
66
|
+
|
|
67
|
+
const index = mesh.count;
|
|
68
|
+
|
|
69
|
+
mesh.ensureCapacity(index + 1);
|
|
70
|
+
|
|
71
|
+
mesh.setTransformAt(index, sg.transform);
|
|
72
|
+
|
|
73
|
+
mesh.count++;
|
|
74
|
+
|
|
75
|
+
this.__active_meshes.add(mesh);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
build_start() {
|
|
79
|
+
this.clear();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
build_end() {
|
|
83
|
+
|
|
84
|
+
for (const activeMesh of this.__active_meshes) {
|
|
85
|
+
// force underlying geometry to update
|
|
86
|
+
activeMesh.setCount(activeMesh.getCount());
|
|
87
|
+
activeMesh.requestAttributeUpdate();
|
|
88
|
+
|
|
89
|
+
this.__objects[this.__object_count++] = activeMesh.mesh;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
clear() {
|
|
95
|
+
super.clear();
|
|
96
|
+
|
|
97
|
+
for (const activeMesh of this.__active_meshes) {
|
|
98
|
+
activeMesh.setCount(0);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
this.__active_meshes.clear();
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
dispose() {
|
|
105
|
+
// release GPU memory
|
|
106
|
+
this.__instanced_meshes.forEach((value, key) => {
|
|
107
|
+
value.dispose();
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { queryBinaryNode_FrustumIntersections_Data } from "../../../../../core/bvh2/traversal/queryBinaryNode_FrustumIntersections.js";
|
|
2
|
+
import { AbstractRenderAdapter } from "./AbstractRenderAdapter.js";
|
|
3
|
+
import { InstancedRendererAdapter } from "./InstancedRendererAdapter.js";
|
|
4
|
+
import { GenericRendererAdapter } from "./GenericRendererAdapter.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 1 - collect visible meshes
|
|
8
|
+
* 2 - figure out how to render a given mesh
|
|
9
|
+
*/
|
|
10
|
+
export class ShadedGeometryRendererContext {
|
|
11
|
+
constructor() {
|
|
12
|
+
/**
|
|
13
|
+
* @readonly
|
|
14
|
+
* @type {AbstractRenderAdapter[]}
|
|
15
|
+
*/
|
|
16
|
+
this.adapters = [
|
|
17
|
+
new GenericRendererAdapter(),
|
|
18
|
+
new InstancedRendererAdapter()
|
|
19
|
+
];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
setAdapter(index, adapter) {
|
|
23
|
+
const existing = this.adapters[index];
|
|
24
|
+
if (existing !== undefined) {
|
|
25
|
+
// dispose of existing adapter
|
|
26
|
+
existing.dispose();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
this.adapters[index] = adapter;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
*
|
|
34
|
+
* @param {THREE.Object3D[]} destination
|
|
35
|
+
* @param {number} destination_offset
|
|
36
|
+
* @param {CameraView} view
|
|
37
|
+
* @param {BinaryNode<ShadedGeometry>} bvh
|
|
38
|
+
*/
|
|
39
|
+
collect(destination, destination_offset, view, bvh) {
|
|
40
|
+
const adapters = this.adapters;
|
|
41
|
+
const adapter_count = adapters.length;
|
|
42
|
+
|
|
43
|
+
let i = 0, j = 0;
|
|
44
|
+
for (; i < adapter_count; i++) {
|
|
45
|
+
const adapter = adapters[i];
|
|
46
|
+
|
|
47
|
+
adapter.build_start();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
// get all meshes
|
|
52
|
+
|
|
53
|
+
const data = [];
|
|
54
|
+
|
|
55
|
+
const intersection_count = queryBinaryNode_FrustumIntersections_Data(data, 0, bvh, view.frustum);
|
|
56
|
+
|
|
57
|
+
for (i = 0; i < intersection_count; i++) {
|
|
58
|
+
/**
|
|
59
|
+
*
|
|
60
|
+
* @type {ShadedGeometry}
|
|
61
|
+
*/
|
|
62
|
+
const sg = data[i];
|
|
63
|
+
|
|
64
|
+
const adapter = adapters[sg.draw_method];
|
|
65
|
+
|
|
66
|
+
adapter.add(sg);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
let additions = 0;
|
|
70
|
+
|
|
71
|
+
for (i = 0; i < adapter_count; i++) {
|
|
72
|
+
const adapter = adapters[i];
|
|
73
|
+
|
|
74
|
+
adapter.build_end();
|
|
75
|
+
|
|
76
|
+
const adapter_object_count = adapter.object_count;
|
|
77
|
+
|
|
78
|
+
for (j = 0; j < adapter_object_count; j++) {
|
|
79
|
+
const object3D = adapter.objects[j];
|
|
80
|
+
|
|
81
|
+
destination[destination_offset + additions] = object3D;
|
|
82
|
+
|
|
83
|
+
additions++;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return additions;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
dispose() {
|
|
92
|
+
for (const adapter of this.adapters) {
|
|
93
|
+
if (adapter !== undefined) {
|
|
94
|
+
adapter.dispose();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -6,6 +6,7 @@ import { GLTFAssetLoader } from "../../../../asset/loaders/GLTFAssetLoader.js";
|
|
|
6
6
|
import { three_object_to_entity_composition } from "../three_object_to_entity_composition.js";
|
|
7
7
|
import { AttachmentSystem } from "../../../../ecs/attachment/AttachmentSystem.js";
|
|
8
8
|
import { TransformAttachmentSystem } from "../../../../ecs/transform-attachment/TransformAttachmentSystem.js";
|
|
9
|
+
import { Camera } from "../../camera/Camera.js";
|
|
9
10
|
|
|
10
11
|
const eh = new EngineHarness();
|
|
11
12
|
|
|
@@ -70,6 +71,10 @@ async function main(engine) {
|
|
|
70
71
|
enableTerrain: false
|
|
71
72
|
});
|
|
72
73
|
|
|
74
|
+
const camera = engine.entityManager.dataset.getAnyComponent(Camera);
|
|
75
|
+
camera.component.autoClip = false;
|
|
76
|
+
camera.component.object.far = 300;
|
|
77
|
+
|
|
73
78
|
// a small delay to let background tasks finish, so we can get better performance reading later on
|
|
74
79
|
timeout(20);
|
|
75
80
|
|
|
@@ -3,7 +3,7 @@ import { ShadedGeometrySystem } from "../ShadedGeometrySystem.js";
|
|
|
3
3
|
import EntityBuilder from "../../../../ecs/EntityBuilder.js";
|
|
4
4
|
import { Transform } from "../../../../ecs/transform/Transform.js";
|
|
5
5
|
import { ShadedGeometry } from "../ShadedGeometry.js";
|
|
6
|
-
import { BoxBufferGeometry,
|
|
6
|
+
import { BoxBufferGeometry, MeshStandardMaterial } from "three";
|
|
7
7
|
import { randomFloatBetween } from "../../../../../core/math/random/randomFloatBetween.js";
|
|
8
8
|
import { seededRandom } from "../../../../../core/math/random/seededRandom.js";
|
|
9
9
|
import ViewportPosition from "../../../../ecs/gui/position/ViewportPosition.js";
|
|
@@ -13,9 +13,15 @@ import { downloadAsFile } from "../../../../../core/binary/ByteArrayTools.js";
|
|
|
13
13
|
import { convert_bvh_to_dot_format_string } from "../../../../../core/bvh2/visual/convert_bvh_to_dot_format_string.js";
|
|
14
14
|
import ViewportPositionSystem from "../../../../ecs/gui/position/ViewportPositionSystem.js";
|
|
15
15
|
import GUIElementSystem from "../../../../ecs/gui/GUIElementSystem.js";
|
|
16
|
+
import Vector3 from "../../../../../core/geom/Vector3.js";
|
|
17
|
+
import Quaternion from "../../../../../core/geom/Quaternion.js";
|
|
18
|
+
import { ShadedGeometryFlags } from "../ShadedGeometryFlags.js";
|
|
16
19
|
|
|
17
20
|
const eh = new EngineHarness();
|
|
18
21
|
|
|
22
|
+
const DRAW_METHOD_PLAIN = 0;
|
|
23
|
+
const DRAW_METHOD_INSTANCED = 1;
|
|
24
|
+
|
|
19
25
|
/**
|
|
20
26
|
*
|
|
21
27
|
* @param {Engine} engine
|
|
@@ -26,12 +32,18 @@ async function main(engine) {
|
|
|
26
32
|
|
|
27
33
|
await em.addSystem(new ShadedGeometrySystem(engine));
|
|
28
34
|
|
|
29
|
-
EngineHarness.buildBasics({
|
|
35
|
+
EngineHarness.buildBasics({
|
|
36
|
+
engine,
|
|
37
|
+
yaw: -0.8,
|
|
38
|
+
pitch: 1,
|
|
39
|
+
distance: 46,
|
|
40
|
+
focus: new Vector3(10, 0, 10)
|
|
41
|
+
});
|
|
30
42
|
|
|
31
43
|
|
|
32
44
|
const ecd = em.dataset;
|
|
33
45
|
|
|
34
|
-
const material = new
|
|
46
|
+
const material = new MeshStandardMaterial({
|
|
35
47
|
color: 0xFFFFFF
|
|
36
48
|
});
|
|
37
49
|
|
|
@@ -45,6 +57,11 @@ async function main(engine) {
|
|
|
45
57
|
|
|
46
58
|
for (let i = 0; i < 100000; i++) {
|
|
47
59
|
|
|
60
|
+
const sg = ShadedGeometry.from(geometry, material);
|
|
61
|
+
|
|
62
|
+
sg.draw_method = DRAW_METHOD_INSTANCED;
|
|
63
|
+
sg.clearFlag(ShadedGeometryFlags.CastShadow | ShadedGeometryFlags.ReceiveShadow);
|
|
64
|
+
|
|
48
65
|
new EntityBuilder()
|
|
49
66
|
.add(Transform.fromJSON({
|
|
50
67
|
position: {
|
|
@@ -52,9 +69,10 @@ async function main(engine) {
|
|
|
52
69
|
y: randomFloatBetween(random, 0, 10),
|
|
53
70
|
z: randomFloatBetween(random, -50, 50)
|
|
54
71
|
},
|
|
55
|
-
|
|
72
|
+
rotation: Quaternion.random(random),
|
|
73
|
+
scale: 0.05
|
|
56
74
|
}))
|
|
57
|
-
.add(
|
|
75
|
+
.add(sg)
|
|
58
76
|
.build(ecd);
|
|
59
77
|
}
|
|
60
78
|
|
|
@@ -12,24 +12,29 @@ export function three_object_to_entity_composition(root) {
|
|
|
12
12
|
|
|
13
13
|
node.transform.fromMatrix4(root.matrix.elements);
|
|
14
14
|
|
|
15
|
-
node.entity
|
|
15
|
+
const entity = node.entity;
|
|
16
|
+
|
|
17
|
+
entity.add(new Transform());
|
|
16
18
|
|
|
17
19
|
if (root.isMesh) {
|
|
18
20
|
if (root.isSkinnedMesh) {
|
|
19
21
|
throw new Error(`Skinned meshes are not supported`);
|
|
20
22
|
}
|
|
21
23
|
|
|
22
|
-
|
|
24
|
+
const sg = ShadedGeometry.from(root.geometry, root.material);
|
|
25
|
+
sg.draw_method = 1;
|
|
26
|
+
|
|
27
|
+
entity.add(sg);
|
|
23
28
|
}
|
|
24
29
|
|
|
25
30
|
const children = root.children;
|
|
26
31
|
const child_count = children.length;
|
|
32
|
+
|
|
27
33
|
for (let i = 0; i < child_count; i++) {
|
|
28
34
|
const child = children[i];
|
|
29
35
|
|
|
30
36
|
const child_node = three_object_to_entity_composition(child);
|
|
31
37
|
|
|
32
|
-
|
|
33
38
|
node.addChild(child_node);
|
|
34
39
|
}
|
|
35
40
|
|