|
1 | 1 | import { XRDevice } from 'iwer'
|
2 |
| -import { Camera, Object3D, WebXRManager } from 'three' |
| 2 | +import { Camera, Object3D, WebXRManager, Vector3 } from 'three' |
3 | 3 | import { StoreApi, createStore } from 'zustand/vanilla'
|
4 | 4 | import { XRControllerLayoutLoaderOptions, updateXRControllerState } from './controller/index.js'
|
5 | 5 | import { XRHandLoaderOptions } from './hand/index.js'
|
@@ -427,6 +427,10 @@ declare global {
|
427 | 427 | }
|
428 | 428 | }
|
429 | 429 |
|
| 430 | +//helpers for layer sorting |
| 431 | +const cameraWorldPosition = new Vector3() |
| 432 | +const tempLayerWorldPosition = new Vector3() |
| 433 | + |
430 | 434 | export function createXRStore<T extends XRElementImplementations>(options?: XRStoreOptions<T>): XRStore<T> {
|
431 | 435 | //dom overlay root element creation
|
432 | 436 | const domOverlayRoot =
|
@@ -678,8 +682,24 @@ export function createXRStore<T extends XRElementImplementations>(options?: XRSt
|
678 | 682 | if (currentLayers == null) {
|
679 | 683 | return
|
680 | 684 | }
|
681 |
| - //TODO: sort by distance to camera |
682 |
| - ;(layerEntries as Array<(typeof layerEntries)[number]>).sort((l1, l2) => l1.renderOrder - l2.renderOrder) |
| 685 | + //sort by distance to camera |
| 686 | + const xrCamera = xrManager.getCamera() |
| 687 | + xrCamera.getWorldPosition(cameraWorldPosition) |
| 688 | + ;(layerEntries as Array<XRLayerEntry>).sort((entryA, entryB) => { |
| 689 | + entryA.object3D.getWorldPosition(tempLayerWorldPosition) |
| 690 | + const distA_sq = tempLayerWorldPosition.distanceToSquared(cameraWorldPosition) |
| 691 | + |
| 692 | + entryB.object3D.getWorldPosition(tempLayerWorldPosition) |
| 693 | + const distB_sq = tempLayerWorldPosition.distanceToSquared(cameraWorldPosition) |
| 694 | + |
| 695 | + const depthDifference = distB_sq - distA_sq |
| 696 | + |
| 697 | + //if the distance is the same, fall back to renderOrder |
| 698 | + if (Math.abs(depthDifference) < 0.00001) { |
| 699 | + return entryA.renderOrder - entryB.renderOrder |
| 700 | + } |
| 701 | + return depthDifference |
| 702 | + }) |
683 | 703 | let changed = false
|
684 | 704 | const layers = layerEntries.map<XRLayer>(({ layer }, i) => {
|
685 | 705 | if (layer != currentLayers[i]) {
|
|
0 commit comments