Skip to content

Instantly share code, notes, and snippets.

@cocopon
Created May 9, 2022 03:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cocopon/7bc77ebe94c07eacd5ddaac66e5b4803 to your computer and use it in GitHub Desktop.
Save cocopon/7bc77ebe94c07eacd5ddaac66e5b4803 to your computer and use it in GitHub Desktop.
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