-
-
Save cocopon/7bc77ebe94c07eacd5ddaac66e5b4803 to your computer and use it in GitHub Desktop.
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
import {Pane} from 'tweakpane'; | |
import * as Three from 'three'; | |
import {VRButton} from 'three/examples/jsm/webxr/VRButton'; | |
import {GLTFLoader} from 'three/examples/jsm/loaders/GLTFLoader'; | |
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'; | |
import {XRSession} from 'three'; | |
const params = { | |
floorY: 0.6, | |
}; | |
const pane = new Pane(); | |
pane.addInput(params, 'floorY', { | |
min: -4, | |
max: 4, | |
}); | |
const scene = new Three.Scene(); | |
// Dolly for keeping the camera transform | |
const dolly = { | |
t: new Three.Object3D(), | |
r: new Three.Object3D(), | |
}; | |
dolly.t.add(dolly.r); | |
// Camera | |
const cam = new Three.PerspectiveCamera(75, 800 / 600); | |
cam.position.set(0, 0, 1); cam.lookAt(0, 0, 0); | |
dolly.r.add(cam); | |
scene.add(dolly.t); | |
const canvasElem = document.createElement('canvas'); | |
document.body.appendChild(canvasElem); | |
const renderer = new Three.WebGLRenderer({ | |
alpha: true, | |
canvas: canvasElem, | |
}); | |
renderer.setClearColor(new Three.Color(0x888888)); | |
renderer.xr.enabled = true; | |
document.body.appendChild(VRButton.createButton(renderer)); | |
new OrbitControls(cam, canvasElem); | |
// Lights | |
(() => { | |
const l1 = new Three.AmbientLight(0xffffff, 1); | |
scene.add(l1); | |
const l2 = new Three.DirectionalLight(0xffffff, 1); | |
l2.position.set(-0.7, 0.2, 0.2); | |
scene.add(l2); | |
})(); | |
function onResize() { | |
const w = window.innerWidth; | |
const h = window.innerHeight; | |
renderer.setPixelRatio(window.devicePixelRatio); | |
renderer.setSize(w, h); | |
cam.aspect = w / h; | |
cam.updateProjectionMatrix(); | |
} | |
window.addEventListener('resize', onResize); | |
onResize(); | |
const loader = new GLTFLoader(); | |
loader.load('home.glb', (glb) => { | |
scene.add(glb.scene); | |
}); | |
renderer.setAnimationLoop(() => { | |
renderer.render(scene, cam); | |
}); | |
function getThumbstick(xrs: Three.XRSession, index: number): {x: number, y: number} { | |
const gp = xrs.inputSources[index].gamepad; | |
return { | |
x: gp.axes[2], | |
y: gp.axes[3], | |
}; | |
} | |
function walk(xrs: XRSession) { | |
const sr = getThumbstick(xrs, 0); | |
const sl = getThumbstick(xrs, 1); | |
const dfront = new Three.Vector3(0, 0, -1); | |
dfront.applyQuaternion(cam.quaternion); | |
dolly.t.translateOnAxis(dfront, -sl.y * 0.05); | |
const dhead = new Three.Vector3(1, 0, 0); | |
dhead.applyQuaternion(cam.quaternion); | |
dolly.t.translateOnAxis(dhead, sl.x * 0.05); | |
dolly.r.rotateY(sr.x * -0.03); | |
} | |
setInterval(() => { | |
dolly.t.position.y = params.floorY; | |
const xrs = renderer.xr.getSession(); | |
if (xrs) { | |
walk(xrs); | |
} | |
}, 1000 / 30); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment