@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
|
@@ -139526,6 +139526,7 @@ fn fragmentMain(input: FragmentInput) -> FragmentOutput {
|
|
|
139526
139526
|
enableStats: false,
|
|
139527
139527
|
autoFocus: true,
|
|
139528
139528
|
maxSplats: 2000000,
|
|
139529
|
+
previewMode: false,
|
|
139529
139530
|
camera: {
|
|
139530
139531
|
position: { x: 0, y: 0, z: 10 },
|
|
139531
139532
|
target: { x: 0, y: 0, z: 0 },
|
|
@@ -139615,6 +139616,10 @@ fn fragmentMain(input: FragmentInput) -> FragmentOutput {
|
|
|
139615
139616
|
if (enableStats !== null) {
|
|
139616
139617
|
config.enableStats = parseBoolean(enableStats);
|
|
139617
139618
|
}
|
|
139619
|
+
const previewMode = element.getAttribute('preview-mode');
|
|
139620
|
+
if (previewMode !== null) {
|
|
139621
|
+
config.previewMode = parseBoolean(previewMode);
|
|
139622
|
+
}
|
|
139618
139623
|
// Parse number attributes
|
|
139619
139624
|
const maxSplats = element.getAttribute('max-splats');
|
|
139620
139625
|
if (maxSplats !== null) {
|
|
@@ -143168,222 +143173,222 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
143168
143173
|
}
|
|
143169
143174
|
}
|
|
143170
143175
|
|
|
143171
|
-
const vertexShader$6 = /* glsl */ `
|
|
143172
|
-
attribute vec2 vertex_position;
|
|
143173
|
-
void main(void) {
|
|
143174
|
-
gl_Position = vec4(vertex_position, 0.0, 1.0);
|
|
143175
|
-
}
|
|
143176
|
-
`;
|
|
143177
|
-
const fragmentShader$6 = /* glsl */ `
|
|
143178
|
-
uniform highp usampler2D transformA; // splat center x, y, z
|
|
143179
|
-
uniform highp usampler2D splatTransform; // transform palette index
|
|
143180
|
-
uniform sampler2D transformPalette; // palette of transforms
|
|
143181
|
-
uniform sampler2D splatState; // per-splat state
|
|
143182
|
-
uniform highp ivec3 splat_params; // texture width, texture height, num splats
|
|
143183
|
-
uniform highp uint mode; // 0: selected, 1: visible
|
|
143184
|
-
|
|
143185
|
-
// calculate min and max for a single column of splats
|
|
143186
|
-
void main(void) {
|
|
143187
|
-
|
|
143188
|
-
vec3 boundMin = vec3(1e6);
|
|
143189
|
-
vec3 boundMax = vec3(-1e6);
|
|
143190
|
-
|
|
143191
|
-
for (int id = 0; id < splat_params.y; id++) {
|
|
143192
|
-
// calculate splatUV
|
|
143193
|
-
ivec2 splatUV = ivec2(gl_FragCoord.x, id);
|
|
143194
|
-
|
|
143195
|
-
// skip out-of-range splats
|
|
143196
|
-
if ((splatUV.x + splatUV.y * splat_params.x) >= splat_params.z) {
|
|
143197
|
-
continue;
|
|
143198
|
-
}
|
|
143199
|
-
|
|
143200
|
-
// read splat state
|
|
143201
|
-
uint state = uint(texelFetch(splatState, splatUV, 0).r * 255.0);
|
|
143202
|
-
|
|
143203
|
-
// skip deleted or locked splats
|
|
143204
|
-
if (((mode == 0u) && (state != 1u)) || ((mode == 1u) && ((state & 4u) != 0u))) {
|
|
143205
|
-
continue;
|
|
143206
|
-
}
|
|
143207
|
-
|
|
143208
|
-
// read splat center
|
|
143209
|
-
vec3 center = uintBitsToFloat(texelFetch(transformA, splatUV, 0).xyz);
|
|
143210
|
-
|
|
143211
|
-
// apply optional per-splat transform
|
|
143212
|
-
uint transformIndex = texelFetch(splatTransform, splatUV, 0).r;
|
|
143213
|
-
if (transformIndex > 0u) {
|
|
143214
|
-
// read transform matrix
|
|
143215
|
-
int u = int(transformIndex % 512u) * 3;
|
|
143216
|
-
int v = int(transformIndex / 512u);
|
|
143217
|
-
|
|
143218
|
-
mat3x4 t;
|
|
143219
|
-
t[0] = texelFetch(transformPalette, ivec2(u, v), 0);
|
|
143220
|
-
t[1] = texelFetch(transformPalette, ivec2(u + 1, v), 0);
|
|
143221
|
-
t[2] = texelFetch(transformPalette, ivec2(u + 2, v), 0);
|
|
143222
|
-
|
|
143223
|
-
center = vec4(center, 1.0) * t;
|
|
143224
|
-
}
|
|
143225
|
-
|
|
143226
|
-
boundMin = min(boundMin, mix(center, boundMin, isinf(center)));
|
|
143227
|
-
boundMax = max(boundMax, mix(center, boundMax, isinf(center)));
|
|
143228
|
-
}
|
|
143229
|
-
|
|
143230
|
-
pcFragColor0 = vec4(boundMin, 0.0);
|
|
143231
|
-
pcFragColor1 = vec4(boundMax, 0.0);
|
|
143232
|
-
}
|
|
143233
|
-
`;
|
|
143234
|
-
|
|
143235
|
-
const vertexShader$5 = /* glsl */ `
|
|
143236
|
-
attribute vec2 vertex_position;
|
|
143237
|
-
void main(void) {
|
|
143238
|
-
gl_Position = vec4(vertex_position, 0.0, 1.0);
|
|
143239
|
-
}
|
|
143240
|
-
`;
|
|
143241
|
-
const fragmentShader$5 = /* glsl */ `
|
|
143242
|
-
uniform highp usampler2D transformA; // splat center x, y, z
|
|
143243
|
-
uniform highp usampler2D splatTransform; // transform palette index
|
|
143244
|
-
uniform sampler2D transformPalette; // palette of transforms
|
|
143245
|
-
uniform uvec2 splat_params; // splat texture width, num splats
|
|
143246
|
-
|
|
143247
|
-
uniform mat4 matrix_model;
|
|
143248
|
-
uniform mat4 matrix_viewProjection;
|
|
143249
|
-
|
|
143250
|
-
uniform uvec2 output_params; // output width, height
|
|
143251
|
-
|
|
143252
|
-
// 0: mask, 1: rect, 2: sphere
|
|
143253
|
-
uniform int mode;
|
|
143254
|
-
|
|
143255
|
-
// mask params
|
|
143256
|
-
uniform sampler2D mask; // mask in alpha channel
|
|
143257
|
-
uniform vec2 mask_params; // mask width, height
|
|
143258
|
-
|
|
143259
|
-
// rect params
|
|
143260
|
-
uniform vec4 rect_params; // rect x, y, width, height
|
|
143261
|
-
|
|
143262
|
-
// sphere params
|
|
143263
|
-
uniform vec4 sphere_params; // sphere x, y, z, radius
|
|
143264
|
-
|
|
143265
|
-
// box params
|
|
143266
|
-
uniform vec4 box_params; // box x, y, z
|
|
143267
|
-
uniform vec4 aabb_params; // len x, y, z
|
|
143268
|
-
|
|
143269
|
-
void main(void) {
|
|
143270
|
-
// calculate output id
|
|
143271
|
-
uvec2 outputUV = uvec2(gl_FragCoord);
|
|
143272
|
-
uint outputId = (outputUV.x + outputUV.y * output_params.x) * 4u;
|
|
143273
|
-
|
|
143274
|
-
vec4 clr = vec4(0.0);
|
|
143275
|
-
|
|
143276
|
-
for (uint i = 0u; i < 4u; i++) {
|
|
143277
|
-
uint id = outputId + i;
|
|
143278
|
-
|
|
143279
|
-
if (id >= splat_params.y) {
|
|
143280
|
-
continue;
|
|
143281
|
-
}
|
|
143282
|
-
|
|
143283
|
-
// calculate splatUV
|
|
143284
|
-
ivec2 splatUV = ivec2(
|
|
143285
|
-
int(id % splat_params.x),
|
|
143286
|
-
int(id / splat_params.x)
|
|
143287
|
-
);
|
|
143288
|
-
|
|
143289
|
-
// read splat center
|
|
143290
|
-
vec3 center = uintBitsToFloat(texelFetch(transformA, splatUV, 0).xyz);
|
|
143291
|
-
|
|
143292
|
-
// apply optional per-splat transform
|
|
143293
|
-
uint transformIndex = texelFetch(splatTransform, splatUV, 0).r;
|
|
143294
|
-
if (transformIndex > 0u) {
|
|
143295
|
-
// read transform matrix
|
|
143296
|
-
int u = int(transformIndex % 512u) * 3;
|
|
143297
|
-
int v = int(transformIndex / 512u);
|
|
143298
|
-
|
|
143299
|
-
mat3x4 t;
|
|
143300
|
-
t[0] = texelFetch(transformPalette, ivec2(u, v), 0);
|
|
143301
|
-
t[1] = texelFetch(transformPalette, ivec2(u + 1, v), 0);
|
|
143302
|
-
t[2] = texelFetch(transformPalette, ivec2(u + 2, v), 0);
|
|
143303
|
-
|
|
143304
|
-
center = vec4(center, 1.0) * t;
|
|
143305
|
-
}
|
|
143306
|
-
|
|
143307
|
-
// transform to clip space and discard if outside
|
|
143308
|
-
vec3 world = (matrix_model * vec4(center, 1.0)).xyz;
|
|
143309
|
-
vec4 clip = matrix_viewProjection * vec4(world, 1.0);
|
|
143310
|
-
vec3 ndc = clip.xyz / clip.w;
|
|
143311
|
-
|
|
143312
|
-
// skip offscreen fragments
|
|
143313
|
-
if (!any(greaterThan(abs(ndc), vec3(1.0)))) {
|
|
143314
|
-
if (mode == 0) {
|
|
143315
|
-
// select by mask
|
|
143316
|
-
ivec2 maskUV = ivec2((ndc.xy * vec2(0.5, -0.5) + 0.5) * mask_params);
|
|
143317
|
-
clr[i] = texelFetch(mask, maskUV, 0).a < 1.0 ? 0.0 : 1.0;
|
|
143318
|
-
} else if (mode == 1) {
|
|
143319
|
-
// select by rect
|
|
143320
|
-
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;
|
|
143321
|
-
} else if (mode == 2) {
|
|
143322
|
-
// select by sphere
|
|
143323
|
-
clr[i] = length(world - sphere_params.xyz) < sphere_params.w ? 1.0 : 0.0;
|
|
143324
|
-
} else if (mode == 3) {
|
|
143325
|
-
// select by box
|
|
143326
|
-
vec3 relativePosition = world - box_params.xyz;
|
|
143327
|
-
bool isInsideCube = true;
|
|
143328
|
-
if (relativePosition.x < -aabb_params.x || relativePosition.x > aabb_params.x) {
|
|
143329
|
-
isInsideCube = false;
|
|
143330
|
-
}
|
|
143331
|
-
if (relativePosition.y < -aabb_params.y || relativePosition.y > aabb_params.y) {
|
|
143332
|
-
isInsideCube = false;
|
|
143333
|
-
}
|
|
143334
|
-
if (relativePosition.z < -aabb_params.z || relativePosition.z > aabb_params.z) {
|
|
143335
|
-
isInsideCube = false;
|
|
143336
|
-
}
|
|
143337
|
-
clr[i] = isInsideCube ? 1.0 : 0.0;
|
|
143338
|
-
}
|
|
143339
|
-
}
|
|
143340
|
-
}
|
|
143341
|
-
|
|
143342
|
-
gl_FragColor = clr;
|
|
143343
|
-
}
|
|
143344
|
-
`;
|
|
143345
|
-
|
|
143346
|
-
const vertexShader$4 = /* glsl */ `
|
|
143347
|
-
attribute vec2 vertex_position;
|
|
143348
|
-
void main(void) {
|
|
143349
|
-
gl_Position = vec4(vertex_position, 0.0, 1.0);
|
|
143350
|
-
}
|
|
143351
|
-
`;
|
|
143352
|
-
const fragmentShader$4 = /* glsl */ `
|
|
143353
|
-
uniform highp usampler2D transformA; // splat center x, y, z
|
|
143354
|
-
uniform highp usampler2D splatTransform; // transform palette index
|
|
143355
|
-
uniform sampler2D transformPalette; // palette of transforms
|
|
143356
|
-
uniform ivec2 splat_params; // splat texture width, num splats
|
|
143357
|
-
|
|
143358
|
-
void main(void) {
|
|
143359
|
-
// calculate output id
|
|
143360
|
-
ivec2 splatUV = ivec2(gl_FragCoord);
|
|
143361
|
-
|
|
143362
|
-
// skip if splat index is out of bounds
|
|
143363
|
-
if (splatUV.x + splatUV.y * splat_params.x >= splat_params.y) {
|
|
143364
|
-
discard;
|
|
143365
|
-
}
|
|
143366
|
-
|
|
143367
|
-
// read splat center
|
|
143368
|
-
vec3 center = uintBitsToFloat(texelFetch(transformA, splatUV, 0).xyz);
|
|
143369
|
-
|
|
143370
|
-
// apply optional per-splat transform
|
|
143371
|
-
uint transformIndex = texelFetch(splatTransform, splatUV, 0).r;
|
|
143372
|
-
if (transformIndex > 0u) {
|
|
143373
|
-
// read transform matrix
|
|
143374
|
-
int u = int(transformIndex % 512u) * 3;
|
|
143375
|
-
int v = int(transformIndex / 512u);
|
|
143376
|
-
|
|
143377
|
-
mat3x4 t;
|
|
143378
|
-
t[0] = texelFetch(transformPalette, ivec2(u, v), 0);
|
|
143379
|
-
t[1] = texelFetch(transformPalette, ivec2(u + 1, v), 0);
|
|
143380
|
-
t[2] = texelFetch(transformPalette, ivec2(u + 2, v), 0);
|
|
143381
|
-
|
|
143382
|
-
center = vec4(center, 1.0) * t;
|
|
143383
|
-
}
|
|
143384
|
-
|
|
143385
|
-
gl_FragColor = vec4(center, 0.0);
|
|
143386
|
-
}
|
|
143176
|
+
const vertexShader$6 = /* glsl */ `
|
|
143177
|
+
attribute vec2 vertex_position;
|
|
143178
|
+
void main(void) {
|
|
143179
|
+
gl_Position = vec4(vertex_position, 0.0, 1.0);
|
|
143180
|
+
}
|
|
143181
|
+
`;
|
|
143182
|
+
const fragmentShader$6 = /* glsl */ `
|
|
143183
|
+
uniform highp usampler2D transformA; // splat center x, y, z
|
|
143184
|
+
uniform highp usampler2D splatTransform; // transform palette index
|
|
143185
|
+
uniform sampler2D transformPalette; // palette of transforms
|
|
143186
|
+
uniform sampler2D splatState; // per-splat state
|
|
143187
|
+
uniform highp ivec3 splat_params; // texture width, texture height, num splats
|
|
143188
|
+
uniform highp uint mode; // 0: selected, 1: visible
|
|
143189
|
+
|
|
143190
|
+
// calculate min and max for a single column of splats
|
|
143191
|
+
void main(void) {
|
|
143192
|
+
|
|
143193
|
+
vec3 boundMin = vec3(1e6);
|
|
143194
|
+
vec3 boundMax = vec3(-1e6);
|
|
143195
|
+
|
|
143196
|
+
for (int id = 0; id < splat_params.y; id++) {
|
|
143197
|
+
// calculate splatUV
|
|
143198
|
+
ivec2 splatUV = ivec2(gl_FragCoord.x, id);
|
|
143199
|
+
|
|
143200
|
+
// skip out-of-range splats
|
|
143201
|
+
if ((splatUV.x + splatUV.y * splat_params.x) >= splat_params.z) {
|
|
143202
|
+
continue;
|
|
143203
|
+
}
|
|
143204
|
+
|
|
143205
|
+
// read splat state
|
|
143206
|
+
uint state = uint(texelFetch(splatState, splatUV, 0).r * 255.0);
|
|
143207
|
+
|
|
143208
|
+
// skip deleted or locked splats
|
|
143209
|
+
if (((mode == 0u) && (state != 1u)) || ((mode == 1u) && ((state & 4u) != 0u))) {
|
|
143210
|
+
continue;
|
|
143211
|
+
}
|
|
143212
|
+
|
|
143213
|
+
// read splat center
|
|
143214
|
+
vec3 center = uintBitsToFloat(texelFetch(transformA, splatUV, 0).xyz);
|
|
143215
|
+
|
|
143216
|
+
// apply optional per-splat transform
|
|
143217
|
+
uint transformIndex = texelFetch(splatTransform, splatUV, 0).r;
|
|
143218
|
+
if (transformIndex > 0u) {
|
|
143219
|
+
// read transform matrix
|
|
143220
|
+
int u = int(transformIndex % 512u) * 3;
|
|
143221
|
+
int v = int(transformIndex / 512u);
|
|
143222
|
+
|
|
143223
|
+
mat3x4 t;
|
|
143224
|
+
t[0] = texelFetch(transformPalette, ivec2(u, v), 0);
|
|
143225
|
+
t[1] = texelFetch(transformPalette, ivec2(u + 1, v), 0);
|
|
143226
|
+
t[2] = texelFetch(transformPalette, ivec2(u + 2, v), 0);
|
|
143227
|
+
|
|
143228
|
+
center = vec4(center, 1.0) * t;
|
|
143229
|
+
}
|
|
143230
|
+
|
|
143231
|
+
boundMin = min(boundMin, mix(center, boundMin, isinf(center)));
|
|
143232
|
+
boundMax = max(boundMax, mix(center, boundMax, isinf(center)));
|
|
143233
|
+
}
|
|
143234
|
+
|
|
143235
|
+
pcFragColor0 = vec4(boundMin, 0.0);
|
|
143236
|
+
pcFragColor1 = vec4(boundMax, 0.0);
|
|
143237
|
+
}
|
|
143238
|
+
`;
|
|
143239
|
+
|
|
143240
|
+
const vertexShader$5 = /* glsl */ `
|
|
143241
|
+
attribute vec2 vertex_position;
|
|
143242
|
+
void main(void) {
|
|
143243
|
+
gl_Position = vec4(vertex_position, 0.0, 1.0);
|
|
143244
|
+
}
|
|
143245
|
+
`;
|
|
143246
|
+
const fragmentShader$5 = /* glsl */ `
|
|
143247
|
+
uniform highp usampler2D transformA; // splat center x, y, z
|
|
143248
|
+
uniform highp usampler2D splatTransform; // transform palette index
|
|
143249
|
+
uniform sampler2D transformPalette; // palette of transforms
|
|
143250
|
+
uniform uvec2 splat_params; // splat texture width, num splats
|
|
143251
|
+
|
|
143252
|
+
uniform mat4 matrix_model;
|
|
143253
|
+
uniform mat4 matrix_viewProjection;
|
|
143254
|
+
|
|
143255
|
+
uniform uvec2 output_params; // output width, height
|
|
143256
|
+
|
|
143257
|
+
// 0: mask, 1: rect, 2: sphere
|
|
143258
|
+
uniform int mode;
|
|
143259
|
+
|
|
143260
|
+
// mask params
|
|
143261
|
+
uniform sampler2D mask; // mask in alpha channel
|
|
143262
|
+
uniform vec2 mask_params; // mask width, height
|
|
143263
|
+
|
|
143264
|
+
// rect params
|
|
143265
|
+
uniform vec4 rect_params; // rect x, y, width, height
|
|
143266
|
+
|
|
143267
|
+
// sphere params
|
|
143268
|
+
uniform vec4 sphere_params; // sphere x, y, z, radius
|
|
143269
|
+
|
|
143270
|
+
// box params
|
|
143271
|
+
uniform vec4 box_params; // box x, y, z
|
|
143272
|
+
uniform vec4 aabb_params; // len x, y, z
|
|
143273
|
+
|
|
143274
|
+
void main(void) {
|
|
143275
|
+
// calculate output id
|
|
143276
|
+
uvec2 outputUV = uvec2(gl_FragCoord);
|
|
143277
|
+
uint outputId = (outputUV.x + outputUV.y * output_params.x) * 4u;
|
|
143278
|
+
|
|
143279
|
+
vec4 clr = vec4(0.0);
|
|
143280
|
+
|
|
143281
|
+
for (uint i = 0u; i < 4u; i++) {
|
|
143282
|
+
uint id = outputId + i;
|
|
143283
|
+
|
|
143284
|
+
if (id >= splat_params.y) {
|
|
143285
|
+
continue;
|
|
143286
|
+
}
|
|
143287
|
+
|
|
143288
|
+
// calculate splatUV
|
|
143289
|
+
ivec2 splatUV = ivec2(
|
|
143290
|
+
int(id % splat_params.x),
|
|
143291
|
+
int(id / splat_params.x)
|
|
143292
|
+
);
|
|
143293
|
+
|
|
143294
|
+
// read splat center
|
|
143295
|
+
vec3 center = uintBitsToFloat(texelFetch(transformA, splatUV, 0).xyz);
|
|
143296
|
+
|
|
143297
|
+
// apply optional per-splat transform
|
|
143298
|
+
uint transformIndex = texelFetch(splatTransform, splatUV, 0).r;
|
|
143299
|
+
if (transformIndex > 0u) {
|
|
143300
|
+
// read transform matrix
|
|
143301
|
+
int u = int(transformIndex % 512u) * 3;
|
|
143302
|
+
int v = int(transformIndex / 512u);
|
|
143303
|
+
|
|
143304
|
+
mat3x4 t;
|
|
143305
|
+
t[0] = texelFetch(transformPalette, ivec2(u, v), 0);
|
|
143306
|
+
t[1] = texelFetch(transformPalette, ivec2(u + 1, v), 0);
|
|
143307
|
+
t[2] = texelFetch(transformPalette, ivec2(u + 2, v), 0);
|
|
143308
|
+
|
|
143309
|
+
center = vec4(center, 1.0) * t;
|
|
143310
|
+
}
|
|
143311
|
+
|
|
143312
|
+
// transform to clip space and discard if outside
|
|
143313
|
+
vec3 world = (matrix_model * vec4(center, 1.0)).xyz;
|
|
143314
|
+
vec4 clip = matrix_viewProjection * vec4(world, 1.0);
|
|
143315
|
+
vec3 ndc = clip.xyz / clip.w;
|
|
143316
|
+
|
|
143317
|
+
// skip offscreen fragments
|
|
143318
|
+
if (!any(greaterThan(abs(ndc), vec3(1.0)))) {
|
|
143319
|
+
if (mode == 0) {
|
|
143320
|
+
// select by mask
|
|
143321
|
+
ivec2 maskUV = ivec2((ndc.xy * vec2(0.5, -0.5) + 0.5) * mask_params);
|
|
143322
|
+
clr[i] = texelFetch(mask, maskUV, 0).a < 1.0 ? 0.0 : 1.0;
|
|
143323
|
+
} else if (mode == 1) {
|
|
143324
|
+
// select by rect
|
|
143325
|
+
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;
|
|
143326
|
+
} else if (mode == 2) {
|
|
143327
|
+
// select by sphere
|
|
143328
|
+
clr[i] = length(world - sphere_params.xyz) < sphere_params.w ? 1.0 : 0.0;
|
|
143329
|
+
} else if (mode == 3) {
|
|
143330
|
+
// select by box
|
|
143331
|
+
vec3 relativePosition = world - box_params.xyz;
|
|
143332
|
+
bool isInsideCube = true;
|
|
143333
|
+
if (relativePosition.x < -aabb_params.x || relativePosition.x > aabb_params.x) {
|
|
143334
|
+
isInsideCube = false;
|
|
143335
|
+
}
|
|
143336
|
+
if (relativePosition.y < -aabb_params.y || relativePosition.y > aabb_params.y) {
|
|
143337
|
+
isInsideCube = false;
|
|
143338
|
+
}
|
|
143339
|
+
if (relativePosition.z < -aabb_params.z || relativePosition.z > aabb_params.z) {
|
|
143340
|
+
isInsideCube = false;
|
|
143341
|
+
}
|
|
143342
|
+
clr[i] = isInsideCube ? 1.0 : 0.0;
|
|
143343
|
+
}
|
|
143344
|
+
}
|
|
143345
|
+
}
|
|
143346
|
+
|
|
143347
|
+
gl_FragColor = clr;
|
|
143348
|
+
}
|
|
143349
|
+
`;
|
|
143350
|
+
|
|
143351
|
+
const vertexShader$4 = /* glsl */ `
|
|
143352
|
+
attribute vec2 vertex_position;
|
|
143353
|
+
void main(void) {
|
|
143354
|
+
gl_Position = vec4(vertex_position, 0.0, 1.0);
|
|
143355
|
+
}
|
|
143356
|
+
`;
|
|
143357
|
+
const fragmentShader$4 = /* glsl */ `
|
|
143358
|
+
uniform highp usampler2D transformA; // splat center x, y, z
|
|
143359
|
+
uniform highp usampler2D splatTransform; // transform palette index
|
|
143360
|
+
uniform sampler2D transformPalette; // palette of transforms
|
|
143361
|
+
uniform ivec2 splat_params; // splat texture width, num splats
|
|
143362
|
+
|
|
143363
|
+
void main(void) {
|
|
143364
|
+
// calculate output id
|
|
143365
|
+
ivec2 splatUV = ivec2(gl_FragCoord);
|
|
143366
|
+
|
|
143367
|
+
// skip if splat index is out of bounds
|
|
143368
|
+
if (splatUV.x + splatUV.y * splat_params.x >= splat_params.y) {
|
|
143369
|
+
discard;
|
|
143370
|
+
}
|
|
143371
|
+
|
|
143372
|
+
// read splat center
|
|
143373
|
+
vec3 center = uintBitsToFloat(texelFetch(transformA, splatUV, 0).xyz);
|
|
143374
|
+
|
|
143375
|
+
// apply optional per-splat transform
|
|
143376
|
+
uint transformIndex = texelFetch(splatTransform, splatUV, 0).r;
|
|
143377
|
+
if (transformIndex > 0u) {
|
|
143378
|
+
// read transform matrix
|
|
143379
|
+
int u = int(transformIndex % 512u) * 3;
|
|
143380
|
+
int v = int(transformIndex / 512u);
|
|
143381
|
+
|
|
143382
|
+
mat3x4 t;
|
|
143383
|
+
t[0] = texelFetch(transformPalette, ivec2(u, v), 0);
|
|
143384
|
+
t[1] = texelFetch(transformPalette, ivec2(u + 1, v), 0);
|
|
143385
|
+
t[2] = texelFetch(transformPalette, ivec2(u + 2, v), 0);
|
|
143386
|
+
|
|
143387
|
+
center = vec4(center, 1.0) * t;
|
|
143388
|
+
}
|
|
143389
|
+
|
|
143390
|
+
gl_FragColor = vec4(center, 0.0);
|
|
143391
|
+
}
|
|
143387
143392
|
`;
|
|
143388
143393
|
|
|
143389
143394
|
const v1 = new Vec3();
|
|
@@ -143420,18 +143425,18 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
143420
143425
|
attributes: {
|
|
143421
143426
|
vertex_position: SEMANTIC_POSITION
|
|
143422
143427
|
},
|
|
143423
|
-
vertexGLSL: `
|
|
143424
|
-
attribute vec2 vertex_position;
|
|
143425
|
-
void main(void) {
|
|
143426
|
-
gl_Position = vec4(vertex_position, 0.0, 1.0);
|
|
143427
|
-
}
|
|
143428
|
+
vertexGLSL: `
|
|
143429
|
+
attribute vec2 vertex_position;
|
|
143430
|
+
void main(void) {
|
|
143431
|
+
gl_Position = vec4(vertex_position, 0.0, 1.0);
|
|
143432
|
+
}
|
|
143428
143433
|
`,
|
|
143429
|
-
fragmentGLSL: `
|
|
143430
|
-
uniform sampler2D colorTex;
|
|
143431
|
-
void main(void) {
|
|
143432
|
-
ivec2 texel = ivec2(gl_FragCoord.xy);
|
|
143433
|
-
gl_FragColor = texelFetch(colorTex, texel, 0);
|
|
143434
|
-
}
|
|
143434
|
+
fragmentGLSL: `
|
|
143435
|
+
uniform sampler2D colorTex;
|
|
143436
|
+
void main(void) {
|
|
143437
|
+
ivec2 texel = ivec2(gl_FragCoord.xy);
|
|
143438
|
+
gl_FragColor = texelFetch(colorTex, texel, 0);
|
|
143439
|
+
}
|
|
143435
143440
|
`
|
|
143436
143441
|
});
|
|
143437
143442
|
// intersection test
|
|
@@ -144670,176 +144675,176 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
144670
144675
|
}
|
|
144671
144676
|
}
|
|
144672
144677
|
|
|
144673
|
-
const vertexShader$3 = /* glsl*/ `
|
|
144674
|
-
uniform vec3 near_origin;
|
|
144675
|
-
uniform vec3 near_x;
|
|
144676
|
-
uniform vec3 near_y;
|
|
144677
|
-
|
|
144678
|
-
uniform vec3 far_origin;
|
|
144679
|
-
uniform vec3 far_x;
|
|
144680
|
-
uniform vec3 far_y;
|
|
144681
|
-
|
|
144682
|
-
attribute vec2 vertex_position;
|
|
144683
|
-
|
|
144684
|
-
varying vec3 worldFar;
|
|
144685
|
-
varying vec3 worldNear;
|
|
144686
|
-
|
|
144687
|
-
void main(void) {
|
|
144688
|
-
gl_Position = vec4(vertex_position, 0.0, 1.0);
|
|
144689
|
-
|
|
144690
|
-
vec2 p = vertex_position * 0.5 + 0.5;
|
|
144691
|
-
worldNear = near_origin + near_x * p.x + near_y * p.y;
|
|
144692
|
-
worldFar = far_origin + far_x * p.x + far_y * p.y;
|
|
144693
|
-
}
|
|
144694
|
-
`;
|
|
144695
|
-
const fragmentShader$3 = /* glsl*/ `
|
|
144696
|
-
uniform vec3 view_position;
|
|
144697
|
-
uniform mat4 matrix_viewProjection;
|
|
144698
|
-
uniform sampler2D blueNoiseTex32;
|
|
144699
|
-
|
|
144700
|
-
uniform int plane; // 0: x (yz), 1: y (xz), 2: z (xy)
|
|
144701
|
-
|
|
144702
|
-
vec4 planes[3] = vec4[3](
|
|
144703
|
-
vec4(1.0, 0.0, 0.0, 0.0),
|
|
144704
|
-
vec4(0.0, 1.0, 0.0, 0.0),
|
|
144705
|
-
vec4(0.0, 0.0, 1.0, 0.0)
|
|
144706
|
-
);
|
|
144707
|
-
|
|
144708
|
-
vec3 colors[3] = vec3[3](
|
|
144709
|
-
vec3(1.0, 0.2, 0.2),
|
|
144710
|
-
vec3(0.2, 1.0, 0.2),
|
|
144711
|
-
vec3(0.2, 0.2, 1.0)
|
|
144712
|
-
);
|
|
144713
|
-
|
|
144714
|
-
int axis0[3] = int[3](1, 0, 0);
|
|
144715
|
-
int axis1[3] = int[3](2, 2, 1);
|
|
144716
|
-
|
|
144717
|
-
varying vec3 worldNear;
|
|
144718
|
-
varying vec3 worldFar;
|
|
144719
|
-
|
|
144720
|
-
bool intersectPlane(inout float t, vec3 pos, vec3 dir, vec4 plane) {
|
|
144721
|
-
float d = dot(dir, plane.xyz);
|
|
144722
|
-
if (abs(d) < 1e-06) {
|
|
144723
|
-
return false;
|
|
144724
|
-
}
|
|
144725
|
-
|
|
144726
|
-
float n = -(dot(pos, plane.xyz) + plane.w) / d;
|
|
144727
|
-
if (n < 0.0) {
|
|
144728
|
-
return false;
|
|
144729
|
-
}
|
|
144730
|
-
|
|
144731
|
-
t = n;
|
|
144732
|
-
|
|
144733
|
-
return true;
|
|
144734
|
-
}
|
|
144735
|
-
|
|
144736
|
-
// https://bgolus.medium.com/the-best-darn-grid-shader-yet-727f9278b9d8#1e7c
|
|
144737
|
-
float pristineGrid(in vec2 uv, in vec2 ddx, in vec2 ddy, vec2 lineWidth) {
|
|
144738
|
-
vec2 uvDeriv = vec2(length(vec2(ddx.x, ddy.x)), length(vec2(ddx.y, ddy.y)));
|
|
144739
|
-
bvec2 invertLine = bvec2(lineWidth.x > 0.5, lineWidth.y > 0.5);
|
|
144740
|
-
vec2 targetWidth = vec2(
|
|
144741
|
-
invertLine.x ? 1.0 - lineWidth.x : lineWidth.x,
|
|
144742
|
-
invertLine.y ? 1.0 - lineWidth.y : lineWidth.y
|
|
144743
|
-
);
|
|
144744
|
-
vec2 drawWidth = clamp(targetWidth, uvDeriv, vec2(0.5));
|
|
144745
|
-
vec2 lineAA = uvDeriv * 1.5;
|
|
144746
|
-
vec2 gridUV = abs(fract(uv) * 2.0 - 1.0);
|
|
144747
|
-
gridUV.x = invertLine.x ? gridUV.x : 1.0 - gridUV.x;
|
|
144748
|
-
gridUV.y = invertLine.y ? gridUV.y : 1.0 - gridUV.y;
|
|
144749
|
-
vec2 grid2 = smoothstep(drawWidth + lineAA, drawWidth - lineAA, gridUV);
|
|
144750
|
-
|
|
144751
|
-
grid2 *= clamp(targetWidth / drawWidth, 0.0, 1.0);
|
|
144752
|
-
grid2 = mix(grid2, targetWidth, clamp(uvDeriv * 2.0 - 1.0, 0.0, 1.0));
|
|
144753
|
-
grid2.x = invertLine.x ? 1.0 - grid2.x : grid2.x;
|
|
144754
|
-
grid2.y = invertLine.y ? 1.0 - grid2.y : grid2.y;
|
|
144755
|
-
|
|
144756
|
-
return mix(grid2.x, 1.0, grid2.y);
|
|
144757
|
-
}
|
|
144758
|
-
|
|
144759
|
-
float calcDepth(vec3 p) {
|
|
144760
|
-
vec4 v = matrix_viewProjection * vec4(p, 1.0);
|
|
144761
|
-
return (v.z / v.w) * 0.5 + 0.5;
|
|
144762
|
-
}
|
|
144763
|
-
|
|
144764
|
-
bool writeDepth(float alpha) {
|
|
144765
|
-
vec2 uv = fract(gl_FragCoord.xy / 32.0);
|
|
144766
|
-
float noise = texture2DLod(blueNoiseTex32, uv, 0.0).y;
|
|
144767
|
-
return alpha > noise;
|
|
144768
|
-
}
|
|
144769
|
-
|
|
144770
|
-
void main(void) {
|
|
144771
|
-
vec3 p = worldNear;
|
|
144772
|
-
vec3 v = normalize(worldFar - worldNear);
|
|
144773
|
-
|
|
144774
|
-
// intersect ray with the world xz plane
|
|
144775
|
-
float t;
|
|
144776
|
-
if (!intersectPlane(t, p, v, planes[plane])) {
|
|
144777
|
-
discard;
|
|
144778
|
-
}
|
|
144779
|
-
|
|
144780
|
-
// calculate grid intersection
|
|
144781
|
-
vec3 worldPos = p + v * t;
|
|
144782
|
-
vec2 pos = plane == 0 ? worldPos.yz : (plane == 1 ? worldPos.xz : worldPos.xy);
|
|
144783
|
-
vec2 ddx = dFdx(pos);
|
|
144784
|
-
vec2 ddy = dFdy(pos);
|
|
144785
|
-
|
|
144786
|
-
float epsilon = 1.0 / 255.0;
|
|
144787
|
-
|
|
144788
|
-
// calculate fade
|
|
144789
|
-
float fade = 1.0 - smoothstep(400.0, 1000.0, length(worldPos - view_position));
|
|
144790
|
-
if (fade < epsilon) {
|
|
144791
|
-
discard;
|
|
144792
|
-
}
|
|
144793
|
-
|
|
144794
|
-
vec2 levelPos;
|
|
144795
|
-
float levelSize;
|
|
144796
|
-
float levelAlpha;
|
|
144797
|
-
|
|
144798
|
-
// 10m grid with colored main axes
|
|
144799
|
-
levelPos = pos * 0.1;
|
|
144800
|
-
levelSize = 2.0 / 1000.0;
|
|
144801
|
-
levelAlpha = pristineGrid(levelPos, ddx * 0.1, ddy * 0.1, vec2(levelSize)) * fade;
|
|
144802
|
-
if (levelAlpha > epsilon) {
|
|
144803
|
-
vec3 color;
|
|
144804
|
-
vec2 loc = abs(levelPos);
|
|
144805
|
-
if (loc.x < levelSize) {
|
|
144806
|
-
if (loc.y < levelSize) {
|
|
144807
|
-
color = vec3(1.0);
|
|
144808
|
-
} else {
|
|
144809
|
-
color = colors[axis1[plane]];
|
|
144810
|
-
}
|
|
144811
|
-
} else if (loc.y < levelSize) {
|
|
144812
|
-
color = colors[axis0[plane]];
|
|
144813
|
-
} else {
|
|
144814
|
-
color = vec3(0.9);
|
|
144815
|
-
}
|
|
144816
|
-
gl_FragColor = vec4(color, levelAlpha);
|
|
144817
|
-
gl_FragDepth = writeDepth(levelAlpha) ? calcDepth(worldPos) : 1.0;
|
|
144818
|
-
return;
|
|
144819
|
-
}
|
|
144820
|
-
|
|
144821
|
-
// 1m grid
|
|
144822
|
-
levelPos = pos;
|
|
144823
|
-
levelSize = 1.0 / 100.0;
|
|
144824
|
-
levelAlpha = pristineGrid(levelPos, ddx, ddy, vec2(levelSize)) * fade;
|
|
144825
|
-
if (levelAlpha > epsilon) {
|
|
144826
|
-
gl_FragColor = vec4(vec3(0.7), levelAlpha);
|
|
144827
|
-
gl_FragDepth = writeDepth(levelAlpha) ? calcDepth(worldPos) : 1.0;
|
|
144828
|
-
return;
|
|
144829
|
-
}
|
|
144830
|
-
|
|
144831
|
-
// 0.1m grid
|
|
144832
|
-
levelPos = pos * 10.0;
|
|
144833
|
-
levelSize = 1.0 / 100.0;
|
|
144834
|
-
levelAlpha = pristineGrid(levelPos, ddx * 10.0, ddy * 10.0, vec2(levelSize)) * fade;
|
|
144835
|
-
if (levelAlpha > epsilon) {
|
|
144836
|
-
gl_FragColor = vec4(vec3(0.7), levelAlpha);
|
|
144837
|
-
gl_FragDepth = writeDepth(levelAlpha) ? calcDepth(worldPos) : 1.0;
|
|
144838
|
-
return;
|
|
144839
|
-
}
|
|
144840
|
-
|
|
144841
|
-
discard;
|
|
144842
|
-
}
|
|
144678
|
+
const vertexShader$3 = /* glsl*/ `
|
|
144679
|
+
uniform vec3 near_origin;
|
|
144680
|
+
uniform vec3 near_x;
|
|
144681
|
+
uniform vec3 near_y;
|
|
144682
|
+
|
|
144683
|
+
uniform vec3 far_origin;
|
|
144684
|
+
uniform vec3 far_x;
|
|
144685
|
+
uniform vec3 far_y;
|
|
144686
|
+
|
|
144687
|
+
attribute vec2 vertex_position;
|
|
144688
|
+
|
|
144689
|
+
varying vec3 worldFar;
|
|
144690
|
+
varying vec3 worldNear;
|
|
144691
|
+
|
|
144692
|
+
void main(void) {
|
|
144693
|
+
gl_Position = vec4(vertex_position, 0.0, 1.0);
|
|
144694
|
+
|
|
144695
|
+
vec2 p = vertex_position * 0.5 + 0.5;
|
|
144696
|
+
worldNear = near_origin + near_x * p.x + near_y * p.y;
|
|
144697
|
+
worldFar = far_origin + far_x * p.x + far_y * p.y;
|
|
144698
|
+
}
|
|
144699
|
+
`;
|
|
144700
|
+
const fragmentShader$3 = /* glsl*/ `
|
|
144701
|
+
uniform vec3 view_position;
|
|
144702
|
+
uniform mat4 matrix_viewProjection;
|
|
144703
|
+
uniform sampler2D blueNoiseTex32;
|
|
144704
|
+
|
|
144705
|
+
uniform int plane; // 0: x (yz), 1: y (xz), 2: z (xy)
|
|
144706
|
+
|
|
144707
|
+
vec4 planes[3] = vec4[3](
|
|
144708
|
+
vec4(1.0, 0.0, 0.0, 0.0),
|
|
144709
|
+
vec4(0.0, 1.0, 0.0, 0.0),
|
|
144710
|
+
vec4(0.0, 0.0, 1.0, 0.0)
|
|
144711
|
+
);
|
|
144712
|
+
|
|
144713
|
+
vec3 colors[3] = vec3[3](
|
|
144714
|
+
vec3(1.0, 0.2, 0.2),
|
|
144715
|
+
vec3(0.2, 1.0, 0.2),
|
|
144716
|
+
vec3(0.2, 0.2, 1.0)
|
|
144717
|
+
);
|
|
144718
|
+
|
|
144719
|
+
int axis0[3] = int[3](1, 0, 0);
|
|
144720
|
+
int axis1[3] = int[3](2, 2, 1);
|
|
144721
|
+
|
|
144722
|
+
varying vec3 worldNear;
|
|
144723
|
+
varying vec3 worldFar;
|
|
144724
|
+
|
|
144725
|
+
bool intersectPlane(inout float t, vec3 pos, vec3 dir, vec4 plane) {
|
|
144726
|
+
float d = dot(dir, plane.xyz);
|
|
144727
|
+
if (abs(d) < 1e-06) {
|
|
144728
|
+
return false;
|
|
144729
|
+
}
|
|
144730
|
+
|
|
144731
|
+
float n = -(dot(pos, plane.xyz) + plane.w) / d;
|
|
144732
|
+
if (n < 0.0) {
|
|
144733
|
+
return false;
|
|
144734
|
+
}
|
|
144735
|
+
|
|
144736
|
+
t = n;
|
|
144737
|
+
|
|
144738
|
+
return true;
|
|
144739
|
+
}
|
|
144740
|
+
|
|
144741
|
+
// https://bgolus.medium.com/the-best-darn-grid-shader-yet-727f9278b9d8#1e7c
|
|
144742
|
+
float pristineGrid(in vec2 uv, in vec2 ddx, in vec2 ddy, vec2 lineWidth) {
|
|
144743
|
+
vec2 uvDeriv = vec2(length(vec2(ddx.x, ddy.x)), length(vec2(ddx.y, ddy.y)));
|
|
144744
|
+
bvec2 invertLine = bvec2(lineWidth.x > 0.5, lineWidth.y > 0.5);
|
|
144745
|
+
vec2 targetWidth = vec2(
|
|
144746
|
+
invertLine.x ? 1.0 - lineWidth.x : lineWidth.x,
|
|
144747
|
+
invertLine.y ? 1.0 - lineWidth.y : lineWidth.y
|
|
144748
|
+
);
|
|
144749
|
+
vec2 drawWidth = clamp(targetWidth, uvDeriv, vec2(0.5));
|
|
144750
|
+
vec2 lineAA = uvDeriv * 1.5;
|
|
144751
|
+
vec2 gridUV = abs(fract(uv) * 2.0 - 1.0);
|
|
144752
|
+
gridUV.x = invertLine.x ? gridUV.x : 1.0 - gridUV.x;
|
|
144753
|
+
gridUV.y = invertLine.y ? gridUV.y : 1.0 - gridUV.y;
|
|
144754
|
+
vec2 grid2 = smoothstep(drawWidth + lineAA, drawWidth - lineAA, gridUV);
|
|
144755
|
+
|
|
144756
|
+
grid2 *= clamp(targetWidth / drawWidth, 0.0, 1.0);
|
|
144757
|
+
grid2 = mix(grid2, targetWidth, clamp(uvDeriv * 2.0 - 1.0, 0.0, 1.0));
|
|
144758
|
+
grid2.x = invertLine.x ? 1.0 - grid2.x : grid2.x;
|
|
144759
|
+
grid2.y = invertLine.y ? 1.0 - grid2.y : grid2.y;
|
|
144760
|
+
|
|
144761
|
+
return mix(grid2.x, 1.0, grid2.y);
|
|
144762
|
+
}
|
|
144763
|
+
|
|
144764
|
+
float calcDepth(vec3 p) {
|
|
144765
|
+
vec4 v = matrix_viewProjection * vec4(p, 1.0);
|
|
144766
|
+
return (v.z / v.w) * 0.5 + 0.5;
|
|
144767
|
+
}
|
|
144768
|
+
|
|
144769
|
+
bool writeDepth(float alpha) {
|
|
144770
|
+
vec2 uv = fract(gl_FragCoord.xy / 32.0);
|
|
144771
|
+
float noise = texture2DLod(blueNoiseTex32, uv, 0.0).y;
|
|
144772
|
+
return alpha > noise;
|
|
144773
|
+
}
|
|
144774
|
+
|
|
144775
|
+
void main(void) {
|
|
144776
|
+
vec3 p = worldNear;
|
|
144777
|
+
vec3 v = normalize(worldFar - worldNear);
|
|
144778
|
+
|
|
144779
|
+
// intersect ray with the world xz plane
|
|
144780
|
+
float t;
|
|
144781
|
+
if (!intersectPlane(t, p, v, planes[plane])) {
|
|
144782
|
+
discard;
|
|
144783
|
+
}
|
|
144784
|
+
|
|
144785
|
+
// calculate grid intersection
|
|
144786
|
+
vec3 worldPos = p + v * t;
|
|
144787
|
+
vec2 pos = plane == 0 ? worldPos.yz : (plane == 1 ? worldPos.xz : worldPos.xy);
|
|
144788
|
+
vec2 ddx = dFdx(pos);
|
|
144789
|
+
vec2 ddy = dFdy(pos);
|
|
144790
|
+
|
|
144791
|
+
float epsilon = 1.0 / 255.0;
|
|
144792
|
+
|
|
144793
|
+
// calculate fade
|
|
144794
|
+
float fade = 1.0 - smoothstep(400.0, 1000.0, length(worldPos - view_position));
|
|
144795
|
+
if (fade < epsilon) {
|
|
144796
|
+
discard;
|
|
144797
|
+
}
|
|
144798
|
+
|
|
144799
|
+
vec2 levelPos;
|
|
144800
|
+
float levelSize;
|
|
144801
|
+
float levelAlpha;
|
|
144802
|
+
|
|
144803
|
+
// 10m grid with colored main axes
|
|
144804
|
+
levelPos = pos * 0.1;
|
|
144805
|
+
levelSize = 2.0 / 1000.0;
|
|
144806
|
+
levelAlpha = pristineGrid(levelPos, ddx * 0.1, ddy * 0.1, vec2(levelSize)) * fade;
|
|
144807
|
+
if (levelAlpha > epsilon) {
|
|
144808
|
+
vec3 color;
|
|
144809
|
+
vec2 loc = abs(levelPos);
|
|
144810
|
+
if (loc.x < levelSize) {
|
|
144811
|
+
if (loc.y < levelSize) {
|
|
144812
|
+
color = vec3(1.0);
|
|
144813
|
+
} else {
|
|
144814
|
+
color = colors[axis1[plane]];
|
|
144815
|
+
}
|
|
144816
|
+
} else if (loc.y < levelSize) {
|
|
144817
|
+
color = colors[axis0[plane]];
|
|
144818
|
+
} else {
|
|
144819
|
+
color = vec3(0.9);
|
|
144820
|
+
}
|
|
144821
|
+
gl_FragColor = vec4(color, levelAlpha);
|
|
144822
|
+
gl_FragDepth = writeDepth(levelAlpha) ? calcDepth(worldPos) : 1.0;
|
|
144823
|
+
return;
|
|
144824
|
+
}
|
|
144825
|
+
|
|
144826
|
+
// 1m grid
|
|
144827
|
+
levelPos = pos;
|
|
144828
|
+
levelSize = 1.0 / 100.0;
|
|
144829
|
+
levelAlpha = pristineGrid(levelPos, ddx, ddy, vec2(levelSize)) * fade;
|
|
144830
|
+
if (levelAlpha > epsilon) {
|
|
144831
|
+
gl_FragColor = vec4(vec3(0.7), levelAlpha);
|
|
144832
|
+
gl_FragDepth = writeDepth(levelAlpha) ? calcDepth(worldPos) : 1.0;
|
|
144833
|
+
return;
|
|
144834
|
+
}
|
|
144835
|
+
|
|
144836
|
+
// 0.1m grid
|
|
144837
|
+
levelPos = pos * 10.0;
|
|
144838
|
+
levelSize = 1.0 / 100.0;
|
|
144839
|
+
levelAlpha = pristineGrid(levelPos, ddx * 10.0, ddy * 10.0, vec2(levelSize)) * fade;
|
|
144840
|
+
if (levelAlpha > epsilon) {
|
|
144841
|
+
gl_FragColor = vec4(vec3(0.7), levelAlpha);
|
|
144842
|
+
gl_FragDepth = writeDepth(levelAlpha) ? calcDepth(worldPos) : 1.0;
|
|
144843
|
+
return;
|
|
144844
|
+
}
|
|
144845
|
+
|
|
144846
|
+
discard;
|
|
144847
|
+
}
|
|
144843
144848
|
`;
|
|
144844
144849
|
|
|
144845
144850
|
const resolve = (scope, values) => {
|
|
@@ -144910,36 +144915,36 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
144910
144915
|
}
|
|
144911
144916
|
}
|
|
144912
144917
|
|
|
144913
|
-
const vertexShader$2 = /* glsl*/ `
|
|
144914
|
-
attribute vec2 vertex_position;
|
|
144915
|
-
void main(void) {
|
|
144916
|
-
gl_Position = vec4(vertex_position, 0.0, 1.0);
|
|
144917
|
-
}
|
|
144918
|
-
`;
|
|
144919
|
-
const fragmentShader$2 = /* glsl*/ `
|
|
144920
|
-
uniform sampler2D outlineTexture;
|
|
144921
|
-
uniform float alphaCutoff;
|
|
144922
|
-
uniform vec4 clr;
|
|
144923
|
-
|
|
144924
|
-
void main(void) {
|
|
144925
|
-
ivec2 texel = ivec2(gl_FragCoord.xy);
|
|
144926
|
-
|
|
144927
|
-
// skip solid pixels
|
|
144928
|
-
if (texelFetch(outlineTexture, texel, 0).a > alphaCutoff) {
|
|
144929
|
-
discard;
|
|
144930
|
-
}
|
|
144931
|
-
|
|
144932
|
-
for (int x = -2; x <= 2; x++) {
|
|
144933
|
-
for (int y = -2; y <= 2; y++) {
|
|
144934
|
-
if ((x != 0) && (y != 0) && (texelFetch(outlineTexture, texel + ivec2(x, y), 0).a > alphaCutoff)) {
|
|
144935
|
-
gl_FragColor = clr;
|
|
144936
|
-
return;
|
|
144937
|
-
}
|
|
144938
|
-
}
|
|
144939
|
-
}
|
|
144940
|
-
|
|
144941
|
-
discard;
|
|
144942
|
-
}
|
|
144918
|
+
const vertexShader$2 = /* glsl*/ `
|
|
144919
|
+
attribute vec2 vertex_position;
|
|
144920
|
+
void main(void) {
|
|
144921
|
+
gl_Position = vec4(vertex_position, 0.0, 1.0);
|
|
144922
|
+
}
|
|
144923
|
+
`;
|
|
144924
|
+
const fragmentShader$2 = /* glsl*/ `
|
|
144925
|
+
uniform sampler2D outlineTexture;
|
|
144926
|
+
uniform float alphaCutoff;
|
|
144927
|
+
uniform vec4 clr;
|
|
144928
|
+
|
|
144929
|
+
void main(void) {
|
|
144930
|
+
ivec2 texel = ivec2(gl_FragCoord.xy);
|
|
144931
|
+
|
|
144932
|
+
// skip solid pixels
|
|
144933
|
+
if (texelFetch(outlineTexture, texel, 0).a > alphaCutoff) {
|
|
144934
|
+
discard;
|
|
144935
|
+
}
|
|
144936
|
+
|
|
144937
|
+
for (int x = -2; x <= 2; x++) {
|
|
144938
|
+
for (int y = -2; y <= 2; y++) {
|
|
144939
|
+
if ((x != 0) && (y != 0) && (texelFetch(outlineTexture, texel + ivec2(x, y), 0).a > alphaCutoff)) {
|
|
144940
|
+
gl_FragColor = clr;
|
|
144941
|
+
return;
|
|
144942
|
+
}
|
|
144943
|
+
}
|
|
144944
|
+
}
|
|
144945
|
+
|
|
144946
|
+
discard;
|
|
144947
|
+
}
|
|
144943
144948
|
`;
|
|
144944
144949
|
|
|
144945
144950
|
class Outline extends Element$1 {
|
|
@@ -145257,72 +145262,72 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
145257
145262
|
}
|
|
145258
145263
|
}
|
|
145259
145264
|
|
|
145260
|
-
const vertexShader$1 = /* glsl */ `
|
|
145261
|
-
attribute uint vertex_id;
|
|
145262
|
-
|
|
145263
|
-
uniform mat4 matrix_model;
|
|
145264
|
-
uniform mat4 matrix_viewProjection;
|
|
145265
|
-
|
|
145266
|
-
uniform sampler2D splatState;
|
|
145267
|
-
uniform highp usampler2D splatPosition;
|
|
145268
|
-
uniform highp usampler2D splatTransform; // per-splat index into transform palette
|
|
145269
|
-
uniform sampler2D transformPalette; // palette of transform matrices
|
|
145270
|
-
|
|
145271
|
-
uniform uvec2 texParams;
|
|
145272
|
-
|
|
145273
|
-
uniform float splatSize;
|
|
145274
|
-
uniform vec4 selectedClr;
|
|
145275
|
-
uniform vec4 unselectedClr;
|
|
145276
|
-
|
|
145277
|
-
varying vec4 varying_color;
|
|
145278
|
-
|
|
145279
|
-
// calculate the current splat index and uv
|
|
145280
|
-
ivec2 calcSplatUV(uint index, uint width) {
|
|
145281
|
-
return ivec2(int(index % width), int(index / width));
|
|
145282
|
-
}
|
|
145283
|
-
|
|
145284
|
-
void main(void) {
|
|
145285
|
-
ivec2 splatUV = calcSplatUV(vertex_id, texParams.x);
|
|
145286
|
-
uint splatState = uint(texelFetch(splatState, splatUV, 0).r * 255.0);
|
|
145287
|
-
|
|
145288
|
-
if ((splatState & 6u) != 0u) {
|
|
145289
|
-
// deleted or locked (4 or 2)
|
|
145290
|
-
gl_Position = vec4(0.0, 0.0, 2.0, 1.0);
|
|
145291
|
-
gl_PointSize = 0.0;
|
|
145292
|
-
} else {
|
|
145293
|
-
mat4 model = matrix_model;
|
|
145294
|
-
|
|
145295
|
-
// handle per-splat transform
|
|
145296
|
-
uint transformIndex = texelFetch(splatTransform, splatUV, 0).r;
|
|
145297
|
-
if (transformIndex > 0u) {
|
|
145298
|
-
// read transform matrix
|
|
145299
|
-
int u = int(transformIndex % 512u) * 3;
|
|
145300
|
-
int v = int(transformIndex / 512u);
|
|
145301
|
-
|
|
145302
|
-
mat4 t;
|
|
145303
|
-
t[0] = texelFetch(transformPalette, ivec2(u, v), 0);
|
|
145304
|
-
t[1] = texelFetch(transformPalette, ivec2(u + 1, v), 0);
|
|
145305
|
-
t[2] = texelFetch(transformPalette, ivec2(u + 2, v), 0);
|
|
145306
|
-
t[3] = vec4(0.0, 0.0, 0.0, 1.0);
|
|
145307
|
-
|
|
145308
|
-
model = matrix_model * transpose(t);
|
|
145309
|
-
}
|
|
145310
|
-
|
|
145311
|
-
varying_color = (splatState == 1u) ? selectedClr : unselectedClr;
|
|
145312
|
-
|
|
145313
|
-
vec3 center = uintBitsToFloat(texelFetch(splatPosition, splatUV, 0).xyz);
|
|
145314
|
-
|
|
145315
|
-
gl_Position = matrix_viewProjection * model * vec4(center, 1.0);
|
|
145316
|
-
gl_PointSize = splatSize;
|
|
145317
|
-
}
|
|
145318
|
-
}
|
|
145319
|
-
`;
|
|
145320
|
-
const fragmentShader$1 = /* glsl */ `
|
|
145321
|
-
varying vec4 varying_color;
|
|
145322
|
-
|
|
145323
|
-
void main(void) {
|
|
145324
|
-
gl_FragColor = varying_color;
|
|
145325
|
-
}
|
|
145265
|
+
const vertexShader$1 = /* glsl */ `
|
|
145266
|
+
attribute uint vertex_id;
|
|
145267
|
+
|
|
145268
|
+
uniform mat4 matrix_model;
|
|
145269
|
+
uniform mat4 matrix_viewProjection;
|
|
145270
|
+
|
|
145271
|
+
uniform sampler2D splatState;
|
|
145272
|
+
uniform highp usampler2D splatPosition;
|
|
145273
|
+
uniform highp usampler2D splatTransform; // per-splat index into transform palette
|
|
145274
|
+
uniform sampler2D transformPalette; // palette of transform matrices
|
|
145275
|
+
|
|
145276
|
+
uniform uvec2 texParams;
|
|
145277
|
+
|
|
145278
|
+
uniform float splatSize;
|
|
145279
|
+
uniform vec4 selectedClr;
|
|
145280
|
+
uniform vec4 unselectedClr;
|
|
145281
|
+
|
|
145282
|
+
varying vec4 varying_color;
|
|
145283
|
+
|
|
145284
|
+
// calculate the current splat index and uv
|
|
145285
|
+
ivec2 calcSplatUV(uint index, uint width) {
|
|
145286
|
+
return ivec2(int(index % width), int(index / width));
|
|
145287
|
+
}
|
|
145288
|
+
|
|
145289
|
+
void main(void) {
|
|
145290
|
+
ivec2 splatUV = calcSplatUV(vertex_id, texParams.x);
|
|
145291
|
+
uint splatState = uint(texelFetch(splatState, splatUV, 0).r * 255.0);
|
|
145292
|
+
|
|
145293
|
+
if ((splatState & 6u) != 0u) {
|
|
145294
|
+
// deleted or locked (4 or 2)
|
|
145295
|
+
gl_Position = vec4(0.0, 0.0, 2.0, 1.0);
|
|
145296
|
+
gl_PointSize = 0.0;
|
|
145297
|
+
} else {
|
|
145298
|
+
mat4 model = matrix_model;
|
|
145299
|
+
|
|
145300
|
+
// handle per-splat transform
|
|
145301
|
+
uint transformIndex = texelFetch(splatTransform, splatUV, 0).r;
|
|
145302
|
+
if (transformIndex > 0u) {
|
|
145303
|
+
// read transform matrix
|
|
145304
|
+
int u = int(transformIndex % 512u) * 3;
|
|
145305
|
+
int v = int(transformIndex / 512u);
|
|
145306
|
+
|
|
145307
|
+
mat4 t;
|
|
145308
|
+
t[0] = texelFetch(transformPalette, ivec2(u, v), 0);
|
|
145309
|
+
t[1] = texelFetch(transformPalette, ivec2(u + 1, v), 0);
|
|
145310
|
+
t[2] = texelFetch(transformPalette, ivec2(u + 2, v), 0);
|
|
145311
|
+
t[3] = vec4(0.0, 0.0, 0.0, 1.0);
|
|
145312
|
+
|
|
145313
|
+
model = matrix_model * transpose(t);
|
|
145314
|
+
}
|
|
145315
|
+
|
|
145316
|
+
varying_color = (splatState == 1u) ? selectedClr : unselectedClr;
|
|
145317
|
+
|
|
145318
|
+
vec3 center = uintBitsToFloat(texelFetch(splatPosition, splatUV, 0).xyz);
|
|
145319
|
+
|
|
145320
|
+
gl_Position = matrix_viewProjection * model * vec4(center, 1.0);
|
|
145321
|
+
gl_PointSize = splatSize;
|
|
145322
|
+
}
|
|
145323
|
+
}
|
|
145324
|
+
`;
|
|
145325
|
+
const fragmentShader$1 = /* glsl */ `
|
|
145326
|
+
varying vec4 varying_color;
|
|
145327
|
+
|
|
145328
|
+
void main(void) {
|
|
145329
|
+
gl_FragColor = varying_color;
|
|
145330
|
+
}
|
|
145326
145331
|
`;
|
|
145327
145332
|
|
|
145328
145333
|
class SplatOverlay extends Element$1 {
|
|
@@ -145411,19 +145416,19 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
145411
145416
|
}
|
|
145412
145417
|
}
|
|
145413
145418
|
|
|
145414
|
-
const vertexShader = /* glsl*/ `
|
|
145415
|
-
attribute vec2 vertex_position;
|
|
145416
|
-
void main(void) {
|
|
145417
|
-
gl_Position = vec4(vertex_position, 0.0, 1.0);
|
|
145418
|
-
}
|
|
145419
|
+
const vertexShader = /* glsl*/ `
|
|
145420
|
+
attribute vec2 vertex_position;
|
|
145421
|
+
void main(void) {
|
|
145422
|
+
gl_Position = vec4(vertex_position, 0.0, 1.0);
|
|
145423
|
+
}
|
|
145419
145424
|
`;
|
|
145420
|
-
const fragmentShader = /* glsl*/ `
|
|
145421
|
-
uniform sampler2D blitTexture;
|
|
145422
|
-
void main(void) {
|
|
145423
|
-
ivec2 texel = ivec2(gl_FragCoord.xy);
|
|
145424
|
-
|
|
145425
|
-
gl_FragColor = texelFetch(blitTexture, texel, 0);
|
|
145426
|
-
}
|
|
145425
|
+
const fragmentShader = /* glsl*/ `
|
|
145426
|
+
uniform sampler2D blitTexture;
|
|
145427
|
+
void main(void) {
|
|
145428
|
+
ivec2 texel = ivec2(gl_FragCoord.xy);
|
|
145429
|
+
|
|
145430
|
+
gl_FragColor = texelFetch(blitTexture, texel, 0);
|
|
145431
|
+
}
|
|
145427
145432
|
`;
|
|
145428
145433
|
|
|
145429
145434
|
class Underlay extends Element$1 {
|
|
@@ -147700,6 +147705,7 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
147700
147705
|
};
|
|
147701
147706
|
this.enableStats = false;
|
|
147702
147707
|
this.autoFocus = true;
|
|
147708
|
+
this.previewMode = false;
|
|
147703
147709
|
this.isLoading = false;
|
|
147704
147710
|
this.hasModel = false;
|
|
147705
147711
|
this.error = null;
|
|
@@ -147752,6 +147758,11 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
147752
147758
|
this.canvas = options.canvas || null;
|
|
147753
147759
|
this.enableStats = options.enableStats || false;
|
|
147754
147760
|
this.autoFocus = options.autoFocus !== false;
|
|
147761
|
+
this.previewMode = options.previewMode || false;
|
|
147762
|
+
// In preview mode, always enable auto-focus
|
|
147763
|
+
if (this.previewMode) {
|
|
147764
|
+
this.autoFocus = true;
|
|
147765
|
+
}
|
|
147755
147766
|
this._navigationCubeConfig = options.navigationCube || null;
|
|
147756
147767
|
if (options.onStatsUpdate !== undefined) {
|
|
147757
147768
|
this._onStatsUpdate = options.onStatsUpdate;
|
|
@@ -147782,11 +147793,20 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
147782
147793
|
const emitEvent = (type, detail) => {
|
|
147783
147794
|
this.emit({ type, detail });
|
|
147784
147795
|
};
|
|
147785
|
-
this._supersplat = new SupersplatAdapter(this.canvas,
|
|
147796
|
+
this._supersplat = new SupersplatAdapter(this.canvas,
|
|
147797
|
+
// Disable navigation cube in preview mode
|
|
147798
|
+
this.previewMode ? null : this._navigationCubeConfig, emitEvent);
|
|
147786
147799
|
this._supersplatReady = this._supersplat.init();
|
|
147787
147800
|
this._supersplatReady
|
|
147788
147801
|
?.then(() => {
|
|
147789
|
-
|
|
147802
|
+
// Disable camera controls in preview mode
|
|
147803
|
+
if (this.previewMode && this._supersplat) {
|
|
147804
|
+
this._supersplat.setCameraControlsEnabled?.(false);
|
|
147805
|
+
}
|
|
147806
|
+
// Only set up fly camera if not in preview mode
|
|
147807
|
+
if (!this.previewMode) {
|
|
147808
|
+
this._setupFlyCameraForSupersplat();
|
|
147809
|
+
}
|
|
147790
147810
|
})
|
|
147791
147811
|
.catch(error => {
|
|
147792
147812
|
console.error('SplatViewerCore.init: Failed to set up fly camera for supersplat path', error);
|
|
@@ -147825,7 +147845,9 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
147825
147845
|
// SuperSplat's PCApp omits ScriptComponentSystem, so `addComponent('script')`
|
|
147826
147846
|
// will not produce `camera.script.create()`. We keep the attempt (in case
|
|
147827
147847
|
// the underlying app changes), but also support a controller-based fallback.
|
|
147828
|
-
if (cameraAny &&
|
|
147848
|
+
if (cameraAny &&
|
|
147849
|
+
!cameraAny.script &&
|
|
147850
|
+
typeof cameraAny.addComponent === 'function') {
|
|
147829
147851
|
try {
|
|
147830
147852
|
cameraAny.addComponent('script');
|
|
147831
147853
|
}
|
|
@@ -147851,7 +147873,9 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
147851
147873
|
// Prefer script-based fly when available; fallback to controller otherwise.
|
|
147852
147874
|
const canCreateScript = typeof cameraAny?.script?.create === 'function';
|
|
147853
147875
|
if (canCreateScript) {
|
|
147854
|
-
const created = cameraAny.script.create('flyCamera', {
|
|
147876
|
+
const created = cameraAny.script.create('flyCamera', {
|
|
147877
|
+
attributes: flyAttributes,
|
|
147878
|
+
});
|
|
147855
147879
|
this._fly = created;
|
|
147856
147880
|
if (this._fly) {
|
|
147857
147881
|
;
|
|
@@ -149715,6 +149739,11 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
149715
149739
|
// Camera Mode / Fly Camera API
|
|
149716
149740
|
// ==========================================
|
|
149717
149741
|
setCameraMode(mode) {
|
|
149742
|
+
// Prevent camera mode changes in preview mode
|
|
149743
|
+
if (this.previewMode) {
|
|
149744
|
+
console.warn('SplatViewerCore.setCameraMode: Camera controls are disabled in preview mode');
|
|
149745
|
+
return;
|
|
149746
|
+
}
|
|
149718
149747
|
// supersplat-core path: manage mode switching explicitly (camera entity is updated by supersplat-core each frame)
|
|
149719
149748
|
if (this._supersplat) {
|
|
149720
149749
|
const prev = this._cameraMode;
|
|
@@ -149744,7 +149773,9 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
149744
149773
|
try {
|
|
149745
149774
|
const pos = this.entities.camera?.getPosition?.();
|
|
149746
149775
|
if (pos) {
|
|
149747
|
-
const posVec = pos.clone
|
|
149776
|
+
const posVec = pos.clone
|
|
149777
|
+
? pos.clone()
|
|
149778
|
+
: new Vec3(pos.x || 0, pos.y || 0, pos.z || 0);
|
|
149748
149779
|
this.entities.camera?.setPosition?.(posVec);
|
|
149749
149780
|
}
|
|
149750
149781
|
const euler = this.entities.camera?.getEulerAngles?.();
|
|
@@ -149967,8 +149998,8 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
149967
149998
|
panSensitivity: 1.0,
|
|
149968
149999
|
zoomSensitivity: 0.1,
|
|
149969
150000
|
};
|
|
149970
|
-
// Add navigation cube configuration if available
|
|
149971
|
-
if (this._navigationCubeConfig) {
|
|
150001
|
+
// Add navigation cube configuration if available (but not in preview mode)
|
|
150002
|
+
if (this._navigationCubeConfig && !this.previewMode) {
|
|
149972
150003
|
orbitAttributes.enableNavigationCube =
|
|
149973
150004
|
this._navigationCubeConfig.enabled || false;
|
|
149974
150005
|
this.entities.camera._navigationCubeConfig =
|
|
@@ -149983,48 +150014,57 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
149983
150014
|
detail: { type: interactionType },
|
|
149984
150015
|
});
|
|
149985
150016
|
};
|
|
150017
|
+
// Disable camera controls in preview mode
|
|
150018
|
+
if (this.previewMode && this._orbit) {
|
|
150019
|
+
const orbitAny = this._orbit;
|
|
150020
|
+
if (typeof orbitAny.setEnabled === 'function') {
|
|
150021
|
+
orbitAny.setEnabled(false);
|
|
150022
|
+
}
|
|
150023
|
+
}
|
|
149986
150024
|
this.entities.camera.setPosition(0, 0, 10);
|
|
149987
150025
|
this.entities.camera.lookAt(Vec3.ZERO);
|
|
149988
150026
|
// ==============================
|
|
149989
|
-
// Setup fly camera (disabled by default)
|
|
150027
|
+
// Setup fly camera (disabled by default, skipped in preview mode)
|
|
149990
150028
|
// ==============================
|
|
149991
|
-
|
|
149992
|
-
|
|
149993
|
-
|
|
149994
|
-
|
|
149995
|
-
|
|
149996
|
-
|
|
149997
|
-
|
|
149998
|
-
|
|
149999
|
-
|
|
150000
|
-
|
|
150001
|
-
|
|
150002
|
-
|
|
150003
|
-
|
|
150004
|
-
|
|
150005
|
-
|
|
150006
|
-
|
|
150007
|
-
this._fly = this.entities.camera.script.create('flyCamera', {
|
|
150008
|
-
attributes: flyAttributes,
|
|
150009
|
-
});
|
|
150010
|
-
// Wire event emission to core
|
|
150011
|
-
if (this._fly) {
|
|
150012
|
-
;
|
|
150013
|
-
this._fly.emitFlyEvent = (type, detail) => {
|
|
150014
|
-
this.emit({ type: type, detail });
|
|
150029
|
+
if (!this.previewMode) {
|
|
150030
|
+
try {
|
|
150031
|
+
registerFlyCameraScript();
|
|
150032
|
+
// Ensure script component exists (created above)
|
|
150033
|
+
const flyAttributes = {
|
|
150034
|
+
moveSpeed: DEFAULT_FLY_CAMERA_CONFIG.moveSpeed,
|
|
150035
|
+
fastSpeedMultiplier: DEFAULT_FLY_CAMERA_CONFIG.fastSpeedMultiplier,
|
|
150036
|
+
slowSpeedMultiplier: DEFAULT_FLY_CAMERA_CONFIG.slowSpeedMultiplier,
|
|
150037
|
+
lookSensitivity: DEFAULT_FLY_CAMERA_CONFIG.lookSensitivity,
|
|
150038
|
+
invertY: DEFAULT_FLY_CAMERA_CONFIG.invertY,
|
|
150039
|
+
keyBindings: DEFAULT_FLY_CAMERA_CONFIG.keyBindings,
|
|
150040
|
+
smoothing: DEFAULT_FLY_CAMERA_CONFIG.smoothing,
|
|
150041
|
+
friction: DEFAULT_FLY_CAMERA_CONFIG.friction,
|
|
150042
|
+
enableCollision: DEFAULT_FLY_CAMERA_CONFIG.enableCollision,
|
|
150043
|
+
minHeight: DEFAULT_FLY_CAMERA_CONFIG.minHeight,
|
|
150044
|
+
maxHeight: DEFAULT_FLY_CAMERA_CONFIG.maxHeight,
|
|
150015
150045
|
};
|
|
150046
|
+
this._fly = this.entities.camera.script.create('flyCamera', {
|
|
150047
|
+
attributes: flyAttributes,
|
|
150048
|
+
});
|
|
150049
|
+
// Wire event emission to core
|
|
150050
|
+
if (this._fly) {
|
|
150051
|
+
;
|
|
150052
|
+
this._fly.emitFlyEvent = (type, detail) => {
|
|
150053
|
+
this.emit({ type: type, detail });
|
|
150054
|
+
};
|
|
150055
|
+
}
|
|
150056
|
+
// Deactivate fly by default; orbit is the initial mode
|
|
150057
|
+
if (this._fly?.deactivate) {
|
|
150058
|
+
this._fly.deactivate();
|
|
150059
|
+
}
|
|
150060
|
+
// Initialize camera mode manager
|
|
150061
|
+
this._cameraModeManager = new CameraModeManager(this.app, this.entities.camera, this._orbit, this._fly, (eventType, detail) => {
|
|
150062
|
+
this.emit({ type: eventType, detail });
|
|
150063
|
+
}, 'orbit');
|
|
150016
150064
|
}
|
|
150017
|
-
|
|
150018
|
-
|
|
150019
|
-
this._fly.deactivate();
|
|
150065
|
+
catch (e) {
|
|
150066
|
+
console.warn('Failed to set up fly camera', e);
|
|
150020
150067
|
}
|
|
150021
|
-
// Initialize camera mode manager
|
|
150022
|
-
this._cameraModeManager = new CameraModeManager(this.app, this.entities.camera, this._orbit, this._fly, (eventType, detail) => {
|
|
150023
|
-
this.emit({ type: eventType, detail });
|
|
150024
|
-
}, 'orbit');
|
|
150025
|
-
}
|
|
150026
|
-
catch (e) {
|
|
150027
|
-
console.warn('Failed to set up fly camera', e);
|
|
150028
150068
|
}
|
|
150029
150069
|
}
|
|
150030
150070
|
_setupStats() {
|
|
@@ -150269,6 +150309,7 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
150269
150309
|
'enable-stats',
|
|
150270
150310
|
'auto-focus',
|
|
150271
150311
|
'max-splats',
|
|
150312
|
+
'preview-mode',
|
|
150272
150313
|
'camera-position',
|
|
150273
150314
|
'camera-target',
|
|
150274
150315
|
'orbit-sensitivity',
|
|
@@ -150299,6 +150340,9 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
150299
150340
|
get autoFocus() {
|
|
150300
150341
|
return this.hasAttribute('auto-focus');
|
|
150301
150342
|
}
|
|
150343
|
+
get previewMode() {
|
|
150344
|
+
return this.hasAttribute('preview-mode');
|
|
150345
|
+
}
|
|
150302
150346
|
get maxSplats() {
|
|
150303
150347
|
return this.getAttribute('max-splats');
|
|
150304
150348
|
}
|
|
@@ -150376,6 +150420,14 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
150376
150420
|
this.removeAttribute('auto-focus');
|
|
150377
150421
|
}
|
|
150378
150422
|
}
|
|
150423
|
+
set previewMode(value) {
|
|
150424
|
+
if (value) {
|
|
150425
|
+
this.setAttribute('preview-mode', '');
|
|
150426
|
+
}
|
|
150427
|
+
else {
|
|
150428
|
+
this.removeAttribute('preview-mode');
|
|
150429
|
+
}
|
|
150430
|
+
}
|
|
150379
150431
|
set maxSplats(value) {
|
|
150380
150432
|
if (value === null) {
|
|
150381
150433
|
this.removeAttribute('max-splats');
|
|
@@ -150557,6 +150609,7 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
150557
150609
|
return value.length > 0;
|
|
150558
150610
|
case 'enable-stats':
|
|
150559
150611
|
case 'auto-focus':
|
|
150612
|
+
case 'preview-mode':
|
|
150560
150613
|
case 'enable-navigation-cube':
|
|
150561
150614
|
// Boolean attributes - any value is valid
|
|
150562
150615
|
return true;
|
|
@@ -151503,7 +151556,7 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
151503
151556
|
if (!this._core) {
|
|
151504
151557
|
throw new Error('SplatViewerElement: Core not initialized. Call connectedCallback first.');
|
|
151505
151558
|
}
|
|
151506
|
-
return this._core.selectSplatsInSphere(center, radius, modelId, addToSelection);
|
|
151559
|
+
return this._core.selectSplatsInSphere(new Vec3(center.x, center.y, center.z), radius, modelId, addToSelection);
|
|
151507
151560
|
}
|
|
151508
151561
|
clearSplatSelection() {
|
|
151509
151562
|
if (!this._core) {
|