webgl_panorama_dualfisheye.html 4.6 KB
Newer Older
1 2 3 4 5 6
<!DOCTYPE html>
<html lang="en">
	<head>
		<title>three.js webgl - dual fisheye panorama</title>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
M
Mr.doob 已提交
7
		<link type="text/css" rel="stylesheet" href="main.css">
8 9
		<style>
			body {
M
Mr.doob 已提交
10 11
				background-color: #fff;
				color: #444;
12 13
			}
			a {
M
Mr.doob 已提交
14
				color: #08f;
15 16 17 18 19 20 21
			}
		</style>
	</head>
	<body>

		<div id="container"></div>
		<div id="info">
M
Mugen87 已提交
22
			<a href="https://threejs.org" target="_blank" rel="noopener">three.js webgl</a> - dualfisheye panorama
23 24
		</div>

M
Mugen87 已提交
25
		<script type="module">
26

M
Mr.doob 已提交
27
			import * as THREE from '../build/three.module.js';
28 29 30 31

			var camera, scene, renderer;

			var isUserInteracting = false,
L
Lewy Blue 已提交
32 33 34 35 36 37 38 39
				lon = 0, lat = 0,
				phi = 0, theta = 0,
				distance = 500,
				onPointerDownPointerX = 0,
				onPointerDownPointerY = 0,

				onPointerDownLon = 0,
				onPointerDownLat = 0;
40 41 42 43 44 45 46 47 48 49

			init();
			animate();

			function init() {

				var container, mesh;

				container = document.getElementById( 'container' );

M
Mr.doob 已提交
50
				camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 2000 );
51

M
Mr.doob 已提交
52
				scene = new THREE.Scene();
53

M
Mr.doob 已提交
54
				var geometry = new THREE.SphereBufferGeometry( 500, 60, 40 ).toNonIndexed();
M
Mugen87 已提交
55
				// invert the geometry on the x-axis so that all of the faces point inward
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
				geometry.scale( - 1, 1, 1 );

				// Remap UVs

				var normals = geometry.attributes.normal.array;
				var uvs = geometry.attributes.uv.array;

				for ( var i = 0, l = normals.length / 3; i < l; i ++ ) {

					var x = normals[ i * 3 + 0 ];
					var y = normals[ i * 3 + 1 ];
					var z = normals[ i * 3 + 2 ];

					if ( i < l / 2 ) {

						var correction = ( x == 0 && z == 0 ) ? 1 : ( Math.acos( y ) / Math.sqrt( x * x + z * z ) ) * ( 2 / Math.PI );
						uvs[ i * 2 + 0 ] = x * ( 404 / 1920 ) * correction + ( 447 / 1920 );
						uvs[ i * 2 + 1 ] = z * ( 404 / 1080 ) * correction + ( 582 / 1080 );

					} else {

						var correction = ( x == 0 && z == 0 ) ? 1 : ( Math.acos( - y ) / Math.sqrt( x * x + z * z ) ) * ( 2 / Math.PI );
						uvs[ i * 2 + 0 ] = - x * ( 404 / 1920 ) * correction + ( 1460 / 1920 );
						uvs[ i * 2 + 1 ] = z * ( 404 / 1080 ) * correction + ( 582 / 1080 );

					}

				}

				geometry.rotateZ( - Math.PI / 2 );

				//

M
Mr.doob 已提交
89 90
				var texture = new THREE.TextureLoader().load( 'textures/ricoh_theta_s.jpg' );
				texture.minFilter = THREE.LinearFilter;
91

M
Mr.doob 已提交
92
				var material = new THREE.MeshBasicMaterial( { map: texture } );
93

M
Mr.doob 已提交
94
				mesh = new THREE.Mesh( geometry, material );
95 96
				scene.add( mesh );

M
Mr.doob 已提交
97
				renderer = new THREE.WebGLRenderer();
98 99 100 101 102 103 104
				renderer.setPixelRatio( window.devicePixelRatio );
				renderer.setSize( window.innerWidth, window.innerHeight );
				container.appendChild( renderer.domElement );

				document.addEventListener( 'mousedown', onDocumentMouseDown, false );
				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
				document.addEventListener( 'mouseup', onDocumentMouseUp, false );
M
Mr.doob 已提交
105
				document.addEventListener( 'wheel', onDocumentMouseWheel, false );
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146

				//

				window.addEventListener( 'resize', onWindowResize, false );

			}

			function onWindowResize() {

				camera.aspect = window.innerWidth / window.innerHeight;
				camera.updateProjectionMatrix();

				renderer.setSize( window.innerWidth, window.innerHeight );

			}

			function onDocumentMouseDown( event ) {

				event.preventDefault();

				isUserInteracting = true;

				onPointerDownPointerX = event.clientX;
				onPointerDownPointerY = event.clientY;

				onPointerDownLon = lon;
				onPointerDownLat = lat;

			}

			function onDocumentMouseMove( event ) {

				if ( isUserInteracting === true ) {

					lon = ( onPointerDownPointerX - event.clientX ) * 0.1 + onPointerDownLon;
					lat = ( onPointerDownPointerY - event.clientY ) * 0.1 + onPointerDownLat;

				}

			}

L
Lewy Blue 已提交
147
			function onDocumentMouseUp() {
148 149 150 151 152 153 154

				isUserInteracting = false;

			}

			function onDocumentMouseWheel( event ) {

M
Mr.doob 已提交
155
				distance += event.deltaY * 0.05;
156

M
Mugen87 已提交
157
				distance = THREE.MathUtils.clamp( distance, 400, 1000 );
W
WestLangley 已提交
158

159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
			}

			function animate() {

				requestAnimationFrame( animate );
				update();

			}

			function update() {

				if ( isUserInteracting === false ) {

					lon += 0.1;

				}

				lat = Math.max( - 85, Math.min( 85, lat ) );
M
Mugen87 已提交
177 178
				phi = THREE.MathUtils.degToRad( 90 - lat );
				theta = THREE.MathUtils.degToRad( lon - 180 );
179 180 181 182 183 184 185 186 187 188 189 190 191 192

				camera.position.x = distance * Math.sin( phi ) * Math.cos( theta );
				camera.position.y = distance * Math.cos( phi );
				camera.position.z = distance * Math.sin( phi ) * Math.sin( theta );

				camera.lookAt( scene.position );

				renderer.render( scene, camera );

			}

		</script>
	</body>
</html>