bate's blog

調べたこと実装したことなどを取りとめもなく書きます。

three.jsとdat.guiで遊ぶ その2

カメラ操作はキーボードの上下左右にした。
dat.guiで軸の表示と非表示の切り替えをする。

http://dl.dropbox.com/u/67579260/sample01.html

CanvasRendererからWebGLRendererに変更した。

<!doctype html>
<html lang="en">
	<head>
		<title>three.js, dat.GUI</title>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
		<style>
			body {
				font-family: Monospace;
				background-color: #f0f0f0;
				margin: 0px;
				overflow: hidden;
			}
		</style>
	</head>
	<body>
		
		<script src="mrdoob-three.js-a4088b8/build/Three.js"></script>
		<script src="mrdoob-three.js-a4088b8/examples/js/Stats.js"></script>
		<script src="mrdoob-three.js-a4088b8/examples/js/DAT.GUI.min.js"></script>
		
		<script>
			
			//---------------------------------------------
			// CameraController class
			var CameraController = function(theta, phi, radius)
			{
				this.name = "Camera Controller";
				this.theta = theta;
				this.phi = phi;
				this.radius = radius;
				
				this.update = function(refCamera)
				{
					refCamera.position.x = this.radius*Math.sin(this.theta*Math.PI/180.0)*Math.cos(this.phi*Math.PI/180.0);
					refCamera.position.y = this.radius*Math.cos(this.theta*Math.PI/180.0);
					refCamera.position.z = this.radius*Math.sin(this.theta*Math.PI/180.0)*Math.sin(this.phi*Math.PI/180.0);
					refCamera.lookAt({x:0, y:0, z:0});
				};
				
				this.addTheta = function(difTheta)
				{
					this.theta += difTheta;
					if(this.theta > 170) {
						this.theta = 170;
					} else if(this.theta < 10) {
						this.theta = 10;
					}
				}
				
				this.addPhi = function(difPhi)
				{
					this.phi += difPhi;
					this.phi = this.phi%360.0;
				}
			}
			//---------------------------------------------
			
			//---------------------------------------------
			// AxisXYZ class
			function AxisXYZ()
			{
				THREE.Object3D.call(this);
				
				this.name = "Axis XYZ";
				
				this.axisX;
				this.axisY;
				this.axisZ;
			}
			
			AxisXYZ.prototype = new THREE.Object3D();
			
			AxisXYZ.prototype.init = function()
			{
				// AxisX
				var geoX = new THREE.Geometry();
				geoX.vertices.push(new THREE.Vertex(new THREE.Vector3(0,0,0)));
				geoX.vertices.push(new THREE.Vertex(new THREE.Vector3(10000,0,0)));
				this.axisX = new THREE.Line(geoX, new THREE.LineBasicMaterial({color:0xff0000, opacity:1.0}));
				this.add(this.axisX);
				// AxisY
				var geoY = new THREE.Geometry();
				geoY.vertices.push(new THREE.Vertex(new THREE.Vector3(0,0,0)));
				geoY.vertices.push(new THREE.Vertex(new THREE.Vector3(0,10000,0)));
				this.axisY = new THREE.Line(geoY, new THREE.LineBasicMaterial({color:0x00ff00, opacity:1.0}));
				this.add(this.axisY);
				// AxisZ
				var geoZ = new THREE.Geometry();
				geoZ.vertices.push(new THREE.Vertex(new THREE.Vector3(0,0,0)));
				geoZ.vertices.push(new THREE.Vertex(new THREE.Vector3(0,0,10000)));
				this.axisZ = new THREE.Line(geoZ, new THREE.LineBasicMaterial({color:0x0000ff, opacity:1.0}))
				this.add(this.axisZ);;
			}
			
			AxisXYZ.prototype.changeShow = function()
			{
				this.axisX.visible = this.visible;
				this.axisY.visible = this.visible;
				this.axisZ.visible = this.visible;
			}
			//---------------------------------------------
			
			var targetRotation = 0;
			var targetRotationOnMouseDown = 0;
			var mouseX = 0;
			var mouseXOnMouseDown = 0;
			var windowHalfX = window.innerWidth / 2;
			var windowHalfY = window.innerHeight / 2;
			
			init();
			animate();
			
			var container;
			function initContainer()
			{
				container = document.createElement( 'div' );
				document.body.appendChild( container );
				
				var info = document.createElement( 'div' );
				info.style.position = 'absolute';
				info.style.top = '10px';
				info.style.width = '100%';
				info.style.textAlign = 'center';
				info.innerHTML = 'press keyboard cursor key to move CAMERA';
				container.appendChild( info );
			}
			
			var camera, cameraController, scene;
			function initScene()
			{
				scene = new THREE.Scene();
				
				camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 );
				camera.position.x = 500;
				camera.position.y = 500;
				camera.position.z = 500;
				camera.lookAt(new THREE.Vector3(0,0,0));
				scene.add( camera );
				cameraController = new CameraController(45, 45, 1000);
				
				initObjects();
			}
			
			var cube, plane, axisXYZ;
			function initObjects()
			{
				// AxisX
				axisXYZ = new AxisXYZ();
				axisXYZ.init();
				scene.add( axisXYZ );
				
				// Cube
				var materials = [];
				for ( var i = 0; i < 6; i ++ ) 
				{
					materials.push( new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff } ) );
				}
				cube = new THREE.Mesh( new THREE.CubeGeometry( 200, 200, 200, 1, 1, 1, materials ), new THREE.MeshFaceMaterial() );
				scene.add( cube );
			}
			
			var renderer;
			function initRenderer()
			{
				//renderer = new THREE.CanvasRenderer();
				renderer = new THREE.WebGLRenderer();
				renderer.setSize( window.innerWidth, window.innerHeight );
				container.appendChild( renderer.domElement );
			}
			
			var stats;
			function initStats()
			{
				stats = new Stats();
				stats.domElement.style.position = 'absolute';
				stats.domElement.style.top = '0px';
				container.appendChild( stats.domElement );
			}
			
			function initDAT()
			{
				var gui = new DAT.GUI();
				gui.close();
				gui.add(axisXYZ, 'name');
				gui.add(axisXYZ, 'visible').onChange(function(value) {
					axisXYZ.changeShow();
				});
			}
			
			function initEventListener()
			{
				// mouse
				document.addEventListener( 'mousedown', onDocumentMouseDown, false );
				document.addEventListener( 'touchstart', onDocumentTouchStart, false );
				document.addEventListener( 'touchmove', onDocumentTouchMove, false );
				
				// keyboard
				document.addEventListener( 'keypress', onDocumentKeyboardPress, false );
			}
			
			function init()
			{
				initContainer();
				initScene();
				initRenderer();
				initStats();
				initDAT();
				initEventListener();
			}
			
			//
			
			function onDocumentMouseDown( event )
			{
				event.preventDefault();
				
				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
				document.addEventListener( 'mouseup', onDocumentMouseUp, false );
				document.addEventListener( 'mouseout', onDocumentMouseOut, false );
				
				mouseXOnMouseDown = event.clientX - windowHalfX;
				targetRotationOnMouseDown = targetRotation;
			}

			function onDocumentMouseMove( event )
			{
				mouseX = event.clientX - windowHalfX;
				targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.02;
			}

			function onDocumentMouseUp( event )
			{
				document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
				document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
				document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
			}

			function onDocumentMouseOut( event )
			{
				document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
				document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
				document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
			}

			function onDocumentTouchStart( event )
			{
				if ( event.touches.length == 1 ) {
					event.preventDefault();
					mouseXOnMouseDown = event.touches[ 0 ].pageX - windowHalfX;
					targetRotationOnMouseDown = targetRotation;
				}
			}

			function onDocumentTouchMove( event )
			{
				if ( event.touches.length == 1 ) {
					event.preventDefault();
					mouseX = event.touches[ 0 ].pageX - windowHalfX;
					targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.05;
				}
			}
			
			function onDocumentKeyboardPress( event )
			{
				switch(event.keyCode)
				{
				case 37://Left
					cameraController.addPhi(2.0);
					break;
				case 39://Right
					cameraController.addPhi(-2.0);
					break;
				case 38://Up
					cameraController.addTheta(-2.0);
					break;
				case 40://Down
					cameraController.addTheta(2.0);
					break;
				}
			}
			
			//

			function animate()
			{
				requestAnimationFrame( animate );
				render();
				stats.update();
			}

			function render() {
				cameraController.update( camera );
				renderer.render( scene, camera );
			}

		</script>

	</body>
</html>