-
-
Notifications
You must be signed in to change notification settings - Fork 157
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Hands component, rework how controllers are loaded, add useContro…
…ller hook, add Hands example, add examples folder
- Loading branch information
Showing
18 changed files
with
13,638 additions
and
144 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
SKIP_PREFLIGHT_CHECK=true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
|
||
# testing | ||
/coverage | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
.env.local | ||
.env.development.local | ||
.env.test.local | ||
.env.production.local | ||
|
||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Explore Examples | ||
|
||
You can explore additional examples locally: | ||
|
||
```shell | ||
git clone https://github.com/react-spring/react-xr | ||
cd react-xr | ||
yarn | ||
cd examples | ||
yarn | ||
yarn start | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
const { addWebpackAlias, removeModuleScopePlugin, babelInclude, override } = require('customize-cra') | ||
const { addReactRefresh } = require('customize-cra-react-refresh') | ||
const path = require('path') | ||
|
||
module.exports = (config, env) => { | ||
config.resolve.extensions = [...config.resolve.extensions, '.ts', '.tsx'] | ||
return override( | ||
addReactRefresh(), | ||
removeModuleScopePlugin(), | ||
babelInclude([path.resolve('src'), path.resolve('../src')]), | ||
addWebpackAlias({ | ||
'react-three-fiber': path.resolve('node_modules/react-three-fiber'), | ||
'react-xr': path.resolve('../src/'), | ||
react: path.resolve('node_modules/react'), | ||
'react-dom': path.resolve('node_modules/react-dom'), | ||
scheduler: path.resolve('node_modules/scheduler'), | ||
'react-scheduler': path.resolve('node_modules/react-scheduler'), | ||
'prop-types': path.resolve('node_modules/prop-types'), | ||
three: path.resolve('node_modules/three'), | ||
// three$: path.res olve('node_modules/three/src/Three'), | ||
//three$: path.resolve('./resources/three.js'), | ||
// '../../../build/three.module.js': path.resolve('./resources/three.js'), | ||
}) | ||
)(config, env) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
{ | ||
"name": "examples-cra", | ||
"version": "0.1.0", | ||
"private": true, | ||
"dependencies": { | ||
"@testing-library/jest-dom": "^5.3.0", | ||
"@testing-library/react": "^10.0.2", | ||
"@testing-library/user-event": "^10.0.1", | ||
"cannon": "^0.6.2", | ||
"drei": "^0.0.64", | ||
"pseudo-worker": "^1.3.0", | ||
"react": "^16.13.1", | ||
"react-dom": "^16.13.1", | ||
"react-merge-refs": "^1.0.0", | ||
"react-router-dom": "^5.1.2", | ||
"react-scripts": "3.4.1", | ||
"react-spring": "^8.0.27", | ||
"react-three-fiber": "^4.2.17", | ||
"react-three-gui": "^0.1.5", | ||
"react-use-gesture": "^7.0.9", | ||
"styled-components": "^5.0.1", | ||
"three": "^0.119.1", | ||
"threejs-meshline": "^2.0.10", | ||
"use-cannon": "https://github.com/react-spring/use-cannon.git", | ||
"zustand": "^2.2.3" | ||
}, | ||
"scripts": { | ||
"start": "HTTPS=true react-app-rewired start", | ||
"build": "react-app-rewired build", | ||
"test": "react-app-rewired test", | ||
"eject": "react-app-rewired eject" | ||
}, | ||
"husky": { | ||
"hooks": { | ||
"pre-commit": "lint-staged" | ||
} | ||
}, | ||
"prettier": { | ||
"semi": false, | ||
"trailingComma": "es5", | ||
"singleQuote": true, | ||
"jsxBracketSameLine": true, | ||
"tabWidth": 2, | ||
"printWidth": 120 | ||
}, | ||
"lint-staged": { | ||
"*.{js,jsx,ts,tsx}": [ | ||
"prettier --write", | ||
"git add" | ||
] | ||
}, | ||
"eslintConfig": { | ||
"extends": "react-app" | ||
}, | ||
"browserslist": { | ||
"production": [ | ||
">0.2%", | ||
"not dead", | ||
"not op_mini all" | ||
], | ||
"development": [ | ||
"last 1 chrome version", | ||
"last 1 firefox version", | ||
"last 1 safari version" | ||
] | ||
}, | ||
"devDependencies": { | ||
"@babel/preset-typescript": "^7.9.0", | ||
"customize-cra": "^0.9.1", | ||
"customize-cra-react-refresh": "^1.0.1", | ||
"husky": "^4.2.3", | ||
"lint-staged": "^10.1.2", | ||
"prettier": "^2.0.2", | ||
"react-app-rewired": "^2.1.5" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>react-xr examples</title> | ||
<style> | ||
#root { | ||
height: 100vh; | ||
width: 100vw; | ||
} | ||
body { | ||
margin: 0; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<div id="root"></div> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
import ReactDOM from 'react-dom' | ||
import React, { useState, useEffect, useRef, Suspense, useMemo, useCallback } from 'react' | ||
import { VRCanvas, useXREvent, DefaultXRControllers, Hands, Select, Hover, useXR } from 'react-xr' | ||
import { useFrame, useThree } from 'react-three-fiber' | ||
import { OrbitControls, Sky, Text, Plane, Box } from 'drei' | ||
import { Color, Box3, BufferGeometry, Vector3, TextureLoader, ImageLoader } from 'three/build/three.module' | ||
|
||
function Key({ name, pos = [0, 0], onClick, width = 1, ...rest }) { | ||
const meshRef = useRef() | ||
|
||
const { gl } = useThree() | ||
|
||
const leftHand = gl.xr.getHand(0) | ||
|
||
const focused = useRef(false) | ||
useFrame(() => { | ||
if (!meshRef.current) { | ||
return | ||
} | ||
const leftTip = leftHand.joints[9] | ||
if (leftTip === undefined) { | ||
return | ||
} | ||
|
||
const box = new Box3().setFromObject(meshRef.current) | ||
|
||
if (box.containsPoint(leftTip.position)) { | ||
if (!focused.current) { | ||
onClick() | ||
focused.current = true | ||
meshRef.current.material.color = new Color(0x444444) | ||
} | ||
} else { | ||
if (focused.current) { | ||
meshRef.current.material.color = new Color(0xffffff) | ||
focused.current = false | ||
} | ||
} | ||
}) | ||
|
||
const keySize = 0.018 | ||
const keyWidth = width * keySize | ||
const keyGap = 0.004 | ||
const size = keySize + keyGap | ||
|
||
const xpi = (pos[0] / 10) * Math.PI | ||
const offset = 0.01 - Math.sin(xpi) / 20 | ||
|
||
const position = [size * pos[0], -size * pos[1], offset] | ||
|
||
return ( | ||
<group {...rest} position={position} rotation={[0, Math.cos(xpi) / 2, 0]}> | ||
<mesh ref={meshRef}> | ||
<boxBufferGeometry attach="geometry" args={[keyWidth, keySize, 0.02]} /> | ||
<meshStandardMaterial attach="material" color="#fafafa" /> | ||
</mesh> | ||
<Text position={[0, 0.003, keySize / 1.7]} fontSize={0.015} color="#333"> | ||
{name} | ||
</Text> | ||
</group> | ||
) | ||
} | ||
|
||
function Keyboard() { | ||
const [state, setState] = useState({ | ||
text: '', | ||
focused: ' ', | ||
}) | ||
|
||
const { gl } = useThree() | ||
|
||
useEffect(() => { | ||
const rightHand = gl.xr.getHand(1) | ||
|
||
const onPinch = () => { | ||
setState((it) => { | ||
const text = it.focused === 'backspace' ? it.text.substring(0, it.text.length - 1) : it.text + it.focused | ||
return { | ||
text, | ||
focused: it.focused, | ||
} | ||
}) | ||
} | ||
rightHand.addEventListener('pinchstart', onPinch) | ||
|
||
return () => { | ||
rightHand.removeEventListener('pinchstart', onPinch) | ||
} | ||
}, [gl, setState]) | ||
|
||
const onClick = (key) => () => setState((it) => ({ ...it, focused: key })) | ||
|
||
return ( | ||
<group position={[-0.2, 1.14, -0.4]} rotation={[0, 0, 0]}> | ||
<Text position={[0.15, 0.1, 0]} fontSize={0.03}> | ||
{state.text + '|'} | ||
</Text> | ||
{['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p'].map((key, i) => ( | ||
<Key name={key} pos={[i - 0.2, 0]} onClick={onClick(key)} /> | ||
))} | ||
{['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l'].map((key, i) => ( | ||
<Key name={key} pos={[i, 1]} onClick={onClick(key)} /> | ||
))} | ||
{['z', 'x', 'c', 'v', 'b', 'n', 'm'].map((key, i) => ( | ||
<Key name={key} pos={[i + 0.4, 2]} onClick={onClick(key)} /> | ||
))} | ||
<Key name={' '} pos={[3, 3]} onClick={onClick(' ')} width={5} /> | ||
<Key name={'<'} pos={[8, 3]} onClick={onClick('backspace')} /> | ||
</group> | ||
) | ||
} | ||
|
||
function Button(props) { | ||
const [hover, setHover] = useState(false) | ||
const [color, setColor] = useState(0x123456) | ||
|
||
const onSelect = useCallback(() => { | ||
setColor((Math.random() * 0xffffff) | 0) | ||
}, [setColor]) | ||
|
||
return ( | ||
<Select onSelect={onSelect}> | ||
<Hover onChange={setHover}> | ||
<Box scale={hover ? [1.5, 1.5, 1.5] : [1, 1, 1]} args={[0.4, 0.1, 0.1]} {...props}> | ||
<meshStandardMaterial attach="material" color={color} /> | ||
<Text position={[0, 0, 0.06]} fontSize={0.05} color="#000" anchorX="center" anchorY="middle"> | ||
Hello react-xr! | ||
</Text> | ||
</Box> | ||
</Hover> | ||
</Select> | ||
) | ||
} | ||
|
||
function App() { | ||
return ( | ||
<VRCanvas> | ||
<ambientLight intensity={0.5} /> | ||
<pointLight position={[5, 5, 5]} /> | ||
|
||
<Hands /> | ||
<DefaultXRControllers /> | ||
<Button position={[0, 0.8, -1]} /> | ||
</VRCanvas> | ||
) | ||
} | ||
|
||
ReactDOM.render(<App />, document.querySelector('#root')) |
Oops, something went wrong.