@heliguy-xyz/splat-viewer 1.0.0-rc.26 → 1.0.0-rc.28
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 +52 -336
- package/dist/web-component/splat-viewer.esm.js +88 -19
- package/dist/web-component/splat-viewer.esm.min.js +1 -1
- package/dist/web-component/splat-viewer.js +88 -19
- package/dist/web-component/splat-viewer.min.js +1 -1
- package/dist/web-component/supersplat-core/controllers.d.ts +5 -0
- package/dist/web-component/supersplat-core/controllers.d.ts.map +1 -1
- package/dist/web-component/supersplat-core/splat.d.ts.map +1 -1
- package/dist/web-component/types/supersplat-core/controllers.d.ts +5 -0
- package/dist/web-component/types/supersplat-core/controllers.d.ts.map +1 -1
- package/dist/web-component/types/supersplat-core/splat.d.ts.map +1 -1
- package/dist/web-component/types/web-component/OrbitCameraScript.d.ts.map +1 -1
- package/dist/web-component/types/web-component/SplatViewerCore.d.ts.map +1 -1
- package/dist/web-component/types/web-component/SupersplatAdapter.d.ts +9 -0
- package/dist/web-component/types/web-component/SupersplatAdapter.d.ts.map +1 -1
- package/dist/web-component/types/web-component/utils/config.d.ts +1 -0
- package/dist/web-component/types/web-component/utils/config.d.ts.map +1 -1
- package/dist/web-component/web-component/OrbitCameraScript.d.ts.map +1 -1
- package/dist/web-component/web-component/SplatViewerCore.d.ts.map +1 -1
- package/dist/web-component/web-component/SupersplatAdapter.d.ts +9 -0
- package/dist/web-component/web-component/SupersplatAdapter.d.ts.map +1 -1
- package/dist/web-component/web-component/utils/config.d.ts +1 -0
- package/dist/web-component/web-component/utils/config.d.ts.map +1 -1
- package/package.json +5 -12
- package/CHANGELOG.md +0 -78
|
@@ -139564,11 +139564,15 @@ fn fragmentMain(input: FragmentInput) -> FragmentOutput {
|
|
|
139564
139564
|
}
|
|
139565
139565
|
/**
|
|
139566
139566
|
* Convert a string to a boolean value
|
|
139567
|
+
* For HTML boolean attributes, an empty string means the attribute is present (true)
|
|
139567
139568
|
*/
|
|
139568
139569
|
function parseBoolean(value) {
|
|
139569
139570
|
if (typeof value === 'boolean')
|
|
139570
139571
|
return value;
|
|
139571
139572
|
if (typeof value === 'string') {
|
|
139573
|
+
// Empty string means attribute is present without value (should be true for boolean attributes)
|
|
139574
|
+
if (value === '')
|
|
139575
|
+
return true;
|
|
139572
139576
|
return value.toLowerCase() === 'true' || value === '1';
|
|
139573
139577
|
}
|
|
139574
139578
|
return false;
|
|
@@ -140459,6 +140463,10 @@ fn fragmentMain(input: FragmentInput) -> FragmentOutput {
|
|
|
140459
140463
|
this.isPanning = false;
|
|
140460
140464
|
// Allow host to temporarily disable camera input (e.g., while dragging gizmos)
|
|
140461
140465
|
this._inputEnabled = true;
|
|
140466
|
+
// Granular control over specific input types
|
|
140467
|
+
this._orbitEnabled = true;
|
|
140468
|
+
this._panEnabled = true;
|
|
140469
|
+
this._zoomEnabled = true;
|
|
140462
140470
|
// Setup context menu prevention
|
|
140463
140471
|
this.setupContextMenuPrevention();
|
|
140464
140472
|
// Use PlayCanvas mouse events for reliable input handling
|
|
@@ -140496,6 +140504,19 @@ fn fragmentMain(input: FragmentInput) -> FragmentOutput {
|
|
|
140496
140504
|
this.isPanning = false;
|
|
140497
140505
|
}
|
|
140498
140506
|
};
|
|
140507
|
+
OrbitCamera.prototype.setInputControls = function (options) {
|
|
140508
|
+
if (options.orbit !== undefined)
|
|
140509
|
+
this._orbitEnabled = !!options.orbit;
|
|
140510
|
+
if (options.pan !== undefined)
|
|
140511
|
+
this._panEnabled = !!options.pan;
|
|
140512
|
+
if (options.zoom !== undefined)
|
|
140513
|
+
this._zoomEnabled = !!options.zoom;
|
|
140514
|
+
// Clear any in-progress interactions if being disabled
|
|
140515
|
+
if (this._orbitEnabled === false)
|
|
140516
|
+
this.isOrbiting = false;
|
|
140517
|
+
if (this._panEnabled === false)
|
|
140518
|
+
this.isPanning = false;
|
|
140519
|
+
};
|
|
140499
140520
|
OrbitCamera.prototype.update = function (dt) {
|
|
140500
140521
|
// Update navigation cube if enabled
|
|
140501
140522
|
if (this.navigationCube &&
|
|
@@ -140512,12 +140533,13 @@ fn fragmentMain(input: FragmentInput) -> FragmentOutput {
|
|
|
140512
140533
|
typeof this.navigationCube.cancelTransition === 'function') {
|
|
140513
140534
|
this.navigationCube.cancelTransition('manual-interaction');
|
|
140514
140535
|
}
|
|
140515
|
-
if (event.button === MOUSEBUTTON_LEFT) {
|
|
140536
|
+
if (event.button === MOUSEBUTTON_LEFT && this._orbitEnabled !== false) {
|
|
140516
140537
|
this.isOrbiting = true;
|
|
140517
140538
|
this.emitInteractionEvent?.('interaction-start', 'rotate');
|
|
140518
140539
|
}
|
|
140519
|
-
else if (event.button === MOUSEBUTTON_RIGHT ||
|
|
140520
|
-
event.button === MOUSEBUTTON_MIDDLE)
|
|
140540
|
+
else if ((event.button === MOUSEBUTTON_RIGHT ||
|
|
140541
|
+
event.button === MOUSEBUTTON_MIDDLE) &&
|
|
140542
|
+
this._panEnabled !== false) {
|
|
140521
140543
|
this.isPanning = true;
|
|
140522
140544
|
this.emitInteractionEvent?.('interaction-start', 'pan');
|
|
140523
140545
|
}
|
|
@@ -140565,7 +140587,7 @@ fn fragmentMain(input: FragmentInput) -> FragmentOutput {
|
|
|
140565
140587
|
}
|
|
140566
140588
|
};
|
|
140567
140589
|
OrbitCamera.prototype.onMouseWheel = function (event) {
|
|
140568
|
-
if (this._inputEnabled === false)
|
|
140590
|
+
if (this._inputEnabled === false || this._zoomEnabled === false)
|
|
140569
140591
|
return;
|
|
140570
140592
|
// Cancel any ongoing navigation cube transition when manual zoom interaction starts
|
|
140571
140593
|
if (this.navigationCube &&
|
|
@@ -142701,6 +142723,10 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
142701
142723
|
this.entity.setEulerAngles(orientation);
|
|
142702
142724
|
this.entity.addComponent('gsplat', { asset });
|
|
142703
142725
|
const instance = this.entity.gsplat.instance;
|
|
142726
|
+
// Check if the gsplat component initialized properly
|
|
142727
|
+
if (!instance || !instance.meshInstance) {
|
|
142728
|
+
throw new Error('Failed to initialize gsplat component. The file may not contain valid Gaussian Splatting data.');
|
|
142729
|
+
}
|
|
142704
142730
|
// use custom render order distance calculation for splats
|
|
142705
142731
|
instance.meshInstance.calculateSortDistance = (meshInstance, pos, dir) => {
|
|
142706
142732
|
const bound = this.localBound;
|
|
@@ -143809,6 +143835,10 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
143809
143835
|
};
|
|
143810
143836
|
// Allow temporarily disabling camera controls (e.g. while dragging gizmos).
|
|
143811
143837
|
let enabled = true;
|
|
143838
|
+
// Granular control over specific input types
|
|
143839
|
+
let orbitEnabled = true;
|
|
143840
|
+
let panEnabled = true;
|
|
143841
|
+
let zoomEnabled = true;
|
|
143812
143842
|
const resetState = () => {
|
|
143813
143843
|
pressedButton = -1;
|
|
143814
143844
|
touches = [];
|
|
@@ -143915,13 +143945,13 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
143915
143945
|
(event.shiftKey || event.ctrlKey ? 'orbit' :
|
|
143916
143946
|
(event.altKey || event.metaKey ? 'zoom' : null)) :
|
|
143917
143947
|
null;
|
|
143918
|
-
if (mod === 'orbit' || (mod === null && pressedButton === 0)) {
|
|
143948
|
+
if ((mod === 'orbit' || (mod === null && pressedButton === 0)) && orbitEnabled) {
|
|
143919
143949
|
orbit(dx, dy);
|
|
143920
143950
|
}
|
|
143921
|
-
else if (mod === 'zoom' || (mod === null && pressedButton === 1)) {
|
|
143951
|
+
else if ((mod === 'zoom' || (mod === null && pressedButton === 1)) && zoomEnabled) {
|
|
143922
143952
|
zoom(dy * -0.02);
|
|
143923
143953
|
}
|
|
143924
|
-
else if (mod === 'pan' || (mod === null && pressedButton === 2)) {
|
|
143954
|
+
else if ((mod === 'pan' || (mod === null && pressedButton === 2)) && panEnabled) {
|
|
143925
143955
|
pan(x, y, dx, dy);
|
|
143926
143956
|
}
|
|
143927
143957
|
}
|
|
@@ -143932,7 +143962,9 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
143932
143962
|
const dy = event.offsetY - touch.y;
|
|
143933
143963
|
touch.x = event.offsetX;
|
|
143934
143964
|
touch.y = event.offsetY;
|
|
143935
|
-
|
|
143965
|
+
if (orbitEnabled) {
|
|
143966
|
+
orbit(dx, dy);
|
|
143967
|
+
}
|
|
143936
143968
|
}
|
|
143937
143969
|
else if (touches.length === 2) {
|
|
143938
143970
|
const touch = touches[touches.map(t => t.id).indexOf(event.pointerId)];
|
|
@@ -143941,8 +143973,12 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
143941
143973
|
const mx = (touches[0].x + touches[1].x) * 0.5;
|
|
143942
143974
|
const my = (touches[0].y + touches[1].y) * 0.5;
|
|
143943
143975
|
const ml = dist(touches[0].x, touches[0].y, touches[1].x, touches[1].y);
|
|
143944
|
-
|
|
143945
|
-
|
|
143976
|
+
if (panEnabled) {
|
|
143977
|
+
pan(mx, my, (mx - midx), (my - midy));
|
|
143978
|
+
}
|
|
143979
|
+
if (zoomEnabled) {
|
|
143980
|
+
zoom((ml - midlen) * 0.01);
|
|
143981
|
+
}
|
|
143946
143982
|
midx = mx;
|
|
143947
143983
|
midy = my;
|
|
143948
143984
|
midlen = ml;
|
|
@@ -143960,16 +143996,20 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
143960
143996
|
return;
|
|
143961
143997
|
const { deltaX, deltaY } = event;
|
|
143962
143998
|
if (isMouseEvent(deltaX, deltaY)) {
|
|
143963
|
-
|
|
143999
|
+
if (zoomEnabled)
|
|
144000
|
+
zoom(deltaY * -2e-3);
|
|
143964
144001
|
}
|
|
143965
144002
|
else if (event.ctrlKey || event.metaKey) {
|
|
143966
|
-
|
|
144003
|
+
if (zoomEnabled)
|
|
144004
|
+
zoom(deltaY * -0.02);
|
|
143967
144005
|
}
|
|
143968
144006
|
else if (event.shiftKey) {
|
|
143969
|
-
|
|
144007
|
+
if (panEnabled)
|
|
144008
|
+
pan(event.offsetX, event.offsetY, deltaX, deltaY);
|
|
143970
144009
|
}
|
|
143971
144010
|
else {
|
|
143972
|
-
|
|
144011
|
+
if (orbitEnabled)
|
|
144012
|
+
orbit(deltaX, deltaY);
|
|
143973
144013
|
}
|
|
143974
144014
|
event.preventDefault();
|
|
143975
144015
|
};
|
|
@@ -144037,6 +144077,14 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
144037
144077
|
resetState();
|
|
144038
144078
|
}
|
|
144039
144079
|
};
|
|
144080
|
+
this.setInputControls = (options) => {
|
|
144081
|
+
if (options.orbit !== undefined)
|
|
144082
|
+
orbitEnabled = !!options.orbit;
|
|
144083
|
+
if (options.pan !== undefined)
|
|
144084
|
+
panEnabled = !!options.pan;
|
|
144085
|
+
if (options.zoom !== undefined)
|
|
144086
|
+
zoomEnabled = !!options.zoom;
|
|
144087
|
+
};
|
|
144040
144088
|
}
|
|
144041
144089
|
}
|
|
144042
144090
|
|
|
@@ -147341,6 +147389,26 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
147341
147389
|
console.warn('SupersplatAdapter: Failed to toggle camera controls', e);
|
|
147342
147390
|
}
|
|
147343
147391
|
}
|
|
147392
|
+
/**
|
|
147393
|
+
* Configure granular control over specific camera input types.
|
|
147394
|
+
* Allows enabling/disabling orbit, pan, and zoom independently.
|
|
147395
|
+
*/
|
|
147396
|
+
setCameraInputControls(options) {
|
|
147397
|
+
const controller = this.scene?.camera?.controller;
|
|
147398
|
+
if (!controller)
|
|
147399
|
+
return;
|
|
147400
|
+
try {
|
|
147401
|
+
if (typeof controller.setInputControls === 'function') {
|
|
147402
|
+
controller.setInputControls(options);
|
|
147403
|
+
}
|
|
147404
|
+
else {
|
|
147405
|
+
console.warn('SupersplatAdapter: Camera controller does not support setInputControls');
|
|
147406
|
+
}
|
|
147407
|
+
}
|
|
147408
|
+
catch (e) {
|
|
147409
|
+
console.warn('SupersplatAdapter: Failed to set camera input controls', e);
|
|
147410
|
+
}
|
|
147411
|
+
}
|
|
147344
147412
|
/**
|
|
147345
147413
|
* Enable/disable supersplat-core camera auto-update (orbit tweens).
|
|
147346
147414
|
* When enabled, the camera entity transform may be driven by an external controller (fly mode).
|
|
@@ -147799,9 +147867,9 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
147799
147867
|
this._supersplatReady = this._supersplat.init();
|
|
147800
147868
|
this._supersplatReady
|
|
147801
147869
|
?.then(() => {
|
|
147802
|
-
//
|
|
147870
|
+
// In preview mode, enable zoom only (disable orbit and pan)
|
|
147803
147871
|
if (this.previewMode && this._supersplat) {
|
|
147804
|
-
this._supersplat.
|
|
147872
|
+
this._supersplat.setCameraInputControls?.({ orbit: false, pan: false, zoom: true });
|
|
147805
147873
|
}
|
|
147806
147874
|
// Only set up fly camera if not in preview mode
|
|
147807
147875
|
if (!this.previewMode) {
|
|
@@ -150014,11 +150082,12 @@ bool initCenter(SplatSource source, vec3 modelCenter, out SplatCenter center) {
|
|
|
150014
150082
|
detail: { type: interactionType },
|
|
150015
150083
|
});
|
|
150016
150084
|
};
|
|
150017
|
-
//
|
|
150085
|
+
// In preview mode, enable zoom only (disable orbit and pan)
|
|
150018
150086
|
if (this.previewMode && this._orbit) {
|
|
150019
150087
|
const orbitAny = this._orbit;
|
|
150020
|
-
if (typeof orbitAny.
|
|
150021
|
-
|
|
150088
|
+
if (typeof orbitAny.setInputControls === 'function') {
|
|
150089
|
+
// Enable zoom, disable orbit and pan
|
|
150090
|
+
orbitAny.setInputControls({ orbit: false, pan: false, zoom: true });
|
|
150022
150091
|
}
|
|
150023
150092
|
}
|
|
150024
150093
|
this.entities.camera.setPosition(0, 0, 10);
|