@cavegiant/cave-world-r3f 1.0.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/CHANGELOG.md +25 -0
- package/LICENSE +21 -0
- package/README.md +189 -0
- package/dist/core/connector-label/readiness.d.ts +11 -0
- package/dist/core/connector-label/readiness.d.ts.map +1 -0
- package/dist/core/connector-label/readiness.js +31 -0
- package/dist/core/connector-label/readiness.js.map +1 -0
- package/dist/core/connector-label/types.d.ts +64 -0
- package/dist/core/connector-label/types.d.ts.map +1 -0
- package/dist/core/connector-label/types.js +47 -0
- package/dist/core/connector-label/types.js.map +1 -0
- package/dist/core/context/cave-world-context.d.ts +96 -0
- package/dist/core/context/cave-world-context.d.ts.map +1 -0
- package/dist/core/context/cave-world-context.js +100 -0
- package/dist/core/context/cave-world-context.js.map +1 -0
- package/dist/core/errors.d.ts +34 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +17 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/events/event-bus.d.ts +122 -0
- package/dist/core/events/event-bus.d.ts.map +1 -0
- package/dist/core/events/event-bus.js +62 -0
- package/dist/core/events/event-bus.js.map +1 -0
- package/dist/core/hooks/use-cave-event.d.ts +13 -0
- package/dist/core/hooks/use-cave-event.d.ts.map +1 -0
- package/dist/core/hooks/use-cave-event.js +12 -0
- package/dist/core/hooks/use-cave-event.js.map +1 -0
- package/dist/core/i18n/messages.d.ts +82 -0
- package/dist/core/i18n/messages.d.ts.map +1 -0
- package/dist/core/i18n/messages.js +131 -0
- package/dist/core/i18n/messages.js.map +1 -0
- package/dist/core/index.d.ts +11 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +47 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/logging/logger.d.ts +29 -0
- package/dist/core/logging/logger.d.ts.map +1 -0
- package/dist/core/logging/logger.js +47 -0
- package/dist/core/logging/logger.js.map +1 -0
- package/dist/core/registry/component-registry.d.ts +41 -0
- package/dist/core/registry/component-registry.d.ts.map +1 -0
- package/dist/core/registry/component-registry.js +34 -0
- package/dist/core/registry/component-registry.js.map +1 -0
- package/dist/core/registry/object-registry.d.ts +38 -0
- package/dist/core/registry/object-registry.d.ts.map +1 -0
- package/dist/core/registry/object-registry.js +32 -0
- package/dist/core/registry/object-registry.js.map +1 -0
- package/dist/explore/cave-explore.d.ts +85 -0
- package/dist/explore/cave-explore.d.ts.map +1 -0
- package/dist/explore/cave-explore.js +204 -0
- package/dist/explore/cave-explore.js.map +1 -0
- package/dist/explore/cave-orbit-viewer.d.ts +76 -0
- package/dist/explore/cave-orbit-viewer.d.ts.map +1 -0
- package/dist/explore/cave-orbit-viewer.js +123 -0
- package/dist/explore/cave-orbit-viewer.js.map +1 -0
- package/dist/explore/characters/character-configs.d.ts +38 -0
- package/dist/explore/characters/character-configs.d.ts.map +1 -0
- package/dist/explore/characters/character-configs.js +45 -0
- package/dist/explore/characters/character-configs.js.map +1 -0
- package/dist/explore/characters/character-controls.d.ts +44 -0
- package/dist/explore/characters/character-controls.d.ts.map +1 -0
- package/dist/explore/characters/character-pose.d.ts +19 -0
- package/dist/explore/characters/character-pose.d.ts.map +1 -0
- package/dist/explore/characters/character-pose.js +13 -0
- package/dist/explore/characters/character-pose.js.map +1 -0
- package/dist/explore/characters/local-character-model.d.ts +53 -0
- package/dist/explore/characters/local-character-model.d.ts.map +1 -0
- package/dist/explore/characters/local-character-model.js +36 -0
- package/dist/explore/characters/local-character-model.js.map +1 -0
- package/dist/explore/characters/mixamo-style-bone-map.d.ts +9 -0
- package/dist/explore/characters/mixamo-style-bone-map.d.ts.map +1 -0
- package/dist/explore/characters/mixamo-style-bone-map.js +28 -0
- package/dist/explore/characters/mixamo-style-bone-map.js.map +1 -0
- package/dist/explore/characters/remote-character-controller.d.ts +38 -0
- package/dist/explore/characters/remote-character-controller.d.ts.map +1 -0
- package/dist/explore/characters/remote-character-controller.js +135 -0
- package/dist/explore/characters/remote-character-controller.js.map +1 -0
- package/dist/explore/characters/remote-character.d.ts +19 -0
- package/dist/explore/characters/remote-character.d.ts.map +1 -0
- package/dist/explore/characters/remote-character.js +63 -0
- package/dist/explore/characters/remote-character.js.map +1 -0
- package/dist/explore/connected-spaces-renderer.d.ts +16 -0
- package/dist/explore/connected-spaces-renderer.d.ts.map +1 -0
- package/dist/explore/connected-spaces-renderer.js +103 -0
- package/dist/explore/connected-spaces-renderer.js.map +1 -0
- package/dist/explore/hooks/use-action-shortcuts.d.ts +16 -0
- package/dist/explore/hooks/use-action-shortcuts.d.ts.map +1 -0
- package/dist/explore/hooks/use-action-shortcuts.js +23 -0
- package/dist/explore/hooks/use-action-shortcuts.js.map +1 -0
- package/dist/explore/hooks/use-active-space-notify.d.ts +11 -0
- package/dist/explore/hooks/use-active-space-notify.d.ts.map +1 -0
- package/dist/explore/hooks/use-active-space-notify.js +17 -0
- package/dist/explore/hooks/use-active-space-notify.js.map +1 -0
- package/dist/explore/hooks/use-character-sync.d.ts +46 -0
- package/dist/explore/hooks/use-character-sync.d.ts.map +1 -0
- package/dist/explore/hooks/use-character-sync.js +72 -0
- package/dist/explore/hooks/use-character-sync.js.map +1 -0
- package/dist/explore/hooks/use-connector-preloader.d.ts +20 -0
- package/dist/explore/hooks/use-connector-preloader.d.ts.map +1 -0
- package/dist/explore/hooks/use-connector-preloader.js +78 -0
- package/dist/explore/hooks/use-connector-preloader.js.map +1 -0
- package/dist/explore/hooks/use-connector-transitions.d.ts +31 -0
- package/dist/explore/hooks/use-connector-transitions.d.ts.map +1 -0
- package/dist/explore/hooks/use-connector-transitions.js +63 -0
- package/dist/explore/hooks/use-connector-transitions.js.map +1 -0
- package/dist/explore/hooks/use-explore-actions.d.ts +17 -0
- package/dist/explore/hooks/use-explore-actions.d.ts.map +1 -0
- package/dist/explore/hooks/use-explore-actions.js +134 -0
- package/dist/explore/hooks/use-explore-actions.js.map +1 -0
- package/dist/explore/hooks/use-load-error-notify.d.ts +11 -0
- package/dist/explore/hooks/use-load-error-notify.d.ts.map +1 -0
- package/dist/explore/hooks/use-load-error-notify.js +18 -0
- package/dist/explore/hooks/use-load-error-notify.js.map +1 -0
- package/dist/explore/hooks/use-primary-space-loader.d.ts +24 -0
- package/dist/explore/hooks/use-primary-space-loader.d.ts.map +1 -0
- package/dist/explore/hooks/use-primary-space-loader.js +29 -0
- package/dist/explore/hooks/use-primary-space-loader.js.map +1 -0
- package/dist/explore/index.d.ts +37 -0
- package/dist/explore/index.d.ts.map +1 -0
- package/dist/explore/index.js +107 -0
- package/dist/explore/index.js.map +1 -0
- package/dist/explore/loaders/cave-loader.d.ts +58 -0
- package/dist/explore/loaders/cave-loader.d.ts.map +1 -0
- package/dist/explore/loaders/cave-loader.js +79 -0
- package/dist/explore/loaders/cave-loader.js.map +1 -0
- package/dist/explore/math/space-transforms.d.ts +49 -0
- package/dist/explore/math/space-transforms.d.ts.map +1 -0
- package/dist/explore/math/space-transforms.js +54 -0
- package/dist/explore/math/space-transforms.js.map +1 -0
- package/dist/explore/overlays/action-bubble.d.ts +8 -0
- package/dist/explore/overlays/action-bubble.d.ts.map +1 -0
- package/dist/explore/overlays/action-bubble.js +18 -0
- package/dist/explore/overlays/action-bubble.js.map +1 -0
- package/dist/explore/overlays/action-panel.d.ts +12 -0
- package/dist/explore/overlays/action-panel.d.ts.map +1 -0
- package/dist/explore/overlays/action-panel.js +69 -0
- package/dist/explore/overlays/action-panel.js.map +1 -0
- package/dist/explore/overlays/connector-label-beacon.d.ts +11 -0
- package/dist/explore/overlays/connector-label-beacon.d.ts.map +1 -0
- package/dist/explore/overlays/connector-label-beacon.js +38 -0
- package/dist/explore/overlays/connector-label-beacon.js.map +1 -0
- package/dist/explore/overlays/connector-label-tag-shell.d.ts +16 -0
- package/dist/explore/overlays/connector-label-tag-shell.d.ts.map +1 -0
- package/dist/explore/overlays/connector-label-tag-shell.js +18 -0
- package/dist/explore/overlays/connector-label-tag-shell.js.map +1 -0
- package/dist/explore/overlays/detail-window.d.ts +9 -0
- package/dist/explore/overlays/detail-window.d.ts.map +1 -0
- package/dist/explore/overlays/detail-window.js +92 -0
- package/dist/explore/overlays/detail-window.js.map +1 -0
- package/dist/explore/overlays/explore-helper.d.ts +44 -0
- package/dist/explore/overlays/explore-helper.d.ts.map +1 -0
- package/dist/explore/overlays/explore-helper.js +57 -0
- package/dist/explore/overlays/explore-helper.js.map +1 -0
- package/dist/explore/overlays/icons.d.ts +16 -0
- package/dist/explore/overlays/icons.d.ts.map +1 -0
- package/dist/explore/overlays/icons.js +34 -0
- package/dist/explore/overlays/icons.js.map +1 -0
- package/dist/explore/overlays/space-load-error-overlay.d.ts +27 -0
- package/dist/explore/overlays/space-load-error-overlay.d.ts.map +1 -0
- package/dist/explore/overlays/space-load-error-overlay.js +24 -0
- package/dist/explore/overlays/space-load-error-overlay.js.map +1 -0
- package/dist/explore/services/websocket.service.d.ts +180 -0
- package/dist/explore/services/websocket.service.d.ts.map +1 -0
- package/dist/explore/services/websocket.service.js +187 -0
- package/dist/explore/services/websocket.service.js.map +1 -0
- package/dist/explore/simple-character.d.ts +46 -0
- package/dist/explore/simple-character.d.ts.map +1 -0
- package/dist/explore/simple-character.js +119 -0
- package/dist/explore/simple-character.js.map +1 -0
- package/dist/explore/stores/action-prompt.store.d.ts +27 -0
- package/dist/explore/stores/action-prompt.store.d.ts.map +1 -0
- package/dist/explore/stores/action-prompt.store.js +14 -0
- package/dist/explore/stores/action-prompt.store.js.map +1 -0
- package/dist/explore/stores/cave-explore.store.d.ts +77 -0
- package/dist/explore/stores/cave-explore.store.d.ts.map +1 -0
- package/dist/explore/stores/cave-explore.store.js +66 -0
- package/dist/explore/stores/cave-explore.store.js.map +1 -0
- package/dist/explore/stores/explore-context.d.ts +35 -0
- package/dist/explore/stores/explore-context.d.ts.map +1 -0
- package/dist/explore/stores/explore-context.js +43 -0
- package/dist/explore/stores/explore-context.js.map +1 -0
- package/dist/explore/styles/cave-world-css.d.ts +10 -0
- package/dist/explore/styles/cave-world-css.d.ts.map +1 -0
- package/dist/explore/styles/cave-world-css.js +935 -0
- package/dist/explore/styles/cave-world-css.js.map +1 -0
- package/dist/explore/styles/inject.d.ts +32 -0
- package/dist/explore/styles/inject.d.ts.map +1 -0
- package/dist/explore/styles/inject.js +40 -0
- package/dist/explore/styles/inject.js.map +1 -0
- package/dist/explore/utils/schedule-idle.d.ts +12 -0
- package/dist/explore/utils/schedule-idle.d.ts.map +1 -0
- package/dist/explore/utils/schedule-idle.js +16 -0
- package/dist/explore/utils/schedule-idle.js.map +1 -0
- package/dist/explore/viewer-shared.d.ts +56 -0
- package/dist/explore/viewer-shared.d.ts.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +78 -0
- package/dist/index.js.map +1 -0
- package/dist/space/cave-base-layer.d.ts +42 -0
- package/dist/space/cave-base-layer.d.ts.map +1 -0
- package/dist/space/cave-base-layer.js +221 -0
- package/dist/space/cave-base-layer.js.map +1 -0
- package/dist/space/cave-custom-layer.d.ts +12 -0
- package/dist/space/cave-custom-layer.d.ts.map +1 -0
- package/dist/space/cave-custom-layer.js +17 -0
- package/dist/space/cave-custom-layer.js.map +1 -0
- package/dist/space/cave-env.d.ts +6 -0
- package/dist/space/cave-env.d.ts.map +1 -0
- package/dist/space/cave-env.js +23 -0
- package/dist/space/cave-env.js.map +1 -0
- package/dist/space/cave-space.d.ts +46 -0
- package/dist/space/cave-space.d.ts.map +1 -0
- package/dist/space/cave-space.js +37 -0
- package/dist/space/cave-space.js.map +1 -0
- package/dist/space/connector-label-host.d.ts +21 -0
- package/dist/space/connector-label-host.d.ts.map +1 -0
- package/dist/space/connector-label-host.js +65 -0
- package/dist/space/connector-label-host.js.map +1 -0
- package/dist/space/index.d.ts +18 -0
- package/dist/space/index.d.ts.map +1 -0
- package/dist/space/index.js +47 -0
- package/dist/space/index.js.map +1 -0
- package/dist/space/objects/builtin-registrar.d.ts +17 -0
- package/dist/space/objects/builtin-registrar.d.ts.map +1 -0
- package/dist/space/objects/builtin-registrar.js +19 -0
- package/dist/space/objects/builtin-registrar.js.map +1 -0
- package/dist/space/objects/custom-object.d.ts +9 -0
- package/dist/space/objects/custom-object.d.ts.map +1 -0
- package/dist/space/objects/custom-object.js +56 -0
- package/dist/space/objects/custom-object.js.map +1 -0
- package/dist/space/objects/image-object.d.ts +7 -0
- package/dist/space/objects/image-object.d.ts.map +1 -0
- package/dist/space/objects/image-object.js +14 -0
- package/dist/space/objects/image-object.js.map +1 -0
- package/dist/space/objects/model-object/fbx-object.d.ts +8 -0
- package/dist/space/objects/model-object/fbx-object.d.ts.map +1 -0
- package/dist/space/objects/model-object/fbx-object.js +26 -0
- package/dist/space/objects/model-object/fbx-object.js.map +1 -0
- package/dist/space/objects/model-object/gltf-object.d.ts +9 -0
- package/dist/space/objects/model-object/gltf-object.d.ts.map +1 -0
- package/dist/space/objects/model-object/gltf-object.js +66 -0
- package/dist/space/objects/model-object/gltf-object.js.map +1 -0
- package/dist/space/objects/model-object/index.d.ts +9 -0
- package/dist/space/objects/model-object/index.d.ts.map +1 -0
- package/dist/space/objects/model-object/index.js +12 -0
- package/dist/space/objects/model-object/index.js.map +1 -0
- package/dist/space/objects/model-object/splat-object.d.ts +9 -0
- package/dist/space/objects/model-object/splat-object.d.ts.map +1 -0
- package/dist/space/objects/model-object/splat-object.js +19 -0
- package/dist/space/objects/model-object/splat-object.js.map +1 -0
- package/dist/space/objects/object-components/windows/index.d.ts +5 -0
- package/dist/space/objects/object-components/windows/index.d.ts.map +1 -0
- package/dist/space/objects/object-components/windows/index.js +20 -0
- package/dist/space/objects/object-components/windows/index.js.map +1 -0
- package/dist/space/objects/placeholder-object.d.ts +7 -0
- package/dist/space/objects/placeholder-object.d.ts.map +1 -0
- package/dist/space/objects/placeholder-object.js +12 -0
- package/dist/space/objects/placeholder-object.js.map +1 -0
- package/dist/space/objects/poi-object.d.ts +7 -0
- package/dist/space/objects/poi-object.d.ts.map +1 -0
- package/dist/space/objects/poi-object.js +38 -0
- package/dist/space/objects/poi-object.js.map +1 -0
- package/dist/space/objects/portal-object.d.ts +7 -0
- package/dist/space/objects/portal-object.d.ts.map +1 -0
- package/dist/space/objects/portal-object.js +84 -0
- package/dist/space/objects/portal-object.js.map +1 -0
- package/dist/space/objects/video-object.d.ts +7 -0
- package/dist/space/objects/video-object.d.ts.map +1 -0
- package/dist/space/objects/video-object.js +32 -0
- package/dist/space/objects/video-object.js.map +1 -0
- package/dist/space/polygon-boundary.d.ts +10 -0
- package/dist/space/polygon-boundary.d.ts.map +1 -0
- package/dist/space/polygon-boundary.js +205 -0
- package/dist/space/polygon-boundary.js.map +1 -0
- package/dist/space/splats/spark/robust-splat-mesh.d.ts +59 -0
- package/dist/space/splats/spark/robust-splat-mesh.d.ts.map +1 -0
- package/dist/space/splats/spark/robust-splat-mesh.js +105 -0
- package/dist/space/splats/spark/robust-splat-mesh.js.map +1 -0
- package/dist/space/splats/spark/splat-mesh.d.ts +5 -0
- package/dist/space/splats/spark/splat-mesh.d.ts.map +1 -0
- package/dist/space/splats/spark/splat-mesh.js +7 -0
- package/dist/space/splats/spark/splat-mesh.js.map +1 -0
- package/dist/space/splats/spark/splat-spread-reveal.d.ts +14 -0
- package/dist/space/splats/spark/splat-spread-reveal.d.ts.map +1 -0
- package/dist/space/splats/spark/splat-spread-reveal.js +45 -0
- package/dist/space/splats/spark/splat-spread-reveal.js.map +1 -0
- package/dist/space/utils/cave-world-player.d.ts +3 -0
- package/dist/space/utils/cave-world-player.d.ts.map +1 -0
- package/dist/space/utils/cave-world-player.js +5 -0
- package/dist/space/utils/cave-world-player.js.map +1 -0
- package/dist/space/utils/configure-canvas.d.ts +20 -0
- package/dist/space/utils/configure-canvas.d.ts.map +1 -0
- package/dist/space/utils/configure-canvas.js +12 -0
- package/dist/space/utils/configure-canvas.js.map +1 -0
- package/dist/space/utils/polygon-boundary-geometry.d.ts +8 -0
- package/dist/space/utils/polygon-boundary-geometry.d.ts.map +1 -0
- package/dist/space/utils/polygon-boundary-geometry.js +20 -0
- package/dist/space/utils/polygon-boundary-geometry.js.map +1 -0
- package/dist/space/utils/polygon-boundary-segments.d.ts +50 -0
- package/dist/space/utils/polygon-boundary-segments.d.ts.map +1 -0
- package/dist/space/utils/polygon-boundary-segments.js +64 -0
- package/dist/space/utils/polygon-boundary-segments.js.map +1 -0
- package/dist/space/utils/rotation-compat.d.ts +4 -0
- package/dist/space/utils/rotation-compat.d.ts.map +1 -0
- package/dist/space/utils/rotation-compat.js +9 -0
- package/dist/space/utils/rotation-compat.js.map +1 -0
- package/dist/space/utils/select-splat-level.d.ts +52 -0
- package/dist/space/utils/select-splat-level.d.ts.map +1 -0
- package/dist/space/utils/select-splat-level.js +43 -0
- package/dist/space/utils/select-splat-level.js.map +1 -0
- package/dist/space/utils/spark-performance.d.ts +10 -0
- package/dist/space/utils/spark-performance.d.ts.map +1 -0
- package/dist/space/utils/spark-performance.js +10 -0
- package/dist/space/utils/spark-performance.js.map +1 -0
- package/dist/space/utils/splat-collider-helper.d.ts +5 -0
- package/dist/space/utils/splat-collider-helper.d.ts.map +1 -0
- package/dist/space/utils/splat-collider-helper.js +162 -0
- package/dist/space/utils/splat-collider-helper.js.map +1 -0
- package/dist/space/utils/touch-primary-device.d.ts +16 -0
- package/dist/space/utils/touch-primary-device.d.ts.map +1 -0
- package/dist/space/utils/touch-primary-device.js +52 -0
- package/dist/space/utils/touch-primary-device.js.map +1 -0
- package/dist/space/utils/use-visibility-frameloop.d.ts +20 -0
- package/dist/space/utils/use-visibility-frameloop.d.ts.map +1 -0
- package/dist/space/utils/use-visibility-frameloop.js +18 -0
- package/dist/space/utils/use-visibility-frameloop.js.map +1 -0
- package/dist/styles.css +930 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/space-types.d.ts +404 -0
- package/dist/types/space-types.d.ts.map +1 -0
- package/doc/API.md +617 -0
- package/doc/ARCHITECTURE.md +264 -0
- package/doc/multiplayer-protocol.md +757 -0
- package/doc/scene-json-structure.md +567 -0
- package/package.json +131 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cave-base-layer.js","sources":["../../space/cave-base-layer.tsx"],"sourcesContent":["import {\n startTransition,\n Suspense,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n type RefObject\n} from 'react'\nimport { useLoader, type ThreeEvent } from '@react-three/fiber'\nimport { BvhPhysicsBody, BvhPhysicsSensor } from '@react-three/viverse'\nimport type { Mesh } from 'three'\nimport { MeshBasicMaterial, type Group, type Object3DEventMap } from 'three'\nimport { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js'\nimport { useCaveEventBus, useCaveWorldStore } from '../core'\nimport type { CaveSpace, ConnectorDef, ModelCollider } from '../types'\nimport ConnectorLabelHost from './connector-label-host'\nimport { PolygonBoundaryColliders, PolygonBoundaryFence } from './polygon-boundary'\nimport RobustSplatMesh from './splats/spark/robust-splat-mesh'\nimport { type SparkSplatMesh } from './splats/spark/splat-mesh'\nimport { toQuaternionRotation } from './utils/rotation-compat'\nimport { selectSplatLevel } from './utils/select-splat-level'\nimport { createSplatCollider } from './utils/splat-collider-helper'\n\n/** Identity quaternion as `[x, y, z, w]` for the R3F `quaternion` prop. */\nconst INIT_QUATERNION: [number, number, number, number] = [1, 0, 0, 0]\n\n/** Target triangle budget when deriving a collider from splat geometry. */\nconst SPLAT_COLLIDER_SAMPLE_COUNT = 100_000\n\nconst INVISIBLE_MATERIAL = /* @__PURE__ */ new MeshBasicMaterial({ visible: false })\n\nfunction ConnectorSensor({\n connector,\n onIntersection\n}: {\n connector: ConnectorDef\n onIntersection: (connector: ConnectorDef, intersected: boolean) => void\n}) {\n const handleChange = useCallback(\n (intersected: boolean) => onIntersection(connector, intersected),\n [connector, onIntersection]\n )\n\n return (\n <BvhPhysicsSensor onIntersectedChanged={handleChange}>\n <mesh\n position={connector.transform.position}\n rotation={connector.transform.rotation}\n scale={connector.transform.scale}\n >\n <boxGeometry />\n <meshStandardMaterial visible={false} />\n </mesh>\n </BvhPhysicsSensor>\n )\n}\n\nfunction ModelColliderMesh({\n collider,\n onLoaded\n}: {\n collider: ModelCollider\n onLoaded: () => void\n}) {\n const obj = useLoader(OBJLoader, collider.url)\n\n const cloned = useMemo(() => {\n const group = obj.clone(true)\n group.traverse((child) => {\n if ((child as Mesh).isMesh) {\n ;(child as Mesh).material = INVISIBLE_MATERIAL\n }\n })\n // Collider OBJs are authored Z-up; Three.js is Y-up.\n group.rotation.set(-Math.PI / 2, 0, 0)\n return group\n }, [obj])\n\n useEffect(() => {\n onLoaded()\n }, [onLoaded])\n\n return <primitive object={cloned} />\n}\n\n/**\n * Track readiness of the scene (splat) and every model collider, firing\n * `onReady` exactly once when all of them have loaded.\n *\n * Counters live in refs rather than state so each collider landing doesn't\n * re-render the base layer; only the final flip publishes to React.\n */\nfunction useInitGate(modelColliderCount: number, requireModelColliders: boolean) {\n const sceneReady = useRef(false)\n const loadedColliders = useRef(0)\n const fired = useRef(false)\n const [ready, setReady] = useState(false)\n\n const requiredColliders = requireModelColliders ? modelColliderCount : 0\n\n const checkReady = useCallback(() => {\n if (fired.current) return\n if (sceneReady.current && loadedColliders.current >= requiredColliders) {\n fired.current = true\n setReady(true)\n }\n }, [requiredColliders])\n\n const markSceneReady = useCallback(() => {\n sceneReady.current = true\n checkReady()\n }, [checkReady])\n\n const markColliderReady = useCallback(() => {\n loadedColliders.current += 1\n checkReady()\n }, [checkReady])\n\n return { ready, markSceneReady, markColliderReady }\n}\n\nexport interface CaveBaseLayerProps {\n space?: CaveSpace\n /** Space id, threaded down for splat load-error context. */\n spaceId?: string\n onProcess?: (percent: number) => void\n onInitialized?: () => void\n onClick?: (event: ThreeEvent<MouseEvent>) => void\n onDoubleClick?: (event: ThreeEvent<MouseEvent>) => void\n physics?: boolean\n /**\n * When `false` this base layer is preloaded-but-not-current: connector\n * sensors don't mount (no spurious `connector:enter` from an adjacent scene\n * occupying the same world coordinates) and physics defaults off.\n */\n active?: boolean\n /** Connected space configs, for resolving portal label metadata. */\n connectedSpaces?: Record<string, CaveSpace>\n /** Space ids whose base layer finished loading — gates portal travel UI. */\n readySpaceIds?: Record<string, true>\n /** Connector the player is inside; its label hides. */\n activeConnectorId?: string\n /** Mount connector label hosts. @default true */\n connectorLabels?: boolean\n /**\n * Play the spread reveal once when this base layer's splat first loads.\n * Only the primary (entry) scene should set this; neighbors reached through\n * a transition leave it `false` so travel feels instant.\n */\n revealOnEnter?: boolean\n children?: ReactNode\n ref?: RefObject<Group<Object3DEventMap>>\n}\n\n/**\n * The scene's ground truth: the 3DGS/splat or model capture, its colliders,\n * boundaries, and connector trigger volumes.\n */\nexport default function CaveBaseLayer(props: CaveBaseLayerProps) {\n const {\n space,\n spaceId,\n active = true,\n revealOnEnter = false,\n onInitialized,\n ref,\n connectedSpaces = {},\n readySpaceIds = {},\n activeConnectorId,\n connectorLabels = true\n } = props\n const physics = props.physics ?? active\n\n const [splatCollider, setSplatCollider] = useState<Mesh | null>(null)\n const eventBus = useCaveEventBus()\n const setSpaceLoadError = useCaveWorldStore((s) => s.setSpaceLoadError)\n\n const modelColliderCount = useMemo(\n () => space?.baseLayer?.colliders?.filter((c) => c.type === 'model').length ?? 0,\n [space?.baseLayer?.colliders]\n )\n const { ready, markSceneReady, markColliderReady } = useInitGate(modelColliderCount, physics)\n\n useEffect(() => {\n if (!ready) return\n startTransition(() => {\n eventBus.emit('space:initialized', {})\n onInitialized?.()\n })\n }, [ready, eventBus, onInitialized])\n\n // Derived splat colliders own GPU buffers that Three.js won't reclaim for us.\n useEffect(() => {\n if (!splatCollider) return\n return () => {\n splatCollider.geometry.dispose()\n }\n }, [splatCollider])\n\n const onSplatLoadImpl = useRef<(mesh: SparkSplatMesh) => void>(() => {})\n // Guards single-shot fallback collider generation regardless of when physics\n // flips on.\n const splatColliderGenerated = useRef(false)\n\n useEffect(() => {\n onSplatLoadImpl.current = (mesh: SparkSplatMesh) => {\n startTransition(() => {\n // Generate the fallback collider eagerly at load time, even while this\n // scene is a hidden preload: otherwise the first transition into it pays\n // the ~1s generation cost as a visible stutter. Skipped when the scene\n // already declares explicit colliders.\n if (!splatColliderGenerated.current && !space?.baseLayer?.colliders?.length) {\n splatColliderGenerated.current = true\n setSplatCollider(createSplatCollider(mesh, SPLAT_COLLIDER_SAMPLE_COUNT))\n }\n markSceneReady()\n })\n }\n }, [space?.baseLayer?.colliders, markSceneReady])\n\n // Stable identity: the mesh is rebuilt whenever its `args` change, so an\n // unstable onLoad would trigger redundant downloads.\n const onSplatLoad = useCallback((mesh: SparkSplatMesh) => {\n onSplatLoadImpl.current(mesh)\n }, [])\n\n // Pick which splat asset to load: with a `splatLevels` LOD list, take the\n // highest-quality variant this device can handle. Recomputed on scene change\n // only — device caps are read once, so a resize/orientation flip must not\n // trigger a re-download.\n const splatSelection = useMemo(\n () => selectSplatLevel(space?.baseLayer?.scene),\n [space?.baseLayer?.scene]\n )\n const splatUrl = splatSelection?.url\n\n const handleSplatError = useCallback(\n (error: unknown) => {\n setSpaceLoadError({ stage: 'splat', url: splatUrl, spaceId, error })\n },\n [setSpaceLoadError, splatUrl, spaceId]\n )\n\n const handleConnectorIntersection = useCallback(\n (connector: ConnectorDef, intersected: boolean) => {\n eventBus.emit(intersected ? 'connector:enter' : 'connector:leave', { connector })\n },\n [eventBus]\n )\n\n if (!space?.baseLayer) return null\n\n const { transform, scene, colliders, boundaries, connectors } = space.baseLayer\n\n return (\n <group\n name=\"base-layer\"\n position={transform.position}\n quaternion={transform.rotation}\n scale={transform.scale}\n ref={ref}\n >\n {scene?.type === 'splat' && splatUrl ? (\n <RobustSplatMesh\n url={splatUrl}\n visible={active}\n quaternion={INIT_QUATERNION}\n spaceId={spaceId}\n revealOnEnter={revealOnEnter}\n onLoad={onSplatLoad}\n // Only surface a terminal error for the active scene: a hidden\n // neighbor failing in the background must not pop a full-screen\n // prompt over a scene that works. It still auto-retries, and a manual\n // retry re-downloads it too.\n onError={active ? handleSplatError : undefined}\n onClick={props.onClick}\n onDoubleClick={props.onDoubleClick}\n />\n ) : null}\n\n {colliders?.map((collider) => {\n if (collider.type !== 'model' || !collider.url) return null\n const mesh = <ModelColliderMesh collider={collider} onLoaded={markColliderReady} />\n return (\n // Each collider gets its own boundary. `useLoader` suspends, and\n // without a boundary here the suspension unwinds to the viewer's,\n // discarding this whole subtree — including the splat mesh, which\n // spark re-downloads from scratch on every remount. Colliders also\n // load in parallel this way instead of one per retry.\n //\n // The boundary must stay *outside* `BvhPhysicsBody`: it snapshots its\n // children into the BVH world in a mount effect, so a child that\n // arrives later is never registered as a collider.\n <Suspense key={collider.id} fallback={null}>\n {physics ? (\n <BvhPhysicsBody>{mesh}</BvhPhysicsBody>\n ) : (\n // Hidden preloads still load collider assets (to satisfy the init\n // gate) but skip BVH registration.\n <group visible={false}>{mesh}</group>\n )}\n </Suspense>\n )\n })}\n\n {physics ? (\n <BvhPhysicsBody>\n {colliders?.map((collider) =>\n collider.type === 'box' ? (\n <mesh\n key={collider.id}\n position={collider.box.position}\n quaternion={toQuaternionRotation(collider.box.rotation)}\n scale={collider.box.scale}\n >\n <boxGeometry />\n <meshStandardMaterial visible={false} />\n </mesh>\n ) : null\n )}\n </BvhPhysicsBody>\n ) : null}\n\n {physics ? (\n <BvhPhysicsBody>\n {boundaries?.map((boundary) => {\n if (boundary.type === 'box' && boundary.collisionEnabled !== false) {\n return (\n <mesh\n key={boundary.id}\n position={boundary.box.position}\n quaternion={toQuaternionRotation(boundary.box.rotation)}\n scale={boundary.box.scale}\n >\n <boxGeometry />\n <meshStandardMaterial visible={false} />\n </mesh>\n )\n }\n if (boundary.type === 'polygon') {\n return <PolygonBoundaryColliders key={boundary.id} boundary={boundary} />\n }\n return null\n })}\n </BvhPhysicsBody>\n ) : null}\n\n {active\n ? boundaries?.map((boundary) =>\n boundary.type === 'polygon' ? (\n <PolygonBoundaryFence\n key={`polygon-vis-${boundary.id}`}\n boundary={boundary}\n active={active}\n />\n ) : null\n )\n : null}\n\n {/* Sensors mount only for the active scene — otherwise a preloaded\n adjacent scene's connector boxes fire `connector:enter` as the player\n walks past the same world position in the scene they're actually in. */}\n {active\n ? connectors?.map((connector) => (\n <ConnectorSensor\n key={connector.id}\n connector={connector}\n onIntersection={handleConnectorIntersection}\n />\n ))\n : null}\n\n {active && connectorLabels\n ? connectors?.map((connector) => (\n <ConnectorLabelHost\n key={`label-${connector.id}`}\n connector={connector}\n connectedSpaces={connectedSpaces}\n readySpaceIds={readySpaceIds}\n activeConnectorId={activeConnectorId}\n />\n ))\n : null}\n\n {physics && splatCollider ? (\n <BvhPhysicsBody>\n <group>\n <primitive object={splatCollider} quaternion={INIT_QUATERNION} />\n </group>\n </BvhPhysicsBody>\n ) : null}\n\n {props.children ?? null}\n </group>\n )\n}\n"],"names":["INIT_QUATERNION","SPLAT_COLLIDER_SAMPLE_COUNT","INVISIBLE_MATERIAL","MeshBasicMaterial","ConnectorSensor","connector","onIntersection","handleChange","useCallback","intersected","jsx","BvhPhysicsSensor","jsxs","ModelColliderMesh","collider","onLoaded","obj","useLoader","OBJLoader","cloned","useMemo","group","child","useEffect","useInitGate","modelColliderCount","requireModelColliders","sceneReady","useRef","loadedColliders","fired","ready","setReady","useState","requiredColliders","checkReady","markSceneReady","markColliderReady","CaveBaseLayer","props","space","spaceId","active","revealOnEnter","onInitialized","ref","connectedSpaces","readySpaceIds","activeConnectorId","connectorLabels","physics","splatCollider","setSplatCollider","eventBus","useCaveEventBus","setSpaceLoadError","useCaveWorldStore","s","c","startTransition","onSplatLoadImpl","splatColliderGenerated","mesh","createSplatCollider","onSplatLoad","splatUrl","selectSplatLevel","handleSplatError","error","handleConnectorIntersection","transform","scene","colliders","boundaries","connectors","RobustSplatMesh","Suspense","BvhPhysicsBody","toQuaternionRotation","boundary","PolygonBoundaryColliders","PolygonBoundaryFence","ConnectorLabelHost"],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CaveSpace } from '../types/index.js';
|
|
2
|
+
export default function CaveCustomLayer(props: {
|
|
3
|
+
space?: CaveSpace;
|
|
4
|
+
physics?: boolean;
|
|
5
|
+
/**
|
|
6
|
+
* When false, the custom layer renders nothing. Used to skip object
|
|
7
|
+
* load/build cost in preloaded but not-yet-active scenes.
|
|
8
|
+
*/
|
|
9
|
+
active?: boolean;
|
|
10
|
+
children?: React.ReactNode;
|
|
11
|
+
}): import("react").JSX.Element | null;
|
|
12
|
+
//# sourceMappingURL=cave-custom-layer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cave-custom-layer.d.ts","sourceRoot":"","sources":["../../space/cave-custom-layer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAGzC,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,KAAK,EAAE;IAC7C,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAC3B,sCAuBA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsxs as i, jsx as c } from "react/jsx-runtime";
|
|
2
|
+
import u from "./objects/custom-object.js";
|
|
3
|
+
function o(e) {
|
|
4
|
+
const n = e.space?.customLayers ?? [], a = e.physics ?? !0;
|
|
5
|
+
return e.active ?? !0 ? /* @__PURE__ */ i("group", { name: "custom-layers", children: [
|
|
6
|
+
n.map(
|
|
7
|
+
(t) => t.visible !== !1 ? /* @__PURE__ */ c("group", { name: `custom-layer-${t.name}`, children: t.objects.map(
|
|
8
|
+
(s) => s.visible !== !1 ? /* @__PURE__ */ c(u, { object: s, physics: a }, s.id) : null
|
|
9
|
+
) }, t.name) : null
|
|
10
|
+
),
|
|
11
|
+
e.children ?? null
|
|
12
|
+
] }) : null;
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
o as default
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=cave-custom-layer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cave-custom-layer.js","sources":["../../space/cave-custom-layer.tsx"],"sourcesContent":["import type { CaveSpace } from '../types'\nimport CustomObject from './objects/custom-object'\n\nexport default function CaveCustomLayer(props: {\n space?: CaveSpace\n physics?: boolean\n /**\n * When false, the custom layer renders nothing. Used to skip object\n * load/build cost in preloaded but not-yet-active scenes.\n */\n active?: boolean\n children?: React.ReactNode\n}) {\n const layers = props.space?.customLayers ?? []\n const physics = props.physics ?? true\n const active = props.active ?? true\n\n if (!active) return null\n\n return (\n <group name=\"custom-layers\">\n {layers.map((layer) =>\n layer.visible !== false ? (\n <group key={layer.name} name={`custom-layer-${layer.name}`}>\n {layer.objects.map((obj) =>\n obj.visible !== false ? (\n <CustomObject key={obj.id} object={obj} physics={physics} />\n ) : null\n )}\n </group>\n ) : null\n )}\n {props.children ?? null}\n </group>\n )\n}\n"],"names":["CaveCustomLayer","props","layers","physics","jsxs","layer","jsx","obj","CustomObject"],"mappings":";;AAGA,SAAwBA,EAAgBC,GASrC;AACD,QAAMC,IAASD,EAAM,OAAO,gBAAgB,CAAA,GACtCE,IAAUF,EAAM,WAAW;AAGjC,SAFeA,EAAM,UAAU,KAK7B,gBAAAG,EAAC,SAAA,EAAM,MAAK,iBACT,UAAA;AAAA,IAAAF,EAAO;AAAA,MAAI,CAACG,MACXA,EAAM,YAAY,KAChB,gBAAAC,EAAC,SAAA,EAAuB,MAAM,gBAAgBD,EAAM,IAAI,IACrD,YAAM,QAAQ;AAAA,QAAI,CAACE,MAClBA,EAAI,YAAY,KACd,gBAAAD,EAACE,GAAA,EAA0B,QAAQD,GAAK,SAAAJ,EAAA,GAArBI,EAAI,EAAmC,IACxD;AAAA,MAAA,KAJIF,EAAM,IAMlB,IACE;AAAA,IAAA;AAAA,IAELJ,EAAM,YAAY;AAAA,EAAA,GACrB,IAhBkB;AAkBtB;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cave-env.d.ts","sourceRoot":"","sources":["../../space/cave-env.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAEzC,MAAM,CAAC,OAAO,UAAU,OAAO,CAAC,KAAK,EAAE;IAAE,KAAK,CAAC,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,sCAuBvF"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsxs as o, Fragment as a, jsx as e } from "react/jsx-runtime";
|
|
2
|
+
function l(t) {
|
|
3
|
+
const { space: n } = t;
|
|
4
|
+
if (!n?.baseLayer) return null;
|
|
5
|
+
const { lighting: i } = n.baseLayer;
|
|
6
|
+
return /* @__PURE__ */ o(a, { children: [
|
|
7
|
+
i?.ambientIntensity && /* @__PURE__ */ e("ambientLight", { intensity: i.ambientIntensity, color: i.ambientColor }),
|
|
8
|
+
i?.directionalLight && /* @__PURE__ */ e(
|
|
9
|
+
"directionalLight",
|
|
10
|
+
{
|
|
11
|
+
intensity: i.directionalLight.intensity,
|
|
12
|
+
color: i.directionalLight.color,
|
|
13
|
+
position: i.directionalLight.position,
|
|
14
|
+
castShadow: i.directionalLight.castShadow
|
|
15
|
+
}
|
|
16
|
+
),
|
|
17
|
+
t.children ?? null
|
|
18
|
+
] });
|
|
19
|
+
}
|
|
20
|
+
export {
|
|
21
|
+
l as default
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=cave-env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cave-env.js","sources":["../../space/cave-env.tsx"],"sourcesContent":["import type { CaveSpace } from '../types'\n\nexport default function CaveEnv(props: { space?: CaveSpace; children?: React.ReactNode }) {\n const { space } = props\n if (!space?.baseLayer) return null\n\n const { lighting } = space.baseLayer\n\n return (\n <>\n {lighting?.ambientIntensity && (\n <ambientLight intensity={lighting.ambientIntensity} color={lighting.ambientColor} />\n )}\n {lighting?.directionalLight && (\n <directionalLight\n intensity={lighting.directionalLight.intensity}\n color={lighting.directionalLight.color}\n position={lighting.directionalLight.position}\n castShadow={lighting.directionalLight.castShadow}\n />\n )}\n\n {props.children ?? null}\n </>\n )\n}\n"],"names":["CaveEnv","props","space","lighting","jsxs","Fragment","jsx"],"mappings":";AAEA,SAAwBA,EAAQC,GAA0D;AACxF,QAAM,EAAE,OAAAC,MAAUD;AAClB,MAAI,CAACC,GAAO,UAAW,QAAO;AAE9B,QAAM,EAAE,UAAAC,MAAaD,EAAM;AAE3B,SACE,gBAAAE,EAAAC,GAAA,EACG,UAAA;AAAA,IAAAF,GAAU,sCACR,gBAAA,EAAa,WAAWA,EAAS,kBAAkB,OAAOA,EAAS,aAAA,CAAc;AAAA,IAEnFA,GAAU,oBACT,gBAAAG;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAWH,EAAS,iBAAiB;AAAA,QACrC,OAAOA,EAAS,iBAAiB;AAAA,QACjC,UAAUA,EAAS,iBAAiB;AAAA,QACpC,YAAYA,EAAS,iBAAiB;AAAA,MAAA;AAAA,IAAA;AAAA,IAIzCF,EAAM,YAAY;AAAA,EAAA,GACrB;AAEJ;"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { CaveSpace as CaveSpaceConfig } from '../types/index.js';
|
|
3
|
+
export interface CaveSpaceProps {
|
|
4
|
+
/** Scene JSON. Renders nothing until provided. */
|
|
5
|
+
space?: CaveSpaceConfig;
|
|
6
|
+
/** Space id, threaded down for load-error context and readiness events. */
|
|
7
|
+
spaceId?: string;
|
|
8
|
+
/** Mount colliders / physics bodies. Defaults to `active`. */
|
|
9
|
+
physics?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Whether this space is the one the player is in.
|
|
12
|
+
*
|
|
13
|
+
* When `false` the space is treated as preloaded-but-not-current: the splat
|
|
14
|
+
* stays rendered (so it remains resident in GPU memory and a transition into
|
|
15
|
+
* it is instant), but connector sensors don't mount and the custom layer is
|
|
16
|
+
* skipped entirely — otherwise an off-screen scene would download its models
|
|
17
|
+
* and its connectors would fire at world positions the player walks through
|
|
18
|
+
* in the *active* scene.
|
|
19
|
+
* @default true
|
|
20
|
+
*/
|
|
21
|
+
active?: boolean;
|
|
22
|
+
/** Loaded neighbor configs, for resolving connector label metadata. */
|
|
23
|
+
connectedSpaces?: Record<string, CaveSpaceConfig>;
|
|
24
|
+
/** Space ids whose base layer finished loading — gates portal travel UI. */
|
|
25
|
+
readySpaceIds?: Record<string, true>;
|
|
26
|
+
/** Connector the player is inside; its own label hides. */
|
|
27
|
+
activeConnectorId?: string;
|
|
28
|
+
/** Mount connector wayfinding labels. @default true */
|
|
29
|
+
connectorLabels?: boolean;
|
|
30
|
+
/** Play the one-shot spread reveal on first splat load (entry scene only). */
|
|
31
|
+
revealOnEnter?: boolean;
|
|
32
|
+
onProcess?: (percent: number) => void;
|
|
33
|
+
/** Fired once when the base layer (splat + colliders) is ready. */
|
|
34
|
+
onInitialized?: () => void;
|
|
35
|
+
children?: ReactNode;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Renders one scene: environment lighting, base layer (splat + colliders +
|
|
39
|
+
* connectors), and the custom object layers.
|
|
40
|
+
*
|
|
41
|
+
* Must be mounted inside a `<CaveWorldProvider>` and, if the scene uses
|
|
42
|
+
* colliders, a viverse `<BvhPhysicsWorld>`. `CaveExplore` / `CaveOrbitViewer`
|
|
43
|
+
* set both up; use this directly only when composing your own canvas.
|
|
44
|
+
*/
|
|
45
|
+
export default function CaveSpace(props: CaveSpaceProps): import("react").JSX.Element | null;
|
|
46
|
+
//# sourceMappingURL=cave-space.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cave-space.d.ts","sourceRoot":"","sources":["../../space/cave-space.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAEzD,OAAO,KAAK,EAAE,SAAS,IAAI,eAAe,EAAE,MAAM,UAAU,CAAA;AAM5D,MAAM,WAAW,cAAc;IAC7B,kDAAkD;IAClD,KAAK,CAAC,EAAE,eAAe,CAAA;IACvB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,8DAA8D;IAC9D,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;;;;;;;;OAUG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,uEAAuE;IACvE,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;IACjD,4EAA4E;IAC5E,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IACpC,2DAA2D;IAC3D,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,uDAAuD;IACvD,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IACrC,mEAAmE;IACnE,aAAa,CAAC,EAAE,MAAM,IAAI,CAAA;IAC1B,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,KAAK,EAAE,cAAc,sCAqCtD"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { jsxs as s, Fragment as m, jsx as n } from "react/jsx-runtime";
|
|
2
|
+
import { useRef as u, useEffect as d } from "react";
|
|
3
|
+
import { useObjectRegistry as l, useComponentRegistry as f } from "../core/context/cave-world-context.js";
|
|
4
|
+
import v from "./cave-base-layer.js";
|
|
5
|
+
import y from "./cave-custom-layer.js";
|
|
6
|
+
import C from "./cave-env.js";
|
|
7
|
+
import { registerBuiltinObjects as g, registerBuiltinComponents as I } from "./objects/builtin-registrar.js";
|
|
8
|
+
function h(e) {
|
|
9
|
+
const { space: t, physics: r, active: c = !0 } = e, o = l(), i = f(), a = u(!1);
|
|
10
|
+
return d(() => {
|
|
11
|
+
a.current || (a.current = !0, g(o), I(i));
|
|
12
|
+
}, [o, i]), t ? /* @__PURE__ */ s(m, { children: [
|
|
13
|
+
/* @__PURE__ */ n(C, { space: t }),
|
|
14
|
+
/* @__PURE__ */ n(
|
|
15
|
+
v,
|
|
16
|
+
{
|
|
17
|
+
space: t,
|
|
18
|
+
spaceId: e.spaceId,
|
|
19
|
+
physics: r,
|
|
20
|
+
active: c,
|
|
21
|
+
connectedSpaces: e.connectedSpaces,
|
|
22
|
+
readySpaceIds: e.readySpaceIds,
|
|
23
|
+
activeConnectorId: e.activeConnectorId,
|
|
24
|
+
connectorLabels: e.connectorLabels,
|
|
25
|
+
revealOnEnter: e.revealOnEnter,
|
|
26
|
+
onProcess: e.onProcess,
|
|
27
|
+
onInitialized: e.onInitialized
|
|
28
|
+
}
|
|
29
|
+
),
|
|
30
|
+
/* @__PURE__ */ n(y, { space: t, active: c, physics: r }),
|
|
31
|
+
e.children ?? null
|
|
32
|
+
] }) : null;
|
|
33
|
+
}
|
|
34
|
+
export {
|
|
35
|
+
h as default
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=cave-space.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cave-space.js","sources":["../../space/cave-space.tsx"],"sourcesContent":["import { useEffect, useRef, type ReactNode } from 'react'\nimport { useComponentRegistry, useObjectRegistry } from '../core'\nimport type { CaveSpace as CaveSpaceConfig } from '../types'\nimport CaveBaseLayer from './cave-base-layer'\nimport CaveCustomLayer from './cave-custom-layer'\nimport CaveEnv from './cave-env'\nimport { registerBuiltinComponents, registerBuiltinObjects } from './objects/builtin-registrar'\n\nexport interface CaveSpaceProps {\n /** Scene JSON. Renders nothing until provided. */\n space?: CaveSpaceConfig\n /** Space id, threaded down for load-error context and readiness events. */\n spaceId?: string\n /** Mount colliders / physics bodies. Defaults to `active`. */\n physics?: boolean\n /**\n * Whether this space is the one the player is in.\n *\n * When `false` the space is treated as preloaded-but-not-current: the splat\n * stays rendered (so it remains resident in GPU memory and a transition into\n * it is instant), but connector sensors don't mount and the custom layer is\n * skipped entirely — otherwise an off-screen scene would download its models\n * and its connectors would fire at world positions the player walks through\n * in the *active* scene.\n * @default true\n */\n active?: boolean\n /** Loaded neighbor configs, for resolving connector label metadata. */\n connectedSpaces?: Record<string, CaveSpaceConfig>\n /** Space ids whose base layer finished loading — gates portal travel UI. */\n readySpaceIds?: Record<string, true>\n /** Connector the player is inside; its own label hides. */\n activeConnectorId?: string\n /** Mount connector wayfinding labels. @default true */\n connectorLabels?: boolean\n /** Play the one-shot spread reveal on first splat load (entry scene only). */\n revealOnEnter?: boolean\n onProcess?: (percent: number) => void\n /** Fired once when the base layer (splat + colliders) is ready. */\n onInitialized?: () => void\n children?: ReactNode\n}\n\n/**\n * Renders one scene: environment lighting, base layer (splat + colliders +\n * connectors), and the custom object layers.\n *\n * Must be mounted inside a `<CaveWorldProvider>` and, if the scene uses\n * colliders, a viverse `<BvhPhysicsWorld>`. `CaveExplore` / `CaveOrbitViewer`\n * set both up; use this directly only when composing your own canvas.\n */\nexport default function CaveSpace(props: CaveSpaceProps) {\n const { space, physics, active = true } = props\n const objectRegistry = useObjectRegistry()\n const componentRegistry = useComponentRegistry()\n const registered = useRef(false)\n\n // Install built-ins once per registry. `registerDefault` means a type the host\n // registered before mount keeps its own renderer.\n useEffect(() => {\n if (registered.current) return\n registered.current = true\n registerBuiltinObjects(objectRegistry)\n registerBuiltinComponents(componentRegistry)\n }, [objectRegistry, componentRegistry])\n\n if (!space) return null\n\n return (\n <>\n <CaveEnv space={space} />\n <CaveBaseLayer\n space={space}\n spaceId={props.spaceId}\n physics={physics}\n active={active}\n connectedSpaces={props.connectedSpaces}\n readySpaceIds={props.readySpaceIds}\n activeConnectorId={props.activeConnectorId}\n connectorLabels={props.connectorLabels}\n revealOnEnter={props.revealOnEnter}\n onProcess={props.onProcess}\n onInitialized={props.onInitialized}\n />\n <CaveCustomLayer space={space} active={active} physics={physics} />\n {props.children ?? null}\n </>\n )\n}\n"],"names":["CaveSpace","props","space","physics","active","objectRegistry","useObjectRegistry","componentRegistry","useComponentRegistry","registered","useRef","useEffect","registerBuiltinObjects","registerBuiltinComponents","jsxs","Fragment","jsx","CaveEnv","CaveBaseLayer","CaveCustomLayer"],"mappings":";;;;;;;AAmDA,SAAwBA,EAAUC,GAAuB;AACvD,QAAM,EAAE,OAAAC,GAAO,SAAAC,GAAS,QAAAC,IAAS,OAASH,GACpCI,IAAiBC,EAAA,GACjBC,IAAoBC,EAAA,GACpBC,IAAaC,EAAO,EAAK;AAW/B,SAPAC,EAAU,MAAM;AACd,IAAIF,EAAW,YACfA,EAAW,UAAU,IACrBG,EAAuBP,CAAc,GACrCQ,EAA0BN,CAAiB;AAAA,EAC7C,GAAG,CAACF,GAAgBE,CAAiB,CAAC,GAEjCL,IAGH,gBAAAY,EAAAC,GAAA,EACE,UAAA;AAAA,IAAA,gBAAAC,EAACC,KAAQ,OAAAf,GAAc;AAAA,IACvB,gBAAAc;AAAA,MAACE;AAAA,MAAA;AAAA,QACC,OAAAhB;AAAA,QACA,SAASD,EAAM;AAAA,QACf,SAAAE;AAAA,QACA,QAAAC;AAAA,QACA,iBAAiBH,EAAM;AAAA,QACvB,eAAeA,EAAM;AAAA,QACrB,mBAAmBA,EAAM;AAAA,QACzB,iBAAiBA,EAAM;AAAA,QACvB,eAAeA,EAAM;AAAA,QACrB,WAAWA,EAAM;AAAA,QACjB,eAAeA,EAAM;AAAA,MAAA;AAAA,IAAA;AAAA,IAEvB,gBAAAe,EAACG,GAAA,EAAgB,OAAAjB,GAAc,QAAAE,GAAgB,SAAAD,EAAA,CAAkB;AAAA,IAChEF,EAAM,YAAY;AAAA,EAAA,GACrB,IApBiB;AAsBrB;"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { CaveSpace, ConnectorDef } from '../types/index.js';
|
|
2
|
+
export interface ConnectorLabelHostProps {
|
|
3
|
+
connector: ConnectorDef;
|
|
4
|
+
/** Loaded neighbor configs, used to resolve destination names/thumbnails. */
|
|
5
|
+
connectedSpaces: Record<string, CaveSpace>;
|
|
6
|
+
/** Which destinations have finished preloading — gates clickability. */
|
|
7
|
+
readySpaceIds: Record<string, true>;
|
|
8
|
+
/** Connector the player is inside; its own label hides. */
|
|
9
|
+
activeConnectorId?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Drives one connector's always-on wayfinding label.
|
|
13
|
+
*
|
|
14
|
+
* Owns visibility (distance fade, hide-while-inside, portal-only) and computes
|
|
15
|
+
* it on the render loop, then pushes to React state only when a threshold is
|
|
16
|
+
* crossed — a per-frame `setState` here would re-render the label on every
|
|
17
|
+
* frame the player moves. The visual itself comes from
|
|
18
|
+
* `connectorLabelRenderer`, so hosts can restyle without touching this logic.
|
|
19
|
+
*/
|
|
20
|
+
export default function ConnectorLabelHost({ connector, connectedSpaces, readySpaceIds, activeConnectorId }: ConnectorLabelHostProps): import("react").JSX.Element | null;
|
|
21
|
+
//# sourceMappingURL=connector-label-host.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connector-label-host.d.ts","sourceRoot":"","sources":["../../space/connector-label-host.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAevD,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,YAAY,CAAA;IACvB,6EAA6E;IAC7E,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IAC1C,wEAAwE;IACxE,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IACnC,2DAA2D;IAC3D,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,EACzC,SAAS,EACT,eAAe,EACf,aAAa,EACb,iBAAiB,EAClB,EAAE,uBAAuB,sCA0FzB"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { jsx as c } from "react/jsx-runtime";
|
|
2
|
+
import { useRef as g, useState as x, useMemo as u, useCallback as E } from "react";
|
|
3
|
+
import { useFrame as N } from "@react-three/fiber";
|
|
4
|
+
import { Vector3 as f } from "three";
|
|
5
|
+
import { useCaveWorld as A, useCaveEventBus as B } from "../core/context/cave-world-context.js";
|
|
6
|
+
import { shouldShowConnectorLabel as D, resolveConnectorLabel as V, getPortalTargetsWithSpaces as j, computeLabelVisibility as F } from "../core/connector-label/types.js";
|
|
7
|
+
import { resolveConnectorTransferStatus as H } from "../core/connector-label/readiness.js";
|
|
8
|
+
const Y = 0.15, q = 0.05, v = /* @__PURE__ */ new f(), I = /* @__PURE__ */ new f(), R = /* @__PURE__ */ new f();
|
|
9
|
+
function $({
|
|
10
|
+
connector: e,
|
|
11
|
+
connectedSpaces: s,
|
|
12
|
+
readySpaceIds: p,
|
|
13
|
+
activeConnectorId: b
|
|
14
|
+
}) {
|
|
15
|
+
const { connectorLabel: T, connectorLabelRenderer: i, messages: m } = A(), y = B(), r = g(null), [_, O] = x(null), h = D(e, T), t = u(
|
|
16
|
+
() => V(e, s, m.connector.fallbackLabel),
|
|
17
|
+
[e, s, m.connector.fallbackLabel]
|
|
18
|
+
), L = u(
|
|
19
|
+
() => H(e, s, p),
|
|
20
|
+
[e, s, p]
|
|
21
|
+
), S = u(
|
|
22
|
+
() => j(e, s),
|
|
23
|
+
[e, s]
|
|
24
|
+
), l = t.clickable && L === "ready", W = E(() => {
|
|
25
|
+
l && y.emit("connector:label:click", { connector: e });
|
|
26
|
+
}, [l, e, y]), P = g({
|
|
27
|
+
distance: -1,
|
|
28
|
+
opacity: -1,
|
|
29
|
+
displayMode: "hidden",
|
|
30
|
+
isPlayerInside: !1
|
|
31
|
+
});
|
|
32
|
+
if (N(({ camera: w }) => {
|
|
33
|
+
if (!h || !i || !r.current) return;
|
|
34
|
+
v.set(...t.anchorOffset), r.current.localToWorld(I.copy(v)), w.getWorldPosition(R);
|
|
35
|
+
const n = R.distanceTo(I), d = b === e.id, { opacity: C, displayMode: M } = F(n, t, d), o = P.current;
|
|
36
|
+
if (Math.abs(o.distance - n) < Y && Math.abs(o.opacity - C) < q && o.displayMode === M && o.isPlayerInside === d) return;
|
|
37
|
+
const k = { distance: n, opacity: C, displayMode: M, isPlayerInside: d };
|
|
38
|
+
P.current = k, O(k);
|
|
39
|
+
}), !h || !i) return null;
|
|
40
|
+
const a = _ ?? {
|
|
41
|
+
distance: t.visibility.maxDistance,
|
|
42
|
+
opacity: 0,
|
|
43
|
+
displayMode: "hidden",
|
|
44
|
+
isPlayerInside: b === e.id
|
|
45
|
+
};
|
|
46
|
+
return /* @__PURE__ */ c("group", { position: e.transform.position, rotation: e.transform.rotation, children: /* @__PURE__ */ c("group", { ref: r, position: t.anchorOffset, children: a.displayMode !== "hidden" && a.opacity > 0 ? /* @__PURE__ */ c(
|
|
47
|
+
i,
|
|
48
|
+
{
|
|
49
|
+
connector: e,
|
|
50
|
+
label: t,
|
|
51
|
+
targets: S,
|
|
52
|
+
distance: a.distance,
|
|
53
|
+
isPlayerInside: a.isPlayerInside,
|
|
54
|
+
opacity: a.opacity,
|
|
55
|
+
displayMode: a.displayMode,
|
|
56
|
+
clickable: t.clickable,
|
|
57
|
+
transferStatus: L,
|
|
58
|
+
onClick: l ? W : void 0
|
|
59
|
+
}
|
|
60
|
+
) : null }) });
|
|
61
|
+
}
|
|
62
|
+
export {
|
|
63
|
+
$ as default
|
|
64
|
+
};
|
|
65
|
+
//# sourceMappingURL=connector-label-host.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connector-label-host.js","sources":["../../space/connector-label-host.tsx"],"sourcesContent":["import { useCallback, useMemo, useRef, useState } from 'react'\nimport { useFrame } from '@react-three/fiber'\nimport type { Group } from 'three'\nimport { Vector3 as ThreeVec3 } from 'three'\nimport {\n computeLabelVisibility,\n getPortalTargetsWithSpaces,\n resolveConnectorLabel,\n resolveConnectorTransferStatus,\n shouldShowConnectorLabel,\n useCaveEventBus,\n useCaveWorld,\n type ConnectorLabelRendererProps\n} from '../core'\nimport type { CaveSpace, ConnectorDef } from '../types'\n\n/** Frame-to-frame deltas below these are not worth a React re-render. */\nconst DISTANCE_EPSILON_M = 0.15\nconst OPACITY_EPSILON = 0.05\n\nconst _anchorLocal = /* @__PURE__ */ new ThreeVec3()\nconst _anchorWorld = /* @__PURE__ */ new ThreeVec3()\nconst _cameraPos = /* @__PURE__ */ new ThreeVec3()\n\ntype LabelRenderState = Pick<\n ConnectorLabelRendererProps,\n 'distance' | 'opacity' | 'displayMode' | 'isPlayerInside'\n>\n\nexport interface ConnectorLabelHostProps {\n connector: ConnectorDef\n /** Loaded neighbor configs, used to resolve destination names/thumbnails. */\n connectedSpaces: Record<string, CaveSpace>\n /** Which destinations have finished preloading — gates clickability. */\n readySpaceIds: Record<string, true>\n /** Connector the player is inside; its own label hides. */\n activeConnectorId?: string\n}\n\n/**\n * Drives one connector's always-on wayfinding label.\n *\n * Owns visibility (distance fade, hide-while-inside, portal-only) and computes\n * it on the render loop, then pushes to React state only when a threshold is\n * crossed — a per-frame `setState` here would re-render the label on every\n * frame the player moves. The visual itself comes from\n * `connectorLabelRenderer`, so hosts can restyle without touching this logic.\n */\nexport default function ConnectorLabelHost({\n connector,\n connectedSpaces,\n readySpaceIds,\n activeConnectorId\n}: ConnectorLabelHostProps) {\n const { connectorLabel, connectorLabelRenderer: Renderer, messages } = useCaveWorld()\n const eventBus = useCaveEventBus()\n const anchorRef = useRef<Group>(null)\n const [renderState, setRenderState] = useState<LabelRenderState | null>(null)\n\n const enabled = shouldShowConnectorLabel(connector, connectorLabel)\n\n const resolvedLabel = useMemo(\n () => resolveConnectorLabel(connector, connectedSpaces, messages.connector.fallbackLabel),\n [connector, connectedSpaces, messages.connector.fallbackLabel]\n )\n\n const transferStatus = useMemo(\n () => resolveConnectorTransferStatus(connector, connectedSpaces, readySpaceIds),\n [connector, connectedSpaces, readySpaceIds]\n )\n\n const targets = useMemo(\n () => getPortalTargetsWithSpaces(connector, connectedSpaces),\n [connector, connectedSpaces]\n )\n\n const canClick = resolvedLabel.clickable && transferStatus === 'ready'\n\n const handleLabelClick = useCallback(() => {\n if (!canClick) return\n eventBus.emit('connector:label:click', { connector })\n }, [canClick, connector, eventBus])\n\n const lastStateRef = useRef<LabelRenderState>({\n distance: -1,\n opacity: -1,\n displayMode: 'hidden',\n isPlayerInside: false\n })\n\n useFrame(({ camera }) => {\n if (!enabled || !Renderer || !anchorRef.current) return\n\n _anchorLocal.set(...resolvedLabel.anchorOffset)\n anchorRef.current.localToWorld(_anchorWorld.copy(_anchorLocal))\n camera.getWorldPosition(_cameraPos)\n const distance = _cameraPos.distanceTo(_anchorWorld)\n\n const isPlayerInside = activeConnectorId === connector.id\n const { opacity, displayMode } = computeLabelVisibility(distance, resolvedLabel, isPlayerInside)\n\n const previous = lastStateRef.current\n const unchanged =\n Math.abs(previous.distance - distance) < DISTANCE_EPSILON_M &&\n Math.abs(previous.opacity - opacity) < OPACITY_EPSILON &&\n previous.displayMode === displayMode &&\n previous.isPlayerInside === isPlayerInside\n if (unchanged) return\n\n const next: LabelRenderState = { distance, opacity, displayMode, isPlayerInside }\n lastStateRef.current = next\n setRenderState(next)\n })\n\n if (!enabled || !Renderer) return null\n\n const state: LabelRenderState = renderState ?? {\n distance: resolvedLabel.visibility.maxDistance,\n opacity: 0,\n displayMode: 'hidden',\n isPlayerInside: activeConnectorId === connector.id\n }\n\n return (\n <group position={connector.transform.position} rotation={connector.transform.rotation}>\n <group ref={anchorRef} position={resolvedLabel.anchorOffset}>\n {state.displayMode !== 'hidden' && state.opacity > 0 ? (\n <Renderer\n connector={connector}\n label={resolvedLabel}\n targets={targets}\n distance={state.distance}\n isPlayerInside={state.isPlayerInside}\n opacity={state.opacity}\n displayMode={state.displayMode}\n clickable={resolvedLabel.clickable}\n transferStatus={transferStatus}\n onClick={canClick ? handleLabelClick : undefined}\n />\n ) : null}\n </group>\n </group>\n )\n}\n"],"names":["DISTANCE_EPSILON_M","OPACITY_EPSILON","_anchorLocal","ThreeVec3","_anchorWorld","_cameraPos","ConnectorLabelHost","connector","connectedSpaces","readySpaceIds","activeConnectorId","connectorLabel","Renderer","messages","useCaveWorld","eventBus","useCaveEventBus","anchorRef","useRef","renderState","setRenderState","useState","enabled","shouldShowConnectorLabel","resolvedLabel","useMemo","resolveConnectorLabel","transferStatus","resolveConnectorTransferStatus","targets","getPortalTargetsWithSpaces","canClick","handleLabelClick","useCallback","lastStateRef","useFrame","camera","distance","isPlayerInside","opacity","displayMode","computeLabelVisibility","previous","next","state","jsx"],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export { default as CaveSpace, type CaveSpaceProps } from './cave-space.js';
|
|
2
|
+
export { default as CaveBaseLayer, type CaveBaseLayerProps } from './cave-base-layer.js';
|
|
3
|
+
export { default as CaveCustomLayer } from './cave-custom-layer.js';
|
|
4
|
+
export { default as CaveEnv } from './cave-env.js';
|
|
5
|
+
export { default as CustomObject } from './objects/custom-object.js';
|
|
6
|
+
export { default as ConnectorLabelHost, type ConnectorLabelHostProps } from './connector-label-host.js';
|
|
7
|
+
export { registerBuiltinObjects, registerBuiltinComponents } from './objects/builtin-registrar.js';
|
|
8
|
+
export { default as SplatMesh, type SparkSplatMesh } from './splats/spark/splat-mesh.js';
|
|
9
|
+
export { default as RobustSplatMesh, type RobustSplatMeshProps } from './splats/spark/robust-splat-mesh.js';
|
|
10
|
+
export { SPREAD_REVEAL_DURATION_SEC, SPREAD_REVEAL_TIME_SCALE, REVEAL_ON_ENTER_DEFAULT_ENABLED } from './splats/spark/splat-spread-reveal.js';
|
|
11
|
+
export { useVisibilityFrameloop, type VisibilityFrameloop } from './utils/use-visibility-frameloop.js';
|
|
12
|
+
export { getSparkCanvasDpr } from './utils/spark-performance.js';
|
|
13
|
+
export { configureSparkWebGLRenderer, configureCaveCanvasDomElement } from './utils/configure-canvas.js';
|
|
14
|
+
export { selectSplatLevel, isMobileDevice, getDeviceSplatCountCap, DESKTOP_SPLAT_COUNT_CAP, MOBILE_SPLAT_COUNT_CAP, type SelectedSplatLevel } from './utils/select-splat-level.js';
|
|
15
|
+
export { isTouchPrimaryDevice, useTouchPrimaryDevice, VIVERSE_MOBILE_MEDIA_QUERY } from './utils/touch-primary-device.js';
|
|
16
|
+
export { CAVE_WORLD_LOCAL_PLAYER_FLAG } from './utils/cave-world-player.js';
|
|
17
|
+
export { toQuaternionRotation } from './utils/rotation-compat.js';
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../space/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAA;AACxE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AACrF,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAChE,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,yBAAyB,CAAA;AACjE,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,KAAK,uBAAuB,EAAE,MAAM,wBAAwB,CAAA;AACpG,OAAO,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAA;AAG/F,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAA;AACrF,OAAO,EACL,OAAO,IAAI,eAAe,EAC1B,KAAK,oBAAoB,EAC1B,MAAM,kCAAkC,CAAA;AACzC,OAAO,EACL,0BAA0B,EAC1B,wBAAwB,EACxB,+BAA+B,EAChC,MAAM,oCAAoC,CAAA;AAG3C,OAAO,EAAE,sBAAsB,EAAE,KAAK,mBAAmB,EAAE,MAAM,kCAAkC,CAAA;AACnG,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAC7D,OAAO,EACL,2BAA2B,EAC3B,6BAA6B,EAC9B,MAAM,0BAA0B,CAAA;AAGjC,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,EACtB,KAAK,kBAAkB,EACxB,MAAM,4BAA4B,CAAA;AACnC,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,0BAA0B,EAC3B,MAAM,8BAA8B,CAAA;AAGrC,OAAO,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAA;AACxE,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { default as r } from "./cave-space.js";
|
|
2
|
+
import { default as a } from "./cave-base-layer.js";
|
|
3
|
+
import { default as f } from "./cave-custom-layer.js";
|
|
4
|
+
import { default as E } from "./cave-env.js";
|
|
5
|
+
import { default as i } from "./objects/custom-object.js";
|
|
6
|
+
import { default as l } from "./connector-label-host.js";
|
|
7
|
+
import { registerBuiltinComponents as C, registerBuiltinObjects as L } from "./objects/builtin-registrar.js";
|
|
8
|
+
import { default as n } from "./splats/spark/splat-mesh.js";
|
|
9
|
+
import { default as S } from "./splats/spark/robust-splat-mesh.js";
|
|
10
|
+
import { REVEAL_ON_ENTER_DEFAULT_ENABLED as R, SPREAD_REVEAL_DURATION_SEC as c, SPREAD_REVEAL_TIME_SCALE as v } from "./splats/spark/splat-spread-reveal.js";
|
|
11
|
+
import { useVisibilityFrameloop as T } from "./utils/use-visibility-frameloop.js";
|
|
12
|
+
import { getSparkCanvasDpr as d } from "./utils/spark-performance.js";
|
|
13
|
+
import { configureCaveCanvasDomElement as M, configureSparkWebGLRenderer as V } from "./utils/configure-canvas.js";
|
|
14
|
+
import { DESKTOP_SPLAT_COUNT_CAP as B, MOBILE_SPLAT_COUNT_CAP as I, getDeviceSplatCountCap as N, isMobileDevice as y, selectSplatLevel as U } from "./utils/select-splat-level.js";
|
|
15
|
+
import { VIVERSE_MOBILE_MEDIA_QUERY as F, isTouchPrimaryDevice as j, useTouchPrimaryDevice as k } from "./utils/touch-primary-device.js";
|
|
16
|
+
import { CAVE_WORLD_LOCAL_PLAYER_FLAG as Q } from "./utils/cave-world-player.js";
|
|
17
|
+
import { toQuaternionRotation as Y } from "./utils/rotation-compat.js";
|
|
18
|
+
export {
|
|
19
|
+
Q as CAVE_WORLD_LOCAL_PLAYER_FLAG,
|
|
20
|
+
a as CaveBaseLayer,
|
|
21
|
+
f as CaveCustomLayer,
|
|
22
|
+
E as CaveEnv,
|
|
23
|
+
r as CaveSpace,
|
|
24
|
+
l as ConnectorLabelHost,
|
|
25
|
+
i as CustomObject,
|
|
26
|
+
B as DESKTOP_SPLAT_COUNT_CAP,
|
|
27
|
+
I as MOBILE_SPLAT_COUNT_CAP,
|
|
28
|
+
R as REVEAL_ON_ENTER_DEFAULT_ENABLED,
|
|
29
|
+
S as RobustSplatMesh,
|
|
30
|
+
c as SPREAD_REVEAL_DURATION_SEC,
|
|
31
|
+
v as SPREAD_REVEAL_TIME_SCALE,
|
|
32
|
+
n as SplatMesh,
|
|
33
|
+
F as VIVERSE_MOBILE_MEDIA_QUERY,
|
|
34
|
+
M as configureCaveCanvasDomElement,
|
|
35
|
+
V as configureSparkWebGLRenderer,
|
|
36
|
+
N as getDeviceSplatCountCap,
|
|
37
|
+
d as getSparkCanvasDpr,
|
|
38
|
+
y as isMobileDevice,
|
|
39
|
+
j as isTouchPrimaryDevice,
|
|
40
|
+
C as registerBuiltinComponents,
|
|
41
|
+
L as registerBuiltinObjects,
|
|
42
|
+
U as selectSplatLevel,
|
|
43
|
+
Y as toQuaternionRotation,
|
|
44
|
+
k as useTouchPrimaryDevice,
|
|
45
|
+
T as useVisibilityFrameloop
|
|
46
|
+
};
|
|
47
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ObjectRegistry } from '../../core/registry/object-registry.js';
|
|
2
|
+
import type { ComponentRegistry } from '../../core/registry/component-registry.js';
|
|
3
|
+
/**
|
|
4
|
+
* Install the built-in object renderers.
|
|
5
|
+
*
|
|
6
|
+
* Uses `registerDefault`, so a type the host registered before mount keeps its
|
|
7
|
+
* own renderer — this is how you override e.g. `poi` or `portal` visuals.
|
|
8
|
+
*
|
|
9
|
+
* Schema types without a built-in renderer (`infoPoint`, `panoramaVideo`,
|
|
10
|
+
* `digitalHuman2D`, `text`, `light`, `audio`, `npc`) are intentionally left to
|
|
11
|
+
* the host: they need product-specific UI. Objects of an unregistered type are
|
|
12
|
+
* skipped silently.
|
|
13
|
+
*/
|
|
14
|
+
export declare function registerBuiltinObjects(registry: ObjectRegistry): void;
|
|
15
|
+
/** Install the built-in behavior components (see {@link registerBuiltinObjects}). */
|
|
16
|
+
export declare function registerBuiltinComponents(registry: ComponentRegistry): void;
|
|
17
|
+
//# sourceMappingURL=builtin-registrar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builtin-registrar.d.ts","sourceRoot":"","sources":["../../../space/objects/builtin-registrar.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAA;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAA;AAU/E;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,CAQrE;AAED,qFAAqF;AACrF,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAE3E"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import t from "./model-object/index.js";
|
|
2
|
+
import o from "./model-object/splat-object.js";
|
|
3
|
+
import r from "./placeholder-object.js";
|
|
4
|
+
import i from "./video-object.js";
|
|
5
|
+
import m from "./image-object.js";
|
|
6
|
+
import l from "./poi-object.js";
|
|
7
|
+
import f from "./portal-object.js";
|
|
8
|
+
import a from "./object-components/windows/index.js";
|
|
9
|
+
function D(e) {
|
|
10
|
+
e.registerDefault("model", t), e.registerDefault("splat", o), e.registerDefault("video", i), e.registerDefault("image", m), e.registerDefault("poi", l), e.registerDefault("portal", f), e.registerDefault("placeholder", r);
|
|
11
|
+
}
|
|
12
|
+
function O(e) {
|
|
13
|
+
e.registerDefault("Window", a, { requiresInteraction: !0 });
|
|
14
|
+
}
|
|
15
|
+
export {
|
|
16
|
+
O as registerBuiltinComponents,
|
|
17
|
+
D as registerBuiltinObjects
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=builtin-registrar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builtin-registrar.js","sources":["../../../space/objects/builtin-registrar.ts"],"sourcesContent":["import type { ObjectRegistry } from '../../core/registry/object-registry'\nimport type { ComponentRegistry } from '../../core/registry/component-registry'\nimport ModelObject from './model-object'\nimport SplatObject from './model-object/splat-object'\nimport PlaceholderObject from './placeholder-object'\nimport VideoObject from './video-object'\nimport ImageObject from './image-object'\nimport PoiObject from './poi-object'\nimport PortalObject from './portal-object'\nimport WindowComponent from './object-components/windows'\n\n/**\n * Install the built-in object renderers.\n *\n * Uses `registerDefault`, so a type the host registered before mount keeps its\n * own renderer — this is how you override e.g. `poi` or `portal` visuals.\n *\n * Schema types without a built-in renderer (`infoPoint`, `panoramaVideo`,\n * `digitalHuman2D`, `text`, `light`, `audio`, `npc`) are intentionally left to\n * the host: they need product-specific UI. Objects of an unregistered type are\n * skipped silently.\n */\nexport function registerBuiltinObjects(registry: ObjectRegistry): void {\n registry.registerDefault('model', ModelObject)\n registry.registerDefault('splat', SplatObject)\n registry.registerDefault('video', VideoObject)\n registry.registerDefault('image', ImageObject)\n registry.registerDefault('poi', PoiObject)\n registry.registerDefault('portal', PortalObject)\n registry.registerDefault('placeholder', PlaceholderObject)\n}\n\n/** Install the built-in behavior components (see {@link registerBuiltinObjects}). */\nexport function registerBuiltinComponents(registry: ComponentRegistry): void {\n registry.registerDefault('Window', WindowComponent, { requiresInteraction: true })\n}\n"],"names":["registerBuiltinObjects","registry","ModelObject","SplatObject","VideoObject","ImageObject","PoiObject","PortalObject","PlaceholderObject","registerBuiltinComponents","WindowComponent"],"mappings":";;;;;;;;AAsBO,SAASA,EAAuBC,GAAgC;AACrE,EAAAA,EAAS,gBAAgB,SAASC,CAAW,GAC7CD,EAAS,gBAAgB,SAASE,CAAW,GAC7CF,EAAS,gBAAgB,SAASG,CAAW,GAC7CH,EAAS,gBAAgB,SAASI,CAAW,GAC7CJ,EAAS,gBAAgB,OAAOK,CAAS,GACzCL,EAAS,gBAAgB,UAAUM,CAAY,GAC/CN,EAAS,gBAAgB,eAAeO,CAAiB;AAC3D;AAGO,SAASC,EAA0BR,GAAmC;AAC3E,EAAAA,EAAS,gBAAgB,UAAUS,GAAiB,EAAE,qBAAqB,IAAM;AACnF;"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ThreeEvent } from '@react-three/fiber';
|
|
2
|
+
import type { CustomObject as CustomObjectType } from '../../types/index.js';
|
|
3
|
+
declare function CustomObject(props: {
|
|
4
|
+
object: CustomObjectType;
|
|
5
|
+
onClick?: (event: ThreeEvent<MouseEvent>) => void;
|
|
6
|
+
physics?: boolean;
|
|
7
|
+
}): import("react").JSX.Element;
|
|
8
|
+
export default CustomObject;
|
|
9
|
+
//# sourceMappingURL=custom-object.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"custom-object.d.ts","sourceRoot":"","sources":["../../../space/objects/custom-object.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,KAAK,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAKnE,iBAAS,YAAY,CAAC,KAAK,EAAE;IAC3B,MAAM,EAAE,gBAAgB,CAAA;IACxB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,UAAU,CAAC,KAAK,IAAI,CAAA;IACjD,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,+BAiFA;AAED,eAAe,YAAY,CAAA"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { jsx as i, jsxs as l } from "react/jsx-runtime";
|
|
2
|
+
import { useRef as d, useMemo as b, useEffect as C, useCallback as v, Suspense as w, createElement as R } from "react";
|
|
3
|
+
import { useCaveEventBus as O, useObjectRegistry as x, useComponentRegistry as B } from "../../core/context/cave-world-context.js";
|
|
4
|
+
import { createLogger as E } from "../../core/logging/logger.js";
|
|
5
|
+
const f = E("space:custom-object");
|
|
6
|
+
function I(o) {
|
|
7
|
+
const { object: e, physics: g } = o, a = O(), y = x(), n = B(), m = d(/* @__PURE__ */ new Set()), u = d(/* @__PURE__ */ new Set()), r = y.get(e.type), s = b(
|
|
8
|
+
() => e.components ? Object.keys(e.components) : [],
|
|
9
|
+
[e.components]
|
|
10
|
+
);
|
|
11
|
+
C(() => {
|
|
12
|
+
!r && !m.current.has(e.type) && (m.current.add(e.type), f.debug(
|
|
13
|
+
`No renderer registered for object type "${e.type}" (id=${e.id ?? "unknown"}). The object group mounts empty. Register a renderer or ignore schema-only types.`
|
|
14
|
+
));
|
|
15
|
+
for (const t of s)
|
|
16
|
+
n.get(t) || u.current.has(t) || (u.current.add(t), f.debug(
|
|
17
|
+
`No behavior component registered for "${t}" on object ${e.id ?? "unknown"}.`
|
|
18
|
+
));
|
|
19
|
+
}, [r, s, n, e.id, e.type]);
|
|
20
|
+
const p = b(() => s.map((t) => {
|
|
21
|
+
const c = n.get(t);
|
|
22
|
+
return c ? { name: t, ...c } : null;
|
|
23
|
+
}).filter(Boolean), [s, n]), j = p.some((t) => t.requiresInteraction), h = v(
|
|
24
|
+
(t) => {
|
|
25
|
+
a.emit("object:click", { object: e, nativeEvent: t }), o.onClick?.(t);
|
|
26
|
+
},
|
|
27
|
+
[a, e, o]
|
|
28
|
+
), k = j || o.onClick ? h : void 0;
|
|
29
|
+
return /* @__PURE__ */ i(
|
|
30
|
+
"group",
|
|
31
|
+
{
|
|
32
|
+
name: "custom-object",
|
|
33
|
+
position: e.transform.position,
|
|
34
|
+
quaternion: e.transform.rotation,
|
|
35
|
+
scale: e.transform.scale,
|
|
36
|
+
userData: { customObject: e },
|
|
37
|
+
children: /* @__PURE__ */ l(
|
|
38
|
+
w,
|
|
39
|
+
{
|
|
40
|
+
fallback: /* @__PURE__ */ l("mesh", { name: "fallback-custom-object", children: [
|
|
41
|
+
/* @__PURE__ */ i("boxGeometry", { args: [1, 1, 1] }),
|
|
42
|
+
/* @__PURE__ */ i("meshBasicMaterial", { transparent: !0, opacity: 0.5, visible: !0 })
|
|
43
|
+
] }),
|
|
44
|
+
children: [
|
|
45
|
+
r && R(r, { object: e, onClick: k, physics: g }),
|
|
46
|
+
p.map(({ name: t, component: c }) => /* @__PURE__ */ i(c, { object: e }, t))
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
export {
|
|
54
|
+
I as default
|
|
55
|
+
};
|
|
56
|
+
//# sourceMappingURL=custom-object.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"custom-object.js","sources":["../../../space/objects/custom-object.tsx"],"sourcesContent":["import { createElement, Suspense, useCallback, useEffect, useMemo, useRef } from 'react'\nimport type { ThreeEvent } from '@react-three/fiber'\nimport type { CustomObject as CustomObjectType } from '../../types'\nimport { createLogger, useCaveEventBus, useObjectRegistry, useComponentRegistry } from '../../core'\n\nconst logger = createLogger('space:custom-object')\n\nfunction CustomObject(props: {\n object: CustomObjectType\n onClick?: (event: ThreeEvent<MouseEvent>) => void\n physics?: boolean\n}) {\n const { object, physics } = props\n const eventBus = useCaveEventBus()\n const objectRegistry = useObjectRegistry()\n const componentRegistry = useComponentRegistry()\n const warnedTypes = useRef(new Set<string>())\n const warnedComponents = useRef(new Set<string>())\n\n const ObjectNode = objectRegistry.get(object.type)\n\n const componentNames = useMemo(\n () => (object.components ? Object.keys(object.components) : []),\n [object.components]\n )\n\n useEffect(() => {\n if (!ObjectNode && !warnedTypes.current.has(object.type)) {\n warnedTypes.current.add(object.type)\n logger.debug(\n `No renderer registered for object type \"${object.type}\" (id=${object.id ?? 'unknown'}). ` +\n 'The object group mounts empty. Register a renderer or ignore schema-only types.'\n )\n }\n\n for (const name of componentNames) {\n if (componentRegistry.get(name) || warnedComponents.current.has(name)) continue\n warnedComponents.current.add(name)\n logger.debug(\n `No behavior component registered for \"${name}\" on object ${object.id ?? 'unknown'}.`\n )\n }\n }, [ObjectNode, componentNames, componentRegistry, object.id, object.type])\n\n const resolvedComponents = useMemo(() => {\n return componentNames\n .map((name) => {\n const entry = componentRegistry.get(name)\n return entry ? { name, ...entry } : null\n })\n .filter(Boolean) as Array<{\n name: string\n component: React.ComponentType<{ object: CustomObjectType }>\n requiresInteraction: boolean\n }>\n }, [componentNames, componentRegistry])\n\n const needsInteraction = resolvedComponents.some((c) => c.requiresInteraction)\n\n const handleClick = useCallback(\n (event: ThreeEvent<MouseEvent>) => {\n eventBus.emit('object:click', { object, nativeEvent: event })\n props.onClick?.(event)\n },\n [eventBus, object, props]\n )\n\n const onClick = needsInteraction || props.onClick ? handleClick : undefined\n\n return (\n <group\n name=\"custom-object\"\n position={object.transform.position}\n quaternion={object.transform.rotation}\n scale={object.transform.scale}\n userData={{ customObject: object }}\n >\n <Suspense\n fallback={\n <mesh name=\"fallback-custom-object\">\n <boxGeometry args={[1, 1, 1]} />\n <meshBasicMaterial transparent opacity={0.5} visible={true} />\n </mesh>\n }\n >\n {ObjectNode && createElement(ObjectNode, { object, onClick, physics })}\n {resolvedComponents.map(({ name, component: Comp }) => (\n <Comp key={name} object={object} />\n ))}\n </Suspense>\n </group>\n )\n}\n\nexport default CustomObject\n"],"names":["logger","createLogger","CustomObject","props","object","physics","eventBus","useCaveEventBus","objectRegistry","useObjectRegistry","componentRegistry","useComponentRegistry","warnedTypes","useRef","warnedComponents","ObjectNode","componentNames","useMemo","useEffect","name","resolvedComponents","entry","needsInteraction","c","handleClick","useCallback","event","onClick","jsx","jsxs","Suspense","createElement","Comp"],"mappings":";;;;AAKA,MAAMA,IAASC,EAAa,qBAAqB;AAEjD,SAASC,EAAaC,GAInB;AACD,QAAM,EAAE,QAAAC,GAAQ,SAAAC,EAAA,IAAYF,GACtBG,IAAWC,EAAA,GACXC,IAAiBC,EAAA,GACjBC,IAAoBC,EAAA,GACpBC,IAAcC,EAAO,oBAAI,KAAa,GACtCC,IAAmBD,EAAO,oBAAI,KAAa,GAE3CE,IAAaP,EAAe,IAAIJ,EAAO,IAAI,GAE3CY,IAAiBC;AAAA,IACrB,MAAOb,EAAO,aAAa,OAAO,KAAKA,EAAO,UAAU,IAAI,CAAA;AAAA,IAC5D,CAACA,EAAO,UAAU;AAAA,EAAA;AAGpB,EAAAc,EAAU,MAAM;AACd,IAAI,CAACH,KAAc,CAACH,EAAY,QAAQ,IAAIR,EAAO,IAAI,MACrDQ,EAAY,QAAQ,IAAIR,EAAO,IAAI,GACnCJ,EAAO;AAAA,MACL,2CAA2CI,EAAO,IAAI,SAASA,EAAO,MAAM,SAAS;AAAA,IAAA;AAKzF,eAAWe,KAAQH;AACjB,MAAIN,EAAkB,IAAIS,CAAI,KAAKL,EAAiB,QAAQ,IAAIK,CAAI,MACpEL,EAAiB,QAAQ,IAAIK,CAAI,GACjCnB,EAAO;AAAA,QACL,yCAAyCmB,CAAI,eAAef,EAAO,MAAM,SAAS;AAAA,MAAA;AAAA,EAGxF,GAAG,CAACW,GAAYC,GAAgBN,GAAmBN,EAAO,IAAIA,EAAO,IAAI,CAAC;AAE1E,QAAMgB,IAAqBH,EAAQ,MAC1BD,EACJ,IAAI,CAACG,MAAS;AACb,UAAME,IAAQX,EAAkB,IAAIS,CAAI;AACxC,WAAOE,IAAQ,EAAE,MAAAF,GAAM,GAAGE,MAAU;AAAA,EACtC,CAAC,EACA,OAAO,OAAO,GAKhB,CAACL,GAAgBN,CAAiB,CAAC,GAEhCY,IAAmBF,EAAmB,KAAK,CAACG,MAAMA,EAAE,mBAAmB,GAEvEC,IAAcC;AAAA,IAClB,CAACC,MAAkC;AACjC,MAAApB,EAAS,KAAK,gBAAgB,EAAE,QAAAF,GAAQ,aAAasB,GAAO,GAC5DvB,EAAM,UAAUuB,CAAK;AAAA,IACvB;AAAA,IACA,CAACpB,GAAUF,GAAQD,CAAK;AAAA,EAAA,GAGpBwB,IAAUL,KAAoBnB,EAAM,UAAUqB,IAAc;AAElE,SACE,gBAAAI;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,UAAUxB,EAAO,UAAU;AAAA,MAC3B,YAAYA,EAAO,UAAU;AAAA,MAC7B,OAAOA,EAAO,UAAU;AAAA,MACxB,UAAU,EAAE,cAAcA,EAAA;AAAA,MAE1B,UAAA,gBAAAyB;AAAA,QAACC;AAAA,QAAA;AAAA,UACC,UACE,gBAAAD,EAAC,QAAA,EAAK,MAAK,0BACT,UAAA;AAAA,YAAA,gBAAAD,EAAC,iBAAY,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG;AAAA,8BAC7B,qBAAA,EAAkB,aAAW,IAAC,SAAS,KAAK,SAAS,GAAA,CAAM;AAAA,UAAA,GAC9D;AAAA,UAGD,UAAA;AAAA,YAAAb,KAAcgB,EAAchB,GAAY,EAAE,QAAAX,GAAQ,SAAAuB,GAAS,SAAAtB,GAAS;AAAA,YACpEe,EAAmB,IAAI,CAAC,EAAE,MAAAD,GAAM,WAAWa,QAC1C,gBAAAJ,EAACI,GAAA,EAAgB,QAAA5B,EAAA,GAANe,CAAsB,CAClC;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IACH;AAAA,EAAA;AAGN;"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CustomObject } from '../../types/index.js';
|
|
2
|
+
import type { ThreeEvent } from '@react-three/fiber';
|
|
3
|
+
export default function ImageObject(props: {
|
|
4
|
+
object: CustomObject;
|
|
5
|
+
onClick?: (event: ThreeEvent<MouseEvent>) => void;
|
|
6
|
+
}): import("react").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=image-object.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-object.d.ts","sourceRoot":"","sources":["../../../space/objects/image-object.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAGpD,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,KAAK,EAAE;IACzC,MAAM,EAAE,YAAY,CAAA;IACpB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,UAAU,CAAC,KAAK,IAAI,CAAA;CAClD,+BAUA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsxs as s, jsx as t } from "react/jsx-runtime";
|
|
2
|
+
import { DoubleSide as m } from "three";
|
|
3
|
+
import { useTexture as u } from "@react-three/drei";
|
|
4
|
+
function l(r) {
|
|
5
|
+
const { object: e, onClick: a } = r, o = u(e.image?.url || "");
|
|
6
|
+
return /* @__PURE__ */ s("mesh", { castShadow: !0, receiveShadow: !0, onClick: a, userData: { customObject: e }, children: [
|
|
7
|
+
/* @__PURE__ */ t("planeGeometry", { args: [1, 1] }),
|
|
8
|
+
/* @__PURE__ */ t("meshBasicMaterial", { map: o, transparent: !0, side: m })
|
|
9
|
+
] });
|
|
10
|
+
}
|
|
11
|
+
export {
|
|
12
|
+
l as default
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=image-object.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-object.js","sources":["../../../space/objects/image-object.tsx"],"sourcesContent":["import type { CustomObject } from '../../types'\nimport { DoubleSide } from 'three'\nimport type { ThreeEvent } from '@react-three/fiber'\nimport { useTexture } from '@react-three/drei'\n\nexport default function ImageObject(props: {\n object: CustomObject\n onClick?: (event: ThreeEvent<MouseEvent>) => void\n}) {\n const { object, onClick } = props\n const texture = useTexture(object.image?.url || '')\n\n return (\n <mesh castShadow receiveShadow onClick={onClick} userData={{ customObject: object }}>\n <planeGeometry args={[1, 1]} />\n <meshBasicMaterial map={texture} transparent side={DoubleSide} />\n </mesh>\n )\n}\n"],"names":["ImageObject","props","object","onClick","texture","useTexture","jsxs","jsx","DoubleSide"],"mappings":";;;AAKA,SAAwBA,EAAYC,GAGjC;AACD,QAAM,EAAE,QAAAC,GAAQ,SAAAC,EAAA,IAAYF,GACtBG,IAAUC,EAAWH,EAAO,OAAO,OAAO,EAAE;AAElD,SACE,gBAAAI,EAAC,QAAA,EAAK,YAAU,IAAC,eAAa,IAAC,SAAAH,GAAkB,UAAU,EAAE,cAAcD,EAAA,GACzE,UAAA;AAAA,IAAA,gBAAAK,EAAC,iBAAA,EAAc,MAAM,CAAC,GAAG,CAAC,GAAG;AAAA,sBAC5B,qBAAA,EAAkB,KAAKH,GAAS,aAAW,IAAC,MAAMI,EAAA,CAAY;AAAA,EAAA,GACjE;AAEJ;"}
|