@woosh/meep-engine 2.43.6 → 2.43.8
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/SurfacePoint3.js +8 -0
- package/core/geom/3d/aabb/compute_aabb_from_points.js +1 -1
- package/core/geom/3d/sphere/harmonics/sh3_dering_optimize_positive.js +10 -4
- package/core/geom/3d/topology/samples/sampleFloodFill.js +275 -0
- package/core/geom/3d/topology/simplify/prototypeMeshSimplification.js +5 -6
- package/core/geom/3d/topology/struct/TopoMesh.js +17 -0
- package/core/geom/3d/topology/three_buffer_geometry_to_topo_mesh.js +30 -0
- package/core/geom/3d/topology/{topoMeshToBufferGeometry.js → topo_mesh_to_three_buffer_geometry.js} +1 -1
- package/core/geom/3d/topology/util/mesh_flood_fill.js +61 -0
- package/engine/Engine.js +1 -1
- package/engine/EngineHarness.js +5 -5
- package/engine/ecs/parent/EntityNode.js +1 -2
- package/engine/graphics/GraphicsEngine.js +5 -2
- package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +1 -1
- package/engine/graphics/ecs/mesh-v2/aggregate/SGMeshSystem.js +10 -0
- package/engine/graphics/geometry/buffered/makeGeometryIndexed.js +5 -4
- package/engine/graphics/geometry/buffered/query/RaycastNearestHitComputingVisitor.js +6 -5
- package/engine/graphics/impostors/octahedral/README.md +4 -0
- package/engine/graphics/impostors/octahedral/prototypeBaker.js +6 -5
- package/engine/graphics/impostors/octahedral/shader/ImpostorShaderV0.js +194 -20
- package/engine/graphics/micron/plugin/GLTFAssetTransformer.js +2 -2
- package/engine/graphics/micron/plugin/MicronRenderPlugin.js +1 -31
- package/engine/graphics/micron/plugin/shaded_geometry/MicronShadedGeometryRenderAdapter.js +23 -5
- package/engine/graphics/micron/simplifyGeometry.js +4 -2
- package/engine/graphics/sh3/LightProbeVolume.js +28 -5
- package/engine/graphics/sh3/README.md +3 -0
- package/engine/graphics/sh3/SH3VisualisationMaterial.js +1 -0
- package/engine/graphics/sh3/prototypeSH3Probe.js +26 -21
- package/engine/graphics/shadows/README.md +6 -0
- package/engine/input/devices/PointerDevice.js +28 -0
- package/package.json +1 -1
- package/samples/terrain/from_image_2.js +1 -45
- package/view/elements/navigation/ViewStack.js +4 -2
|
@@ -32,7 +32,6 @@ export class RaycastNearestHitComputingVisitor extends GeometrySpatialAccelerato
|
|
|
32
32
|
*/
|
|
33
33
|
this.__temp_hit = new SurfacePoint3();
|
|
34
34
|
|
|
35
|
-
|
|
36
35
|
/**
|
|
37
36
|
*
|
|
38
37
|
* @type {boolean}
|
|
@@ -112,17 +111,17 @@ export class RaycastNearestHitComputingVisitor extends GeometrySpatialAccelerato
|
|
|
112
111
|
|
|
113
112
|
let a, b, c;
|
|
114
113
|
|
|
115
|
-
if(indices !== null) {
|
|
114
|
+
if (indices !== null) {
|
|
116
115
|
assert.lessThan(index3 + 2, indices.length, 'triangle index overflow, possibly geometry changed but tree was not rebuilt?');
|
|
117
116
|
|
|
118
117
|
a = indices[index3];
|
|
119
118
|
b = indices[index3 + 1];
|
|
120
119
|
c = indices[index3 + 2];
|
|
121
|
-
}else{
|
|
120
|
+
} else {
|
|
122
121
|
// implicit indices
|
|
123
122
|
a = index3;
|
|
124
|
-
b = index3+1;
|
|
125
|
-
c = index3+2;
|
|
123
|
+
b = index3 + 1;
|
|
124
|
+
c = index3 + 2;
|
|
126
125
|
}
|
|
127
126
|
|
|
128
127
|
const vertices = this.__buffer_vertices;
|
|
@@ -168,6 +167,8 @@ export class RaycastNearestHitComputingVisitor extends GeometrySpatialAccelerato
|
|
|
168
167
|
|
|
169
168
|
if (d < this.__nearest_distance) {
|
|
170
169
|
this.__nearest_hit.copy(temp_hit);
|
|
170
|
+
this.__nearest_hit.index = index;
|
|
171
|
+
|
|
171
172
|
this.__nearest_distance = d;
|
|
172
173
|
|
|
173
174
|
this.__hit_found = true;
|
|
@@ -18,6 +18,9 @@ This is inherently a deferred rendering technique, where an impostor asset is re
|
|
|
18
18
|
* Animations are not supported, neither vertex, nor pixel-shader based ones. The whole impostor can move around and be transformed, but the contents are static and pre-baked.
|
|
19
19
|
* When camera moves too close to the impostor, or an extreme projection is applied - artefacts will become visible. In case of camera getting too close - parts of the mesh that are occluded by outer shell will not become visible in the impostor, as that information is simply not captured. In cases of extreme projection - certain parts of the captured G-Buffer may undergo warping and stretching converting a handful of baked pixel to a larger number of on-screen pixels, creating pixelation and smearing. Note that impostors are not a replacement for your meshes, so use them sensibly.
|
|
20
20
|
|
|
21
|
+
## Drawing
|
|
22
|
+
### reconstruction of image from multiple perspectives
|
|
23
|
+
- based on MO95 and TSK07
|
|
21
24
|
|
|
22
25
|
---
|
|
23
26
|
references:
|
|
@@ -28,3 +31,4 @@ references:
|
|
|
28
31
|
- [2018] https://github.com/wojtekpil/Godot-Octahedral-Impostors
|
|
29
32
|
- [2011] BN11 : "Real-time Realistic Rendering and Lighting of Forests" by Eric Bruneton, Fabrice Neyret
|
|
30
33
|
- [2007] TSK07: "Fast (Spherical) Light Field Rendering with Per-Pixel Depth." by Severin Todt, Christof Rezk-Salama and Andreas Kolb
|
|
34
|
+
- [1995] MO95: Nelson Max and Keiichi Ohsaki. Rendering trees from precomputed z-buffer views. In Eurographics Rendering Workshop, pages 45–54, 1995
|
|
@@ -47,14 +47,15 @@ async function main(engine) {
|
|
|
47
47
|
baker.renderer = renderer;
|
|
48
48
|
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
const path = 'data/models/LowPolyTownshipSet/Small_house/Small_house.gltf';
|
|
51
51
|
// const path = 'data/models/road_bike/road_bike.gltf'; //large CAD-type model
|
|
52
52
|
// const path = 'data/models/LowPolyTownshipSet/Barrel/model.gltf';
|
|
53
53
|
// const path = 'data/models/LowPolyTownshipSet/Town_Hall/model.gltf';
|
|
54
54
|
// const path = 'data/models/RTS_Buildings_Humans/18/Building_R_18_out/Building_R_18.gltf';
|
|
55
55
|
// const path = 'data/models/MOBA and Tower Defense/Tree_01.gltf';
|
|
56
56
|
// const path = 'data/models/samples/transform-hierarchy.glb';
|
|
57
|
-
const path = 'data/models/sponza-pbr/gltf/sponza.glb';
|
|
57
|
+
// const path = 'data/models/sponza-pbr/gltf/sponza.glb';
|
|
58
|
+
// const path = 'data/models/snaps/cube_blue.gltf';
|
|
58
59
|
// const path = 'moicon/gnutti_not_optimized/model.gltf';
|
|
59
60
|
// const path = 'moicon/isiflow_Oct_15_21/1/model.gltf';
|
|
60
61
|
// const path = 'moicon/Kople/EVCharger1.gltf';
|
|
@@ -65,7 +66,7 @@ async function main(engine) {
|
|
|
65
66
|
const id = baker.bake({
|
|
66
67
|
objects,
|
|
67
68
|
frames: 24,
|
|
68
|
-
resolution:
|
|
69
|
+
resolution: 2048,
|
|
69
70
|
type: ImpostorCaptureType.Hemisphere
|
|
70
71
|
});
|
|
71
72
|
// console.profileEnd('bake');
|
|
@@ -97,8 +98,8 @@ async function main(engine) {
|
|
|
97
98
|
const entity_impostor = make_impostor_entity(id, t0);
|
|
98
99
|
entity_impostor.build(ecd);
|
|
99
100
|
|
|
100
|
-
const entity_impostor_wireframe = make_impostor_wireframe(id, t0);
|
|
101
|
-
entity_impostor_wireframe.build(ecd);
|
|
101
|
+
// const entity_impostor_wireframe = make_impostor_wireframe(id, t0);
|
|
102
|
+
// entity_impostor_wireframe.build(ecd);
|
|
102
103
|
|
|
103
104
|
const t1 = new Transform();
|
|
104
105
|
t1.copy(t0);
|
|
@@ -25,20 +25,150 @@ const shader_vx = `
|
|
|
25
25
|
|
|
26
26
|
out vec3 local_ray_near;
|
|
27
27
|
out vec3 local_ray_far;
|
|
28
|
+
|
|
29
|
+
flat out vec2 frame1;
|
|
30
|
+
out vec2 uv_frame1;
|
|
31
|
+
out vec2 xy_frame1;
|
|
28
32
|
|
|
29
33
|
uniform mat4 modelViewMatrix;
|
|
30
34
|
uniform mat4 projectionMatrix;
|
|
31
35
|
uniform mat3 normalMatrix;
|
|
36
|
+
uniform mat4 modelMatrix;
|
|
32
37
|
|
|
33
38
|
uniform vec3 uOffset;
|
|
34
39
|
uniform float uRadius;
|
|
35
40
|
uniform float uFrames;
|
|
36
41
|
|
|
42
|
+
uniform bool uIsFullSphere;
|
|
43
|
+
|
|
44
|
+
vec2 VecToSphereOct(vec3 pivotToCamera)
|
|
45
|
+
{
|
|
46
|
+
vec3 octant = sign(pivotToCamera);
|
|
47
|
+
|
|
48
|
+
// |x| + |y| + |z| = 1
|
|
49
|
+
float sum = dot(pivotToCamera, octant);
|
|
50
|
+
vec3 octahedron = pivotToCamera / sum;
|
|
51
|
+
|
|
52
|
+
if (octahedron.y < 0.0){
|
|
53
|
+
vec3 absolute = abs(octahedron);
|
|
54
|
+
octahedron.xz = octant.xz * vec2(1.0 - absolute.z, 1.0 - absolute.x);
|
|
55
|
+
}
|
|
56
|
+
return octahedron.xz;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
//for hemisphere
|
|
60
|
+
vec2 VecToHemiSphereOct(vec3 vec)
|
|
61
|
+
{
|
|
62
|
+
vec.y = max(vec.y, 0.001);
|
|
63
|
+
vec = normalize(vec);
|
|
64
|
+
vec3 octant = sign(vec);
|
|
65
|
+
|
|
66
|
+
// |x| + |y| + |z| = 1
|
|
67
|
+
float sum = dot(vec, octant);
|
|
68
|
+
vec3 octahedron = vec / sum;
|
|
69
|
+
|
|
70
|
+
return vec2(
|
|
71
|
+
octahedron.x + octahedron.z,
|
|
72
|
+
octahedron.z - octahedron.x
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
//for hemisphere
|
|
76
|
+
vec3 OctaHemiSphereEnc(vec2 coord)
|
|
77
|
+
{
|
|
78
|
+
coord = vec2(coord.x + coord.y, coord.x - coord.y) * 0.5;
|
|
79
|
+
vec3 vec = vec3(coord.x, 1.0 - dot(vec2(1.0, 1.0), abs(coord.xy)), coord.y);
|
|
80
|
+
return vec;
|
|
81
|
+
}
|
|
82
|
+
//for sphere
|
|
83
|
+
vec3 OctaSphereEnc(vec2 coord)
|
|
84
|
+
{
|
|
85
|
+
vec3 vec = vec3(coord.x, 1.0 - dot(vec2(1.0), abs(coord)), coord.y);
|
|
86
|
+
if (vec.y < 0.0)
|
|
87
|
+
{
|
|
88
|
+
vec.x = (vec.x >=0.0 ? 1.0: -1.0)* (1.0 - abs(vec.z));
|
|
89
|
+
vec.z = (vec.z >=0.0 ? 1.0: -1.0)* (1.0 - abs(vec.x));
|
|
90
|
+
}
|
|
91
|
+
return vec;
|
|
92
|
+
}
|
|
93
|
+
vec2 VectorToGrid(vec3 vec)
|
|
94
|
+
{
|
|
95
|
+
if (uIsFullSphere)
|
|
96
|
+
{
|
|
97
|
+
return VecToSphereOct(vec);
|
|
98
|
+
}
|
|
99
|
+
else
|
|
100
|
+
{
|
|
101
|
+
return VecToHemiSphereOct(vec);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
vec3 GridToVector(vec2 coord)
|
|
106
|
+
{
|
|
107
|
+
if (uIsFullSphere)
|
|
108
|
+
{
|
|
109
|
+
return OctaSphereEnc(coord);
|
|
110
|
+
}
|
|
111
|
+
else
|
|
112
|
+
{
|
|
113
|
+
return OctaHemiSphereEnc(coord);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
vec3 FrameXYToRay(vec2 frame, vec2 frameCountMinusOne)
|
|
118
|
+
{
|
|
119
|
+
//divide frame x y by framecount minus one to get 0-1
|
|
120
|
+
vec2 f = (frame.xy/ frameCountMinusOne);
|
|
121
|
+
//bias and scale to -1 to 1
|
|
122
|
+
|
|
123
|
+
vec3 vec = GridToVector(f);
|
|
124
|
+
vec = normalize(vec);
|
|
125
|
+
return vec;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
vec4 TriangleInterpolate(vec2 uv){
|
|
129
|
+
uv = fract(uv);
|
|
130
|
+
|
|
131
|
+
vec2 omuv = vec2(1.0, 1.0) - uv.xy;
|
|
132
|
+
|
|
133
|
+
vec4 res = vec4(0, 0, 0, 0);
|
|
134
|
+
//frame 0
|
|
135
|
+
res.x = min(omuv.x, omuv.y);
|
|
136
|
+
//frame 1
|
|
137
|
+
res.y = abs(dot(uv, vec2(1.0, -1.0)));
|
|
138
|
+
//frame 2
|
|
139
|
+
res.z = min(uv.x, uv.y);
|
|
140
|
+
//mask
|
|
141
|
+
res.w = clamp(ceil(uv.x-uv.y),0.0, 1.0);
|
|
142
|
+
|
|
143
|
+
return res;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
void calcuateXYbasis(vec3 plane_normal, out vec3 plane_x, out vec3 plane_y)
|
|
147
|
+
{
|
|
148
|
+
vec3 up = vec3(0,1,0);
|
|
149
|
+
//cross product doesnt work if we look directly from bottom
|
|
150
|
+
if (abs(plane_normal.y) > 0.999f)
|
|
151
|
+
{
|
|
152
|
+
up = vec3(0,0,1);
|
|
153
|
+
}
|
|
154
|
+
plane_x = normalize(cross(plane_normal, up));
|
|
155
|
+
plane_y = normalize(cross(plane_x, plane_normal));
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
|
|
37
159
|
void main() {
|
|
38
160
|
vUv = uv;
|
|
39
161
|
|
|
40
162
|
vec2 framesMinusOne = uFrames - vec2(1.0);
|
|
41
163
|
|
|
164
|
+
vec3 cameraPos_WS = (projectionMatrix * vec4(vec3(0), 1.0)).xyz;
|
|
165
|
+
vec3 cameraPos_OS = (inverse(modelMatrix) * vec4(cameraPos_WS, 1.0)).xyz;
|
|
166
|
+
|
|
167
|
+
//TODO: check if this is correct. We are using orho projected images, so
|
|
168
|
+
// camera far away
|
|
169
|
+
vec3 pivotToCameraRay = (cameraPos_OS) * 10.0;
|
|
170
|
+
vec3 pivotToCameraDir = normalize(cameraPos_OS);
|
|
171
|
+
|
|
42
172
|
mat4 m4 = modelViewMatrix;
|
|
43
173
|
|
|
44
174
|
m4[0][0] = 1.0;
|
|
@@ -65,6 +195,7 @@ const shader_vx = `
|
|
|
65
195
|
|
|
66
196
|
vec3 transformedNormal = normalize(normalMatrix * normal);
|
|
67
197
|
|
|
198
|
+
|
|
68
199
|
vec4 mvPosition = m4 * vec4( object_scale*(position+uOffset/card_diameter), 1.0 );
|
|
69
200
|
|
|
70
201
|
gl_Position = projectionMatrix * mvPosition;
|
|
@@ -75,6 +206,10 @@ const shader_vx = `
|
|
|
75
206
|
//get 2D projection of this vertex in normalized device coordinates
|
|
76
207
|
vec2 pos = gl_Position.xy/gl_Position.w;
|
|
77
208
|
|
|
209
|
+
vec3 projected = position;
|
|
210
|
+
vec3 vertexToCameraRay = (pivotToCameraRay - (projected));
|
|
211
|
+
vec3 vertexToCameraDir = normalize(vertexToCameraRay);
|
|
212
|
+
|
|
78
213
|
//compute ray's start and end as inversion of this coordinates
|
|
79
214
|
//in near and far clip planes
|
|
80
215
|
vec4 near_4 = inverse_matrix * (vec4(pos, -1.0, 1.0));
|
|
@@ -82,6 +217,29 @@ const shader_vx = `
|
|
|
82
217
|
|
|
83
218
|
local_ray_near = near_4.xyz / near_4.w;
|
|
84
219
|
local_ray_far = far_4.xyz/ far_4.w;
|
|
220
|
+
|
|
221
|
+
//
|
|
222
|
+
vec3 view_direction = normalize(local_ray_near-local_ray_far);
|
|
223
|
+
|
|
224
|
+
vec2 octahedral_uv = clamp(VectorToGrid(view_direction)*0.5 + 0.5, 0.0, 1.0);
|
|
225
|
+
vec2 grid = octahedral_uv * vec2(uFrames - 1.0);
|
|
226
|
+
|
|
227
|
+
vec2 gridFrac = fract(grid);
|
|
228
|
+
vec2 gridFloor = floor(grid);
|
|
229
|
+
|
|
230
|
+
vec4 weights = TriangleInterpolate( gridFrac );
|
|
231
|
+
|
|
232
|
+
vec2 frame1 = gridFloor;
|
|
233
|
+
vec2 frame2 = gridFloor + mix(vec2(0,1),vec2(1,0),weights.w);
|
|
234
|
+
vec2 frame3 = gridFloor + vec2(1.0,1.0);
|
|
235
|
+
|
|
236
|
+
vec3 plane_x1, plane_y1, plane_x2, plane_y2, plane_x3, plane_y3;
|
|
237
|
+
vec3 projectedQuadADir = FrameXYToRay(frame1, framesMinusOne);
|
|
238
|
+
calcuateXYbasis(projectedQuadADir, plane_x1, plane_y1);
|
|
239
|
+
|
|
240
|
+
uv_frame1 = virtualPlaneUV(projectedQuadADir, plane_x1, plane_y1, pivotToCameraRay, vertexToCameraRay, scale);
|
|
241
|
+
xy_frame1 = projectOnPlaneBasis(-vertexToCameraDir, projectedQuadADir, plane_x1, plane_y1).xy;
|
|
242
|
+
|
|
85
243
|
}
|
|
86
244
|
`;
|
|
87
245
|
const shader_fg = `
|
|
@@ -194,20 +352,25 @@ const shader_fg = `
|
|
|
194
352
|
return result;
|
|
195
353
|
}
|
|
196
354
|
|
|
197
|
-
|
|
355
|
+
vec4 ImposterBlendWeightsNearest(sampler2D tex, vec2 frame0, vec2 frame1, vec2 frame2, vec4 weights, vec4 ddxy)
|
|
198
356
|
{
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
357
|
+
vec4 samp0 = textureGrad(tex, frame0, ddxy.xy, ddxy.zw);
|
|
358
|
+
vec4 samp1 = textureGrad(tex, frame1, ddxy.xy, ddxy.zw);
|
|
359
|
+
vec4 samp2 = textureGrad(tex, frame2, ddxy.xy, ddxy.zw);
|
|
360
|
+
|
|
361
|
+
vec4 result;
|
|
362
|
+
|
|
363
|
+
if(weights.x > weights.y && weights.x > weights.z){
|
|
364
|
+
result = samp0;
|
|
365
|
+
}if(weights.y > weights.z){
|
|
366
|
+
result = samp1;
|
|
367
|
+
}else{
|
|
368
|
+
result = samp2;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
return result;
|
|
210
372
|
}
|
|
373
|
+
|
|
211
374
|
|
|
212
375
|
void calcuateXYbasis(vec3 plane_normal, out vec3 plane_x, out vec3 plane_y)
|
|
213
376
|
{
|
|
@@ -237,10 +400,14 @@ const shader_fg = `
|
|
|
237
400
|
vec2 source_uv = (frame + frame_uv)*frame_size;
|
|
238
401
|
|
|
239
402
|
float n_depth = texture(gBuffer, source_uv).a;
|
|
240
|
-
|
|
241
|
-
vec2 offset = clamp(length(frame_uv*2.0 - 1.0)*vec2(0.5-n_depth )*depth_scale,
|
|
403
|
+
|
|
404
|
+
vec2 offset = clamp(length(frame_uv*2.0 - 1.0) * vec2(0.5-n_depth ) * depth_scale,0.0, 1.0);
|
|
242
405
|
|
|
243
|
-
|
|
406
|
+
vec2 uv_f = clamp(frame_uv+offset, 0.0, 1.0);
|
|
407
|
+
|
|
408
|
+
uv_f = ( frame + uv_f)*frame_size;
|
|
409
|
+
|
|
410
|
+
return clamp(uv_f,0.0, 1.0);
|
|
244
411
|
// return source_uv;
|
|
245
412
|
}
|
|
246
413
|
|
|
@@ -255,23 +422,30 @@ const shader_fg = `
|
|
|
255
422
|
|
|
256
423
|
vec4 weights = TriangleInterpolate( gridFrac );
|
|
257
424
|
|
|
425
|
+
vec2 frame_uv = vUv;
|
|
426
|
+
|
|
258
427
|
//3 nearest frames
|
|
259
428
|
vec2 frame0 = gridFloor;
|
|
260
429
|
vec2 frame1 = gridFloor + mix(vec2(0,1),vec2(1,0),weights.w);
|
|
261
430
|
vec2 frame2 = gridFloor + vec2(1.0,1.0);
|
|
262
431
|
|
|
432
|
+
vec2 uv0 = recompute_uv(frame0, frame_uv, tGeometry);
|
|
433
|
+
vec2 uv1 = recompute_uv(frame1, frame_uv, tGeometry);
|
|
434
|
+
vec2 uv2 = recompute_uv(frame2, frame_uv, tGeometry);
|
|
435
|
+
|
|
263
436
|
vec4 ddxy = vec4( dFdx(vUv.xy), dFdy(vUv.xy) );
|
|
264
437
|
|
|
265
|
-
vec2 frame_uv = vUv;
|
|
266
438
|
vec2 frame_size = vec2(1.0/ uFrames);
|
|
267
439
|
|
|
268
440
|
vec4 texel_color = ImposterBlendWeights(
|
|
441
|
+
// vec4 texel_color = ImposterBlendWeightsNearest(
|
|
269
442
|
tBase,
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
443
|
+
uv0,
|
|
444
|
+
uv1,
|
|
445
|
+
uv2,
|
|
273
446
|
weights, ddxy
|
|
274
|
-
);
|
|
447
|
+
);
|
|
448
|
+
|
|
275
449
|
|
|
276
450
|
// texel_color = vec4(texel_color.aaa, 1.0);
|
|
277
451
|
|
|
@@ -59,14 +59,14 @@ function ensureProxy(object) {
|
|
|
59
59
|
export class GLTFAssetTransformer extends AssetTransformer {
|
|
60
60
|
/**
|
|
61
61
|
*
|
|
62
|
-
* @param {AbstractAsyncMap<THREE.BufferGeometry, MicronGeometry>} cache
|
|
62
|
+
* @param {AbstractAsyncMap<THREE.BufferGeometry, MicronGeometry>} [cache]
|
|
63
63
|
*/
|
|
64
64
|
constructor(cache) {
|
|
65
65
|
super();
|
|
66
66
|
|
|
67
67
|
/**
|
|
68
68
|
*
|
|
69
|
-
* @type {AbstractAsyncMap<THREE.BufferGeometry, MicronGeometry
|
|
69
|
+
* @type {AbstractAsyncMap<THREE.BufferGeometry, MicronGeometry>|undefined}
|
|
70
70
|
* @private
|
|
71
71
|
*/
|
|
72
72
|
this.__cache = cache;
|
|
@@ -47,39 +47,13 @@ export class MicronRenderPlugin extends EnginePlugin {
|
|
|
47
47
|
|
|
48
48
|
});
|
|
49
49
|
|
|
50
|
-
/**
|
|
51
|
-
*
|
|
52
|
-
* @type {AsyncRemoteHashMap<THREE.BufferGeometry, MicronGeometry>}
|
|
53
|
-
* @private
|
|
54
|
-
*/
|
|
55
|
-
this.__persisted_geometry = new AsyncRemoteHashMap({
|
|
56
|
-
keyHashFunction: computeGeometryHash,
|
|
57
|
-
keyEqualityFunction: computeGeometryEquality,
|
|
58
|
-
keySerializationAdapter: new BufferGeometrySerializationAdapter(),
|
|
59
|
-
valueSerializationAdapter: new MicronGeometryBinarySerializationAdapter(),
|
|
60
|
-
storageKeyPrefix: STORAGE_KEY,
|
|
61
|
-
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
*
|
|
66
|
-
* @type {AbstractAsyncMap<THREE.BufferGeometry, MicronGeometry>}
|
|
67
|
-
* @private
|
|
68
|
-
*/
|
|
69
|
-
this.__cache = new CachedAsyncMap(
|
|
70
|
-
new AsyncMapWrapper(new Cache({
|
|
71
|
-
keyHashFunction: computeGeometryHash,
|
|
72
|
-
keyEqualityFunction: computeGeometryEquality
|
|
73
|
-
})),
|
|
74
|
-
this.__persisted_geometry
|
|
75
|
-
);
|
|
76
50
|
|
|
77
51
|
/**
|
|
78
52
|
*
|
|
79
53
|
* @type {GLTFAssetTransformer}
|
|
80
54
|
* @private
|
|
81
55
|
*/
|
|
82
|
-
this.__asset_transformer = new GLTFAssetTransformer(
|
|
56
|
+
this.__asset_transformer = new GLTFAssetTransformer();
|
|
83
57
|
|
|
84
58
|
/**
|
|
85
59
|
*
|
|
@@ -159,8 +133,6 @@ export class MicronRenderPlugin extends EnginePlugin {
|
|
|
159
133
|
am.registerTransformer("model/gltf", this.__asset_transformer);
|
|
160
134
|
am.registerTransformer("model/gltf+json", this.__asset_transformer);
|
|
161
135
|
|
|
162
|
-
this.__persisted_geometry.attach_storage(engine.storage);
|
|
163
|
-
|
|
164
136
|
engine.entityManager.on.systemAdded.add(this.__handle_system_added, this);
|
|
165
137
|
engine.entityManager.on.systemRemoved.add(this.__handle_system_removed, this);
|
|
166
138
|
|
|
@@ -172,8 +144,6 @@ export class MicronRenderPlugin extends EnginePlugin {
|
|
|
172
144
|
async shutdown() {
|
|
173
145
|
const engine = this.engine;
|
|
174
146
|
|
|
175
|
-
this.__persisted_geometry.detach_storage();
|
|
176
|
-
|
|
177
147
|
const am = engine.assetManager;
|
|
178
148
|
|
|
179
149
|
am.unregisterTransformer("model/gltf", this.__asset_transformer);
|
|
@@ -4,6 +4,8 @@ import { ShadedGeometryFlags } from "../../../ecs/mesh-v2/ShadedGeometryFlags.js
|
|
|
4
4
|
import { MaterialVertexSpec, MaterialVertexSpecFlags } from "../../render/v1/MaterialVertexSpec.js";
|
|
5
5
|
import { compute_geometry_polycount } from "../../../geometry/compute_geometry_polycount.js";
|
|
6
6
|
import { inverseLerp } from "../../../../../core/math/inverseLerp.js";
|
|
7
|
+
import { MICRON_GEOMETRY_FIELD } from "../../MICRON_GEOMETRY_FIELD.js";
|
|
8
|
+
import { assert } from "../../../../../core/assert.js";
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
*
|
|
@@ -27,7 +29,7 @@ export class MicronShadedGeometryRenderAdapter extends AbstractRenderAdapter {
|
|
|
27
29
|
|
|
28
30
|
/**
|
|
29
31
|
*
|
|
30
|
-
* @param {AbstractAsyncMap<THREE.BufferGeometry, MicronGeometry>} cache
|
|
32
|
+
* @param {AbstractAsyncMap<THREE.BufferGeometry, MicronGeometry>} [cache]
|
|
31
33
|
*/
|
|
32
34
|
constructor(cache) {
|
|
33
35
|
super();
|
|
@@ -54,7 +56,7 @@ export class MicronShadedGeometryRenderAdapter extends AbstractRenderAdapter {
|
|
|
54
56
|
|
|
55
57
|
/**
|
|
56
58
|
*
|
|
57
|
-
* @type {AbstractAsyncMap<THREE.BufferGeometry, MicronGeometry
|
|
59
|
+
* @type {AbstractAsyncMap<THREE.BufferGeometry, MicronGeometry>|undefined}
|
|
58
60
|
* @private
|
|
59
61
|
*/
|
|
60
62
|
this.__cache = cache;
|
|
@@ -73,7 +75,18 @@ export class MicronShadedGeometryRenderAdapter extends AbstractRenderAdapter {
|
|
|
73
75
|
* @private
|
|
74
76
|
*/
|
|
75
77
|
__obtain_micron_geometry(sg) {
|
|
76
|
-
const
|
|
78
|
+
const buffer_geometry = sg.geometry;
|
|
79
|
+
|
|
80
|
+
const attached_micron_data = buffer_geometry[MICRON_GEOMETRY_FIELD];
|
|
81
|
+
|
|
82
|
+
if (attached_micron_data !== undefined) {
|
|
83
|
+
assert.equal(attached_micron_data.isMicronGeometry, true, `geometry[${MICRON_GEOMETRY_FIELD}].isMicronGeometry !== true`);
|
|
84
|
+
|
|
85
|
+
// data was found directly on the geometry
|
|
86
|
+
return attached_micron_data;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const geometry_id = buffer_geometry.id;
|
|
77
90
|
|
|
78
91
|
const micron_geometry = this.__geometry_map.get(geometry_id);
|
|
79
92
|
|
|
@@ -84,8 +97,11 @@ export class MicronShadedGeometryRenderAdapter extends AbstractRenderAdapter {
|
|
|
84
97
|
} else {
|
|
85
98
|
|
|
86
99
|
// no micron geometry
|
|
87
|
-
if (
|
|
88
|
-
|
|
100
|
+
if (
|
|
101
|
+
this.__cache !== undefined // cache is attached
|
|
102
|
+
&& !this.__geometry_building_promises.has(geometry_id)
|
|
103
|
+
) {
|
|
104
|
+
const p = this.__cache.get(buffer_geometry);
|
|
89
105
|
|
|
90
106
|
this.__geometry_building_promises.set(geometry_id, p);
|
|
91
107
|
|
|
@@ -98,7 +114,9 @@ export class MicronShadedGeometryRenderAdapter extends AbstractRenderAdapter {
|
|
|
98
114
|
p.finally(() => {
|
|
99
115
|
this.__geometry_building_promises.delete(geometry_id);
|
|
100
116
|
});
|
|
117
|
+
|
|
101
118
|
}
|
|
119
|
+
|
|
102
120
|
return undefined;
|
|
103
121
|
}
|
|
104
122
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { TopoMesh } from "../../../core/geom/3d/topology/struct/TopoMesh.js";
|
|
2
2
|
import { simplifyTopoMesh } from "../../../core/geom/3d/topology/simplify/simplifyTopoMesh.js";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
topo_mesh_to_three_buffer_geometry
|
|
5
|
+
} from "../../../core/geom/3d/topology/topo_mesh_to_three_buffer_geometry.js";
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
8
|
*
|
|
@@ -20,5 +22,5 @@ function simplifyGeometry(input, target) {
|
|
|
20
22
|
|
|
21
23
|
simplifyTopoMesh(topo, target);
|
|
22
24
|
|
|
23
|
-
return
|
|
25
|
+
return topo_mesh_to_three_buffer_geometry(topo);
|
|
24
26
|
}
|
|
@@ -28,6 +28,7 @@ import { applyTransformToThreeObject } from "../ecs/mesh/applyTransformToThreeOb
|
|
|
28
28
|
import { build_three_object } from "../ecs/mesh-v2/build_three_object.js";
|
|
29
29
|
import { ShadedGeometryFlags } from "../ecs/mesh-v2/ShadedGeometryFlags.js";
|
|
30
30
|
import { v3_length_sqr } from "../../../core/geom/v3_length_sqr.js";
|
|
31
|
+
import { sh3_dering_optimize_positive } from "../../../core/geom/3d/sphere/harmonics/sh3_dering_optimize_positive.js";
|
|
31
32
|
|
|
32
33
|
const TEMP_CONTACT = new SurfacePoint3();
|
|
33
34
|
|
|
@@ -171,11 +172,11 @@ function fromCubeRenderTarget(data, renderer, cubeRenderTarget) {
|
|
|
171
172
|
const color_b = data[i + 2] * weight_conv;
|
|
172
173
|
|
|
173
174
|
// accumulate
|
|
174
|
-
for (let j = 0; j <
|
|
175
|
+
for (let j = 0; j < 9; j++) {
|
|
175
176
|
|
|
176
|
-
coefficients[j] += sh_basis[j] * color_r;
|
|
177
|
-
coefficients[j + 1] += sh_basis[j] * color_g;
|
|
178
|
-
coefficients[j + 2] += sh_basis[j] * color_b;
|
|
177
|
+
coefficients[j * 3] += sh_basis[j] * color_r;
|
|
178
|
+
coefficients[j * 3 + 1] += sh_basis[j] * color_g;
|
|
179
|
+
coefficients[j * 3 + 2] += sh_basis[j] * color_b;
|
|
179
180
|
|
|
180
181
|
}
|
|
181
182
|
|
|
@@ -192,6 +193,8 @@ function fromCubeRenderTarget(data, renderer, cubeRenderTarget) {
|
|
|
192
193
|
|
|
193
194
|
}
|
|
194
195
|
|
|
196
|
+
sh3_dering_optimize_positive(coefficients, 0, coefficients, 0, 3);
|
|
197
|
+
|
|
195
198
|
return coefficients;
|
|
196
199
|
|
|
197
200
|
}
|
|
@@ -239,6 +242,8 @@ class CubeRenderer {
|
|
|
239
242
|
* @private
|
|
240
243
|
*/
|
|
241
244
|
this.__scene = new Scene();
|
|
245
|
+
// this.__scene.autoUpdate = false;
|
|
246
|
+
// this.__scene.matrixAutoUpdate = false;
|
|
242
247
|
}
|
|
243
248
|
|
|
244
249
|
/**
|
|
@@ -251,7 +256,18 @@ class CubeRenderer {
|
|
|
251
256
|
ecd.traverseEntities([ShadedGeometry, Transform], (sg, t, entity) => {
|
|
252
257
|
const object3D = build_three_object(sg);
|
|
253
258
|
|
|
254
|
-
|
|
259
|
+
const source_material = sg.material;
|
|
260
|
+
|
|
261
|
+
//
|
|
262
|
+
// if (source_material.isMeshStandardMaterial === true) {
|
|
263
|
+
// object3D.material = new MeshStandardMaterial({
|
|
264
|
+
// map: source_material.map,
|
|
265
|
+
// });
|
|
266
|
+
//
|
|
267
|
+
// object3D.material.color.copy(source_material.color);
|
|
268
|
+
// } else {
|
|
269
|
+
object3D.material = source_material.clone();
|
|
270
|
+
// }
|
|
255
271
|
|
|
256
272
|
applyTransformToThreeObject(object3D, t);
|
|
257
273
|
|
|
@@ -312,6 +328,13 @@ class CubeRenderer {
|
|
|
312
328
|
renderer.autoClear = true;
|
|
313
329
|
|
|
314
330
|
this.__cube_camera.position.fromArray(position, position_offset);
|
|
331
|
+
|
|
332
|
+
this.__cube_camera.children.forEach(c => {
|
|
333
|
+
c.updateProjectionMatrix();
|
|
334
|
+
c.updateMatrix();
|
|
335
|
+
c.updateMatrixWorld(true);
|
|
336
|
+
});
|
|
337
|
+
|
|
315
338
|
this.__cube_camera.update(renderer, this.__scene);
|
|
316
339
|
|
|
317
340
|
|