Skip to content

Instantly share code, notes, and snippets.

@gtk2k
Last active August 29, 2015 14:09
Show Gist options
  • Save gtk2k/8c479980729cb850a3a4 to your computer and use it in GitHub Desktop.
Save gtk2k/8c479980729cb850a3a4 to your computer and use it in GitHub Desktop.
WebVR使ったコード
<!--
ゲーム用フレームワークは使ったことがないため、ほぼナマなJSに書き換えました。
FキーでOculusRift描画、Zキーでゼロポジションリセット。
-->
<!DOCTYPE html>
<html>
<head>
<title>sample</title>
<style type="text/css">
body {
margin: 0;
padding: 0;
}
</style>
<script src="extlib/three.min.js"></script>
</head>
<body>
<video id="video" src="media/video/video-1920x960.mp4" autoplay loop style="display:none"></video>
<div id="webgl"></div>
<script>
var video = document.getElementById('video');
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
webgl.appendChild(renderer.domElement);
var scene = new THREE.Scene();
var cameraLeft = new THREE.PerspectiveCamera(75, 4 / 3, 0.1, 1000);
cameraLeft.position.set(0, 0, 0);
var cameraRight = new THREE.PerspectiveCamera(75, 4 / 3, 0.1, 1000);
cameraRight.position.set(0, 0, 0);
var camera = new THREE.PerspectiveCamera(90, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 0, 0);
var light = new THREE.DirectionalLight(0xffffff, 0.5);
light.position = new THREE.Vector3(100.0, 100.0, 100.0);
light.castShadow = true;
scene.add(light);
var light2 = new THREE.AmbientLight(0xffffff);
scene.add(light2);
var rotateBase = new THREE.Mesh();
var material = new THREE.MeshPhongMaterial({
color: 'gray',
ambient: 0x303030,
specular: 0xffffff,
shininess: 1,
metal: true
});
var balls = [];
for (var i = 1; i <= 4; i++) {
for (var j = 1; j <= 4; j++) {
var ballGeometory = new THREE.SphereGeometry(10, 20, 20);
var ballMesh = new THREE.Mesh(ballGeometory, material);
ballMesh.position.set(i * 32, 0, j * 32 - 140);
ballMesh.r = i;
ballMesh.c = j;
ballMesh.i = 0.0;
ballMesh.rows = 4;
ballMesh.cols = 4;
ballMesh.org = (Math.sin(ballMesh.r / ballMesh.rows + ballMesh.i) + Math.sin(ballMesh.c / ballMesh.cols + ballMesh.i)) * 16;
rotateBase.add(ballMesh);
balls.push(ballMesh);
}
}
var wallGeometory = new THREE.BoxGeometry(640, 480, 1);
var wallMesh = new THREE.Mesh(wallGeometory, material);
wallMesh.position.set(400, 40, -400);
rotateBase.add(wallMesh);
var videoGeometory = new THREE.SphereGeometry(1000, 32, 32);
var videoTexture = new THREE.Texture(video);
var videoMaterial = new THREE.MeshBasicMaterial({
map: videoTexture,
overdraw: true,
side: THREE.DoubleSide
});
var videoMesh = new THREE.Mesh(videoGeometory, videoMaterial);
rotateBase.add(videoMesh);
scene.add(rotateBase);
// VR Device Setup
var sensorDevice = null;
var hmdDevice = null;
var vrMode = false;
var renderTargetWidth = window.innerWidth;
var renderTargetHeight = window.innerHeight;
function PerspectiveMatrixFromVRFieldOfView(fov, zNear, zFar) {
var outMat = new THREE.Matrix4();
var out = outMat.elements;
var upTan, downTan, leftTan, rightTan;
if (fov == null) {
// If no FOV is given plug in some dummy values
upTan = Math.tan(50 * Math.PI / 180.0);
downTan = Math.tan(50 * Math.PI / 180.0);
leftTan = Math.tan(45 * Math.PI / 180.0);
rightTan = Math.tan(45 * Math.PI / 180.0);
} else {
upTan = Math.tan(fov.upDegrees * Math.PI / 180.0);
downTan = Math.tan(fov.downDegrees * Math.PI / 180.0);
leftTan = Math.tan(fov.leftDegrees * Math.PI / 180.0);
rightTan = Math.tan(fov.rightDegrees * Math.PI / 180.0);
}
var xScale = 2.0 / (leftTan + rightTan);
var yScale = 2.0 / (upTan + downTan);
out[0] = xScale;
out[4] = 0.0;
out[8] = -((leftTan - rightTan) * xScale * 0.5);
out[12] = 0.0;
out[1] = 0.0;
out[5] = yScale;
out[9] = ((upTan - downTan) * yScale * 0.5);
out[13] = 0.0;
out[2] = 0.0;
out[6] = 0.0;
out[10] = zFar / (zNear - zFar);
out[14] = (zFar * zNear) / (zNear - zFar);
out[3] = 0.0;
out[7] = 0.0;
out[11] = -1.0;
out[15] = 0.0;
return outMat;
}
var fovScale = 1.0;
function resizeFOV(amount) {
var fovLeft, fovRight;
if (!hmdDevice) { return; }
if (amount != 0 && 'setFieldOfView' in hmdDevice) {
fovScale += amount;
if (fovScale < 0.1) { fovScale = 0.1; }
fovLeft = hmdDevice.getRecommendedEyeFieldOfView("left");
fovRight = hmdDevice.getRecommendedEyeFieldOfView("right");
fovLeft.upDegrees *= fovScale;
fovLeft.downDegrees *= fovScale;
fovLeft.leftDegrees *= fovScale;
fovLeft.rightDegrees *= fovScale;
fovRight.upDegrees *= fovScale;
fovRight.downDegrees *= fovScale;
fovRight.leftDegrees *= fovScale;
fovRight.rightDegrees *= fovScale;
hmdDevice.setFieldOfView(fovLeft, fovRight);
}
//if ('getRecommendedEyeRenderRect' in hmdDevice) {
// var leftEyeViewport = hmdDevice.getRecommendedEyeRenderRect("left");
// var rightEyeViewport = hmdDevice.getRecommendedEyeRenderRect("right");
// renderTargetWidth = leftEyeViewport.width + rightEyeViewport.width;
// renderTargetHeight = Math.max(leftEyeViewport.height, rightEyeViewport.height);
//}
resize();
if ('getCurrentEyeFieldOfView' in hmdDevice) {
fovLeft = hmdDevice.getCurrentEyeFieldOfView("left");
fovRight = hmdDevice.getCurrentEyeFieldOfView("right");
} else {
fovLeft = hmdDevice.getRecommendedEyeFieldOfView("left");
fovRight = hmdDevice.getRecommendedEyeFieldOfView("right");
}
cameraLeft.projectionMatrix = PerspectiveMatrixFromVRFieldOfView(fovLeft, 0.1, 1000);
cameraRight.projectionMatrix = PerspectiveMatrixFromVRFieldOfView(fovRight, 0.1, 1000);
}
function EnumerateVRDevices(devices) {
// First find an HMD device
for (var i = 0; i < devices.length; ++i) {
if (devices[i] instanceof HMDVRDevice) {
hmdDevice = devices[i];
var eyeOffsetLeft = hmdDevice.getEyeTranslation("left");
var eyeOffsetRight = hmdDevice.getEyeTranslation("right");
cameraLeft.position.add(eyeOffsetLeft);
cameraRight.position.add(eyeOffsetRight);
console.log(cameraLeft.position.x, cameraRight.position.x);
resizeFOV(0.0);
}
}
// Next find a sensor that matches the HMD hardwareUnitId
for (var i = 0; i < devices.length; ++i) {
if (devices[i] instanceof PositionSensorVRDevice &&
(!hmdDevice || devices[i].hardwareUnitId == hmdDevice.hardwareUnitId)) {
sensorDevice = devices[i];
}
}
}
if (navigator.getVRDevices) {
navigator.getVRDevices().then(EnumerateVRDevices);
} else if (navigator.mozGetVRDevices) {
navigator.mozGetVRDevices(EnumerateVRDevices);
}
function resize() {
if (vrMode) {
camera.aspect = renderTargetWidth / renderTargetHeight;
camera.updateProjectionMatrix();
renderer.setSize(renderTargetWidth, renderTargetHeight);
} else {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
}
resize();
//window.addEventListener("resize", resize, false);
// Fullscreen VR mode handling
function onFullscreenChange() {
if (!document.webkitFullscreenElement && !document.mozFullScreenElement) {
vrMode = false;
}
resize();
}
document.addEventListener("webkitfullscreenchange", onFullscreenChange, false);
document.addEventListener("mozfullscreenchange", onFullscreenChange, false);
function render() {
requestAnimationFrame(render);
videoTexture.needsUpdate = true;
for (var i = 0; i < balls.length; i++){
var ball = balls[i];
ball.position.y = (Math.sin(ball.r / ball.rows + ball.i) + Math.sin(ball.c / ball.cols + ball.i)) * 32;
ball.i += 0.1;
if (ball.position.y === ball.org) {
ball.i = 0.0;
}
}
if (vrMode) {
if (sensorDevice) {
var vrState = sensorDevice.getState();
rotateBase.quaternion.x = vrState.orientation.x;
rotateBase.quaternion.y = vrState.orientation.y;
rotateBase.quaternion.z = vrState.orientation.z;
rotateBase.quaternion.w = -vrState.orientation.w;
}
// Render left eye
renderer.enableScissorTest(true);
renderer.setScissor(0, 0, renderTargetWidth / 2, renderTargetHeight);
renderer.setViewport(0, 0, renderTargetWidth / 2, renderTargetHeight);
renderer.render(scene, cameraLeft);
// Render right eye
renderer.setScissor(renderTargetWidth / 2, 0, renderTargetWidth / 2, renderTargetHeight);
renderer.setViewport(renderTargetWidth / 2, 0, renderTargetWidth / 2, renderTargetHeight);
renderer.render(scene, cameraRight);
} else {
// Render mono view
renderer.enableScissorTest(false);
renderer.setViewport(0, 0, window.innerWidth, window.innerHeight);
renderer.render(scene, camera);
}
}
render();
document.addEventListener('keydown', function (e) {
if (e.keyCode == 'F'.charCodeAt(0)) { // 'F'キーが押された場合
if (!hmdDevice) return;
var cnvs = document.getElementsByTagName('canvas');
if (cnvs.length) {
for (var i = cnvs.length; i--;) {
var cnv = cnvs[i];
if (cnv.parentNode.id === 'webgl') {
if (cnv.webkitRequestFullscreen) {
cnv.webkitRequestFullscreen({ vrDisplay: hmdDevice, /*vrDistortion: false*/ });
vrMode = true;
} else if (cnv.mozRequestFullScreen) {
cnv.mozRequestFullScreen({ vrDisplay: hmdDevice });
vrMode = true;
}
return;
}
}
}
} else if (e.keyCode == 'Z'.charCodeAt(0)) {
sensorDevice.zeroSensor();
}
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment