Skip to content

Commit

Permalink
Add XRCanvas component, update documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
sniok committed May 17, 2020
1 parent 1d1d615 commit eb126cc
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 49 deletions.
74 changes: 28 additions & 46 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ React components and hooks for creating VR/AR/XR applications with [react-three-
<a href="https://codesandbox.io/s/react-xr-paddle-demo-v4uet"><img width="288" src="https://i.imgur.com/K71D3Ts.gif" /></a>
<a href="https://codesandbox.io/s/react-xr-simple-demo-8i9ro"><img width="288" src="https://i.imgur.com/5yh7LKz.gif" /></a>
</p>
<p align="middle">
<i>These demos are real, you can click them! They contain the full code, too.</i>
</p>

## Installation

Expand All @@ -21,83 +24,60 @@ npm install react-xr

## Getting started

Enable VR in the `Canvas` component, add VR button and add `XR` component at the root of your application. This will provide context for XR related state.
Add `XRCanvas` component (or replace your existing react-three-fiber `Canvas` component)

```js
import { XR } from 'react-xr'
import { VRButton } from 'three/examples/jsm/webxr/VRButton'
import { XRCanvas } from 'react-xr'

function App() {
return (
<Canvas
vr
colorManagement
onCreated={({ gl }) => {
document.body.appendChild(VRButton.createButton(gl))
}}>
<XR>{/* All the stuff goes here */}</XR>
</Canvas>
)
return <XRCanvas>{/* All the stuff goes here */}</XRCanvas>
}
```

## Adding controllers to the scene

You can access controllers' state (position, orientation, etc.) by using `useXR()` hook

```js
const { controllers } = useXR()
```

To get started with default controller models add `DefaultXRControllers` component. It will fetch appropriate input profile models. You can learn more [here](https://github.com/immersive-web/webxr-input-profiles/tree/master/packages/motion-controllers).

```js
import { XR, DefaultXRControllers } from 'react-xr'
import { VRButton } from 'three/examples/jsm/webxr/VRButton'
import { XRCanvas, DefaultXRControllers } from 'react-xr'

function App() {
return (
<Canvas
vr
colorManagement
onCreated={({ gl }) => {
document.body.appendChild(VRButton.createButton(gl))
}}>
<XR>
<DefaultXRControllers />
</XR>
</Canvas>
<XRCanvas>
<DefaultXRControllers />
</XRCanvas>
)
}
```

You can access controllers' state (position, orientation, etc.) by using `useXR()` hook

```js
const { controllers } = useXR()
```

## API

### XR
### XRCanvas

Context for all XR related state
Extended react-three-fiber [Canvas](https://github.com/react-spring/react-three-fiber/blob/master/api.md#canvas) that includes:

- Button to start VR session
- Color management
- VR Mode
- react-xr context

```js
import { XR } from 'react-xr'
import { VRButton } from 'three/examples/jsm/webxr/VRButton'
import { XRCanvas } from 'react-xr'

function App() {
return (
<Canvas
vr
colorManagement
onCreated={({ gl }) => {
document.body.appendChild(VRButton.createButton(gl))
}}>
<XR>{/* All the stuff goes here */}</XR>
</Canvas>
)
return <XRCanvas>{/* All the stuff goes here */}</XRCanvas>
}
```

### useXR

Hook that can only beused by components insde <XR> component.
Hook that can only beused by components insde <XRCanvas> component.

```js
const { controllers } = useXR()
Expand All @@ -117,6 +97,8 @@ interface XRController {

`grip` and `controller` are ThreeJS groups that have the position and orientation of xr controllers. `grip` has an orientation that should be used to render virtual objects such that they appear to be held in the user’s hand and `controller` has an orientation of the preferred pointing ray.

<img width="200" height="200" src="https://i.imgur.com/3stLjfR.jpg" />

`inputSource` is the WebXR input source [(MDN)](https://developer.mozilla.org/en-US/docs/Web/API/XRInputSource). Note that it will not be available before controller is connected.

### useXREvent
Expand Down
22 changes: 19 additions & 3 deletions src/XR.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import * as React from 'react'
import { Object3D, Matrix4, Raycaster, Intersection, Color } from 'three'
import { XRControllerModelFactory } from 'three/examples/jsm/webxr/XRControllerModelFactory'
import { useThree, useFrame } from 'react-three-fiber'
import { useThree, useFrame, Canvas } from 'react-three-fiber'
import { XRHandedness } from './webxr'
import { VRButton } from 'three/examples/jsm/webxr/VRButton'
import { XRController } from './XRController'
import { ContainerProps } from 'react-three-fiber/targets/shared/web/ResizeContainer'

const XRContext = React.createContext<{
export const XRContext = React.createContext<{
controllers: XRController[]
addInteraction: (object: Object3D, eventType: XRInteractionType, handler: XRInteractionHandler) => any
}>({
Expand All @@ -21,7 +23,7 @@ export type XRInteractionType = 'onHover' | 'onBlur'

export type XRInteractionHandler = (event: XRInteractionEvent) => any

export function XR(props: { children: React.ReactNode }) {
export function XRContextProvider(props: { children: React.ReactNode }) {
const { gl } = useThree()
const [controllers, setControllers] = React.useState<XRController[]>([])

Expand Down Expand Up @@ -109,6 +111,20 @@ export function XR(props: { children: React.ReactNode }) {
return <XRContext.Provider value={{ controllers, addInteraction }}>{props.children}</XRContext.Provider>
}

export function XRCanvas({ children, ...rest }: ContainerProps) {
return (
<Canvas
vr
colorManagement
onCreated={({ gl }) => {
document.body.appendChild(VRButton.createButton(gl))
}}
{...rest}>
<XRContextProvider>{children}</XRContextProvider>
</Canvas>
)
}

export const useXR = () => React.useContext(XRContext)

export interface XREvent {
Expand Down

0 comments on commit eb126cc

Please sign in to comment.