Skip to content

Commit 4e235bb

Browse files
committed
add devtools
1 parent c876a13 commit 4e235bb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+3790
-7
lines changed

src/devtool/EmulatorDevtools.tsx

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/*
2+
CPAL-1.0 License
3+
4+
The contents of this file are subject to the Common Public Attribution License
5+
Version 1.0. (the "License"); you may not use this file except in compliance
6+
with the License. You may obtain a copy of the License at
7+
https://github.com/ir-engine/ir-engine/blob/dev/LICENSE.
8+
The License is based on the Mozilla Public License Version 1.1, but Sections 14
9+
and 15 have been added to cover use of software over a computer network and
10+
provide for limited attribution for the Original Developer. In addition,
11+
Exhibit A has been modified to be consistent with Exhibit B.
12+
13+
Software distributed under the License is distributed on an "AS IS" basis,
14+
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
15+
specific language governing rights and limitations under the License.
16+
17+
The Original Code is Infinite Reality Engine.
18+
19+
The Original Developer is the Initial Developer. The Initial Developer of the
20+
Original Code is the Infinite Reality Engine team.
21+
22+
All portions of the code written by the Infinite Reality Engine team are Copyright © 2021-2023
23+
Infinite Reality Engine. All Rights Reserved.
24+
*/
25+
26+
import { useHookstate, useImmediateEffect, useMutableState } from '@ir-engine/hyperflux'
27+
import { endXRSession, requestXRSession } from '@ir-engine/spatial/src/xr/XRSessionFunctions'
28+
import Button from '@ir-engine/ui/src/primitives/tailwind/Button'
29+
import React from 'react'
30+
31+
import EmulatedDevice from './js/emulatedDevice'
32+
import { EmulatorSettings, emulatorStates } from './js/emulatorStates'
33+
import { syncDevicePose } from './js/messenger'
34+
import Devtool from './jsx/app'
35+
import devtoolCSS from './styles/index.css?inline'
36+
37+
import { XRState } from '@ir-engine/spatial/src/xr/XRState'
38+
39+
import { WebXREventDispatcher } from '@ir-engine/spatial/tests/webxr/emulator/WebXREventDispatcher'
40+
import { POLYFILL_ACTIONS } from '@ir-engine/spatial/tests/webxr/emulator/actions'
41+
42+
export async function overrideXR(args: { mode: 'immersive-vr' | 'immersive-ar' }) {
43+
// inject the webxr polyfill from the webxr emulator source - this is a script added by the bot
44+
// globalThis.WebXRPolyfillInjection()
45+
46+
const { CustomWebXRPolyfill } = await import('@ir-engine/spatial/tests/webxr/emulator/CustomWebXRPolyfill')
47+
new CustomWebXRPolyfill()
48+
// override session supported request, it hangs indefinitely for some reason
49+
;(navigator as any).xr.isSessionSupported = () => {
50+
return true
51+
}
52+
53+
const deviceDefinition = {
54+
id: 'Oculus Quest',
55+
name: 'Oculus Quest',
56+
modes: ['inline', 'immersive-vr', 'immersive-ar'],
57+
headset: {
58+
hasPosition: true,
59+
hasRotation: true
60+
},
61+
controllers: [
62+
{
63+
id: 'Oculus Touch (Right)',
64+
buttonNum: 7,
65+
primaryButtonIndex: 0,
66+
primarySqueezeButtonIndex: 1,
67+
hasPosition: true,
68+
hasRotation: true,
69+
hasSqueezeButton: true,
70+
isComplex: true
71+
},
72+
{
73+
id: 'Oculus Touch (Left)',
74+
buttonNum: 7,
75+
primaryButtonIndex: 0,
76+
primarySqueezeButtonIndex: 1,
77+
hasPosition: true,
78+
hasRotation: true,
79+
hasSqueezeButton: true,
80+
isComplex: true
81+
}
82+
],
83+
environmentBlendMode: args.mode === 'immersive-vr' ? 'opaque' : 'additive'
84+
}
85+
86+
// send our device info to the polyfill API so it knows our capabilities
87+
WebXREventDispatcher.instance.dispatchEvent({
88+
type: POLYFILL_ACTIONS.DEVICE_INIT,
89+
detail: { stereoEffect: false, deviceDefinition }
90+
})
91+
}
92+
93+
const setup = async (mode: 'immersive-vr' | 'immersive-ar') => {
94+
await overrideXR({ mode })
95+
await EmulatorSettings.instance.load()
96+
const device = new EmulatedDevice()
97+
device.on('pose', syncDevicePose)
98+
;(emulatorStates as any).emulatedDevice = device
99+
100+
return device
101+
}
102+
103+
export const EmulatorDevtools = (props: { mode: 'immersive-vr' | 'immersive-ar' }) => {
104+
const xrState = useMutableState(XRState)
105+
const xrActive = xrState.sessionActive.value && !xrState.requestingSession.value
106+
107+
const deviceState = useHookstate(null as null | EmulatedDevice)
108+
useImmediateEffect(() => {
109+
setup(props.mode).then((device) => {
110+
deviceState.set(device)
111+
})
112+
}, [])
113+
114+
const toggleXR = async () => {
115+
if (xrActive) {
116+
endXRSession()
117+
} else {
118+
requestXRSession({ mode: props.mode })
119+
}
120+
}
121+
122+
const togglePlacement = () => {
123+
if (xrState.scenePlacementMode.value !== 'placing') {
124+
xrState.scenePlacementMode.set('placing')
125+
xrState.sceneScaleAutoMode.set(false)
126+
xrState.sceneScaleTarget.set(0.1)
127+
} else {
128+
xrState.scenePlacementMode.set('placed')
129+
}
130+
}
131+
132+
return (
133+
<>
134+
<style type="text/css">{devtoolCSS.toString()}</style>
135+
<div
136+
id="devtools"
137+
className="flex-no-wrap m-0 flex h-full h-full select-none flex-col overflow-hidden overflow-hidden bg-gray-900 text-xs text-gray-900"
138+
>
139+
<div className="flex-no-wrap z-50 flex h-10 select-none flex-row bg-gray-800 text-xs text-gray-900">
140+
<Button className="my-1 ml-auto mr-6 px-10" onClick={toggleXR} disabled={xrState.requestingSession.value}>
141+
{(xrActive ? 'Exit ' : 'Enter ') + (props.mode === 'immersive-ar' ? 'AR' : 'VR')}
142+
</Button>
143+
{props.mode === 'immersive-ar' && (
144+
<Button className="my-1 ml-auto mr-6 px-10" onClick={togglePlacement} disabled={!xrActive}>
145+
Place Scene
146+
</Button>
147+
)}
148+
</div>
149+
{deviceState.value && <Devtool device={deviceState.value} />}
150+
</div>
151+
</>
152+
)
153+
}

src/devtool/assets/headset.glb

34.4 KB
Binary file not shown.
1.15 KB
3.22 KB
3.18 KB
2.94 KB
3.15 KB
924 Bytes

src/devtool/assets/images/exit.png

943 Bytes
1.03 KB

0 commit comments

Comments
 (0)