@terraware/web-components 5.0.27 → 5.1.1-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/AntSwitch/index.js +19 -22
- package/components/Autocomplete/Autocomplete.js +106 -130
- package/components/Badge/index.js +28 -29
- package/components/BusySpinner/index.js +40 -45
- package/components/Button/Button.js +41 -47
- package/components/Checkbox.js +64 -63
- package/components/Confirm/index.js +74 -83
- package/components/DatePicker/DatePicker.js +138 -141
- package/components/DialogBox/DialogBox.js +111 -118
- package/components/Divisor.js +18 -18
- package/components/Dropdown.js +66 -94
- package/components/EditableTable/index.js +211 -271
- package/components/ErrorBox/ErrorBox.js +47 -49
- package/components/FileChooser/index.js +117 -135
- package/components/FormBottomBar/index.js +75 -84
- package/components/Icon/Icon.js +12 -20
- package/components/Icon/icons/index.js +256 -256
- package/components/IconTooltip/index.js +49 -60
- package/components/Map/MapBox.js +545 -452
- package/components/Map/MapContainer.js +25 -29
- package/components/Map/MapDateSliderControl.js +64 -64
- package/components/Map/MapDrawer.js +41 -47
- package/components/Map/MapLegend.js +176 -172
- package/components/Map/MapViewStyleControl.js +59 -63
- package/components/Map/ReactMapboxWrapper.js +3 -2
- package/components/Map/index.js +161 -180
- package/components/Map/types.js +12 -17
- package/components/Map/useMaintainLayerOrder.js +16 -26
- package/components/Markdown/index.js +25 -26
- package/components/Message/Message.js +73 -76
- package/components/MultiSelect/index.js +112 -124
- package/components/Navbar/NavFooter.js +9 -13
- package/components/Navbar/NavItem.js +70 -76
- package/components/Navbar/NavSection.js +17 -19
- package/components/Navbar/Navbar.js +39 -46
- package/components/Navbar/SubNavbar.js +9 -13
- package/components/Note.js +18 -22
- package/components/OverlayModal/OverlayModal.js +56 -63
- package/components/PageForm/index.js +33 -41
- package/components/PhotoChooser/index.js +165 -173
- package/components/PhotosCarousel/PhotoSlide.js +32 -35
- package/components/PhotosCarousel/index.js +80 -85
- package/components/PhotosCarousel/usePhotosCarousel.js +69 -76
- package/components/Pill/index.js +41 -45
- package/components/PillList/index.js +17 -24
- package/components/PlacementWrapper/index.js +38 -59
- package/components/PopoverMenu/Popover.js +68 -85
- package/components/PopoverMenu/index.js +51 -56
- package/components/PopoverMultiSelect/index.js +52 -59
- package/components/ProgressCircle/ProgressCircle.js +28 -32
- package/components/RadioButton.js +17 -19
- package/components/Select/Select.js +13 -15
- package/components/Select/SelectT.js +235 -250
- package/components/Separator/index.js +14 -17
- package/components/Size.js +0 -1
- package/components/Slider/index.js +43 -56
- package/components/Stepper/index.d.ts +33 -0
- package/components/Stepper/index.d.ts.map +1 -0
- package/components/Stepper/index.js +66 -0
- package/components/SummaryBox.js +70 -72
- package/components/Tabs/index.js +133 -135
- package/components/TextTruncated/index.js +117 -130
- package/components/Textfield/Textfield.js +158 -190
- package/components/Textfield/TruncatedTextArea.js +70 -84
- package/components/TimelineSlider/TimelineMarker.js +25 -30
- package/components/TimelineSlider/TimelineRail.js +8 -11
- package/components/TimelineSlider/index.js +64 -66
- package/components/TimelineSliderV2/ClusterBadge.js +25 -29
- package/components/TimelineSliderV2/TimelineDot.js +31 -35
- package/components/TimelineSliderV2/TimelineRail.js +8 -11
- package/components/TimelineSliderV2/index.js +121 -103
- package/components/TimelineSliderV2/layout.js +124 -147
- package/components/TimelineSliderV2/types.js +0 -1
- package/components/Tooltip/Tooltip.js +47 -56
- package/components/ViewPhotosDialog/index.js +28 -35
- package/components/VirtualWalkthrough/Annotation.js +163 -207
- package/components/VirtualWalkthrough/AnnotationEditPane.js +198 -184
- package/components/VirtualWalkthrough/AnnotationPanel.js +187 -199
- package/components/VirtualWalkthrough/Application.js +31 -34
- package/components/VirtualWalkthrough/AutoRotator.js +85 -223
- package/components/VirtualWalkthrough/BlockingSpinner.js +26 -28
- package/components/VirtualWalkthrough/BoundaryRing.js +30 -34
- package/components/VirtualWalkthrough/BoundaryWall.js +32 -36
- package/components/VirtualWalkthrough/CameraInfo.js +100 -89
- package/components/VirtualWalkthrough/ControlsInfoPane.js +254 -195
- package/components/VirtualWalkthrough/GradientSky.js +72 -73
- package/components/VirtualWalkthrough/SplatControls.js +209 -221
- package/components/VirtualWalkthrough/SplatCrop.js +21 -20
- package/components/VirtualWalkthrough/SplatFadeCrop.js +21 -20
- package/components/VirtualWalkthrough/SplatModel.js +65 -85
- package/components/VirtualWalkthrough/SplatRevealRain.js +41 -46
- package/components/VirtualWalkthrough/TfAnnotationManager.js +197 -379
- package/components/VirtualWalkthrough/TfXrNavigation.js +73 -162
- package/components/VirtualWalkthrough/VirtualWalkthroughViewer.js +438 -431
- package/components/VirtualWalkthrough/VrAnnotationPanel.js +18 -22
- package/components/VirtualWalkthrough/XrAnnotationInteraction.js +14 -17
- package/components/VirtualWalkthrough/XrExitButton.js +14 -17
- package/components/VirtualWalkthrough/XrGazeDwell.js +14 -17
- package/components/VirtualWalkthrough/XrPointerRay.js +14 -17
- package/components/VirtualWalkthrough/XrStartPose.js +67 -121
- package/components/VirtualWalkthrough/boundary-ring.js +87 -117
- package/components/VirtualWalkthrough/boundary-wall.js +175 -258
- package/components/VirtualWalkthrough/camera-adoption.js +18 -64
- package/components/VirtualWalkthrough/groundPlane.js +32 -47
- package/components/VirtualWalkthrough/gsplat-fade-crop-effect.js +35 -35
- package/components/VirtualWalkthrough/splatFormat.js +13 -47
- package/components/VirtualWalkthrough/useAdoptedCamera.js +23 -44
- package/components/VirtualWalkthrough/useRestartOnVr.js +26 -37
- package/components/VirtualWalkthrough/useXrRenderTuning.js +33 -54
- package/components/VirtualWalkthrough/vr-annotation-panel-layout.js +67 -99
- package/components/VirtualWalkthrough/vr-annotation-panel.js +403 -433
- package/components/VirtualWalkthrough/vr-annotation-scroll.js +10 -28
- package/components/VirtualWalkthrough/walkthrough-camera.js +204 -329
- package/components/VirtualWalkthrough/xr-annotation-candidate-buffer.js +39 -80
- package/components/VirtualWalkthrough/xr-annotation-candidates.js +6 -18
- package/components/VirtualWalkthrough/xr-annotation-interaction.js +31 -56
- package/components/VirtualWalkthrough/xr-annotation-targeting.js +22 -38
- package/components/VirtualWalkthrough/xr-button-arming.js +7 -17
- package/components/VirtualWalkthrough/xr-button-hold.js +22 -36
- package/components/VirtualWalkthrough/xr-exit-button-mask.js +22 -36
- package/components/VirtualWalkthrough/xr-exit-button.js +148 -207
- package/components/VirtualWalkthrough/xr-face-buttons.js +19 -29
- package/components/VirtualWalkthrough/xr-gaze-dwell-state.js +23 -34
- package/components/VirtualWalkthrough/xr-gaze-dwell.js +107 -144
- package/components/VirtualWalkthrough/xr-interactive-ui.js +12 -24
- package/components/VirtualWalkthrough/xr-pointer-ray.js +13 -20
- package/components/VirtualWalkthrough/xr-progress-pie-material.js +117 -88
- package/components/VirtualWalkthrough/xr-progress-pie.js +1 -10
- package/components/VirtualWalkthrough/xr-ray-quad.js +16 -30
- package/components/VirtualWalkthrough/xr-render-tuning.js +17 -48
- package/components/VirtualWalkthrough/xr-scene-bounds.js +21 -37
- package/components/VirtualWalkthrough/xr-start-pose.js +27 -73
- package/components/VirtualWalkthrough/xr-teleport-gesture.js +16 -42
- package/components/svg/BlobbyGrayIconImage.js +41 -39
- package/components/svg/BlobbyGrayIconImport.js +41 -39
- package/components/svg/BlobbyGrayIconUploadToTheCloud.js +41 -39
- package/components/svg/BlobbyIconCloudChecked.js +202 -164
- package/components/svg/BlobbyIconExportOrUploadPhoto.js +202 -164
- package/components/svg/BlobbyIconFolder.js +202 -164
- package/components/svg/BlobbyIconGraphReport.js +202 -164
- package/components/svg/BlobbyIconHappy.js +202 -164
- package/components/svg/BlobbyIconHeartMonitor.js +202 -164
- package/components/svg/BlobbyIconLeaf.js +202 -164
- package/components/svg/BlobbyIconLibrary.js +202 -164
- package/components/svg/BlobbyIconNursery.js +204 -166
- package/components/svg/BlobbyIconOrganization.js +202 -164
- package/components/svg/BlobbyIconParchment.js +202 -164
- package/components/svg/BlobbyIconPeople.js +202 -164
- package/components/svg/BlobbyIconSeedBank.js +202 -164
- package/components/svg/BlobbyIconSeedling.js +202 -164
- package/components/svg/BlobbyIconSeeds.js +202 -164
- package/components/svg/BlobbyIconSite.js +206 -167
- package/components/svg/BlobbyIconSparkles.js +202 -164
- package/components/svg/BlobbyIconWrench.js +202 -164
- package/components/svg/Bug.js +19 -21
- package/components/svg/Calendar.js +19 -21
- package/components/svg/CaretDown.js +19 -21
- package/components/svg/CaretLeft.js +19 -21
- package/components/svg/CaretRight.js +19 -21
- package/components/svg/CaretUp.js +19 -21
- package/components/svg/ChevronDown.js +19 -21
- package/components/svg/ChevronUp.js +19 -21
- package/components/svg/Close.js +19 -21
- package/components/svg/Critical.js +19 -21
- package/components/svg/Edit.js +202 -164
- package/components/svg/Error.js +19 -21
- package/components/svg/Filter.js +19 -21
- package/components/svg/Folder.js +19 -21
- package/components/svg/Help.js +19 -21
- package/components/svg/Home.js +19 -21
- package/components/svg/IconAdd.js +19 -21
- package/components/svg/IconArrowRight.js +21 -23
- package/components/svg/IconBusinessNetwork.js +19 -21
- package/components/svg/IconCalendar.js +19 -21
- package/components/svg/IconCancel.js +19 -21
- package/components/svg/IconChargingBattery.js +19 -21
- package/components/svg/IconChecklist.js +21 -23
- package/components/svg/IconCheckmark.js +19 -21
- package/components/svg/IconCoinInHand.js +19 -21
- package/components/svg/IconColumns.js +19 -21
- package/components/svg/IconComment.js +20 -22
- package/components/svg/IconDashboard.js +19 -21
- package/components/svg/IconDataMigration.js +19 -21
- package/components/svg/IconDocument.js +21 -23
- package/components/svg/IconDownloadFromTheCloud.js +21 -23
- package/components/svg/IconEdit.js +21 -23
- package/components/svg/IconExpand.js +21 -23
- package/components/svg/IconExport.js +19 -21
- package/components/svg/IconExternalLink.js +19 -21
- package/components/svg/IconEye.js +19 -21
- package/components/svg/IconEyeOff.js +19 -21
- package/components/svg/IconFile.js +19 -21
- package/components/svg/IconFolder.js +19 -21
- package/components/svg/IconFullScreen.js +20 -22
- package/components/svg/IconFutures.js +19 -21
- package/components/svg/IconGraphReport.js +19 -21
- package/components/svg/IconGrid.js +19 -21
- package/components/svg/IconHeartMonitor.js +19 -21
- package/components/svg/IconHelp.js +21 -23
- package/components/svg/IconHistory.js +19 -21
- package/components/svg/IconImport.js +19 -21
- package/components/svg/IconIndex.js +19 -21
- package/components/svg/IconLayers.js +19 -21
- package/components/svg/IconLibrary.js +20 -22
- package/components/svg/IconList.js +19 -21
- package/components/svg/IconLivePlant.js +19 -21
- package/components/svg/IconLocations.js +19 -21
- package/components/svg/IconMail.js +19 -21
- package/components/svg/IconManager.js +19 -21
- package/components/svg/IconMap.js +19 -21
- package/components/svg/IconMarker.js +19 -21
- package/components/svg/IconMenu.js +19 -21
- package/components/svg/IconMenuHorizontal.js +19 -21
- package/components/svg/IconModule.js +19 -21
- package/components/svg/IconMyLocation.js +19 -21
- package/components/svg/IconNote.js +21 -23
- package/components/svg/IconNursery.js +21 -23
- package/components/svg/IconOrg.js +19 -21
- package/components/svg/IconParchment.js +19 -21
- package/components/svg/IconPhoto.js +19 -21
- package/components/svg/IconPlantsFilled.js +19 -21
- package/components/svg/IconRedo.js +19 -21
- package/components/svg/IconRestorationSite.js +19 -21
- package/components/svg/IconSeedBank.js +19 -21
- package/components/svg/IconSeedling.js +19 -21
- package/components/svg/IconSettings.js +19 -21
- package/components/svg/IconSlice.js +19 -21
- package/components/svg/IconSubmit.js +19 -21
- package/components/svg/IconSubtract.js +21 -23
- package/components/svg/IconSynced.js +19 -21
- package/components/svg/IconTrashCan.js +19 -21
- package/components/svg/IconTreasureMap.js +19 -21
- package/components/svg/IconUnavailable.js +19 -21
- package/components/svg/IconUndo.js +19 -21
- package/components/svg/IconVariable.js +19 -21
- package/components/svg/IconVideo.js +30 -31
- package/components/svg/IconWifi.js +19 -21
- package/components/svg/Info.js +19 -21
- package/components/svg/Key.js +19 -21
- package/components/svg/Leaf.js +19 -21
- package/components/svg/Lock.js +19 -21
- package/components/svg/Logo.js +48 -43
- package/components/svg/MenuVertical.js +19 -21
- package/components/svg/Notification.js +19 -21
- package/components/svg/Person.js +19 -21
- package/components/svg/Plus.js +19 -21
- package/components/svg/RestorationSite.js +19 -21
- package/components/svg/Search.js +19 -21
- package/components/svg/Seeds.js +19 -21
- package/components/svg/Site.js +19 -21
- package/components/svg/Sparkles.js +19 -21
- package/components/svg/Species.js +19 -21
- package/components/svg/Species2.js +202 -164
- package/components/svg/Spinner.js +54 -48
- package/components/svg/Star.js +19 -21
- package/components/svg/Success.js +19 -21
- package/components/svg/SuccessFilled.js +19 -21
- package/components/svg/TerrawareLogoDesktop.js +55 -49
- package/components/svg/TerrawareLogoMobile.js +25 -26
- package/components/svg/Touchscreen.js +19 -21
- package/components/svg/UploadCloud.js +202 -164
- package/components/svg/Warning.js +19 -21
- package/components/svg/WelcomeClipboard.js +156 -133
- package/components/svg/index.js +129 -129
- package/components/table/EnhancedTableToolbar.js +68 -74
- package/components/table/EnhancedTableToolbarV2.js +31 -41
- package/components/table/TableCellRenderer.js +196 -231
- package/components/table/TableHeader.js +71 -73
- package/components/table/TableHeaderItem.js +97 -102
- package/components/table/density.js +18 -19
- package/components/table/index.js +350 -369
- package/components/table/sort.js +27 -52
- package/components/table/types.js +0 -1
- package/components/types/index.js +0 -1
- package/hooks/cameraEntityContext.js +2 -13
- package/hooks/useBoolean.js +17 -13
- package/hooks/useCameraPosition.js +56 -56
- package/hooks/useDevicePerformance.js +17 -17
- package/hooks/useXr.js +85 -87
- package/index.d.ts +3 -1
- package/index.d.ts.map +1 -1
- package/index.js +59 -58
- package/package.json +1 -1
- package/setupTests.js +0 -4
- package/strings/csv/en.csv +1 -0
- package/strings/csv/es.csv +1 -0
- package/strings/csv/fr.csv +1 -0
- package/strings/export.js +111 -170
- package/strings/index.js +25 -54
- package/strings/locales.js +21 -41
- package/strings/strings-en.d.ts +1 -0
- package/strings/strings-en.d.ts.map +1 -1
- package/strings/strings-en.js +50 -51
- package/strings/strings-es.d.ts +1 -0
- package/strings/strings-es.d.ts.map +1 -1
- package/strings/strings-es.js +50 -51
- package/strings/strings-fr.d.ts +1 -0
- package/strings/strings-fr.d.ts.map +1 -1
- package/strings/strings-fr.js +50 -51
- package/strings/strings-gx.d.ts +1 -0
- package/strings/strings-gx.d.ts.map +1 -1
- package/strings/strings-gx.js +50 -51
- package/style-dictionary-dist/TerrawareTheme.js +186 -186
- package/theme.js +74 -76
- package/utils/color.js +8 -15
- package/utils/date.js +42 -108
- package/utils/index.js +4 -4
- package/utils/preventDefaultEvent.js +3 -3
- package/utils/text.js +11 -11
- package/utils/useDeviceInfo.js +42 -79
- package/virtualWalkthrough.js +23 -23
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { Vec3 } from
|
|
2
|
-
import { GSplatShaderEffect } from
|
|
3
|
-
|
|
4
|
-
const shaderGLSL = /* glsl */`
|
|
1
|
+
import { Vec3 } from "playcanvas";
|
|
2
|
+
import { GSplatShaderEffect } from "playcanvas/scripts/esm/gsplat/gsplat-shader-effect.mjs";
|
|
3
|
+
const shaderGLSL = `
|
|
5
4
|
uniform vec3 uAabbMin;
|
|
6
5
|
uniform vec3 uAabbMax;
|
|
7
6
|
uniform float uFadeDistance;
|
|
@@ -44,7 +43,7 @@ void modifySplatColor(vec3 center, inout vec4 color) {
|
|
|
44
43
|
// No color modification needed
|
|
45
44
|
}
|
|
46
45
|
`;
|
|
47
|
-
const shaderWGSL =
|
|
46
|
+
const shaderWGSL = `
|
|
48
47
|
uniform uAabbMin: vec3f;
|
|
49
48
|
uniform uAabbMax: vec3f;
|
|
50
49
|
uniform uFadeDistance: f32;
|
|
@@ -87,36 +86,37 @@ fn modifySplatColor(center: vec3f, color: ptr<function, vec4f>) {
|
|
|
87
86
|
// No color modification needed
|
|
88
87
|
}
|
|
89
88
|
`;
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Fade crop shader effect for gaussian splats.
|
|
93
|
-
* Applies a smooth fade to splats outside the AABB based on distance.
|
|
94
|
-
* Splats at the AABB edge are fully visible, and fade to invisible at fadeDistance away.
|
|
95
|
-
*/
|
|
96
89
|
class GsplatFadeCropShaderEffect extends GSplatShaderEffect {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
90
|
+
static scriptName = 'gsplatFadeCropShaderEffect';
|
|
91
|
+
_aabbMinArray = [
|
|
92
|
+
0,
|
|
93
|
+
0,
|
|
94
|
+
0
|
|
95
|
+
];
|
|
96
|
+
_aabbMaxArray = [
|
|
97
|
+
0,
|
|
98
|
+
0,
|
|
99
|
+
0
|
|
100
|
+
];
|
|
101
|
+
aabbMin = new Vec3(-0.5, -0.5, -0.5);
|
|
102
|
+
aabbMax = new Vec3(0.5, 0.5, 0.5);
|
|
103
|
+
fadeDistance = 0.5;
|
|
104
|
+
getShaderGLSL() {
|
|
105
|
+
return shaderGLSL;
|
|
106
|
+
}
|
|
107
|
+
getShaderWGSL() {
|
|
108
|
+
return shaderWGSL;
|
|
109
|
+
}
|
|
110
|
+
updateEffect() {
|
|
111
|
+
this._aabbMinArray[0] = this.aabbMin.x;
|
|
112
|
+
this._aabbMinArray[1] = this.aabbMin.y;
|
|
113
|
+
this._aabbMinArray[2] = this.aabbMin.z;
|
|
114
|
+
this.setUniform('uAabbMin', this._aabbMinArray);
|
|
115
|
+
this._aabbMaxArray[0] = this.aabbMax.x;
|
|
116
|
+
this._aabbMaxArray[1] = this.aabbMax.y;
|
|
117
|
+
this._aabbMaxArray[2] = this.aabbMax.z;
|
|
118
|
+
this.setUniform('uAabbMax', this._aabbMaxArray);
|
|
119
|
+
this.setUniform('uFadeDistance', this.fadeDistance);
|
|
120
|
+
}
|
|
120
121
|
}
|
|
121
|
-
|
|
122
122
|
export { GsplatFadeCropShaderEffect };
|
|
@@ -1,52 +1,18 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* The playcanvas gsplat loader picks its parser from the asset's `filename`, not from the URL it
|
|
3
|
-
* actually downloads, because a splat is frequently served from a signed or extensionless URL. Each
|
|
4
|
-
* supported format therefore maps to a canonical filename whose extension/basename routes the asset
|
|
5
|
-
* to the matching engine parser:
|
|
6
|
-
*
|
|
7
|
-
* model.sog -> SogBundleParser sog packed into a single zip archive
|
|
8
|
-
* meta.json -> SogParser the same sog data left unpacked as separate files
|
|
9
|
-
* lod-meta.json -> GSplatOctreeParser sog with LOD levels, streamed in as the camera moves
|
|
10
|
-
* model.ply -> PlyParser
|
|
11
|
-
*
|
|
12
|
-
* `sog` and `sogUnbundled` are two packagings of one format, not two formats: both parsers build a
|
|
13
|
-
* GSplatSogData/GSplatSogResource and both await every texture before the resource exists. Only
|
|
14
|
-
* `sogStreamed` streams — playcanvas.d.ts on GSplatOctreeResource#numSplats: "Not all of these are
|
|
15
|
-
* resident at runtime: the LOD streaming system selects a subset per node based on view distance and
|
|
16
|
-
* the configured splat budget."
|
|
17
|
-
*
|
|
18
|
-
* Only the filename is faked; the textures an unbundled or streamed sog references are still
|
|
19
|
-
* resolved relative to the real URL, so no rewriting of splatSrc is needed.
|
|
20
|
-
*/
|
|
21
1
|
const LOADER_FILENAMES = {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
2
|
+
sog: 'model.sog',
|
|
3
|
+
sogUnbundled: 'meta.json',
|
|
4
|
+
sogStreamed: 'lod-meta.json',
|
|
5
|
+
ply: 'model.ply'
|
|
26
6
|
};
|
|
27
|
-
/**
|
|
28
|
-
* Format assumed when a URL is too opaque to tell us anything. Kept as the bundled `.sog` archive so
|
|
29
|
-
* that existing extensionless splat URLs keep loading the way they did before the other formats were
|
|
30
|
-
* supported.
|
|
31
|
-
*/
|
|
32
7
|
const DEFAULT_SPLAT_FORMAT = 'sog';
|
|
33
|
-
const splatLoaderFilename = format
|
|
34
|
-
const detectSplatFormat = splatSrc
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return '
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
return
|
|
42
|
-
}
|
|
43
|
-
if (basename.endsWith('.ply')) {
|
|
44
|
-
return 'ply';
|
|
45
|
-
}
|
|
46
|
-
if (basename.endsWith('.sog')) {
|
|
47
|
-
return 'sog';
|
|
48
|
-
}
|
|
49
|
-
return DEFAULT_SPLAT_FORMAT;
|
|
8
|
+
const splatLoaderFilename = (format)=>LOADER_FILENAMES[format];
|
|
9
|
+
const detectSplatFormat = (splatSrc)=>{
|
|
10
|
+
const path = splatSrc.split(/[?#]/)[0];
|
|
11
|
+
const basename = path.slice(path.lastIndexOf('/') + 1).toLowerCase();
|
|
12
|
+
if ('lod-meta.json' === basename) return 'sogStreamed';
|
|
13
|
+
if ('meta.json' === basename) return 'sogUnbundled';
|
|
14
|
+
if (basename.endsWith('.ply')) return 'ply';
|
|
15
|
+
if (basename.endsWith('.sog')) return 'sog';
|
|
16
|
+
return DEFAULT_SPLAT_FORMAT;
|
|
50
17
|
};
|
|
51
|
-
|
|
52
18
|
export { DEFAULT_SPLAT_FORMAT, detectSplatFormat, splatLoaderFilename };
|
|
@@ -1,45 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useApp } from
|
|
3
|
-
import { adoptSceneCamera } from
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
// destroying an entity destroys its children — so a release deferred to a passive effect runs
|
|
22
|
-
// after the host's camera has already been destroyed along with the walkthrough, leaving the host
|
|
23
|
-
// scene with no camera to render through at all.
|
|
24
|
-
//
|
|
25
|
-
// The rig is a child of the viewer, and React tears an unmounting tree's layout effects down from
|
|
26
|
-
// the top, so this runs first.
|
|
27
|
-
useLayoutEffect(() => {
|
|
28
|
-
if (!rig || !ownCamera) {
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// Both entities are state set from refs, so this runs a commit after the child that mounts the
|
|
33
|
-
// camera component: a viewer that was given a camera is recognised as owning one rather than
|
|
34
|
-
// adopted on top of.
|
|
35
|
-
const adoption = adoptSceneCamera(app.root, rig, ownCamera);
|
|
36
|
-
setAdopted(adoption?.camera ?? null);
|
|
37
|
-
return () => {
|
|
38
|
-
adoption?.release();
|
|
39
|
-
setAdopted(null);
|
|
40
|
-
};
|
|
41
|
-
}, [app, rig, ownCamera]);
|
|
42
|
-
return adopted;
|
|
1
|
+
import { useLayoutEffect, useState } from "react";
|
|
2
|
+
import { useApp } from "@playcanvas/react/hooks";
|
|
3
|
+
import { adoptSceneCamera } from "./camera-adoption.js";
|
|
4
|
+
const useAdoptedCamera = (rig, ownCamera)=>{
|
|
5
|
+
const app = useApp();
|
|
6
|
+
const [adopted, setAdopted] = useState(null);
|
|
7
|
+
useLayoutEffect(()=>{
|
|
8
|
+
if (!rig || !ownCamera) return;
|
|
9
|
+
const adoption = adoptSceneCamera(app.root, rig, ownCamera);
|
|
10
|
+
setAdopted(adoption?.camera ?? null);
|
|
11
|
+
return ()=>{
|
|
12
|
+
adoption?.release();
|
|
13
|
+
setAdopted(null);
|
|
14
|
+
};
|
|
15
|
+
}, [
|
|
16
|
+
app,
|
|
17
|
+
rig,
|
|
18
|
+
ownCamera
|
|
19
|
+
]);
|
|
20
|
+
return adopted;
|
|
43
21
|
};
|
|
44
|
-
|
|
45
|
-
export
|
|
22
|
+
const VirtualWalkthrough_useAdoptedCamera = useAdoptedCamera;
|
|
23
|
+
export default VirtualWalkthrough_useAdoptedCamera;
|
|
24
|
+
export { useAdoptedCamera };
|
|
@@ -1,38 +1,27 @@
|
|
|
1
|
-
import { useEffect } from
|
|
2
|
-
import { useApp } from
|
|
3
|
-
import { XRTYPE_VR } from
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const script = scriptRef.current;
|
|
25
|
-
if (!script || xr.type !== XRTYPE_VR) {
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
script.enabled = false;
|
|
29
|
-
script.enabled = true;
|
|
30
|
-
};
|
|
31
|
-
xr.on('start', restart);
|
|
32
|
-
return () => {
|
|
33
|
-
xr.off('start', restart);
|
|
34
|
-
};
|
|
35
|
-
}, [app, enabled, scriptRef]);
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
import { useApp } from "@playcanvas/react/hooks";
|
|
3
|
+
import { XRTYPE_VR } from "playcanvas";
|
|
4
|
+
const useRestartOnVr = (scriptRef, enabled)=>{
|
|
5
|
+
const app = useApp();
|
|
6
|
+
useEffect(()=>{
|
|
7
|
+
const xr = app?.xr;
|
|
8
|
+
if (!xr || !enabled) return;
|
|
9
|
+
const restart = ()=>{
|
|
10
|
+
const script = scriptRef.current;
|
|
11
|
+
if (!script || xr.type !== XRTYPE_VR) return;
|
|
12
|
+
script.enabled = false;
|
|
13
|
+
script.enabled = true;
|
|
14
|
+
};
|
|
15
|
+
xr.on('start', restart);
|
|
16
|
+
return ()=>{
|
|
17
|
+
xr.off('start', restart);
|
|
18
|
+
};
|
|
19
|
+
}, [
|
|
20
|
+
app,
|
|
21
|
+
enabled,
|
|
22
|
+
scriptRef
|
|
23
|
+
]);
|
|
36
24
|
};
|
|
37
|
-
|
|
38
|
-
export
|
|
25
|
+
const VirtualWalkthrough_useRestartOnVr = useRestartOnVr;
|
|
26
|
+
export default VirtualWalkthrough_useRestartOnVr;
|
|
27
|
+
export { useRestartOnVr };
|
|
@@ -1,55 +1,34 @@
|
|
|
1
|
-
import { useEffect } from
|
|
2
|
-
import { useApp } from
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
previous = applyGsplatTuning(app.scene.gsplat);
|
|
32
|
-
}
|
|
33
|
-
// Only settable on an active session, so it cannot go in the start options alongside
|
|
34
|
-
// framebufferScaleFactor. A no-op when the presentation layer doesn't support it.
|
|
35
|
-
xr.fixedFoveation = XR_FIXED_FOVEATION;
|
|
36
|
-
};
|
|
37
|
-
xr.on('start', handleStart);
|
|
38
|
-
xr.on('end', restore);
|
|
39
|
-
|
|
40
|
-
// A viewer can be mounted into a scene that is already in a headset, in which case `start`
|
|
41
|
-
// fired before this hook existed and waiting for it would leave the whole session rendering
|
|
42
|
-
// with the desktop settings. `handleStart` is idempotent, so a session that goes on to fire
|
|
43
|
-
// `start` anyway does not capture the tuned values as the ones to restore.
|
|
44
|
-
if (xr.active) {
|
|
45
|
-
handleStart();
|
|
46
|
-
}
|
|
47
|
-
return () => {
|
|
48
|
-
xr.off('start', handleStart);
|
|
49
|
-
xr.off('end', restore);
|
|
50
|
-
restore();
|
|
51
|
-
};
|
|
52
|
-
}, [app]);
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
import { useApp } from "@playcanvas/react/hooks";
|
|
3
|
+
import { XR_FIXED_FOVEATION, applyGsplatTuning, restoreGsplatTuning } from "./xr-render-tuning.js";
|
|
4
|
+
const useXrRenderTuning = ()=>{
|
|
5
|
+
const app = useApp();
|
|
6
|
+
useEffect(()=>{
|
|
7
|
+
const xr = app.xr;
|
|
8
|
+
if (!xr) return;
|
|
9
|
+
let previous = null;
|
|
10
|
+
const restore = ()=>{
|
|
11
|
+
if (previous) {
|
|
12
|
+
restoreGsplatTuning(app.scene.gsplat, previous);
|
|
13
|
+
previous = null;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
const handleStart = ()=>{
|
|
17
|
+
if (!previous) previous = applyGsplatTuning(app.scene.gsplat);
|
|
18
|
+
xr.fixedFoveation = XR_FIXED_FOVEATION;
|
|
19
|
+
};
|
|
20
|
+
xr.on('start', handleStart);
|
|
21
|
+
xr.on('end', restore);
|
|
22
|
+
if (xr.active) handleStart();
|
|
23
|
+
return ()=>{
|
|
24
|
+
xr.off('start', handleStart);
|
|
25
|
+
xr.off('end', restore);
|
|
26
|
+
restore();
|
|
27
|
+
};
|
|
28
|
+
}, [
|
|
29
|
+
app
|
|
30
|
+
]);
|
|
53
31
|
};
|
|
54
|
-
|
|
55
|
-
export
|
|
32
|
+
const VirtualWalkthrough_useXrRenderTuning = useXrRenderTuning;
|
|
33
|
+
export default VirtualWalkthrough_useXrRenderTuning;
|
|
34
|
+
export { useXrRenderTuning };
|
|
@@ -1,29 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
current = word;
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
if (current) {
|
|
19
|
-
lines.push(current);
|
|
20
|
-
}
|
|
21
|
-
return lines;
|
|
1
|
+
const wrapText = (text, maxWidth, measure)=>{
|
|
2
|
+
const words = text.split(/\s+/).filter(Boolean);
|
|
3
|
+
const lines = [];
|
|
4
|
+
let current = '';
|
|
5
|
+
words.forEach((word)=>{
|
|
6
|
+
const candidate = current ? `${current} ${word}` : word;
|
|
7
|
+
if (!current || measure(candidate) <= maxWidth) current = candidate;
|
|
8
|
+
else {
|
|
9
|
+
lines.push(current);
|
|
10
|
+
current = word;
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
if (current) lines.push(current);
|
|
14
|
+
return lines;
|
|
22
15
|
};
|
|
23
16
|
const PANEL_CANVAS_WIDTH = 1024;
|
|
24
|
-
/** Tallest the panel can grow; also the canvas the content is painted into. */
|
|
25
17
|
const PANEL_MAX_HEIGHT = 768;
|
|
26
|
-
/** Shortest the panel can shrink, so a bare title still reads as a panel rather than a sliver. */
|
|
27
18
|
const PANEL_MIN_HEIGHT = 200;
|
|
28
19
|
const PANEL_PAD_X = 48;
|
|
29
20
|
const PANEL_PAD_Y = 40;
|
|
@@ -37,86 +28,63 @@ const CHIP_GAP = 24;
|
|
|
37
28
|
const TITLE_LINE_HEIGHT = 56;
|
|
38
29
|
const TITLE_GAP = 16;
|
|
39
30
|
const BODY_LINE_HEIGHT = 40;
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Tallest canvas the body text is rasterised into. The body scrolls as a window onto this canvas,
|
|
43
|
-
* so it bounds how much text an annotation can show — far more than the panel itself holds.
|
|
44
|
-
*/
|
|
45
31
|
const TEXT_CANVAS_MAX_HEIGHT = 2048;
|
|
46
32
|
const PANEL_FONTS = {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
33
|
+
label: '600 28px sans-serif',
|
|
34
|
+
title: '700 48px sans-serif',
|
|
35
|
+
body: '400 32px sans-serif'
|
|
50
36
|
};
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
return lines.slice(0, room);
|
|
37
|
+
const fitLines = (lines, y, lineHeight)=>{
|
|
38
|
+
const room = Math.max(0, Math.floor((PANEL_MAX_HEIGHT - PANEL_PAD_Y - y) / lineHeight));
|
|
39
|
+
return lines.slice(0, room);
|
|
55
40
|
};
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}) => {
|
|
71
|
-
let y = PANEL_PAD_Y;
|
|
72
|
-
const image = imageCount > 0 ? {
|
|
73
|
-
y,
|
|
74
|
-
height: IMAGE_BAND_HEIGHT
|
|
75
|
-
} : null;
|
|
76
|
-
let dotsY = null;
|
|
77
|
-
if (image) {
|
|
78
|
-
y += IMAGE_BAND_HEIGHT + IMAGE_GAP;
|
|
79
|
-
if (imageCount > 1) {
|
|
80
|
-
dotsY = y + DOTS_CENTER_OFFSET;
|
|
81
|
-
y += DOTS_BLOCK_HEIGHT;
|
|
82
|
-
}
|
|
83
|
-
y += IMAGE_GAP;
|
|
84
|
-
}
|
|
85
|
-
const chip = label ? {
|
|
86
|
-
y,
|
|
87
|
-
width: measure(label, 'label') + CHIP_PAD_X * 2,
|
|
88
|
-
height: CHIP_HEIGHT
|
|
89
|
-
} : null;
|
|
90
|
-
if (chip) {
|
|
91
|
-
y += CHIP_HEIGHT + CHIP_GAP;
|
|
92
|
-
}
|
|
93
|
-
const titleLines = wrapText(title, contentWidth, segment => measure(segment, 'title'));
|
|
94
|
-
const fittedTitle = fitLines(titleLines, y, TITLE_LINE_HEIGHT);
|
|
95
|
-
const titleY = y;
|
|
96
|
-
y += fittedTitle.length * TITLE_LINE_HEIGHT + TITLE_GAP;
|
|
97
|
-
const bodyLines = bodyText ? wrapText(bodyText, contentWidth, segment => measure(segment, 'body')) : [];
|
|
98
|
-
const fittedBody = bodyLines.slice(0, Math.floor(TEXT_CANVAS_MAX_HEIGHT / BODY_LINE_HEIGHT));
|
|
99
|
-
const bodyY = y;
|
|
100
|
-
const contentHeight = fittedBody.length * BODY_LINE_HEIGHT;
|
|
101
|
-
const viewportHeight = Math.min(contentHeight, Math.max(0, PANEL_MAX_HEIGHT - PANEL_PAD_Y - bodyY));
|
|
102
|
-
const height = Math.max(PANEL_MIN_HEIGHT, Math.min(PANEL_MAX_HEIGHT, bodyY + viewportHeight + PANEL_PAD_Y));
|
|
103
|
-
return {
|
|
104
|
-
height,
|
|
105
|
-
image,
|
|
106
|
-
dotsY,
|
|
107
|
-
chip,
|
|
108
|
-
title: {
|
|
109
|
-
y: titleY,
|
|
110
|
-
lines: fittedTitle
|
|
111
|
-
},
|
|
112
|
-
body: {
|
|
113
|
-
y: bodyY,
|
|
114
|
-
lines: fittedBody,
|
|
115
|
-
contentHeight,
|
|
116
|
-
viewportHeight,
|
|
117
|
-
scrollable: viewportHeight > 0 && contentHeight > viewportHeight
|
|
41
|
+
const layoutPanel = ({ title, label, bodyText, imageCount, contentWidth, measure })=>{
|
|
42
|
+
let y = PANEL_PAD_Y;
|
|
43
|
+
const image = imageCount > 0 ? {
|
|
44
|
+
y,
|
|
45
|
+
height: IMAGE_BAND_HEIGHT
|
|
46
|
+
} : null;
|
|
47
|
+
let dotsY = null;
|
|
48
|
+
if (image) {
|
|
49
|
+
y += IMAGE_BAND_HEIGHT + IMAGE_GAP;
|
|
50
|
+
if (imageCount > 1) {
|
|
51
|
+
dotsY = y + DOTS_CENTER_OFFSET;
|
|
52
|
+
y += DOTS_BLOCK_HEIGHT;
|
|
53
|
+
}
|
|
54
|
+
y += IMAGE_GAP;
|
|
118
55
|
}
|
|
119
|
-
|
|
56
|
+
const chip = label ? {
|
|
57
|
+
y,
|
|
58
|
+
width: measure(label, 'label') + 2 * CHIP_PAD_X,
|
|
59
|
+
height: CHIP_HEIGHT
|
|
60
|
+
} : null;
|
|
61
|
+
if (chip) y += CHIP_HEIGHT + CHIP_GAP;
|
|
62
|
+
const titleLines = wrapText(title, contentWidth, (segment)=>measure(segment, 'title'));
|
|
63
|
+
const fittedTitle = fitLines(titleLines, y, TITLE_LINE_HEIGHT);
|
|
64
|
+
const titleY = y;
|
|
65
|
+
y += fittedTitle.length * TITLE_LINE_HEIGHT + TITLE_GAP;
|
|
66
|
+
const bodyLines = bodyText ? wrapText(bodyText, contentWidth, (segment)=>measure(segment, 'body')) : [];
|
|
67
|
+
const fittedBody = bodyLines.slice(0, Math.floor(TEXT_CANVAS_MAX_HEIGHT / BODY_LINE_HEIGHT));
|
|
68
|
+
const bodyY = y;
|
|
69
|
+
const contentHeight = fittedBody.length * BODY_LINE_HEIGHT;
|
|
70
|
+
const viewportHeight = Math.min(contentHeight, Math.max(0, PANEL_MAX_HEIGHT - PANEL_PAD_Y - bodyY));
|
|
71
|
+
const height = Math.max(PANEL_MIN_HEIGHT, Math.min(PANEL_MAX_HEIGHT, bodyY + viewportHeight + PANEL_PAD_Y));
|
|
72
|
+
return {
|
|
73
|
+
height,
|
|
74
|
+
image,
|
|
75
|
+
dotsY,
|
|
76
|
+
chip,
|
|
77
|
+
title: {
|
|
78
|
+
y: titleY,
|
|
79
|
+
lines: fittedTitle
|
|
80
|
+
},
|
|
81
|
+
body: {
|
|
82
|
+
y: bodyY,
|
|
83
|
+
lines: fittedBody,
|
|
84
|
+
contentHeight,
|
|
85
|
+
viewportHeight,
|
|
86
|
+
scrollable: viewportHeight > 0 && contentHeight > viewportHeight
|
|
87
|
+
}
|
|
88
|
+
};
|
|
120
89
|
};
|
|
121
|
-
|
|
122
90
|
export { BODY_LINE_HEIGHT, CHIP_HEIGHT, IMAGE_BAND_HEIGHT, PANEL_CANVAS_WIDTH, PANEL_FONTS, PANEL_MAX_HEIGHT, PANEL_MIN_HEIGHT, PANEL_PAD_X, PANEL_PAD_Y, TEXT_CANVAS_MAX_HEIGHT, TITLE_LINE_HEIGHT, layoutPanel, wrapText };
|