Stereo example 2 (for reference; optional)

stereo2.html  [download]

<!DOCTYPE html>

<html>
<head>

<title>Comp 86 example: Stereo 2</title>

<script src="libs/build/three.min.js"></script>
<script src="libs/examples/js/Detector.js"></script>
<script src="libs/examples/js/controls/OrbitControls.js"></script>

<script type="text/javascript">

/*
 * Example: Stereo, homemade version, without library
 *
 * Uses 2 cameras but 1 scene
 * Crude approach, camera geometry may be slightly off,
 * built in library version does it better.
 */

/*
 ***************************************************
 * This code replaces boiler.js to do stereo
 ***************************************************
 */

// Global variables
var scene, renderer1, renderer2, camera1, camera2, controls, size;
var eyeOffset = 20.5/12 // ie sort of as if WC = feet

window.onload = function () {
	// Most browsers now support WebGLRenderer
	renderer1 = new THREE.WebGLRenderer( { antialias: true } ); //*1 2 renderers
	renderer1.setClearColor( new THREE.Color ("lightgrey"))
	renderer2 = new THREE.WebGLRenderer( { antialias: true } ); //*1
	renderer2.setClearColor( new THREE.Color ("lightgrey"))
	size = window.innerWidth/2 - 50
	renderer1.setSize( size, size );
	renderer2.setSize( size, size );
	document.getElementById('theContainer').appendChild(renderer1.domElement); //*1
	document.getElementById('theContainer').appendChild(renderer2.domElement); //*1
	renderer1.domElement.style = "border-style: solid; border-color: black; border-width: 1px";
	renderer2.domElement.style = "border-style: solid; border-color: black; border-width: 1px";

	// Create the scene
	scene = new THREE.Scene();

	// Put 2 cameras into the scene
	camera1 = new THREE.PerspectiveCamera( 60, 1, 1, 1000 ); //*2 2 cameras
	camera2 = new THREE.PerspectiveCamera( 60, 1, 1, 1000 ); //*2
	camera1.position.set(0, 0, 5);
	camera2.position.set(eyeOffset, 0, 5);
	camera2.lookAt (camera1.getWorldDirection())
	scene.add(camera1); //*2
	scene.add(camera2); //*2

	// Create one camera (head) contol
	controls = new THREE.OrbitControls( camera1, renderer1.domElement );
	controls.addEventListener( 'change', render );

	// Add our stuff to the scene, kept in a separate function
	makeSceneGraph()

	render()
	animate()
}

// Animation loop
function animate() {
	requestAnimationFrame( animate );
	controls.update()

	// Take the latest camera1 position and set camera2
	camera2.position.set (camera1.position.x + eyeOffset, camera1.position.y, camera1.position.z) //*3 camera2 position = camera1 + eye offset
	camera2.lookAt (camera1.getWorldDirection())
}

// Render the scene on both cameras
function render() {
	renderer1.render( scene, camera1 ); //*4 Render same scene on both cameras
	renderer2.render( scene, camera2 ); //*4
}

// In case window is resized
window.onresize = function () {
	renderer1.setSize( size, size );
	renderer2.setSize( size, size );

	camera1.aspect = 1
	camera2.aspect = 1
	camera1.updateProjectionMatrix();
	camera2.updateProjectionMatrix();

	render();
}

/*
 ***************************************************
 * The rest of this code is identical to lights.html
 ***************************************************
 */

// Global used by callbacks from HTML
var lights

function makeSceneGraph () {
	scene.add (new Scene())
	lights = new Lights()
}

/*
 * Same as previous example, except
 * this time we provide materials.
 */
class Scene extends THREE.Object3D {
    constructor () {
	super ()

	// First item = a box, rotated and translated
	var box = new THREE.Mesh (
		new THREE.BoxGeometry (1, 3, 1),
		new THREE.MeshPhongMaterial ({ color: "yellow" }))

	// Move it back from origin and to the right
	box.position.set (5, 0, -4)

	// Rotate it in X and Y
	box.rotation.set (45 * Math.PI/180, 30 * Math.PI/180, 0)

	// Plug it in to our scene
	this.add (box)

	// A sphere, in a different location
	var sphere = new THREE.Mesh (
		new THREE.SphereGeometry(1, 32, 32),
		new THREE.MeshPhongMaterial ({
			color: "red", shininess: 60 }))
	sphere.position.set (-5, 0, -3)
	this.add (sphere)

	// A pyramid, using our subroutine below
	var pyramid = new Pyramid (new THREE.MeshPhongMaterial ({
		color: "green", shininess: 60 }))
	pyramid.position.set (0, 0, -6)
	pyramid.rotation.set (0, 45 * Math.PI/180, 0)
	this.add (pyramid)
    }
}

/*
 * Same as previous example, except
 * this time, you pass us the material you want.
 */
class Pyramid extends THREE.Object3D {
    constructor (material) {
	super ()

	// Bottom Box, located slightly down
	// (relative to origin of the pyramid)
	var bot = new THREE.Mesh (
		new THREE.BoxGeometry (3, 3, 3),
		material)
	bot.position.set (0, -3/2, 0)
	this.add (bot)

	// Middle Box, slightly up
	var mid = new THREE.Mesh (
		new THREE.BoxGeometry (2, 2, 2),
		material)
	mid.position.set (0, 2/2, 0)
	this.add (mid)

	// Top box, further up
	var top = new THREE.Mesh (
		new THREE.BoxGeometry (1, 1, 1),
		material)
	top.position.set (0, 2 + 1/2, 0)
	this.add (top)
    }
}

/*
 * An object to hold the lights,
 * constructor just adds them to global var scene
 */
class Lights {
    constructor () {
	// Uses typical lighting setup, like portrait or TV studio...

	// Main (key) light, directional, 
	// from 45 deg. user's right, above, bright white
	this.mainLight = new THREE.DirectionalLight ("white", 1)
	this.mainLight.position.set (1, 0.5, 1)
	scene.add (this.mainLight)

	// Fill light, directional, from 45deg. user's left,
	// white, half as bright
	this.fillLight = new THREE.DirectionalLight ("white", 0.5)
	this.fillLight.position.set (-1, 0, 1 )
	scene.add (this.fillLight)

	// Ambient light, white, still less bright
	this.ambientLight = new THREE.AmbientLight (0x404040)
	scene.add (this.ambientLight);
    }

    // Callback from checkboxes
    pressed (state, light) {
	light.visible = state
	render ()
    }
}

</script>
</head>

<body>
Main light: <input type=checkbox checked="checked"
	onclick="lights.pressed(this.checked, lights.mainLight)">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

Fill light: <input type=checkbox checked="checked"
	onclick="lights.pressed(this.checked, lights.fillLight)">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

Ambient light: <input type=checkbox checked="checked"
	onclick="lights.pressed(this.checked, lights.ambientLight)">

<br/>

<!-- Container for three.js -->
<div id="theContainer">&nbsp;</div>
</body>
</html>