Your browser doesn't support the features required by impress.js, so you are presented with a simplified version of this presentation.
(function () {
"use strict";
var PLAYER_HEIGHT = 1.65;
var vrDisplay = null;
var projectionMat = mat4.create();
var viewMat = mat4.create();
var poseMat = mat4.create();
var gamepadMat = mat4.create();
var gamepadColor = vec4.create();
var standingPosition = vec3.create();
var vrPresentButton = null;
var orientation = [0, 0, 0, 1];
var position = [0, 0, 0];
// ===================================================
// WebGL scene setup. This code is not WebVR specific.
// ===================================================
// WebGL setup.
var webglCanvas = document.getElementById("webgl-canvas");
var gl = null;
var cubeIsland = null;
var stats = null;
var debugGeom = null;
function initWebGL (preserveDrawingBuffer) {
var glAttribs = {
alpha: false,
antialias: !VRSamplesUtil.isMobile(),
preserveDrawingBuffer: preserveDrawingBuffer
};
gl = webglCanvas.getContext("webgl", glAttribs);
gl.clearColor(0.1, 0.2, 0.3, 1.0);
gl.enable(gl.DEPTH_TEST);
gl.enable(gl.CULL_FACE);
var textureLoader = new WGLUTextureLoader(gl);
var texture = textureLoader.loadTexture("media/textures/cube-sea.png");
cubeIsland = new VRCubeIsland(gl, texture, 2, 2);
stats = new WGLUStats(gl);
debugGeom = new WGLUDebugGeometry(gl);
// Wait until we have a WebGL context to resize and start rendering.
window.addEventListener("resize", onResize, false);
onResize();
window.requestAnimationFrame(onAnimationFrame);
}
// ================================
// WebVR-specific code begins here.
// ================================
function onVRRequestPresent () {
vrDisplay.requestPresent([{ source: webglCanvas }]).then(function () {
}, function () {
VRSamplesUtil.addError("requestPresent failed.", 2000);
});
}
function onVRExitPresent () {
if (!vrDisplay.isPresenting)
return;
vrDisplay.exitPresent().then(function () {
}, function () {
VRSamplesUtil.addError("exitPresent failed.", 2000);
});
}
function onVRPresentChange () {
onResize();
if (vrDisplay.isPresenting) {
if (vrDisplay.capabilities.hasExternalDisplay) {
VRSamplesUtil.removeButton(vrPresentButton);
vrPresentButton = VRSamplesUtil.addButton("Exit VR", "E", "media/icons/cardboard64.png", onVRExitPresent);
}
} else {
if (vrDisplay.capabilities.hasExternalDisplay) {
VRSamplesUtil.removeButton(vrPresentButton);
vrPresentButton = VRSamplesUtil.addButton("Enter VR", "E", "media/icons/cardboard64.png", onVRRequestPresent);
}
}
}
if (navigator.getVRDisplays) {
navigator.getVRDisplays().then(function (displays) {
if (displays.length > 0) {
vrDisplay = displays[0];
vrDisplay.depthNear = 0.1;
vrDisplay.depthFar = 1024.0;
initWebGL(true);
if (vrDisplay.stageParameters &&
vrDisplay.stageParameters.sizeX > 0 &&
vrDisplay.stageParameters.sizeZ > 0) {
cubeIsland.resize(vrDisplay.stageParameters.sizeX, vrDisplay.stageParameters.sizeZ);
}
VRSamplesUtil.addButton("Reset Pose", "R", null, function () { vrDisplay.resetPose(); });
if (vrDisplay.capabilities.canPresent)
vrPresentButton = VRSamplesUtil.addButton("Enter VR", "E", "media/icons/cardboard64.png", onVRRequestPresent);
window.addEventListener('vrdisplaypresentchange', onVRPresentChange, false);
window.addEventListener('vrdisplayactivate', onVRRequestPresent, false);
window.addEventListener('vrdisplaydeactivate', onVRExitPresent, false);
} else {
initWebGL(false);
VRSamplesUtil.addInfo("WebVR supported, but no VRDisplays found.", 3000);
}
});
} else if (navigator.getVRDevices) {
initWebGL(false);
VRSamplesUtil.addError("Your browser supports WebVR but not the latest version. See <a href='http://webvr.info'>webvr.info</a> for more info.");
} else {
initWebGL(false);
VRSamplesUtil.addError("Your browser does not support WebVR. See <a href='http://webvr.info'>webvr.info</a> for assistance.");
}
function onResize () {
if (vrDisplay && vrDisplay.isPresenting) {
var leftEye = vrDisplay.getEyeParameters("left");
var rightEye = vrDisplay.getEyeParameters("right");
webglCanvas.width = Math.max(leftEye.renderWidth, rightEye.renderWidth) * 2;
webglCanvas.height = Math.max(leftEye.renderHeight, rightEye.renderHeight);
} else {
webglCanvas.width = webglCanvas.offsetWidth * window.devicePixelRatio;
webglCanvas.height = webglCanvas.offsetHeight * window.devicePixelRatio;
}
}
function getStandingViewMatrix (out, view) {
if (vrDisplay.stageParameters) {
mat4.invert(out, vrDisplay.stageParameters.sittingToStandingTransform);
mat4.multiply(out, view, out);
} else {
mat4.identity(out);
mat4.translate(out, out, [0, PLAYER_HEIGHT, 0]);
mat4.invert(out, out);
mat4.multiply(out, view, out);
}
}
function getPoseMatrix (out, pose, isGamepad) {
orientation = pose.orientation;
position = pose.position;
if (!orientation) { orientation = [0, 0, 0, 1]; }
if (!position) {
// If this is a gamepad without a pose set it out in front of us so
// we can see it.
position = isGamepad ? [0.1, -0.1, -0.5] : [0, 0, 0];
}
if (vrDisplay.stageParameters) {
mat4.fromRotationTranslation(out, orientation, position);
mat4.multiply(out, vrDisplay.stageParameters.sittingToStandingTransform, out);
} else {
vec3.add(standingPosition, position, [0, PLAYER_HEIGHT, 0]);
mat4.fromRotationTranslation(out, orientation, standingPosition);
}
}
function renderSceneView (projection, view, gamepads) {
cubeIsland.render(projection, view, stats);
debugGeom.bind(projection, view);
// Render every gamepad with a pose we found
for (var i = 0; i < gamepads.length; ++i) {
var gamepad = gamepads[i];
// Because this sample is done in standing space we need to apply
// the same transformation to the gamepad pose as we did the
// VRDisplay's pose.
getPoseMatrix(gamepadMat, gamepad.pose, true);
// Scaled down to from 1 meter to be something closer to the size of
// a hand.
mat4.scale(gamepadMat, gamepadMat, [0.1, 0.1, 0.1]);
// Loop through all the gamepad's axes and rotate the cube by their
// value.
for (var j = 0; j < gamepad.axes.length; ++j) {
switch (j%3) {
case 0:
mat4.rotateX(gamepadMat, gamepadMat, gamepad.axes[j] * Math.PI);
break;
case 1:
mat4.rotateY(gamepadMat, gamepadMat, gamepad.axes[j] * Math.PI);
break;
case 2:
mat4.rotateZ(gamepadMat, gamepadMat, gamepad.axes[j] * Math.PI);
break;
}
}
// Show the gamepad's cube as red if any buttons are pressed, blue
// otherwise.
vec4.set(gamepadColor, 0, 0, 1, 1);
for (var j = 0; j < gamepad.buttons.length; ++j) {
if (gamepad.buttons[j].pressed) {
vec4.set(gamepadColor, gamepad.buttons[j].value, 0, 0, 1);
break;
}
}
debugGeom.drawBoxWithMatrix(gamepadMat, gamepadColor);
}
}
var frameData = new VRFrameData();
function onAnimationFrame (t) {
stats.begin();
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
if (vrDisplay) {
vrDisplay.requestAnimationFrame(onAnimationFrame);
// Loop over every gamepad and if we find any that have a pose use it.
var vrGamepads = [];
var gamepads = navigator.getGamepads();
for (var i = 0; i < gamepads.length; ++i) {
var gamepad = gamepads[i];
// The array may contain undefined gamepads, so check for that as
// well as a non-null pose.
if (gamepad) {
if (gamepad.pose)
vrGamepads.push(gamepad);
if ("haptics" in gamepad && gamepad.haptics.length > 0) {
for (var j = 0; j < gamepad.buttons.length; ++j) {
if (gamepad.buttons[j].pressed) {
// Vibrate the gamepad using to the value of the button as
// the vibration intensity.
gamepad.haptics[0].vibrate(gamepad.buttons[j].value, 100);
break;
}
}
}
}
}
vrDisplay.getFrameData(frameData);
if (vrDisplay.isPresenting) {
gl.viewport(0, 0, webglCanvas.width * 0.5, webglCanvas.height);
getStandingViewMatrix(viewMat, frameData.leftViewMatrix);
renderSceneView(frameData.leftProjectionMatrix, viewMat, vrGamepads);
gl.viewport(webglCanvas.width * 0.5, 0, webglCanvas.width * 0.5, webglCanvas.height);
getStandingViewMatrix(viewMat, frameData.rightViewMatrix);
renderSceneView(frameData.rightProjectionMatrix, viewMat, vrGamepads);
vrDisplay.submitFrame();
} else {
gl.viewport(0, 0, webglCanvas.width, webglCanvas.height);
mat4.perspective(projectionMat, Math.PI*0.4, webglCanvas.width / webglCanvas.height, 0.1, 1024.0);
getStandingViewMatrix(viewMat, frameData.leftViewMatrix);
renderSceneView(projectionMat, viewMat, frameData.pose);
stats.renderOrtho();
}
} else {
window.requestAnimationFrame(onAnimationFrame);
// No VRDisplay found.
gl.viewport(0, 0, webglCanvas.width, webglCanvas.height);
mat4.perspective(projectionMat, Math.PI*0.4, webglCanvas.width / webglCanvas.height, 0.1, 1024.0);
mat4.identity(viewMat);
mat4.translate(viewMat, viewMat, [0, -PLAYER_HEIGHT, 0]);
cubeIsland.render(projectionMat, viewMat, stats);
stats.renderOrtho();
}
stats.end();
}
})();
// https://github.com/toji/webvr-samples/blob/master/XX-vr-controllers.html
<a-scene>
<a-sphere position="0 1.25 -1"
radius="1.25" color="#EF2D5E">
</a-sphere>
<a-plane rotation="-90 0 0" width="4" height="4"
color="#7BC8A4"></a-plane>
<a-sky color="#ECECEC"></a-sky>
</a-scene>
Use a spacebar or arrow keys to navigate