@heliguy-xyz/splat-viewer 1.0.0-rc.25 → 1.0.0-rc.26
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/README.md +39 -0
- package/dist/web-component/splat-viewer.esm.js +601 -548
- package/dist/web-component/splat-viewer.esm.min.js +1 -1
- package/dist/web-component/splat-viewer.js +601 -548
- package/dist/web-component/splat-viewer.min.js +1 -1
- package/dist/web-component/types/web-component/SplatViewerCore.d.ts +1 -0
- package/dist/web-component/types/web-component/SplatViewerCore.d.ts.map +1 -1
- package/dist/web-component/types/web-component/SplatViewerElement.d.ts +2 -0
- package/dist/web-component/types/web-component/SplatViewerElement.d.ts.map +1 -1
- package/dist/web-component/types/web-component/types/attributes.d.ts +3 -0
- package/dist/web-component/types/web-component/types/attributes.d.ts.map +1 -1
- package/dist/web-component/types/web-component/types/core.d.ts +2 -0
- package/dist/web-component/types/web-component/types/core.d.ts.map +1 -1
- package/dist/web-component/types/web-component/utils/config.d.ts.map +1 -1
- package/dist/web-component/web-component/SplatViewerCore.d.ts +1 -0
- package/dist/web-component/web-component/SplatViewerCore.d.ts.map +1 -1
- package/dist/web-component/web-component/SplatViewerElement.d.ts +2 -0
- package/dist/web-component/web-component/SplatViewerElement.d.ts.map +1 -1
- package/dist/web-component/web-component/types/attributes.d.ts +3 -0
- package/dist/web-component/web-component/types/attributes.d.ts.map +1 -1
- package/dist/web-component/web-component/types/core.d.ts +2 -0
- package/dist/web-component/web-component/types/core.d.ts.map +1 -1
- package/dist/web-component/web-component/utils/config.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -139519,6 +139519,7 @@ const DEFAULT_CONFIG = {
|
|
|
139519
139519
|
enableStats: false,
|
|
139520
139520
|
autoFocus: true,
|
|
139521
139521
|
maxSplats: 2000000,
|
|
139522
|
+
previewMode: false,
|
|
139522
139523
|
camera: {
|
|
139523
139524
|
position: { x: 0, y: 0, z: 10 },
|
|
139524
139525
|
target: { x: 0, y: 0, z: 0 },
|
|
@@ -139608,6 +139609,10 @@ function getConfigFromAttributes(element) {
|
|
|
139608
139609
|
if (enableStats !== null) {
|
|
139609
139610
|
config.enableStats = parseBoolean(enableStats);
|
|
139610
139611
|
}
|
|
139612
|
+
const previewMode = element.getAttribute('preview-mode');
|
|
139613
|
+
if (previewMode !== null) {
|
|
139614
|
+
config.previewMode = parseBoolean(previewMode);
|
|
139615
|
+
}
|
|
139611
139616
|
// Parse number attributes
|
|
139612
139617
|
const maxSplats = element.getAttribute('max-splats');
|
|
139613
139618
|
if (maxSplats !== null) {
|
|
@@ -143161,222 +143166,222 @@ class AssetLoader {
|
|
|
143161
143166
|
}
|
|
143162
143167
|
}
|
|
143163
143168
|
|
|
143164
|
-
const vertexShader$6 = /* glsl */ `
|
|
143165
|
-
attribute vec2 vertex_position;
|
|
143166
|
-
void main(void) {
|
|
143167
|
-
gl_Position = vec4(vertex_position, 0.0, 1.0);
|
|
143168
|
-
}
|
|
143169
|
-
`;
|
|
143170
|
-
const fragmentShader$6 = /* glsl */ `
|
|
143171
|
-
uniform highp usampler2D transformA; // splat center x, y, z
|
|
143172
|
-
uniform highp usampler2D splatTransform; // transform palette index
|
|
143173
|
-
uniform sampler2D transformPalette; // palette of transforms
|
|
143174
|
-
uniform sampler2D splatState; // per-splat state
|
|
143175
|
-
uniform highp ivec3 splat_params; // texture width, texture height, num splats
|
|
143176
|
-
uniform highp uint mode; // 0: selected, 1: visible
|
|
143177
|
-
|
|
143178
|
-
// calculate min and max for a single column of splats
|
|
143179
|
-
void main(void) {
|
|
143180
|
-
|
|
143181
|
-
vec3 boundMin = vec3(1e6);
|
|
143182
|
-
vec3 boundMax = vec3(-1e6);
|
|
143183
|
-
|
|
143184
|
-
for (int id = 0; id < splat_params.y; id++) {
|
|
143185
|
-
// calculate splatUV
|
|
143186
|
-
ivec2 splatUV = ivec2(gl_FragCoord.x, id);
|
|
143187
|
-
|
|
143188
|
-
// skip out-of-range splats
|
|
143189
|
-
if ((splatUV.x + splatUV.y * splat_params.x) >= splat_params.z) {
|
|
143190
|
-
continue;
|
|
143191
|
-
}
|
|
143192
|
-
|
|
143193
|
-
// read splat state
|
|
143194
|
-
uint state = uint(texelFetch(splatState, splatUV, 0).r * 255.0);
|
|
143195
|
-
|
|
143196
|
-
// skip deleted or locked splats
|
|
143197
|
-
if (((mode == 0u) && (state != 1u)) || ((mode == 1u) && ((state & 4u) != 0u))) {
|
|
143198
|
-
continue;
|
|
143199
|
-
}
|
|
143200
|
-
|
|
143201
|
-
// read splat center
|
|
143202
|
-
vec3 center = uintBitsToFloat(texelFetch(transformA, splatUV, 0).xyz);
|
|
143203
|
-
|
|
143204
|
-
// apply optional per-splat transform
|
|
143205
|
-
uint transformIndex = texelFetch(splatTransform, splatUV, 0).r;
|
|
143206
|
-
if (transformIndex > 0u) {
|
|
143207
|
-
// read transform matrix
|
|
143208
|
-
int u = int(transformIndex % 512u) * 3;
|
|
143209
|
-
int v = int(transformIndex / 512u);
|
|
143210
|
-
|
|
143211
|
-
mat3x4 t;
|
|
143212
|
-
t[0] = texelFetch(transformPalette, ivec2(u, v), 0);
|
|
143213
|
-
t[1] = texelFetch(transformPalette, ivec2(u + 1, v), 0);
|
|
143214
|
-
t[2] = texelFetch(transformPalette, ivec2(u + 2, v), 0);
|
|
143215
|
-
|
|
143216
|
-
center = vec4(center, 1.0) * t;
|
|
143217
|
-
}
|
|
143218
|
-
|
|
143219
|
-
boundMin = min(boundMin, mix(center, boundMin, isinf(center)));
|
|
143220
|
-
boundMax = max(boundMax, mix(center, boundMax, isinf(center)));
|
|
143221
|
-
}
|
|
143222
|
-
|
|
143223
|
-
pcFragColor0 = vec4(boundMin, 0.0);
|
|
143224
|
-
pcFragColor1 = vec4(boundMax, 0.0);
|
|
143225
|
-
}
|
|
143226
|
-
`;
|
|
143227
|
-
|
|
143228
|
-
const vertexShader$5 = /* glsl */ `
|
|
143229
|
-
attribute vec2 vertex_position;
|
|
143230
|
-
void main(void) {
|
|
143231
|
-
gl_Position = vec4(vertex_position, 0.0, 1.0);
|
|
143232
|
-
}
|
|
143233
|
-
`;
|
|
143234
|
-
const fragmentShader$5 = /* glsl */ `
|
|
143235
|
-
uniform highp usampler2D transformA; // splat center x, y, z
|
|
143236
|
-
uniform highp usampler2D splatTransform; // transform palette index
|
|
143237
|
-
uniform sampler2D transformPalette; // palette of transforms
|
|
143238
|
-
uniform uvec2 splat_params; // splat texture width, num splats
|
|
143239
|
-
|
|
143240
|
-
uniform mat4 matrix_model;
|
|
143241
|
-
uniform mat4 matrix_viewProjection;
|
|
143242
|
-
|
|
143243
|
-
uniform uvec2 output_params; // output width, height
|
|
143244
|
-
|
|
143245
|
-
// 0: mask, 1: rect, 2: sphere
|
|
143246
|
-
uniform int mode;
|
|
143247
|
-
|
|
143248
|
-
// mask params
|
|
143249
|
-
uniform sampler2D mask; // mask in alpha channel
|
|
143250
|
-
uniform vec2 mask_params; // mask width, height
|
|
143251
|
-
|
|
143252
|
-
// rect params
|
|
143253
|
-
uniform vec4 rect_params; // rect x, y, width, height
|
|
143254
|
-
|
|
143255
|
-
// sphere params
|
|
143256
|
-
uniform vec4 sphere_params; // sphere x, y, z, radius
|
|
143257
|
-
|
|
143258
|
-
// box params
|
|
143259
|
-
uniform vec4 box_params; // box x, y, z
|
|
143260
|
-
uniform vec4 aabb_params; // len x, y, z
|
|
143261
|
-
|
|
143262
|
-
void main(void) {
|
|
143263
|
-
// calculate output id
|
|
143264
|
-
uvec2 outputUV = uvec2(gl_FragCoord);
|
|
143265
|
-
uint outputId = (outputUV.x + outputUV.y * output_params.x) * 4u;
|
|
143266
|
-
|
|
143267
|
-
vec4 clr = vec4(0.0);
|
|
143268
|
-
|
|
143269
|
-
for (uint i = 0u; i < 4u; i++) {
|
|
143270
|
-
uint id = outputId + i;
|
|
143271
|
-
|
|
143272
|
-
if (id >= splat_params.y) {
|
|
143273
|
-
continue;
|
|
143274
|
-
}
|
|
143275
|
-
|
|
143276
|
-
// calculate splatUV
|
|
143277
|
-
ivec2 splatUV = ivec2(
|
|
143278
|
-
int(id % splat_params.x),
|
|
143279
|
-
int(id / splat_params.x)
|
|
143280
|
-
);
|
|
143281
|
-
|
|
143282
|
-
// read splat center
|
|
143283
|
-
vec3 center = uintBitsToFloat(texelFetch(transformA, splatUV, 0).xyz);
|
|
143284
|
-
|
|
143285
|
-
// apply optional per-splat transform
|
|
143286
|
-
uint transformIndex = texelFetch(splatTransform, splatUV, 0).r;
|
|
143287
|
-
if (transformIndex > 0u) {
|
|
143288
|
-
// read transform matrix
|
|
143289
|
-
int u = int(transformIndex % 512u) * 3;
|
|
143290
|
-
int v = int(transformIndex / 512u);
|
|
143291
|
-
|
|
143292
|
-
mat3x4 t;
|
|
143293
|
-
t[0] = texelFetch(transformPalette, ivec2(u, v), 0);
|
|
143294
|
-
t[1] = texelFetch(transformPalette, ivec2(u + 1, v), 0);
|
|
143295
|
-
t[2] = texelFetch(transformPalette, ivec2(u + 2, v), 0);
|
|
143296
|
-
|
|
143297
|
-
center = vec4(center, 1.0) * t;
|
|
143298
|
-
}
|
|
143299
|
-
|
|
143300
|
-
// transform to clip space and discard if outside
|
|
143301
|
-
vec3 world = (matrix_model * vec4(center, 1.0)).xyz;
|
|
143302
|
-
vec4 clip = matrix_viewProjection * vec4(world, 1.0);
|
|
143303
|
-
vec3 ndc = clip.xyz / clip.w;
|
|
143304
|
-
|
|
143305
|
-
// skip offscreen fragments
|
|
143306
|
-
if (!any(greaterThan(abs(ndc), vec3(1.0)))) {
|
|
143307
|
-
if (mode == 0) {
|
|
143308
|
-
// select by mask
|
|
143309
|
-
ivec2 maskUV = ivec2((ndc.xy * vec2(0.5, -0.5) + 0.5) * mask_params);
|
|
143310
|
-
clr[i] = texelFetch(mask, maskUV, 0).a < 1.0 ? 0.0 : 1.0;
|
|
143311
|
-
} else if (mode == 1) {
|
|
143312
|
-
// select by rect
|
|
143313
|
-
clr[i] = all(greaterThan(ndc.xy * vec2(1.0, -1.0), rect_params.xy)) && all(lessThan(ndc.xy * vec2(1.0, -1.0), rect_params.zw)) ? 1.0 : 0.0;
|
|
143314
|
-
} else if (mode == 2) {
|
|
143315
|
-
// select by sphere
|
|
143316
|
-
clr[i] = length(world - sphere_params.xyz) < sphere_params.w ? 1.0 : 0.0;
|
|
143317
|
-
} else if (mode == 3) {
|
|
143318
|
-
// select by box
|
|
143319
|
-
vec3 relativePosition = world - box_params.xyz;
|
|
143320
|
-
bool isInsideCube = true;
|
|
143321
|
-
if (relativePosition.x < -aabb_params.x || relativePosition.x > aabb_params.x) {
|
|
143322
|
-
isInsideCube = false;
|
|
143323
|
-
}
|
|
143324
|
-
if (relativePosition.y < -aabb_params.y || relativePosition.y > aabb_params.y) {
|
|
143325
|
-
isInsideCube = false;
|
|
143326
|
-
}
|
|
143327
|
-
if (relativePosition.z < -aabb_params.z || relativePosition.z > aabb_params.z) {
|
|
143328
|
-
isInsideCube = false;
|
|
143329
|
-
}
|
|
143330
|
-
clr[i] = isInsideCube ? 1.0 : 0.0;
|
|
143331
|
-
}
|
|
143332
|
-
}
|
|
143333
|
-
}
|
|
143334
|
-
|
|
143335
|
-
gl_FragColor = clr;
|
|
143336
|
-
}
|
|
143337
|
-
`;
|
|
143338
|
-
|
|
143339
|
-
const vertexShader$4 = /* glsl */ `
|
|
143340
|
-
attribute vec2 vertex_position;
|
|
143341
|
-
void main(void) {
|
|
143342
|
-
gl_Position = vec4(vertex_position, 0.0, 1.0);
|
|
143343
|
-
}
|
|
143344
|
-
`;
|
|
143345
|
-
const fragmentShader$4 = /* glsl */ `
|
|
143346
|
-
uniform highp usampler2D transformA; // splat center x, y, z
|
|
143347
|
-
uniform highp usampler2D splatTransform; // transform palette index
|
|
143348
|
-
uniform sampler2D transformPalette; // palette of transforms
|
|
143349
|
-
uniform ivec2 splat_params; // splat texture width, num splats
|
|
143350
|
-
|
|
143351
|
-
void main(void) {
|
|
143352
|
-
// calculate output id
|
|
143353
|
-
ivec2 splatUV = ivec2(gl_FragCoord);
|
|
143354
|
-
|
|
143355
|
-
// skip if splat index is out of bounds
|
|
143356
|
-
if (splatUV.x + splatUV.y * splat_params.x >= splat_params.y) {
|
|
143357
|
-
discard;
|
|
143358
|
-
}
|
|
143359
|
-
|
|
143360
|
-
// read splat center
|
|
143361
|
-
vec3 center = uintBitsToFloat(texelFetch(transformA, splatUV, 0).xyz);
|
|
143362
|
-
|
|
143363
|
-
// apply optional per-splat transform
|
|
143364
|
-
uint transformIndex = texelFetch(splatTransform, splatUV, 0).r;
|
|
143365
|
-
if (transformIndex > 0u) {
|
|
143366
|
-
// read transform matrix
|
|
143367
|
-
int u = int(transformIndex % 512u) * 3;
|
|
143368
|
-
int v = int(transformIndex / 512u);
|
|
143369
|
-
|
|
143370
|
-
mat3x4 t;
|
|
143371
|
-
t[0] = texelFetch(transformPalette, ivec2(u, v), 0);
|
|
143372
|
-
t[1] = texelFetch(transformPalette, ivec2(u + 1, v), 0);
|
|
143373
|
-
t[2] = texelFetch(transformPalette, ivec2(u + 2, v), 0);
|
|
143374
|
-
|
|
143375
|
-
center = vec4(center, 1.0) * t;
|
|
143376
|
-
}
|
|
143377
|
-
|
|
143378
|
-
gl_FragColor = vec4(center, 0.0);
|
|
143379
|
-
}
|
|
143169
|
+
const vertexShader$6 = /* glsl */ `
|
|
143170
|
+
attribute vec2 vertex_position;
|
|
143171
|
+
void main(void) {
|
|
143172
|
+
gl_Position = vec4(vertex_position, 0.0, 1.0);
|
|
143173
|
+
}
|
|
143174
|
+
`;
|
|
143175
|
+
const fragmentShader$6 = /* glsl */ `
|
|
143176
|
+
uniform highp usampler2D transformA; // splat center x, y, z
|
|
143177
|
+
uniform highp usampler2D splatTransform; // transform palette index
|
|
143178
|
+
uniform sampler2D transformPalette; // palette of transforms
|
|
143179
|
+
uniform sampler2D splatState; // per-splat state
|
|
143180
|
+
uniform highp ivec3 splat_params; // texture width, texture height, num splats
|
|
143181
|
+
uniform highp uint mode; // 0: selected, 1: visible
|
|
143182
|
+
|
|
143183
|
+
// calculate min and max for a single column of splats
|
|
143184
|
+
void main(void) {
|
|
143185
|
+
|
|
143186
|
+
vec3 boundMin = vec3(1e6);
|
|
143187
|
+
vec3 boundMax = vec3(-1e6);
|
|
143188
|
+
|
|
143189
|
+
for (int id = 0; id < splat_params.y; id++) {
|
|
143190
|
+
// calculate splatUV
|
|
143191
|
+
ivec2 splatUV = ivec2(gl_FragCoord.x, id);
|
|
143192
|
+
|
|
143193
|
+
// skip out-of-range splats
|
|
143194
|
+
if ((splatUV.x + splatUV.y * splat_params.x) >= splat_params.z) {
|
|
143195
|
+
continue;
|
|
143196
|
+
}
|
|
143197
|
+
|
|
143198
|
+
// read splat state
|
|
143199
|
+
uint state = uint(texelFetch(splatState, splatUV, 0).r * 255.0);
|
|
143200
|
+
|
|
143201
|
+
// skip deleted or locked splats
|
|
143202
|
+
if (((mode == 0u) && (state != 1u)) || ((mode == 1u) && ((state & 4u) != 0u))) {
|
|
143203
|
+
continue;
|
|
143204
|
+
}
|
|
143205
|
+
|
|
143206
|
+
// read splat center
|
|
143207
|
+
vec3 center = uintBitsToFloat(texelFetch(transformA, splatUV, 0).xyz);
|
|
143208
|
+
|
|
143209
|
+
// apply optional per-splat transform
|
|
143210
|
+
uint transformIndex = texelFetch(splatTransform, splatUV, 0).r;
|
|
143211
|
+
if (transformIndex > 0u) {
|
|
143212
|
+
// read transform matrix
|
|
143213
|
+
int u = int(transformIndex % 512u) * 3;
|
|
143214
|
+
int v = int(transformIndex / 512u);
|
|
143215
|
+
|
|
143216
|
+
mat3x4 t;
|
|
143217
|
+
t[0] = texelFetch(transformPalette, ivec2(u, v), 0);
|
|
143218
|
+
t[1] = texelFetch(transformPalette, ivec2(u + 1, v), 0);
|
|
143219
|
+
t[2] = texelFetch(transformPalette, ivec2(u + 2, v), 0);
|
|
143220
|
+
|
|
143221
|
+
center = vec4(center, 1.0) * t;
|
|
143222
|
+
}
|
|
143223
|
+
|
|
143224
|
+
boundMin = min(boundMin, mix(center, boundMin, isinf(center)));
|
|
143225
|
+
boundMax = max(boundMax, mix(center, boundMax, isinf(center)));
|
|
143226
|
+
}
|
|
143227
|
+
|
|
143228
|
+
pcFragColor0 = vec4(boundMin, 0.0);
|
|
143229
|
+
pcFragColor1 = vec4(boundMax, 0.0);
|
|
143230
|
+
}
|
|
143231
|
+
`;
|
|
143232
|
+
|
|
143233
|
+
const vertexShader$5 = /* glsl */ `
|
|
143234
|
+
attribute vec2 vertex_position;
|
|
143235
|
+
void main(void) {
|
|
143236
|
+
gl_Position = vec4(vertex_position, 0.0, 1.0);
|
|
143237
|
+
}
|
|
143238
|
+
`;
|
|
143239
|
+
const fragmentShader$5 = /* glsl */ `
|
|
143240
|
+
uniform highp usampler2D transformA; // splat center x, y, z
|
|
143241
|
+
uniform highp usampler2D splatTransform; // transform palette index
|
|
143242
|
+
uniform sampler2D transformPalette; // palette of transforms
|
|
143243
|
+
uniform uvec2 splat_params; // splat texture width, num splats
|
|
143244
|
+
|
|
143245
|
+
uniform mat4 matrix_model;
|
|
143246
|
+
uniform mat4 matrix_viewProjection;
|
|
143247
|
+
|
|
143248
|
+
uniform uvec2 output_params; // output width, height
|
|
143249
|
+
|
|
143250
|
+
// 0: mask, 1: rect, 2: sphere
|
|
143251
|
+
uniform int mode;
|
|
143252
|
+
|
|
143253
|
+
// mask params
|
|
143254
|
+
uniform sampler2D mask; // mask in alpha channel
|
|
143255
|
+
uniform vec2 mask_params; // mask width, height
|
|
143256
|
+
|
|
143257
|
+
// rect params
|
|
143258
|
+
uniform vec4 rect_params; // rect x, y, width, height
|
|
143259
|
+
|
|
143260
|
+
// sphere params
|
|
143261
|
+
uniform vec4 sphere_params; // sphere x, y, z, radius
|
|
143262
|
+
|
|
143263
|
+
// box params
|
|
143264
|
+
uniform vec4 box_params; // box x, y, z
|
|
143265
|
+
uniform vec4 aabb_params; // len x, y, z
|
|
143266
|
+
|
|
143267
|
+
void main(void) {
|
|
143268
|
+
// calculate output id
|
|
143269
|
+
uvec2 outputUV = uvec2(gl_FragCoord);
|
|
143270
|
+
uint outputId = (outputUV.x + outputUV.y * output_params.x) * 4u;
|
|
143271
|
+
|
|
143272
|
+
vec4 clr = vec4(0.0);
|
|
143273
|
+
|
|
143274
|
+
for (uint i = 0u; i < 4u; i++) {
|
|
143275
|
+
uint id = outputId + i;
|
|
143276
|
+
|
|
143277
|
+
if (id >= splat_params.y) {
|
|
143278
|
+
continue;
|
|
143279
|
+
}
|
|
143280
|
+
|
|
143281
|
+
// calculate splatUV
|
|
143282
|
+
ivec2 splatUV = ivec2(
|
|
143283
|
+
int(id % splat_params.x),
|
|
143284
|
+
int(id / splat_params.x)
|
|
143285
|
+
);
|
|
143286
|
+
|
|
143287
|
+
// read splat center
|
|
143288
|
+
vec3 center = uintBitsToFloat(texelFetch(transformA, splatUV, 0).xyz);
|
|
143289
|
+
|
|
143290
|
+
// apply optional per-splat transform
|
|
143291
|
+
uint transformIndex = texelFetch(splatTransform, splatUV, 0).r;
|
|
143292
|
+
if (transformIndex > 0u) {
|
|
143293
|
+
// read transform matrix
|
|
143294
|
+
int u = int(transformIndex % 512u) * 3;
|
|
143295
|
+
int v = int(transformIndex / 512u);
|
|
143296
|
+
|
|
143297
|
+
mat3x4 t;
|
|
143298
|
+
t[0] = texelFetch(transformPalette, ivec2(u, v), 0);
|
|
143299
|
+
t[1] = texelFetch(transformPalette, ivec2(u + 1, v), 0);
|
|
143300
|
+
t[2] = texelFetch(transformPalette, ivec2(u + 2, v), 0);
|
|
143301
|
+
|
|
143302
|
+
center = vec4(center, 1.0) * t;
|
|
143303
|
+
}
|
|
143304
|
+
|
|
143305
|
+
// transform to clip space and discard if outside
|
|
143306
|
+
vec3 world = (matrix_model * vec4(center, 1.0)).xyz;
|
|
143307
|
+
vec4 clip = matrix_viewProjection * vec4(world, 1.0);
|
|
143308
|
+
vec3 ndc = clip.xyz / clip.w;
|
|
143309
|
+
|
|
143310
|
+
// skip offscreen fragments
|
|
143311
|
+
if (!any(greaterThan(abs(ndc), vec3(1.0)))) {
|
|
143312
|
+
if (mode == 0) {
|
|
143313
|
+
// select by mask
|
|
143314
|
+
ivec2 maskUV = ivec2((ndc.xy * vec2(0.5, -0.5) + 0.5) * mask_params);
|
|
143315
|
+
clr[i] = texelFetch(mask, maskUV, 0).a < 1.0 ? 0.0 : 1.0;
|
|
143316
|
+
} else if (mode == 1) {
|
|
143317
|
+
// select by rect
|
|
143318
|
+
clr[i] = all(greaterThan(ndc.xy * vec2(1.0, -1.0), rect_params.xy)) && all(lessThan(ndc.xy * vec2(1.0, -1.0), rect_params.zw)) ? 1.0 : 0.0;
|
|
143319
|
+
} else if (mode == 2) {
|
|
143320
|
+
// select by sphere
|
|
143321
|
+
clr[i] = length(world - sphere_params.xyz) < sphere_params.w ? 1.0 : 0.0;
|
|
143322
|
+
} else if (mode == 3) {
|
|
143323
|
+
// select by box
|
|
143324
|
+
vec3 relativePosition = world - box_params.xyz;
|
|
143325
|
+
bool isInsideCube = true;
|
|
143326
|
+
if (relativePosition.x < -aabb_params.x || relativePosition.x > aabb_params.x) {
|
|
143327
|
+
isInsideCube = false;
|
|
143328
|
+
}
|
|
143329
|
+
if (relativePosition.y < -aabb_params.y || relativePosition.y > aabb_params.y) {
|
|
143330
|
+
isInsideCube = false;
|
|
143331
|
+
}
|
|
143332
|
+
if (relativePosition.z < -aabb_params.z || relativePosition.z > aabb_params.z) {
|
|
143333
|
+
isInsideCube = false;
|
|
143334
|
+
}
|
|
143335
|
+
clr[i] = isInsideCube ? 1.0 : 0.0;
|
|
143336
|
+
}
|
|
143337
|
+
}
|
|
143338
|
+
}
|
|
143339
|
+
|
|
143340
|
+
gl_FragColor = clr;
|
|
143341
|
+
}
|
|
143342
|
+
`;
|
|
143343
|
+
|
|
143344
|
+
const vertexShader$4 = /* glsl */ `
|
|
143345
|
+
attribute vec2 vertex_position;
|
|
143346
|
+
void main(void) {
|
|
143347
|
+
gl_Position = vec4(vertex_position, 0.0, 1.0);
|
|
143348
|
+
}
|
|
143349
|
+
`;
|
|
143350
|
+
const fragmentShader$4 = /* glsl */ `
|
|
143351
|
+
uniform highp usampler2D transformA; // splat center x, y, z
|
|
143352
|
+
uniform highp usampler2D splatTransform; // transform palette index
|
|
143353
|
+
uniform sampler2D transformPalette; // palette of transforms
|
|
143354
|
+
uniform ivec2 splat_params; // splat texture width, num splats
|
|
143355
|
+
|
|
143356
|
+
void main(void) {
|
|
143357
|
+
// calculate output id
|
|
143358
|
+
ivec2 splatUV = ivec2(gl_FragCoord);
|
|
143359
|
+
|
|
143360
|
+
// skip if splat index is out of bounds
|
|
143361
|
+
if (splatUV.x + splatUV.y * splat_params.x >= splat_params.y) {
|
|
143362
|
+
discard;
|
|
143363
|
+
}
|
|
143364
|
+
|
|
143365
|
+
// read splat center
|
|
143366
|
+
vec3 center = uintBitsToFloat(texelFetch(transformA, splatUV, 0).xyz);
|
|
143367
|
+
|
|
143368
|
+
// apply optional per-splat transform
|
|
143369
|
+
uint transformIndex = texelFetch(splatTransform, splatUV, 0).r;
|
|
143370
|
+
if (transformIndex > 0u) {
|
|
143371
|
+
// read transform matrix
|
|
143372
|
+
int u = int(transformIndex % 512u) * 3;
|
|
143373
|
+
int v = int(transformIndex / 512u);
|
|
143374
|
+
|
|
143375
|
+
mat3x4 t;
|
|
143376
|
+
t[0] = texelFetch(transformPalette, ivec2(u, v), 0);
|
|
143377
|
+
t[1] = texelFetch(transformPalette, ivec2(u + 1, v), 0);
|
|
143378
|
+
t[2] = texelFetch(transformPalette, ivec2(u + 2, v), 0);
|
|
143379
|
+
|
|
143380
|
+
center = vec4(center, 1.0) * t;
|
|
143381
|
+
}
|
|
143382
|
+
|
|
143383
|
+
gl_FragColor = vec4(center, 0.0);
|
|
143384
|
+
}
|
|
143380
143385
|
`;
|
|
143381
143386
|
|
|
143382
143387
|
const v1 = new Vec3();
|
|
@@ -143413,18 +143418,18 @@ class DataProcessor {
|
|
|
143413
143418
|
attributes: {
|
|
143414
143419
|
vertex_position: SEMANTIC_POSITION
|
|
143415
143420
|
},
|
|
143416
|
-
vertexGLSL: `
|
|
143417
|
-
attribute vec2 vertex_position;
|
|
143418
|
-
void main(void) {
|
|
143419
|
-
gl_Position = vec4(vertex_position, 0.0, 1.0);
|
|
143420
|
-
}
|
|
143421
|
+
vertexGLSL: `
|
|
143422
|
+
attribute vec2 vertex_position;
|
|
143423
|
+
void main(void) {
|
|
143424
|
+
gl_Position = vec4(vertex_position, 0.0, 1.0);
|
|
143425
|
+
}
|
|
143421
143426
|
`,
|
|
143422
|
-
fragmentGLSL: `
|
|
143423
|
-
uniform sampler2D colorTex;
|
|
143424
|
-
void main(void) {
|
|
143425
|
-
ivec2 texel = ivec2(gl_FragCoord.xy);
|
|
143426
|
-
gl_FragColor = texelFetch(colorTex, texel, 0);
|
|
143427
|
-
}
|
|
143427
|
+
fragmentGLSL: `
|
|
143428
|
+
uniform sampler2D colorTex;
|
|
143429
|
+
void main(void) {
|
|
143430
|
+
ivec2 texel = ivec2(gl_FragCoord.xy);
|
|
143431
|
+
gl_FragColor = texelFetch(colorTex, texel, 0);
|
|
143432
|
+
}
|
|
143428
143433
|
`
|
|
143429
143434
|
});
|
|
143430
143435
|
// intersection test
|
|
@@ -144663,176 +144668,176 @@ class Camera extends Element$1 {
|
|
|
144663
144668
|
}
|
|
144664
144669
|
}
|
|
144665
144670
|
|
|
144666
|
-
const vertexShader$3 = /* glsl*/ `
|
|
144667
|
-
uniform vec3 near_origin;
|
|
144668
|
-
uniform vec3 near_x;
|
|
144669
|
-
uniform vec3 near_y;
|
|
144670
|
-
|
|
144671
|
-
uniform vec3 far_origin;
|
|
144672
|
-
uniform vec3 far_x;
|
|
144673
|
-
uniform vec3 far_y;
|
|
144674
|
-
|
|
144675
|
-
attribute vec2 vertex_position;
|
|
144676
|
-
|
|
144677
|
-
varying vec3 worldFar;
|
|
144678
|
-
varying vec3 worldNear;
|
|
144679
|
-
|
|
144680
|
-
void main(void) {
|
|
144681
|
-
gl_Position = vec4(vertex_position, 0.0, 1.0);
|
|
144682
|
-
|
|
144683
|
-
vec2 p = vertex_position * 0.5 + 0.5;
|
|
144684
|
-
worldNear = near_origin + near_x * p.x + near_y * p.y;
|
|
144685
|
-
worldFar = far_origin + far_x * p.x + far_y * p.y;
|
|
144686
|
-
}
|
|
144687
|
-
`;
|
|
144688
|
-
const fragmentShader$3 = /* glsl*/ `
|
|
144689
|
-
uniform vec3 view_position;
|
|
144690
|
-
uniform mat4 matrix_viewProjection;
|
|
144691
|
-
uniform sampler2D blueNoiseTex32;
|
|
144692
|
-
|
|
144693
|
-
uniform int plane; // 0: x (yz), 1: y (xz), 2: z (xy)
|
|
144694
|
-
|
|
144695
|
-
vec4 planes[3] = vec4[3](
|
|
144696
|
-
vec4(1.0, 0.0, 0.0, 0.0),
|
|
144697
|
-
vec4(0.0, 1.0, 0.0, 0.0),
|
|
144698
|
-
vec4(0.0, 0.0, 1.0, 0.0)
|
|
144699
|
-
);
|
|
144700
|
-
|
|
144701
|
-
vec3 colors[3] = vec3[3](
|
|
144702
|
-
vec3(1.0, 0.2, 0.2),
|
|
144703
|
-
vec3(0.2, 1.0, 0.2),
|
|
144704
|
-
vec3(0.2, 0.2, 1.0)
|
|
144705
|
-
);
|
|
144706
|
-
|
|
144707
|
-
int axis0[3] = int[3](1, 0, 0);
|
|
144708
|
-
int axis1[3] = int[3](2, 2, 1);
|
|
144709
|
-
|
|
144710
|
-
varying vec3 worldNear;
|
|
144711
|
-
varying vec3 worldFar;
|
|
144712
|
-
|
|
144713
|
-
bool intersectPlane(inout float t, vec3 pos, vec3 dir, vec4 plane) {
|
|
144714
|
-
float d = dot(dir, plane.xyz);
|
|
144715
|
-
if (abs(d) < 1e-06) {
|
|
144716
|
-
return false;
|
|
144717
|
-
}
|
|
144718
|
-
|
|
144719
|
-
float n = -(dot(pos, plane.xyz) + plane.w) / d;
|
|
144720
|
-
if (n < 0.0) {
|
|
144721
|
-
return false;
|
|
144722
|
-
}
|
|
144723
|
-
|
|
144724
|
-
t = n;
|
|
144725
|
-
|
|
144726
|
-
return true;
|
|
144727
|
-
}
|
|
144728
|
-
|
|
144729
|
-
// https://bgolus.medium.com/the-best-darn-grid-shader-yet-727f9278b9d8#1e7c
|
|
144730
|
-
float pristineGrid(in vec2 uv, in vec2 ddx, in vec2 ddy, vec2 lineWidth) {
|
|
144731
|
-
vec2 uvDeriv = vec2(length(vec2(ddx.x, ddy.x)), length(vec2(ddx.y, ddy.y)));
|
|
144732
|
-
bvec2 invertLine = bvec2(lineWidth.x > 0.5, lineWidth.y > 0.5);
|
|
144733
|
-
vec2 targetWidth = vec2(
|
|
144734
|
-
invertLine.x ? 1.0 - lineWidth.x : lineWidth.x,
|
|
144735
|
-
invertLine.y ? 1.0 - lineWidth.y : lineWidth.y
|
|
144736
|
-
);
|
|
144737
|
-
vec2 drawWidth = clamp(targetWidth, uvDeriv, vec2(0.5));
|
|
144738
|
-
vec2 lineAA = uvDeriv * 1.5;
|
|
144739
|
-
vec2 gridUV = abs(fract(uv) * 2.0 - 1.0);
|
|
144740
|
-
gridUV.x = invertLine.x ? gridUV.x : 1.0 - gridUV.x;
|
|
144741
|
-
gridUV.y = invertLine.y ? gridUV.y : 1.0 - gridUV.y;
|
|
144742
|
-
vec2 grid2 = smoothstep(drawWidth + lineAA, drawWidth - lineAA, gridUV);
|
|
144743
|
-
|
|
144744
|
-
grid2 *= clamp(targetWidth / drawWidth, 0.0, 1.0);
|
|
144745
|
-
grid2 = mix(grid2, targetWidth, clamp(uvDeriv * 2.0 - 1.0, 0.0, 1.0));
|
|
144746
|
-
grid2.x = invertLine.x ? 1.0 - grid2.x : grid2.x;
|
|
144747
|
-
grid2.y = invertLine.y ? 1.0 - grid2.y : grid2.y;
|
|
144748
|
-
|
|
144749
|
-
return mix(grid2.x, 1.0, grid2.y);
|
|
144750
|
-
}
|
|
144751
|
-
|
|
144752
|
-
float calcDepth(vec3 p) {
|
|
144753
|
-
vec4 v = matrix_viewProjection * vec4(p, 1.0);
|
|
144754
|
-
return (v.z / v.w) * 0.5 + 0.5;
|
|
144755
|
-
}
|
|
144756
|
-
|
|
144757
|
-
bool writeDepth(float alpha) {
|
|
144758
|
-
vec2 uv = fract(gl_FragCoord.xy / 32.0);
|
|
144759
|
-
float noise = texture2DLod(blueNoiseTex32, uv, 0.0).y;
|
|
144760
|
-
return alpha > noise;
|
|
144761
|
-
}
|
|
144762
|
-
|
|
144763
|
-
void main(void) {
|
|
144764
|
-
vec3 p = worldNear;
|
|
144765
|
-
vec3 v = normalize(worldFar - worldNear);
|
|
144766
|
-
|
|
144767
|
-
// intersect ray with the world xz plane
|
|
144768
|
-
float t;
|
|
144769
|
-
if (!intersectPlane(t, p, v, planes[plane])) {
|
|
144770
|
-
discard;
|
|
144771
|
-
}
|
|
144772
|
-
|
|
144773
|
-
// calculate grid intersection
|
|
144774
|
-
vec3 worldPos = p + v * t;
|
|
144775
|
-
vec2 pos = plane == 0 ? worldPos.yz : (plane == 1 ? worldPos.xz : worldPos.xy);
|
|
144776
|
-
vec2 ddx = dFdx(pos);
|
|
144777
|
-
vec2 ddy = dFdy(pos);
|
|
144778
|
-
|
|
144779
|
-
float epsilon = 1.0 / 255.0;
|
|
144780
|
-
|
|
144781
|
-
// calculate fade
|
|
144782
|
-
float fade = 1.0 - smoothstep(400.0, 1000.0, length(worldPos - view_position));
|
|
144783
|
-
if (fade < epsilon) {
|
|
144784
|
-
discard;
|
|
144785
|
-
}
|
|
144786
|
-
|
|
144787
|
-
vec2 levelPos;
|
|
144788
|
-
float levelSize;
|
|
144789
|
-
float levelAlpha;
|
|
144790
|
-
|
|
144791
|
-
// 10m grid with colored main axes
|
|
144792
|
-
levelPos = pos * 0.1;
|
|
144793
|
-
levelSize = 2.0 / 1000.0;
|
|
144794
|
-
levelAlpha = pristineGrid(levelPos, ddx * 0.1, ddy * 0.1, vec2(levelSize)) * fade;
|
|
144795
|
-
if (levelAlpha > epsilon) {
|
|
144796
|
-
vec3 color;
|
|
144797
|
-
vec2 loc = abs(levelPos);
|
|
144798
|
-
if (loc.x < levelSize) {
|
|
144799
|
-
if (loc.y < levelSize) {
|
|
144800
|
-
color = vec3(1.0);
|
|
144801
|
-
} else {
|
|
144802
|
-
color = colors[axis1[plane]];
|
|
144803
|
-
}
|
|
144804
|
-
} else if (loc.y < levelSize) {
|
|
144805
|
-
color = colors[axis0[plane]];
|
|
144806
|
-
} else {
|
|
144807
|
-
color = vec3(0.9);
|
|
144808
|
-
}
|
|
144809
|
-
gl_FragColor = vec4(color, levelAlpha);
|
|
144810
|
-
gl_FragDepth = writeDepth(levelAlpha) ? calcDepth(worldPos) : 1.0;
|
|
144811
|
-
return;
|
|
144812
|
-
}
|
|
144813
|
-
|
|
144814
|
-
// 1m grid
|
|
144815
|
-
levelPos = pos;
|
|
144816
|
-
levelSize = 1.0 / 100.0;
|
|
144817
|
-
levelAlpha = pristineGrid(levelPos, ddx, ddy, vec2(levelSize)) * fade;
|
|
144818
|
-
if (levelAlpha > epsilon) {
|
|
144819
|
-
gl_FragColor = vec4(vec3(0.7), levelAlpha);
|
|
144820
|
-
gl_FragDepth = writeDepth(levelAlpha) ? calcDepth(worldPos) : 1.0;
|
|
144821
|
-
return;
|
|
144822
|
-
}
|
|
144823
|
-
|
|
144824
|
-
// 0.1m grid
|
|
144825
|
-
levelPos = pos * 10.0;
|
|
144826
|
-
levelSize = 1.0 / 100.0;
|
|
144827
|
-
levelAlpha = pristineGrid(levelPos, ddx * 10.0, ddy * 10.0, vec2(levelSize)) * fade;
|
|
144828
|
-
if (levelAlpha > epsilon) {
|
|
144829
|
-
gl_FragColor = vec4(vec3(0.7), levelAlpha);
|
|
144830
|
-
gl_FragDepth = writeDepth(levelAlpha) ? calcDepth(worldPos) : 1.0;
|
|
144831
|
-
return;
|
|
144832
|
-
}
|
|
144833
|
-
|
|
144834
|
-
discard;
|
|
144835
|
-
}
|
|
144671
|
+
const vertexShader$3 = /* glsl*/ `
|
|
144672
|
+
uniform vec3 near_origin;
|
|
144673
|
+
uniform vec3 near_x;
|
|
144674
|
+
uniform vec3 near_y;
|
|
144675
|
+
|
|
144676
|
+
uniform vec3 far_origin;
|
|
144677
|
+
uniform vec3 far_x;
|
|
144678
|
+
uniform vec3 far_y;
|
|
144679
|
+
|
|
144680
|
+
attribute vec2 vertex_position;
|
|
144681
|
+
|
|
144682
|
+
varying vec3 worldFar;
|
|
144683
|
+
varying vec3 worldNear;
|
|
144684
|
+
|
|
144685
|
+
void main(void) {
|
|
144686
|
+
gl_Position = vec4(vertex_position, 0.0, 1.0);
|
|
144687
|
+
|
|
144688
|
+
vec2 p = vertex_position * 0.5 + 0.5;
|
|
144689
|
+
worldNear = near_origin + near_x * p.x + near_y * p.y;
|
|
144690
|
+
worldFar = far_origin + far_x * p.x + far_y * p.y;
|
|
144691
|
+
}
|
|
144692
|
+
`;
|
|
144693
|
+
const fragmentShader$3 = /* glsl*/ `
|
|
144694
|
+
uniform vec3 view_position;
|
|
144695
|
+
uniform mat4 matrix_viewProjection;
|
|
144696
|
+
uniform sampler2D blueNoiseTex32;
|
|
144697
|
+
|
|
144698
|
+
uniform int plane; // 0: x (yz), 1: y (xz), 2: z (xy)
|
|
144699
|
+
|
|
144700
|
+
vec4 planes[3] = vec4[3](
|
|
144701
|
+
vec4(1.0, 0.0, 0.0, 0.0),
|
|
144702
|
+
vec4(0.0, 1.0, 0.0, 0.0),
|
|
144703
|
+
vec4(0.0, 0.0, 1.0, 0.0)
|
|
144704
|
+
);
|
|
144705
|
+
|
|
144706
|
+
vec3 colors[3] = vec3[3](
|
|
144707
|
+
vec3(1.0, 0.2, 0.2),
|
|
144708
|
+
vec3(0.2, 1.0, 0.2),
|
|
144709
|
+
vec3(0.2, 0.2, 1.0)
|
|
144710
|
+
);
|
|
144711
|
+
|
|
144712
|
+
int axis0[3] = int[3](1, 0, 0);
|
|
144713
|
+
int axis1[3] = int[3](2, 2, 1);
|
|
144714
|
+
|
|
144715
|
+
varying vec3 worldNear;
|
|
144716
|
+
varying vec3 worldFar;
|
|
144717
|
+
|
|
144718
|
+
bool intersectPlane(inout float t, vec3 pos, vec3 dir, vec4 plane) {
|
|
144719
|
+
float d = dot(dir, plane.xyz);
|
|
144720
|
+
if (abs(d) < 1e-06) {
|
|
144721
|
+
return false;
|
|
144722
|
+
}
|
|
144723
|
+
|
|
144724
|
+
float n = -(dot(pos, plane.xyz) + plane.w) / d;
|
|
144725
|
+
if (n < 0.0) {
|
|
144726
|
+
return false;
|
|
144727
|
+
}
|
|
144728
|
+
|
|
144729
|
+
t = n;
|
|
144730
|
+
|
|
144731
|
+
return true;
|
|
144732
|
+
}
|
|
144733
|
+
|
|
144734
|
+
// https://bgolus.medium.com/the-best-darn-grid-shader-yet-727f9278b9d8#1e7c
|
|
144735
|
+
float pristineGrid(in vec2 uv, in vec2 ddx, in vec2 ddy, vec2 lineWidth) {
|
|
144736
|
+
vec2 uvDeriv = vec2(length(vec2(ddx.x, ddy.x)), length(vec2(ddx.y, ddy.y)));
|
|
144737
|
+
bvec2 invertLine = bvec2(lineWidth.x > 0.5, lineWidth.y > 0.5);
|
|
144738
|
+
vec2 targetWidth = vec2(
|
|
144739
|
+
invertLine.x ? 1.0 - lineWidth.x : lineWidth.x,
|
|
144740
|
+
invertLine.y ? 1.0 - lineWidth.y : lineWidth.y
|
|
144741
|
+
);
|
|
144742
|
+
vec2 drawWidth = clamp(targetWidth, uvDeriv, vec2(0.5));
|
|
144743
|
+
vec2 lineAA = uvDeriv * 1.5;
|
|
144744
|
+
vec2 gridUV = abs(fract(uv) * 2.0 - 1.0);
|
|
144745
|
+
gridUV.x = invertLine.x ? gridUV.x : 1.0 - gridUV.x;
|
|
144746
|
+
gridUV.y = invertLine.y ? gridUV.y : 1.0 - gridUV.y;
|
|
144747
|
+
vec2 grid2 = smoothstep(drawWidth + lineAA, drawWidth - lineAA, gridUV);
|
|
144748
|
+
|
|
144749
|
+
grid2 *= clamp(targetWidth / drawWidth, 0.0, 1.0);
|
|
144750
|
+
grid2 = mix(grid2, targetWidth, clamp(uvDeriv * 2.0 - 1.0, 0.0, 1.0));
|
|
144751
|
+
grid2.x = invertLine.x ? 1.0 - grid2.x : grid2.x;
|
|
144752
|
+
grid2.y = invertLine.y ? 1.0 - grid2.y : grid2.y;
|
|
144753
|
+
|
|
144754
|
+
return mix(grid2.x, 1.0, grid2.y);
|
|
144755
|
+
}
|
|
144756
|
+
|
|
144757
|
+
float calcDepth(vec3 p) {
|
|
144758
|
+
vec4 v = matrix_viewProjection * vec4(p, 1.0);
|
|
144759
|
+
return (v.z / v.w) * 0.5 + 0.5;
|
|
144760
|
+
}
|
|
144761
|
+
|
|
144762
|
+
bool writeDepth(float alpha) {
|
|
144763
|
+
vec2 uv = fract(gl_FragCoord.xy / 32.0);
|
|
144764
|
+
float noise = texture2DLod(blueNoiseTex32, uv, 0.0).y;
|
|
144765
|
+
return alpha > noise;
|
|
144766
|
+
}
|
|
144767
|
+
|
|
144768
|
+
void main(void) {
|
|
144769
|
+
vec3 p = worldNear;
|
|
144770
|
+
vec3 v = normalize(worldFar - worldNear);
|
|
144771
|
+
|
|
144772
|
+
// intersect ray with the world xz plane
|
|
144773
|
+
float t;
|
|
144774
|
+
if (!intersectPlane(t, p, v, planes[plane])) {
|
|
144775
|
+
discard;
|
|
144776
|
+
}
|
|
144777
|
+
|
|
144778
|
+
// calculate grid intersection
|
|
144779
|
+
vec3 worldPos = p + v * t;
|
|
144780
|
+
vec2 pos = plane == 0 ? worldPos.yz : (plane == 1 ? worldPos.xz : worldPos.xy);
|
|
144781
|
+
vec2 ddx = dFdx(pos);
|
|
144782
|
+
vec2 ddy = dFdy(pos);
|
|
144783
|
+
|
|
144784
|
+
float epsilon = 1.0 / 255.0;
|
|
144785
|
+
|
|
144786
|
+
// calculate fade
|
|
144787
|
+
float fade = 1.0 - smoothstep(400.0, 1000.0, length(worldPos - view_position));
|
|
144788
|
+
if (fade < epsilon) {
|
|
144789
|
+
discard;
|
|
144790
|
+
}
|
|
144791
|
+
|
|
144792
|
+
vec2 levelPos;
|
|
144793
|
+
float levelSize;
|
|
144794
|
+
float levelAlpha;
|
|
144795
|
+
|
|
144796
|
+
// 10m grid with colored main axes
|
|
144797
|
+
levelPos = pos * 0.1;
|
|
144798
|
+
levelSize = 2.0 / 1000.0;
|
|
144799
|
+
levelAlpha = pristineGrid(levelPos, ddx * 0.1, ddy * 0.1, vec2(levelSize)) * fade;
|
|
144800
|
+
if (levelAlpha > epsilon) {
|
|
144801
|
+
vec3 color;
|
|
144802
|
+
vec2 loc = abs(levelPos);
|
|
144803
|
+
if (loc.x < levelSize) {
|
|
144804
|
+
if (loc.y < levelSize) {
|
|
144805
|
+
color = vec3(1.0);
|
|
144806
|
+
} else {
|
|
144807
|
+
color = colors[axis1[plane]];
|
|
144808
|
+
}
|
|
144809
|
+
} else if (loc.y < levelSize) {
|
|
144810
|
+
color = colors[axis0[plane]];
|
|
144811
|
+
} else {
|
|
144812
|
+
color = vec3(0.9);
|
|
144813
|
+
}
|
|
144814
|
+
gl_FragColor = vec4(color, levelAlpha);
|
|
144815
|
+
gl_FragDepth = writeDepth(levelAlpha) ? calcDepth(worldPos) : 1.0;
|
|
144816
|
+
return;
|
|
144817
|
+
}
|
|
144818
|
+
|
|
144819
|
+
// 1m grid
|
|
144820
|
+
levelPos = pos;
|
|
144821
|
+
levelSize = 1.0 / 100.0;
|
|
144822
|
+
levelAlpha = pristineGrid(levelPos, ddx, ddy, vec2(levelSize)) * fade;
|
|
144823
|
+
if (levelAlpha > epsilon) {
|
|
144824
|
+
gl_FragColor = vec4(vec3(0.7), levelAlpha);
|
|
144825
|
+
gl_FragDepth = writeDepth(levelAlpha) ? calcDepth(worldPos) : 1.0;
|
|
144826
|
+
return;
|
|
144827
|
+
}
|
|
144828
|
+
|
|
144829
|
+
// 0.1m grid
|
|
144830
|
+
levelPos = pos * 10.0;
|
|
144831
|
+
levelSize = 1.0 / 100.0;
|
|
144832
|
+
levelAlpha = pristineGrid(levelPos, ddx * 10.0, ddy * 10.0, vec2(levelSize)) * fade;
|
|
144833
|
+
if (levelAlpha > epsilon) {
|
|
144834
|
+
gl_FragColor = vec4(vec3(0.7), levelAlpha);
|
|
144835
|
+
gl_FragDepth = writeDepth(levelAlpha) ? calcDepth(worldPos) : 1.0;
|
|
144836
|
+
return;
|
|
144837
|
+
}
|
|
144838
|
+
|
|
144839
|
+
discard;
|
|
144840
|
+
}
|
|
144836
144841
|
`;
|
|
144837
144842
|
|
|
144838
144843
|
const resolve = (scope, values) => {
|
|
@@ -144903,36 +144908,36 @@ class InfiniteGrid extends Element$1 {
|
|
|
144903
144908
|
}
|
|
144904
144909
|
}
|
|
144905
144910
|
|
|
144906
|
-
const vertexShader$2 = /* glsl*/ `
|
|
144907
|
-
attribute vec2 vertex_position;
|
|
144908
|
-
void main(void) {
|
|
144909
|
-
gl_Position = vec4(vertex_position, 0.0, 1.0);
|
|
144910
|
-
}
|
|
144911
|
-
`;
|
|
144912
|
-
const fragmentShader$2 = /* glsl*/ `
|
|
144913
|
-
uniform sampler2D outlineTexture;
|
|
144914
|
-
uniform float alphaCutoff;
|
|
144915
|
-
uniform vec4 clr;
|
|
144916
|
-
|
|
144917
|
-
void main(void) {
|
|
144918
|
-
ivec2 texel = ivec2(gl_FragCoord.xy);
|
|
144919
|
-
|
|
144920
|
-
// skip solid pixels
|
|
144921
|
-
if (texelFetch(outlineTexture, texel, 0).a > alphaCutoff) {
|
|
144922
|
-
discard;
|
|
144923
|
-
}
|
|
144924
|
-
|
|
144925
|
-
for (int x = -2; x <= 2; x++) {
|
|
144926
|
-
for (int y = -2; y <= 2; y++) {
|
|
144927
|
-
if ((x != 0) && (y != 0) && (texelFetch(outlineTexture, texel + ivec2(x, y), 0).a > alphaCutoff)) {
|
|
144928
|
-
gl_FragColor = clr;
|
|
144929
|
-
return;
|
|
144930
|
-
}
|
|
144931
|
-
}
|
|
144932
|
-
}
|
|
144933
|
-
|
|
144934
|
-
discard;
|
|
144935
|
-
}
|
|
144911
|
+
const vertexShader$2 = /* glsl*/ `
|
|
144912
|
+
attribute vec2 vertex_position;
|
|
144913
|
+
void main(void) {
|
|
144914
|
+
gl_Position = vec4(vertex_position, 0.0, 1.0);
|
|
144915
|
+
}
|
|
144916
|
+
`;
|
|
144917
|
+
const fragmentShader$2 = /* glsl*/ `
|
|
144918
|
+
uniform sampler2D outlineTexture;
|
|
144919
|
+
uniform float alphaCutoff;
|
|
144920
|
+
uniform vec4 clr;
|
|
144921
|
+
|
|
144922
|
+
void main(void) {
|
|
144923
|
+
ivec2 texel = ivec2(gl_FragCoord.xy);
|
|
144924
|
+
|
|
144925
|
+
// skip solid pixels
|
|
144926
|
+
if (texelFetch(outlineTexture, texel, 0).a > alphaCutoff) {
|
|
144927
|
+
discard;
|
|
144928
|
+
}
|
|
144929
|
+
|
|
144930
|
+
for (int x = -2; x <= 2; x++) {
|
|
144931
|
+
for (int y = -2; y <= 2; y++) {
|
|
144932
|
+
if ((x != 0) && (y != 0) && (texelFetch(outlineTexture, texel + ivec2(x, y), 0).a > alphaCutoff)) {
|
|
144933
|
+
gl_FragColor = clr;
|
|
144934
|
+
return;
|
|
144935
|
+
}
|
|
144936
|
+
}
|
|
144937
|
+
}
|
|
144938
|
+
|
|
144939
|
+
discard;
|
|
144940
|
+
}
|
|
144936
144941
|
`;
|
|
144937
144942
|
|
|
144938
144943
|
class Outline extends Element$1 {
|
|
@@ -145250,72 +145255,72 @@ class SceneState {
|
|
|
145250
145255
|
}
|
|
145251
145256
|
}
|
|
145252
145257
|
|
|
145253
|
-
const vertexShader$1 = /* glsl */ `
|
|
145254
|
-
attribute uint vertex_id;
|
|
145255
|
-
|
|
145256
|
-
uniform mat4 matrix_model;
|
|
145257
|
-
uniform mat4 matrix_viewProjection;
|
|
145258
|
-
|
|
145259
|
-
uniform sampler2D splatState;
|
|
145260
|
-
uniform highp usampler2D splatPosition;
|
|
145261
|
-
uniform highp usampler2D splatTransform; // per-splat index into transform palette
|
|
145262
|
-
uniform sampler2D transformPalette; // palette of transform matrices
|
|
145263
|
-
|
|
145264
|
-
uniform uvec2 texParams;
|
|
145265
|
-
|
|
145266
|
-
uniform float splatSize;
|
|
145267
|
-
uniform vec4 selectedClr;
|
|
145268
|
-
uniform vec4 unselectedClr;
|
|
145269
|
-
|
|
145270
|
-
varying vec4 varying_color;
|
|
145271
|
-
|
|
145272
|
-
// calculate the current splat index and uv
|
|
145273
|
-
ivec2 calcSplatUV(uint index, uint width) {
|
|
145274
|
-
return ivec2(int(index % width), int(index / width));
|
|
145275
|
-
}
|
|
145276
|
-
|
|
145277
|
-
void main(void) {
|
|
145278
|
-
ivec2 splatUV = calcSplatUV(vertex_id, texParams.x);
|
|
145279
|
-
uint splatState = uint(texelFetch(splatState, splatUV, 0).r * 255.0);
|
|
145280
|
-
|
|
145281
|
-
if ((splatState & 6u) != 0u) {
|
|
145282
|
-
// deleted or locked (4 or 2)
|
|
145283
|
-
gl_Position = vec4(0.0, 0.0, 2.0, 1.0);
|
|
145284
|
-
gl_PointSize = 0.0;
|
|
145285
|
-
} else {
|
|
145286
|
-
mat4 model = matrix_model;
|
|
145287
|
-
|
|
145288
|
-
// handle per-splat transform
|
|
145289
|
-
uint transformIndex = texelFetch(splatTransform, splatUV, 0).r;
|
|
145290
|
-
if (transformIndex > 0u) {
|
|
145291
|
-
// read transform matrix
|
|
145292
|
-
int u = int(transformIndex % 512u) * 3;
|
|
145293
|
-
int v = int(transformIndex / 512u);
|
|
145294
|
-
|
|
145295
|
-
mat4 t;
|
|
145296
|
-
t[0] = texelFetch(transformPalette, ivec2(u, v), 0);
|
|
145297
|
-
t[1] = texelFetch(transformPalette, ivec2(u + 1, v), 0);
|
|
145298
|
-
t[2] = texelFetch(transformPalette, ivec2(u + 2, v), 0);
|
|
145299
|
-
t[3] = vec4(0.0, 0.0, 0.0, 1.0);
|
|
145300
|
-
|
|
145301
|
-
model = matrix_model * transpose(t);
|
|
145302
|
-
}
|
|
145303
|
-
|
|
145304
|
-
varying_color = (splatState == 1u) ? selectedClr : unselectedClr;
|
|
145305
|
-
|
|
145306
|
-
vec3 center = uintBitsToFloat(texelFetch(splatPosition, splatUV, 0).xyz);
|
|
145307
|
-
|
|
145308
|
-
gl_Position = matrix_viewProjection * model * vec4(center, 1.0);
|
|
145309
|
-
gl_PointSize = splatSize;
|
|
145310
|
-
}
|
|
145311
|
-
}
|
|
145312
|
-
`;
|
|
145313
|
-
const fragmentShader$1 = /* glsl */ `
|
|
145314
|
-
varying vec4 varying_color;
|
|
145315
|
-
|
|
145316
|
-
void main(void) {
|
|
145317
|
-
gl_FragColor = varying_color;
|
|
145318
|
-
}
|
|
145258
|
+
const vertexShader$1 = /* glsl */ `
|
|
145259
|
+
attribute uint vertex_id;
|
|
145260
|
+
|
|
145261
|
+
uniform mat4 matrix_model;
|
|
145262
|
+
uniform mat4 matrix_viewProjection;
|
|
145263
|
+
|
|
145264
|
+
uniform sampler2D splatState;
|
|
145265
|
+
uniform highp usampler2D splatPosition;
|
|
145266
|
+
uniform highp usampler2D splatTransform; // per-splat index into transform palette
|
|
145267
|
+
uniform sampler2D transformPalette; // palette of transform matrices
|
|
145268
|
+
|
|
145269
|
+
uniform uvec2 texParams;
|
|
145270
|
+
|
|
145271
|
+
uniform float splatSize;
|
|
145272
|
+
uniform vec4 selectedClr;
|
|
145273
|
+
uniform vec4 unselectedClr;
|
|
145274
|
+
|
|
145275
|
+
varying vec4 varying_color;
|
|
145276
|
+
|
|
145277
|
+
// calculate the current splat index and uv
|
|
145278
|
+
ivec2 calcSplatUV(uint index, uint width) {
|
|
145279
|
+
return ivec2(int(index % width), int(index / width));
|
|
145280
|
+
}
|
|
145281
|
+
|
|
145282
|
+
void main(void) {
|
|
145283
|
+
ivec2 splatUV = calcSplatUV(vertex_id, texParams.x);
|
|
145284
|
+
uint splatState = uint(texelFetch(splatState, splatUV, 0).r * 255.0);
|
|
145285
|
+
|
|
145286
|
+
if ((splatState & 6u) != 0u) {
|
|
145287
|
+
// deleted or locked (4 or 2)
|
|
145288
|
+
gl_Position = vec4(0.0, 0.0, 2.0, 1.0);
|
|
145289
|
+
gl_PointSize = 0.0;
|
|
145290
|
+
} else {
|
|
145291
|
+
mat4 model = matrix_model;
|
|
145292
|
+
|
|
145293
|
+
// handle per-splat transform
|
|
145294
|
+
uint transformIndex = texelFetch(splatTransform, splatUV, 0).r;
|
|
145295
|
+
if (transformIndex > 0u) {
|
|
145296
|
+
// read transform matrix
|
|
145297
|
+
int u = int(transformIndex % 512u) * 3;
|
|
145298
|
+
int v = int(transformIndex / 512u);
|
|
145299
|
+
|
|
145300
|
+
mat4 t;
|
|
145301
|
+
t[0] = texelFetch(transformPalette, ivec2(u, v), 0);
|
|
145302
|
+
t[1] = texelFetch(transformPalette, ivec2(u + 1, v), 0);
|
|
145303
|
+
t[2] = texelFetch(transformPalette, ivec2(u + 2, v), 0);
|
|
145304
|
+
t[3] = vec4(0.0, 0.0, 0.0, 1.0);
|
|
145305
|
+
|
|
145306
|
+
model = matrix_model * transpose(t);
|
|
145307
|
+
}
|
|
145308
|
+
|
|
145309
|
+
varying_color = (splatState == 1u) ? selectedClr : unselectedClr;
|
|
145310
|
+
|
|
145311
|
+
vec3 center = uintBitsToFloat(texelFetch(splatPosition, splatUV, 0).xyz);
|
|
145312
|
+
|
|
145313
|
+
gl_Position = matrix_viewProjection * model * vec4(center, 1.0);
|
|
145314
|
+
gl_PointSize = splatSize;
|
|
145315
|
+
}
|
|
145316
|
+
}
|
|
145317
|
+
`;
|
|
145318
|
+
const fragmentShader$1 = /* glsl */ `
|
|
145319
|
+
varying vec4 varying_color;
|
|
145320
|
+
|
|
145321
|
+
void main(void) {
|
|
145322
|
+
gl_FragColor = varying_color;
|
|
145323
|
+
}
|
|
145319
145324
|
`;
|
|
145320
145325
|
|
|
145321
145326
|
class SplatOverlay extends Element$1 {
|
|
@@ -145404,19 +145409,19 @@ class SplatOverlay extends Element$1 {
|
|
|
145404
145409
|
}
|
|
145405
145410
|
}
|
|
145406
145411
|
|
|
145407
|
-
const vertexShader = /* glsl*/ `
|
|
145408
|
-
attribute vec2 vertex_position;
|
|
145409
|
-
void main(void) {
|
|
145410
|
-
gl_Position = vec4(vertex_position, 0.0, 1.0);
|
|
145411
|
-
}
|
|
145412
|
+
const vertexShader = /* glsl*/ `
|
|
145413
|
+
attribute vec2 vertex_position;
|
|
145414
|
+
void main(void) {
|
|
145415
|
+
gl_Position = vec4(vertex_position, 0.0, 1.0);
|
|
145416
|
+
}
|
|
145412
145417
|
`;
|
|
145413
|
-
const fragmentShader = /* glsl*/ `
|
|
145414
|
-
uniform sampler2D blitTexture;
|
|
145415
|
-
void main(void) {
|
|
145416
|
-
ivec2 texel = ivec2(gl_FragCoord.xy);
|
|
145417
|
-
|
|
145418
|
-
gl_FragColor = texelFetch(blitTexture, texel, 0);
|
|
145419
|
-
}
|
|
145418
|
+
const fragmentShader = /* glsl*/ `
|
|
145419
|
+
uniform sampler2D blitTexture;
|
|
145420
|
+
void main(void) {
|
|
145421
|
+
ivec2 texel = ivec2(gl_FragCoord.xy);
|
|
145422
|
+
|
|
145423
|
+
gl_FragColor = texelFetch(blitTexture, texel, 0);
|
|
145424
|
+
}
|
|
145420
145425
|
`;
|
|
145421
145426
|
|
|
145422
145427
|
class Underlay extends Element$1 {
|
|
@@ -147693,6 +147698,7 @@ class SplatViewerCore {
|
|
|
147693
147698
|
};
|
|
147694
147699
|
this.enableStats = false;
|
|
147695
147700
|
this.autoFocus = true;
|
|
147701
|
+
this.previewMode = false;
|
|
147696
147702
|
this.isLoading = false;
|
|
147697
147703
|
this.hasModel = false;
|
|
147698
147704
|
this.error = null;
|
|
@@ -147745,6 +147751,11 @@ class SplatViewerCore {
|
|
|
147745
147751
|
this.canvas = options.canvas || null;
|
|
147746
147752
|
this.enableStats = options.enableStats || false;
|
|
147747
147753
|
this.autoFocus = options.autoFocus !== false;
|
|
147754
|
+
this.previewMode = options.previewMode || false;
|
|
147755
|
+
// In preview mode, always enable auto-focus
|
|
147756
|
+
if (this.previewMode) {
|
|
147757
|
+
this.autoFocus = true;
|
|
147758
|
+
}
|
|
147748
147759
|
this._navigationCubeConfig = options.navigationCube || null;
|
|
147749
147760
|
if (options.onStatsUpdate !== undefined) {
|
|
147750
147761
|
this._onStatsUpdate = options.onStatsUpdate;
|
|
@@ -147775,11 +147786,20 @@ class SplatViewerCore {
|
|
|
147775
147786
|
const emitEvent = (type, detail) => {
|
|
147776
147787
|
this.emit({ type, detail });
|
|
147777
147788
|
};
|
|
147778
|
-
this._supersplat = new SupersplatAdapter(this.canvas,
|
|
147789
|
+
this._supersplat = new SupersplatAdapter(this.canvas,
|
|
147790
|
+
// Disable navigation cube in preview mode
|
|
147791
|
+
this.previewMode ? null : this._navigationCubeConfig, emitEvent);
|
|
147779
147792
|
this._supersplatReady = this._supersplat.init();
|
|
147780
147793
|
this._supersplatReady
|
|
147781
147794
|
?.then(() => {
|
|
147782
|
-
|
|
147795
|
+
// Disable camera controls in preview mode
|
|
147796
|
+
if (this.previewMode && this._supersplat) {
|
|
147797
|
+
this._supersplat.setCameraControlsEnabled?.(false);
|
|
147798
|
+
}
|
|
147799
|
+
// Only set up fly camera if not in preview mode
|
|
147800
|
+
if (!this.previewMode) {
|
|
147801
|
+
this._setupFlyCameraForSupersplat();
|
|
147802
|
+
}
|
|
147783
147803
|
})
|
|
147784
147804
|
.catch(error => {
|
|
147785
147805
|
console.error('SplatViewerCore.init: Failed to set up fly camera for supersplat path', error);
|
|
@@ -147818,7 +147838,9 @@ class SplatViewerCore {
|
|
|
147818
147838
|
// SuperSplat's PCApp omits ScriptComponentSystem, so `addComponent('script')`
|
|
147819
147839
|
// will not produce `camera.script.create()`. We keep the attempt (in case
|
|
147820
147840
|
// the underlying app changes), but also support a controller-based fallback.
|
|
147821
|
-
if (cameraAny &&
|
|
147841
|
+
if (cameraAny &&
|
|
147842
|
+
!cameraAny.script &&
|
|
147843
|
+
typeof cameraAny.addComponent === 'function') {
|
|
147822
147844
|
try {
|
|
147823
147845
|
cameraAny.addComponent('script');
|
|
147824
147846
|
}
|
|
@@ -147844,7 +147866,9 @@ class SplatViewerCore {
|
|
|
147844
147866
|
// Prefer script-based fly when available; fallback to controller otherwise.
|
|
147845
147867
|
const canCreateScript = typeof cameraAny?.script?.create === 'function';
|
|
147846
147868
|
if (canCreateScript) {
|
|
147847
|
-
const created = cameraAny.script.create('flyCamera', {
|
|
147869
|
+
const created = cameraAny.script.create('flyCamera', {
|
|
147870
|
+
attributes: flyAttributes,
|
|
147871
|
+
});
|
|
147848
147872
|
this._fly = created;
|
|
147849
147873
|
if (this._fly) {
|
|
147850
147874
|
;
|
|
@@ -149708,6 +149732,11 @@ class SplatViewerCore {
|
|
|
149708
149732
|
// Camera Mode / Fly Camera API
|
|
149709
149733
|
// ==========================================
|
|
149710
149734
|
setCameraMode(mode) {
|
|
149735
|
+
// Prevent camera mode changes in preview mode
|
|
149736
|
+
if (this.previewMode) {
|
|
149737
|
+
console.warn('SplatViewerCore.setCameraMode: Camera controls are disabled in preview mode');
|
|
149738
|
+
return;
|
|
149739
|
+
}
|
|
149711
149740
|
// supersplat-core path: manage mode switching explicitly (camera entity is updated by supersplat-core each frame)
|
|
149712
149741
|
if (this._supersplat) {
|
|
149713
149742
|
const prev = this._cameraMode;
|
|
@@ -149737,7 +149766,9 @@ class SplatViewerCore {
|
|
|
149737
149766
|
try {
|
|
149738
149767
|
const pos = this.entities.camera?.getPosition?.();
|
|
149739
149768
|
if (pos) {
|
|
149740
|
-
const posVec = pos.clone
|
|
149769
|
+
const posVec = pos.clone
|
|
149770
|
+
? pos.clone()
|
|
149771
|
+
: new Vec3(pos.x || 0, pos.y || 0, pos.z || 0);
|
|
149741
149772
|
this.entities.camera?.setPosition?.(posVec);
|
|
149742
149773
|
}
|
|
149743
149774
|
const euler = this.entities.camera?.getEulerAngles?.();
|
|
@@ -149960,8 +149991,8 @@ class SplatViewerCore {
|
|
|
149960
149991
|
panSensitivity: 1.0,
|
|
149961
149992
|
zoomSensitivity: 0.1,
|
|
149962
149993
|
};
|
|
149963
|
-
// Add navigation cube configuration if available
|
|
149964
|
-
if (this._navigationCubeConfig) {
|
|
149994
|
+
// Add navigation cube configuration if available (but not in preview mode)
|
|
149995
|
+
if (this._navigationCubeConfig && !this.previewMode) {
|
|
149965
149996
|
orbitAttributes.enableNavigationCube =
|
|
149966
149997
|
this._navigationCubeConfig.enabled || false;
|
|
149967
149998
|
this.entities.camera._navigationCubeConfig =
|
|
@@ -149976,48 +150007,57 @@ class SplatViewerCore {
|
|
|
149976
150007
|
detail: { type: interactionType },
|
|
149977
150008
|
});
|
|
149978
150009
|
};
|
|
150010
|
+
// Disable camera controls in preview mode
|
|
150011
|
+
if (this.previewMode && this._orbit) {
|
|
150012
|
+
const orbitAny = this._orbit;
|
|
150013
|
+
if (typeof orbitAny.setEnabled === 'function') {
|
|
150014
|
+
orbitAny.setEnabled(false);
|
|
150015
|
+
}
|
|
150016
|
+
}
|
|
149979
150017
|
this.entities.camera.setPosition(0, 0, 10);
|
|
149980
150018
|
this.entities.camera.lookAt(Vec3.ZERO);
|
|
149981
150019
|
// ==============================
|
|
149982
|
-
// Setup fly camera (disabled by default)
|
|
150020
|
+
// Setup fly camera (disabled by default, skipped in preview mode)
|
|
149983
150021
|
// ==============================
|
|
149984
|
-
|
|
149985
|
-
|
|
149986
|
-
|
|
149987
|
-
|
|
149988
|
-
|
|
149989
|
-
|
|
149990
|
-
|
|
149991
|
-
|
|
149992
|
-
|
|
149993
|
-
|
|
149994
|
-
|
|
149995
|
-
|
|
149996
|
-
|
|
149997
|
-
|
|
149998
|
-
|
|
149999
|
-
|
|
150000
|
-
this._fly = this.entities.camera.script.create('flyCamera', {
|
|
150001
|
-
attributes: flyAttributes,
|
|
150002
|
-
});
|
|
150003
|
-
// Wire event emission to core
|
|
150004
|
-
if (this._fly) {
|
|
150005
|
-
;
|
|
150006
|
-
this._fly.emitFlyEvent = (type, detail) => {
|
|
150007
|
-
this.emit({ type: type, detail });
|
|
150022
|
+
if (!this.previewMode) {
|
|
150023
|
+
try {
|
|
150024
|
+
registerFlyCameraScript();
|
|
150025
|
+
// Ensure script component exists (created above)
|
|
150026
|
+
const flyAttributes = {
|
|
150027
|
+
moveSpeed: DEFAULT_FLY_CAMERA_CONFIG.moveSpeed,
|
|
150028
|
+
fastSpeedMultiplier: DEFAULT_FLY_CAMERA_CONFIG.fastSpeedMultiplier,
|
|
150029
|
+
slowSpeedMultiplier: DEFAULT_FLY_CAMERA_CONFIG.slowSpeedMultiplier,
|
|
150030
|
+
lookSensitivity: DEFAULT_FLY_CAMERA_CONFIG.lookSensitivity,
|
|
150031
|
+
invertY: DEFAULT_FLY_CAMERA_CONFIG.invertY,
|
|
150032
|
+
keyBindings: DEFAULT_FLY_CAMERA_CONFIG.keyBindings,
|
|
150033
|
+
smoothing: DEFAULT_FLY_CAMERA_CONFIG.smoothing,
|
|
150034
|
+
friction: DEFAULT_FLY_CAMERA_CONFIG.friction,
|
|
150035
|
+
enableCollision: DEFAULT_FLY_CAMERA_CONFIG.enableCollision,
|
|
150036
|
+
minHeight: DEFAULT_FLY_CAMERA_CONFIG.minHeight,
|
|
150037
|
+
maxHeight: DEFAULT_FLY_CAMERA_CONFIG.maxHeight,
|
|
150008
150038
|
};
|
|
150039
|
+
this._fly = this.entities.camera.script.create('flyCamera', {
|
|
150040
|
+
attributes: flyAttributes,
|
|
150041
|
+
});
|
|
150042
|
+
// Wire event emission to core
|
|
150043
|
+
if (this._fly) {
|
|
150044
|
+
;
|
|
150045
|
+
this._fly.emitFlyEvent = (type, detail) => {
|
|
150046
|
+
this.emit({ type: type, detail });
|
|
150047
|
+
};
|
|
150048
|
+
}
|
|
150049
|
+
// Deactivate fly by default; orbit is the initial mode
|
|
150050
|
+
if (this._fly?.deactivate) {
|
|
150051
|
+
this._fly.deactivate();
|
|
150052
|
+
}
|
|
150053
|
+
// Initialize camera mode manager
|
|
150054
|
+
this._cameraModeManager = new CameraModeManager(this.app, this.entities.camera, this._orbit, this._fly, (eventType, detail) => {
|
|
150055
|
+
this.emit({ type: eventType, detail });
|
|
150056
|
+
}, 'orbit');
|
|
150009
150057
|
}
|
|
150010
|
-
|
|
150011
|
-
|
|
150012
|
-
this._fly.deactivate();
|
|
150058
|
+
catch (e) {
|
|
150059
|
+
console.warn('Failed to set up fly camera', e);
|
|
150013
150060
|
}
|
|
150014
|
-
// Initialize camera mode manager
|
|
150015
|
-
this._cameraModeManager = new CameraModeManager(this.app, this.entities.camera, this._orbit, this._fly, (eventType, detail) => {
|
|
150016
|
-
this.emit({ type: eventType, detail });
|
|
150017
|
-
}, 'orbit');
|
|
150018
|
-
}
|
|
150019
|
-
catch (e) {
|
|
150020
|
-
console.warn('Failed to set up fly camera', e);
|
|
150021
150061
|
}
|
|
150022
150062
|
}
|
|
150023
150063
|
_setupStats() {
|
|
@@ -150262,6 +150302,7 @@ class SplatViewerElement extends HTMLElement {
|
|
|
150262
150302
|
'enable-stats',
|
|
150263
150303
|
'auto-focus',
|
|
150264
150304
|
'max-splats',
|
|
150305
|
+
'preview-mode',
|
|
150265
150306
|
'camera-position',
|
|
150266
150307
|
'camera-target',
|
|
150267
150308
|
'orbit-sensitivity',
|
|
@@ -150292,6 +150333,9 @@ class SplatViewerElement extends HTMLElement {
|
|
|
150292
150333
|
get autoFocus() {
|
|
150293
150334
|
return this.hasAttribute('auto-focus');
|
|
150294
150335
|
}
|
|
150336
|
+
get previewMode() {
|
|
150337
|
+
return this.hasAttribute('preview-mode');
|
|
150338
|
+
}
|
|
150295
150339
|
get maxSplats() {
|
|
150296
150340
|
return this.getAttribute('max-splats');
|
|
150297
150341
|
}
|
|
@@ -150369,6 +150413,14 @@ class SplatViewerElement extends HTMLElement {
|
|
|
150369
150413
|
this.removeAttribute('auto-focus');
|
|
150370
150414
|
}
|
|
150371
150415
|
}
|
|
150416
|
+
set previewMode(value) {
|
|
150417
|
+
if (value) {
|
|
150418
|
+
this.setAttribute('preview-mode', '');
|
|
150419
|
+
}
|
|
150420
|
+
else {
|
|
150421
|
+
this.removeAttribute('preview-mode');
|
|
150422
|
+
}
|
|
150423
|
+
}
|
|
150372
150424
|
set maxSplats(value) {
|
|
150373
150425
|
if (value === null) {
|
|
150374
150426
|
this.removeAttribute('max-splats');
|
|
@@ -150550,6 +150602,7 @@ class SplatViewerElement extends HTMLElement {
|
|
|
150550
150602
|
return value.length > 0;
|
|
150551
150603
|
case 'enable-stats':
|
|
150552
150604
|
case 'auto-focus':
|
|
150605
|
+
case 'preview-mode':
|
|
150553
150606
|
case 'enable-navigation-cube':
|
|
150554
150607
|
// Boolean attributes - any value is valid
|
|
150555
150608
|
return true;
|
|
@@ -151496,7 +151549,7 @@ class SplatViewerElement extends HTMLElement {
|
|
|
151496
151549
|
if (!this._core) {
|
|
151497
151550
|
throw new Error('SplatViewerElement: Core not initialized. Call connectedCallback first.');
|
|
151498
151551
|
}
|
|
151499
|
-
return this._core.selectSplatsInSphere(center, radius, modelId, addToSelection);
|
|
151552
|
+
return this._core.selectSplatsInSphere(new Vec3(center.x, center.y, center.z), radius, modelId, addToSelection);
|
|
151500
151553
|
}
|
|
151501
151554
|
clearSplatSelection() {
|
|
151502
151555
|
if (!this._core) {
|