@terraware/web-components 5.0.27-rc.0 → 5.0.27
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 +22 -19
- package/components/Autocomplete/Autocomplete.js +130 -106
- package/components/Badge/index.js +29 -28
- package/components/BusySpinner/index.js +45 -40
- package/components/Button/Button.js +47 -41
- package/components/Checkbox.js +63 -64
- package/components/Confirm/index.js +83 -74
- package/components/DatePicker/DatePicker.js +141 -138
- package/components/DialogBox/DialogBox.js +118 -111
- package/components/Divisor.js +18 -18
- package/components/Dropdown.js +94 -66
- package/components/EditableTable/index.js +271 -211
- package/components/ErrorBox/ErrorBox.js +49 -47
- package/components/FileChooser/index.js +135 -117
- package/components/FormBottomBar/index.js +84 -75
- package/components/Icon/Icon.js +20 -12
- package/components/Icon/icons/index.js +256 -256
- package/components/IconTooltip/index.js +60 -49
- package/components/Map/MapBox.js +452 -545
- package/components/Map/MapContainer.js +29 -25
- package/components/Map/MapDateSliderControl.js +64 -64
- package/components/Map/MapDrawer.js +47 -41
- package/components/Map/MapLegend.js +172 -176
- package/components/Map/MapViewStyleControl.js +63 -59
- package/components/Map/ReactMapboxWrapper.js +2 -3
- package/components/Map/index.js +180 -161
- package/components/Map/types.js +17 -12
- package/components/Map/useMaintainLayerOrder.js +26 -16
- package/components/Markdown/index.js +26 -25
- package/components/Message/Message.js +76 -73
- package/components/MultiSelect/index.js +124 -112
- package/components/Navbar/NavFooter.js +13 -9
- package/components/Navbar/NavItem.js +76 -70
- package/components/Navbar/NavSection.js +19 -17
- package/components/Navbar/Navbar.js +46 -39
- package/components/Navbar/SubNavbar.js +13 -9
- package/components/Note.js +22 -18
- package/components/OverlayModal/OverlayModal.js +63 -56
- package/components/PageForm/index.js +41 -33
- package/components/PhotoChooser/index.js +173 -165
- package/components/PhotosCarousel/PhotoSlide.js +35 -32
- package/components/PhotosCarousel/index.js +85 -80
- package/components/PhotosCarousel/usePhotosCarousel.js +76 -69
- package/components/Pill/index.js +45 -41
- package/components/PillList/index.js +24 -17
- package/components/PlacementWrapper/index.js +59 -38
- package/components/PopoverMenu/Popover.js +85 -68
- package/components/PopoverMenu/index.js +56 -51
- package/components/PopoverMultiSelect/index.js +59 -52
- package/components/ProgressCircle/ProgressCircle.js +32 -28
- package/components/RadioButton.js +19 -17
- package/components/Select/Select.js +15 -13
- package/components/Select/SelectT.js +250 -235
- package/components/Separator/index.js +17 -14
- package/components/Size.js +1 -0
- package/components/Slider/index.js +56 -43
- package/components/SummaryBox.js +72 -70
- package/components/Tabs/index.js +135 -133
- package/components/TextTruncated/index.js +130 -117
- package/components/Textfield/Textfield.js +190 -158
- package/components/Textfield/TruncatedTextArea.js +84 -70
- package/components/TimelineSlider/TimelineMarker.js +30 -25
- package/components/TimelineSlider/TimelineRail.js +11 -8
- package/components/TimelineSlider/index.js +66 -64
- package/components/TimelineSliderV2/ClusterBadge.js +29 -25
- package/components/TimelineSliderV2/TimelineDot.js +35 -31
- package/components/TimelineSliderV2/TimelineRail.js +11 -8
- package/components/TimelineSliderV2/index.js +103 -121
- package/components/TimelineSliderV2/layout.js +147 -124
- package/components/TimelineSliderV2/types.js +1 -0
- package/components/Tooltip/Tooltip.js +56 -47
- package/components/ViewPhotosDialog/index.js +35 -28
- package/components/VirtualWalkthrough/Annotation.js +207 -163
- package/components/VirtualWalkthrough/AnnotationEditPane.js +184 -198
- package/components/VirtualWalkthrough/AnnotationPanel.js +199 -187
- package/components/VirtualWalkthrough/Application.js +34 -31
- package/components/VirtualWalkthrough/AutoRotator.js +223 -85
- package/components/VirtualWalkthrough/BlockingSpinner.js +28 -26
- package/components/VirtualWalkthrough/BoundaryRing.js +34 -30
- package/components/VirtualWalkthrough/BoundaryWall.js +36 -32
- package/components/VirtualWalkthrough/CameraInfo.js +89 -100
- package/components/VirtualWalkthrough/ControlsInfoPane.js +195 -254
- package/components/VirtualWalkthrough/GradientSky.js +73 -72
- package/components/VirtualWalkthrough/SplatControls.js +221 -209
- package/components/VirtualWalkthrough/SplatCrop.js +20 -21
- package/components/VirtualWalkthrough/SplatFadeCrop.js +20 -21
- package/components/VirtualWalkthrough/SplatModel.js +85 -65
- package/components/VirtualWalkthrough/SplatRevealRain.js +46 -41
- package/components/VirtualWalkthrough/TfAnnotationManager.js +379 -197
- package/components/VirtualWalkthrough/TfXrNavigation.js +162 -73
- package/components/VirtualWalkthrough/VirtualWalkthroughViewer.js +431 -438
- package/components/VirtualWalkthrough/VrAnnotationPanel.js +22 -18
- package/components/VirtualWalkthrough/XrAnnotationInteraction.js +17 -14
- package/components/VirtualWalkthrough/XrExitButton.js +17 -14
- package/components/VirtualWalkthrough/XrGazeDwell.js +17 -14
- package/components/VirtualWalkthrough/XrPointerRay.js +17 -14
- package/components/VirtualWalkthrough/XrStartPose.js +121 -67
- package/components/VirtualWalkthrough/boundary-ring.js +117 -87
- package/components/VirtualWalkthrough/boundary-wall.js +258 -175
- package/components/VirtualWalkthrough/camera-adoption.js +64 -18
- package/components/VirtualWalkthrough/groundPlane.js +47 -32
- package/components/VirtualWalkthrough/gsplat-fade-crop-effect.js +35 -35
- package/components/VirtualWalkthrough/splatFormat.js +47 -13
- package/components/VirtualWalkthrough/useAdoptedCamera.js +44 -23
- package/components/VirtualWalkthrough/useRestartOnVr.js +37 -26
- package/components/VirtualWalkthrough/useXrRenderTuning.js +54 -33
- package/components/VirtualWalkthrough/vr-annotation-panel-layout.js +99 -67
- package/components/VirtualWalkthrough/vr-annotation-panel.js +433 -403
- package/components/VirtualWalkthrough/vr-annotation-scroll.js +28 -10
- package/components/VirtualWalkthrough/walkthrough-camera.js +329 -204
- package/components/VirtualWalkthrough/xr-annotation-candidate-buffer.js +80 -39
- package/components/VirtualWalkthrough/xr-annotation-candidates.js +18 -6
- package/components/VirtualWalkthrough/xr-annotation-interaction.js +56 -31
- package/components/VirtualWalkthrough/xr-annotation-targeting.js +38 -22
- package/components/VirtualWalkthrough/xr-button-arming.js +17 -7
- package/components/VirtualWalkthrough/xr-button-hold.js +36 -22
- package/components/VirtualWalkthrough/xr-exit-button-mask.js +36 -22
- package/components/VirtualWalkthrough/xr-exit-button.js +207 -148
- package/components/VirtualWalkthrough/xr-face-buttons.js +29 -19
- package/components/VirtualWalkthrough/xr-gaze-dwell-state.js +34 -23
- package/components/VirtualWalkthrough/xr-gaze-dwell.js +144 -107
- package/components/VirtualWalkthrough/xr-interactive-ui.js +24 -12
- package/components/VirtualWalkthrough/xr-pointer-ray.js +20 -13
- package/components/VirtualWalkthrough/xr-progress-pie-material.js +88 -117
- package/components/VirtualWalkthrough/xr-progress-pie.js +10 -1
- package/components/VirtualWalkthrough/xr-ray-quad.js +30 -16
- package/components/VirtualWalkthrough/xr-render-tuning.js +48 -17
- package/components/VirtualWalkthrough/xr-scene-bounds.js +37 -21
- package/components/VirtualWalkthrough/xr-start-pose.js +73 -27
- package/components/VirtualWalkthrough/xr-teleport-gesture.js +42 -16
- package/components/svg/BlobbyGrayIconImage.js +39 -41
- package/components/svg/BlobbyGrayIconImport.js +39 -41
- package/components/svg/BlobbyGrayIconUploadToTheCloud.js +39 -41
- package/components/svg/BlobbyIconCloudChecked.js +164 -202
- package/components/svg/BlobbyIconExportOrUploadPhoto.js +164 -202
- package/components/svg/BlobbyIconFolder.js +164 -202
- package/components/svg/BlobbyIconGraphReport.js +164 -202
- package/components/svg/BlobbyIconHappy.js +164 -202
- package/components/svg/BlobbyIconHeartMonitor.js +164 -202
- package/components/svg/BlobbyIconLeaf.js +164 -202
- package/components/svg/BlobbyIconLibrary.js +164 -202
- package/components/svg/BlobbyIconNursery.js +166 -204
- package/components/svg/BlobbyIconOrganization.js +164 -202
- package/components/svg/BlobbyIconParchment.js +164 -202
- package/components/svg/BlobbyIconPeople.js +164 -202
- package/components/svg/BlobbyIconSeedBank.js +164 -202
- package/components/svg/BlobbyIconSeedling.js +164 -202
- package/components/svg/BlobbyIconSeeds.js +164 -202
- package/components/svg/BlobbyIconSite.js +167 -206
- package/components/svg/BlobbyIconSparkles.js +164 -202
- package/components/svg/BlobbyIconWrench.js +164 -202
- package/components/svg/Bug.js +21 -19
- package/components/svg/Calendar.js +21 -19
- package/components/svg/CaretDown.js +21 -19
- package/components/svg/CaretLeft.js +21 -19
- package/components/svg/CaretRight.js +21 -19
- package/components/svg/CaretUp.js +21 -19
- package/components/svg/ChevronDown.js +21 -19
- package/components/svg/ChevronUp.js +21 -19
- package/components/svg/Close.js +21 -19
- package/components/svg/Critical.js +21 -19
- package/components/svg/Edit.js +164 -202
- package/components/svg/Error.js +21 -19
- package/components/svg/Filter.js +21 -19
- package/components/svg/Folder.js +21 -19
- package/components/svg/Help.js +21 -19
- package/components/svg/Home.js +21 -19
- package/components/svg/IconAdd.js +21 -19
- package/components/svg/IconArrowRight.js +23 -21
- package/components/svg/IconBusinessNetwork.js +21 -19
- package/components/svg/IconCalendar.js +21 -19
- package/components/svg/IconCancel.js +21 -19
- package/components/svg/IconChargingBattery.js +21 -19
- package/components/svg/IconChecklist.js +23 -21
- package/components/svg/IconCheckmark.js +21 -19
- package/components/svg/IconCoinInHand.js +21 -19
- package/components/svg/IconColumns.js +21 -19
- package/components/svg/IconComment.js +22 -20
- package/components/svg/IconDashboard.js +21 -19
- package/components/svg/IconDataMigration.js +21 -19
- package/components/svg/IconDocument.js +23 -21
- package/components/svg/IconDownloadFromTheCloud.js +23 -21
- package/components/svg/IconEdit.js +23 -21
- package/components/svg/IconExpand.js +23 -21
- package/components/svg/IconExport.js +21 -19
- package/components/svg/IconExternalLink.js +21 -19
- package/components/svg/IconEye.js +21 -19
- package/components/svg/IconEyeOff.js +21 -19
- package/components/svg/IconFile.js +21 -19
- package/components/svg/IconFolder.js +21 -19
- package/components/svg/IconFullScreen.js +22 -20
- package/components/svg/IconFutures.js +21 -19
- package/components/svg/IconGraphReport.js +21 -19
- package/components/svg/IconGrid.js +21 -19
- package/components/svg/IconHeartMonitor.js +21 -19
- package/components/svg/IconHelp.js +23 -21
- package/components/svg/IconHistory.js +21 -19
- package/components/svg/IconImport.js +21 -19
- package/components/svg/IconIndex.js +21 -19
- package/components/svg/IconLayers.js +21 -19
- package/components/svg/IconLibrary.js +22 -20
- package/components/svg/IconList.js +21 -19
- package/components/svg/IconLivePlant.js +21 -19
- package/components/svg/IconLocations.js +21 -19
- package/components/svg/IconMail.js +21 -19
- package/components/svg/IconManager.js +21 -19
- package/components/svg/IconMap.js +21 -19
- package/components/svg/IconMarker.js +21 -19
- package/components/svg/IconMenu.js +21 -19
- package/components/svg/IconMenuHorizontal.js +21 -19
- package/components/svg/IconModule.js +21 -19
- package/components/svg/IconMyLocation.js +21 -19
- package/components/svg/IconNote.js +23 -21
- package/components/svg/IconNursery.js +23 -21
- package/components/svg/IconOrg.js +21 -19
- package/components/svg/IconParchment.js +21 -19
- package/components/svg/IconPhoto.js +21 -19
- package/components/svg/IconPlantsFilled.js +21 -19
- package/components/svg/IconRedo.js +21 -19
- package/components/svg/IconRestorationSite.js +21 -19
- package/components/svg/IconSeedBank.js +21 -19
- package/components/svg/IconSeedling.js +21 -19
- package/components/svg/IconSettings.js +21 -19
- package/components/svg/IconSlice.js +21 -19
- package/components/svg/IconSubmit.js +21 -19
- package/components/svg/IconSubtract.js +23 -21
- package/components/svg/IconSynced.js +21 -19
- package/components/svg/IconTrashCan.js +21 -19
- package/components/svg/IconTreasureMap.js +21 -19
- package/components/svg/IconUnavailable.js +21 -19
- package/components/svg/IconUndo.js +21 -19
- package/components/svg/IconVariable.js +21 -19
- package/components/svg/IconVideo.js +31 -30
- package/components/svg/IconWifi.js +21 -19
- package/components/svg/Info.js +21 -19
- package/components/svg/Key.js +21 -19
- package/components/svg/Leaf.js +21 -19
- package/components/svg/Lock.js +21 -19
- package/components/svg/Logo.js +43 -48
- package/components/svg/MenuVertical.js +21 -19
- package/components/svg/Notification.js +21 -19
- package/components/svg/Person.js +21 -19
- package/components/svg/Plus.js +21 -19
- package/components/svg/RestorationSite.js +21 -19
- package/components/svg/Search.js +21 -19
- package/components/svg/Seeds.js +21 -19
- package/components/svg/Site.js +21 -19
- package/components/svg/Sparkles.js +21 -19
- package/components/svg/Species.js +21 -19
- package/components/svg/Species2.js +164 -202
- package/components/svg/Spinner.js +48 -54
- package/components/svg/Star.js +21 -19
- package/components/svg/Success.js +21 -19
- package/components/svg/SuccessFilled.js +21 -19
- package/components/svg/TerrawareLogoDesktop.js +49 -55
- package/components/svg/TerrawareLogoMobile.js +26 -25
- package/components/svg/Touchscreen.js +21 -19
- package/components/svg/UploadCloud.js +164 -202
- package/components/svg/Warning.js +21 -19
- package/components/svg/WelcomeClipboard.js +133 -156
- package/components/svg/index.js +129 -129
- package/components/table/EnhancedTableToolbar.js +74 -68
- package/components/table/EnhancedTableToolbarV2.js +41 -31
- package/components/table/TableCellRenderer.js +231 -196
- package/components/table/TableHeader.js +73 -71
- package/components/table/TableHeaderItem.js +102 -97
- package/components/table/density.js +19 -18
- package/components/table/index.js +369 -350
- package/components/table/sort.js +52 -27
- package/components/table/types.js +1 -0
- package/components/types/index.js +1 -0
- package/hooks/cameraEntityContext.js +13 -2
- package/hooks/useBoolean.js +13 -17
- package/hooks/useCameraPosition.js +56 -56
- package/hooks/useDevicePerformance.js +17 -17
- package/hooks/useXr.js +87 -85
- package/index.js +58 -58
- package/package.json +1 -1
- package/setupTests.js +4 -0
- package/strings/export.js +170 -111
- package/strings/index.js +54 -25
- package/strings/locales.js +41 -21
- package/strings/strings-en.js +51 -49
- package/strings/strings-es.js +51 -49
- package/strings/strings-fr.js +51 -49
- package/strings/strings-gx.js +51 -49
- package/style-dictionary-dist/TerrawareTheme.js +186 -186
- package/theme.js +76 -74
- package/utils/color.js +15 -8
- package/utils/date.js +108 -42
- package/utils/index.js +4 -4
- package/utils/preventDefaultEvent.js +3 -3
- package/utils/text.js +11 -11
- package/utils/useDeviceInfo.js +79 -42
- package/virtualWalkthrough.js +23 -23
|
@@ -1,18 +1,22 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
1
|
+
import 'react';
|
|
2
|
+
import { Entity } from '@playcanvas/react';
|
|
3
|
+
import { Script } from '@playcanvas/react/components';
|
|
4
|
+
import { VrAnnotationPanel as VrAnnotationPanel$1 } from './vr-annotation-panel.js';
|
|
5
|
+
import { jsx } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
const VrAnnotationPanel = ({
|
|
8
|
+
annotation,
|
|
9
|
+
annotationIndex
|
|
10
|
+
}) => /*#__PURE__*/jsx(Entity, {
|
|
11
|
+
name: "vr-annotation-panel",
|
|
12
|
+
children: /*#__PURE__*/jsx(Script, {
|
|
13
|
+
script: VrAnnotationPanel$1,
|
|
14
|
+
title: annotation.title,
|
|
15
|
+
label: annotation.label,
|
|
16
|
+
bodyText: annotation.bodyText,
|
|
17
|
+
imageUrls: annotation.imageUrls,
|
|
18
|
+
annotationIndex: annotationIndex
|
|
19
|
+
})
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
export { VrAnnotationPanel as default };
|
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
import 'react';
|
|
2
|
+
import { Entity } from '@playcanvas/react';
|
|
3
|
+
import { Script } from '@playcanvas/react/components';
|
|
4
|
+
import { XrAnnotationInteraction as XrAnnotationInteraction$1 } from './xr-annotation-interaction.js';
|
|
5
|
+
import { jsx } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
const XrAnnotationInteraction = ({
|
|
8
|
+
onDismiss
|
|
9
|
+
}) => /*#__PURE__*/jsx(Entity, {
|
|
10
|
+
name: "xr-annotation-interaction",
|
|
11
|
+
children: /*#__PURE__*/jsx(Script, {
|
|
12
|
+
script: XrAnnotationInteraction$1,
|
|
13
|
+
onDismissCallback: onDismiss
|
|
14
|
+
})
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export { XrAnnotationInteraction as default };
|
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
import 'react';
|
|
2
|
+
import { Entity } from '@playcanvas/react';
|
|
3
|
+
import { Script } from '@playcanvas/react/components';
|
|
4
|
+
import { XrExitButton as XrExitButton$1 } from './xr-exit-button.js';
|
|
5
|
+
import { jsx } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
const XrExitButton = ({
|
|
8
|
+
onClose
|
|
9
|
+
}) => /*#__PURE__*/jsx(Entity, {
|
|
10
|
+
name: "xr-exit-button",
|
|
11
|
+
children: /*#__PURE__*/jsx(Script, {
|
|
12
|
+
script: XrExitButton$1,
|
|
13
|
+
onClose: onClose
|
|
14
|
+
})
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export { XrExitButton as default };
|
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
import 'react';
|
|
2
|
+
import { Entity } from '@playcanvas/react';
|
|
3
|
+
import { Script } from '@playcanvas/react/components';
|
|
4
|
+
import { XrGazeDwell as XrGazeDwell$1 } from './xr-gaze-dwell.js';
|
|
5
|
+
import { jsx } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
const XrGazeDwell = ({
|
|
8
|
+
activeIndex
|
|
9
|
+
}) => /*#__PURE__*/jsx(Entity, {
|
|
10
|
+
name: "xr-gaze-dwell",
|
|
11
|
+
children: /*#__PURE__*/jsx(Script, {
|
|
12
|
+
script: XrGazeDwell$1,
|
|
13
|
+
activeIndex: activeIndex
|
|
14
|
+
})
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export { XrGazeDwell as default };
|
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
import 'react';
|
|
2
|
+
import { Entity } from '@playcanvas/react';
|
|
3
|
+
import { Script } from '@playcanvas/react/components';
|
|
4
|
+
import { DEFAULT_RAY_COLOR, XrPointerRay as XrPointerRay$1 } from './xr-pointer-ray.js';
|
|
5
|
+
import { jsx } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
const XrPointerRay = ({
|
|
8
|
+
color = DEFAULT_RAY_COLOR
|
|
9
|
+
}) => /*#__PURE__*/jsx(Entity, {
|
|
10
|
+
name: "xr-pointer-ray",
|
|
11
|
+
children: /*#__PURE__*/jsx(Script, {
|
|
12
|
+
script: XrPointerRay$1,
|
|
13
|
+
color: color
|
|
14
|
+
})
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export { XrPointerRay as default };
|
|
@@ -1,74 +1,128 @@
|
|
|
1
|
-
import { Script,
|
|
2
|
-
import { xrStartRigPose, yawFromBasis } from
|
|
1
|
+
import { Script, XRTYPE_VR, XRTYPE_AR } from 'playcanvas';
|
|
2
|
+
import { xrStartRigPose, yawFromBasis } from './xr-start-pose.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Starts an immersive session at the scene's camera position rather than at the world origin.
|
|
6
|
+
*
|
|
7
|
+
* PlayCanvas overwrites the camera entity's local transform with the head pose every frame, so the
|
|
8
|
+
* head lands wherever the headset's reference space puts it — near (0, 0) for a rig that has never
|
|
9
|
+
* been moved. This script moves the rig on the first frame of a session so the head instead starts
|
|
10
|
+
* at `targetX`/`targetZ` facing `focusX`/`focusZ`.
|
|
11
|
+
*
|
|
12
|
+
* Only XZ is touched: the user stands on the rig floor, which the boundary wall is also built
|
|
13
|
+
* against, so lifting the rig onto the splat's ground plane would put them through it.
|
|
14
|
+
*
|
|
15
|
+
* Attach to the rig entity — the camera's parent, alongside TfXrNavigation, whose bounds clamp
|
|
16
|
+
* pulls the start point back inside the scene bounds when the camera position sits outside them.
|
|
17
|
+
*/
|
|
3
18
|
class XrStartPose extends Script {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
static scriptName = 'xrStartPose';
|
|
20
|
+
|
|
21
|
+
/** World-space X the head should start at, i.e. the viewer's `cameraPosition`. */
|
|
22
|
+
targetX = 0;
|
|
23
|
+
|
|
24
|
+
/** World-space Z the head should start at. */
|
|
25
|
+
targetZ = 0;
|
|
26
|
+
|
|
27
|
+
/** World-space X the head should face from there, i.e. the viewer's `origin`. */
|
|
28
|
+
focusX = 0;
|
|
29
|
+
|
|
30
|
+
/** World-space Z the head should face from there. */
|
|
31
|
+
focusZ = 0;
|
|
32
|
+
|
|
33
|
+
/** Set when a session starts, cleared once the rig has been placed. */
|
|
34
|
+
_pending = false;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Whether the engine has written a head pose for this session yet.
|
|
38
|
+
*/
|
|
39
|
+
_posed = false;
|
|
40
|
+
_onXrStart = () => {
|
|
41
|
+
this._pending = true;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/** Fired from XrManager.update only after the head pose has been written to the camera. */
|
|
45
|
+
_onXrUpdate = () => {
|
|
46
|
+
this._posed = true;
|
|
47
|
+
};
|
|
48
|
+
_onXrEnd = () => {
|
|
49
|
+
this._posed = false;
|
|
50
|
+
};
|
|
51
|
+
initialize() {
|
|
52
|
+
// Covers mounting into a session that is already running as well as the usual mount before one.
|
|
53
|
+
this._pending = this._isXrActive();
|
|
54
|
+
this.app.xr?.on('start', this._onXrStart);
|
|
55
|
+
this.app.xr?.on('update', this._onXrUpdate);
|
|
56
|
+
this.app.xr?.on('end', this._onXrEnd);
|
|
57
|
+
// Script removal fires a 'destroy' event rather than calling a destroy() method, so the
|
|
58
|
+
// teardown has to be registered as a listener or these handlers outlive the script.
|
|
59
|
+
this.once('destroy', () => this._teardown());
|
|
60
|
+
}
|
|
61
|
+
_isXrActive = () => this.app.xr?.active === true && (this.app.xr?.type === XRTYPE_VR || this.app.xr?.type === XRTYPE_AR);
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* The bounds circle to place the start point in, or undefined when nothing is clamping the head.
|
|
65
|
+
* Resolved per call rather than cached: the React wrapper assigns the bounds to the navigation
|
|
66
|
+
* script imperatively, so they can land after this script initializes.
|
|
67
|
+
*/
|
|
68
|
+
_bounds = () => {
|
|
69
|
+
// @ts-expect-error - scripts are added dynamically to the entity
|
|
70
|
+
const navigation = this.entity.script?.tfXrNavigation;
|
|
71
|
+
if (!navigation || navigation.boundsRadius <= 0) {
|
|
72
|
+
return undefined;
|
|
26
73
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return {
|
|
32
|
-
x: navigation.boundsCenter.x,
|
|
33
|
-
z: navigation.boundsCenter.z,
|
|
34
|
-
radius: navigation.boundsRadius
|
|
35
|
-
};
|
|
74
|
+
return {
|
|
75
|
+
x: navigation.boundsCenter.x,
|
|
76
|
+
z: navigation.boundsCenter.z,
|
|
77
|
+
radius: navigation.boundsRadius
|
|
36
78
|
};
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
z: head.z
|
|
48
|
-
},
|
|
49
|
-
headYaw: yawFromBasis(camera.forward, camera.right),
|
|
50
|
-
rig: {
|
|
51
|
-
x: rig.x,
|
|
52
|
-
z: rig.z
|
|
53
|
-
},
|
|
54
|
-
target: {
|
|
55
|
-
x: this.targetX,
|
|
56
|
-
z: this.targetZ
|
|
57
|
-
},
|
|
58
|
-
focus: {
|
|
59
|
-
x: this.focusX,
|
|
60
|
-
z: this.focusZ
|
|
61
|
-
},
|
|
62
|
-
bounds: this._bounds()
|
|
63
|
-
});
|
|
64
|
-
this.entity.rotate(0, pose.yawDelta, 0);
|
|
65
|
-
this.entity.setPosition(pose.x, rigY, pose.z);
|
|
66
|
-
this._pending = false;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Runs in update rather than on the 'start' event: the engine writes the head pose during
|
|
83
|
+
* xr.update, which precedes the script update in the same tick, so a frame that has posed is the
|
|
84
|
+
* first point at which there is a real head to solve the rig pose from.
|
|
85
|
+
*/
|
|
86
|
+
update() {
|
|
87
|
+
if (!this._pending || !this._posed || !this._isXrActive()) {
|
|
88
|
+
return;
|
|
67
89
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
this.app.xr?.off('end', this._onXrEnd);
|
|
90
|
+
const camera = this.entity.findComponent('camera')?.entity;
|
|
91
|
+
if (!camera) {
|
|
92
|
+
return;
|
|
72
93
|
}
|
|
94
|
+
const head = camera.getPosition();
|
|
95
|
+
const rig = this.entity.getPosition();
|
|
96
|
+
const rigY = rig.y;
|
|
97
|
+
const pose = xrStartRigPose({
|
|
98
|
+
head: {
|
|
99
|
+
x: head.x,
|
|
100
|
+
z: head.z
|
|
101
|
+
},
|
|
102
|
+
headYaw: yawFromBasis(camera.forward, camera.right),
|
|
103
|
+
rig: {
|
|
104
|
+
x: rig.x,
|
|
105
|
+
z: rig.z
|
|
106
|
+
},
|
|
107
|
+
target: {
|
|
108
|
+
x: this.targetX,
|
|
109
|
+
z: this.targetZ
|
|
110
|
+
},
|
|
111
|
+
focus: {
|
|
112
|
+
x: this.focusX,
|
|
113
|
+
z: this.focusZ
|
|
114
|
+
},
|
|
115
|
+
bounds: this._bounds()
|
|
116
|
+
});
|
|
117
|
+
this.entity.rotate(0, pose.yawDelta, 0);
|
|
118
|
+
this.entity.setPosition(pose.x, rigY, pose.z);
|
|
119
|
+
this._pending = false;
|
|
120
|
+
}
|
|
121
|
+
_teardown() {
|
|
122
|
+
this.app.xr?.off('start', this._onXrStart);
|
|
123
|
+
this.app.xr?.off('update', this._onXrUpdate);
|
|
124
|
+
this.app.xr?.off('end', this._onXrEnd);
|
|
125
|
+
}
|
|
73
126
|
}
|
|
127
|
+
|
|
74
128
|
export { XrStartPose };
|
|
@@ -1,97 +1,127 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { computeGroundPlane, yOnPlane } from
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const a1 = a0 + on;
|
|
23
|
-
const base = 4 * i;
|
|
24
|
-
pushVertex(innerR, a0);
|
|
25
|
-
pushVertex(outerR, a0);
|
|
26
|
-
pushVertex(innerR, a1);
|
|
27
|
-
pushVertex(outerR, a1);
|
|
28
|
-
indices.push(base, base + 1, base + 3, base, base + 3, base + 2);
|
|
29
|
-
}
|
|
1
|
+
import { Script, Vec3, Color, StandardMaterial, CULLFACE_NONE, Mesh, MeshInstance, LAYERID_IMMEDIATE } from 'playcanvas';
|
|
2
|
+
import { computeGroundPlane, yOnPlane } from './groundPlane.js';
|
|
3
|
+
|
|
4
|
+
/** Flat-array triangle geometry ready for `Mesh.setPositions` / `Mesh.setIndices`. */
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Triangle geometry for a dashed boundary ring laid flat on the ground plane. Each dash is a
|
|
8
|
+
* short band (a quad = two triangles) sweeping from `radius - width / 2` to `radius + width / 2`;
|
|
9
|
+
* every vertex is sampled on the circle in XZ and lifted onto the plane via `yOnPlane`.
|
|
10
|
+
* Returns empty arrays when radius, width, or dashCount is non-positive, or the plane is invalid.
|
|
11
|
+
*/
|
|
12
|
+
const boundaryRingMesh = ({
|
|
13
|
+
center,
|
|
14
|
+
radius,
|
|
15
|
+
groundPlane,
|
|
16
|
+
width,
|
|
17
|
+
dashCount = 64,
|
|
18
|
+
dashRatio = 0.5
|
|
19
|
+
}) => {
|
|
20
|
+
const plane = computeGroundPlane(groundPlane);
|
|
21
|
+
if (radius <= 0 || width <= 0 || dashCount <= 0 || !plane) {
|
|
30
22
|
return {
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
positions: [],
|
|
24
|
+
indices: []
|
|
33
25
|
};
|
|
26
|
+
}
|
|
27
|
+
const innerR = radius - width / 2;
|
|
28
|
+
const outerR = radius + width / 2;
|
|
29
|
+
const step = Math.PI * 2 / dashCount;
|
|
30
|
+
const on = step * dashRatio;
|
|
31
|
+
const positions = [];
|
|
32
|
+
const indices = [];
|
|
33
|
+
const pushVertex = (r, angle) => {
|
|
34
|
+
const x = center.x + r * Math.cos(angle);
|
|
35
|
+
const z = center.z + r * Math.sin(angle);
|
|
36
|
+
positions.push(x, yOnPlane(x, z, plane.normal, plane.point, center.y), z);
|
|
37
|
+
};
|
|
38
|
+
for (let i = 0; i < dashCount; i++) {
|
|
39
|
+
const a0 = i * step;
|
|
40
|
+
const a1 = a0 + on;
|
|
41
|
+
const base = i * 4;
|
|
42
|
+
// Per dash: v0 inner@a0, v1 outer@a0, v2 inner@a1, v3 outer@a1.
|
|
43
|
+
pushVertex(innerR, a0);
|
|
44
|
+
pushVertex(outerR, a0);
|
|
45
|
+
pushVertex(innerR, a1);
|
|
46
|
+
pushVertex(outerR, a1);
|
|
47
|
+
indices.push(base, base + 1, base + 3, base, base + 3, base + 2);
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
positions,
|
|
51
|
+
indices
|
|
52
|
+
};
|
|
34
53
|
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Draws a dashed boundary ring as a flat band mesh on the ground plane.
|
|
57
|
+
*
|
|
58
|
+
* Rendered as a thin triangle band whose width is a fraction of the radius (`widthRatio`).
|
|
59
|
+
* center / radius / groundPlane are set imperatively by the BoundaryRing component (see BoundaryRing.tsx for why
|
|
60
|
+
* they are not reactive Script props), which calls `rebuild()` after updating them.
|
|
61
|
+
*/
|
|
35
62
|
class BoundaryRingScript extends Script {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
63
|
+
static scriptName = 'boundaryRing';
|
|
64
|
+
center = new Vec3();
|
|
65
|
+
radius = 0;
|
|
66
|
+
groundPlane = [];
|
|
67
|
+
color = new Color(1, 1, 1);
|
|
68
|
+
dashCount = 64;
|
|
69
|
+
dashRatio = 0.5;
|
|
70
|
+
/** Band width as a fraction of the radius. */
|
|
71
|
+
widthRatio = 0.05;
|
|
72
|
+
initialize() {
|
|
73
|
+
const material = new StandardMaterial();
|
|
74
|
+
material.useLighting = false;
|
|
75
|
+
material.emissive = this.color;
|
|
76
|
+
material.cull = CULLFACE_NONE;
|
|
77
|
+
material.update();
|
|
78
|
+
this._material = material;
|
|
79
|
+
this.rebuild();
|
|
80
|
+
}
|
|
81
|
+
rebuild() {
|
|
82
|
+
this._clearMesh();
|
|
83
|
+
const geometry = boundaryRingMesh({
|
|
84
|
+
center: this.center,
|
|
85
|
+
radius: this.radius,
|
|
86
|
+
groundPlane: this.groundPlane,
|
|
87
|
+
width: this.radius * this.widthRatio,
|
|
88
|
+
dashCount: this.dashCount,
|
|
89
|
+
dashRatio: this.dashRatio
|
|
90
|
+
});
|
|
91
|
+
if (geometry.positions.length === 0 || !this._material) {
|
|
92
|
+
return;
|
|
54
93
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
this._mesh = mesh;
|
|
71
|
-
const meshInstance = new MeshInstance(mesh, this._material);
|
|
72
|
-
if (this.entity.render) this.entity.render.meshInstances = [
|
|
73
|
-
meshInstance
|
|
74
|
-
];
|
|
75
|
-
else this.entity.addComponent('render', {
|
|
76
|
-
meshInstances: [
|
|
77
|
-
meshInstance
|
|
78
|
-
],
|
|
79
|
-
layers: [
|
|
80
|
-
LAYERID_IMMEDIATE
|
|
81
|
-
]
|
|
82
|
-
});
|
|
94
|
+
const mesh = new Mesh(this.app.graphicsDevice);
|
|
95
|
+
mesh.setPositions(geometry.positions);
|
|
96
|
+
mesh.setIndices(geometry.indices);
|
|
97
|
+
mesh.update();
|
|
98
|
+
this._mesh = mesh;
|
|
99
|
+
const meshInstance = new MeshInstance(mesh, this._material);
|
|
100
|
+
if (this.entity.render) {
|
|
101
|
+
this.entity.render.meshInstances = [meshInstance];
|
|
102
|
+
} else {
|
|
103
|
+
// Render on the Immediate layer (drawn after the World layer where the splats render) so
|
|
104
|
+
// the ring is not composited behind them.
|
|
105
|
+
this.entity.addComponent('render', {
|
|
106
|
+
meshInstances: [meshInstance],
|
|
107
|
+
layers: [LAYERID_IMMEDIATE]
|
|
108
|
+
});
|
|
83
109
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
this._mesh = void 0;
|
|
89
|
-
}
|
|
110
|
+
}
|
|
111
|
+
_clearMesh() {
|
|
112
|
+
if (this.entity.render) {
|
|
113
|
+
this.entity.render.meshInstances = [];
|
|
90
114
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
this._material = void 0;
|
|
115
|
+
if (this._mesh) {
|
|
116
|
+
this._mesh.destroy();
|
|
117
|
+
this._mesh = undefined;
|
|
95
118
|
}
|
|
119
|
+
}
|
|
120
|
+
destroy() {
|
|
121
|
+
this._clearMesh();
|
|
122
|
+
this._material?.destroy();
|
|
123
|
+
this._material = undefined;
|
|
124
|
+
}
|
|
96
125
|
}
|
|
126
|
+
|
|
97
127
|
export { BoundaryRingScript, boundaryRingMesh };
|