Advertisement
Guest User

Untitled

a guest
Mar 6th, 2014
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.84 KB | None | 0 0
  1. /**
  2. * dat.globe Javascript WebGL Globe Toolkit
  3. * http://dataarts.github.com/dat.globe
  4. *
  5. * Copyright 2011 Data Arts Team, Google Creative Lab
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the 'License');
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. */
  13.  
  14. var DAT = DAT || {};
  15.  
  16. DAT.Globe = function(container, colorFn) {
  17.  
  18. colorFn = colorFn || function(x) {
  19. var c = new THREE.Color();
  20. c.setHSL( ( 0.6 - ( x * 0.5 ) ), 1.0, 0.5 );
  21. return c;
  22. };
  23.  
  24. var Shaders = {
  25. 'earth' : {
  26. uniforms: {
  27. 'texture': { type: 't', value: null }
  28. },
  29. vertexShader: [
  30. 'varying vec3 vNormal;',
  31. 'varying vec2 vUv;',
  32. 'void main() {',
  33. 'gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
  34. 'vNormal = normalize( normalMatrix * normal );',
  35. 'vUv = uv;',
  36. '}'
  37. ].join('\n'),
  38. fragmentShader: [
  39. 'uniform sampler2D texture;',
  40. 'varying vec3 vNormal;',
  41. 'varying vec2 vUv;',
  42. 'void main() {',
  43. 'vec3 diffuse = texture2D( texture, vUv ).xyz;',
  44. 'float intensity = 1.05 - dot( vNormal, vec3( 0.0, 0.0, 1.0 ) );',
  45. 'vec3 atmosphere = vec3( 1.0, 1.0, 1.0 ) * pow( intensity, 3.0 );',
  46. 'gl_FragColor = vec4( diffuse + atmosphere, 1.0 );',
  47. '}'
  48. ].join('\n')
  49. },
  50. 'atmosphere' : {
  51. uniforms: {},
  52. vertexShader: [
  53. 'varying vec3 vNormal;',
  54. 'void main() {',
  55. 'vNormal = normalize( normalMatrix * normal );',
  56. 'gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
  57. '}'
  58. ].join('\n'),
  59. fragmentShader: [
  60. 'varying vec3 vNormal;',
  61. 'void main() {',
  62. 'float intensity = pow( 0.8 - dot( vNormal, vec3( 0, 0, 1.0 ) ), 12.0 );',
  63. 'gl_FragColor = vec4( 1.0, 1.0, 1.0, 1.0 ) * intensity;',
  64. '}'
  65. ].join('\n')
  66. }
  67. };
  68.  
  69. var camera, scene, renderer, w, h;
  70. var mesh, atmosphere, point;
  71.  
  72. var overRenderer;
  73.  
  74. var imgDir = 'globe/';
  75.  
  76. var curZoomSpeed = 0;
  77. var zoomSpeed = 50;
  78.  
  79. var mouse = { x: 0, y: 0 }, mouseOnDown = { x: 0, y: 0 };
  80. var rotation = { x: 0, y: 0 },
  81. target = { x: Math.PI*3/2, y: Math.PI / 6.0 },
  82. targetOnDown = { x: 0, y: 0 };
  83.  
  84. var distance = 100000, distanceTarget = 100000;
  85. var padding = 40;
  86. var PI_HALF = Math.PI / 2;
  87.  
  88. function init() {
  89.  
  90. container.style.color = '#fff';
  91. container.style.font = '13px/20px Arial, sans-serif';
  92.  
  93. var shader, uniforms, material;
  94. w = container.offsetWidth || window.innerWidth;
  95. h = container.offsetHeight || window.innerHeight;
  96.  
  97. camera = new THREE.PerspectiveCamera(30, w / h, 1, 10000);
  98. camera.position.z = distance;
  99.  
  100. scene = new THREE.Scene();
  101.  
  102. var geometry = new THREE.SphereGeometry(200, 40, 30);
  103.  
  104. shader = Shaders['earth'];
  105. uniforms = THREE.UniformsUtils.clone(shader.uniforms);
  106.  
  107. uniforms['texture'].value = THREE.ImageUtils.loadTexture('world.jpg');
  108.  
  109. material = new THREE.ShaderMaterial({
  110.  
  111. uniforms: uniforms,
  112. vertexShader: shader.vertexShader,
  113. fragmentShader: shader.fragmentShader
  114.  
  115. });
  116.  
  117. mesh = new THREE.Mesh(geometry, material);
  118. mesh.rotation.y = Math.PI;
  119. scene.add(mesh);
  120.  
  121. shader = Shaders['atmosphere'];
  122. uniforms = THREE.UniformsUtils.clone(shader.uniforms);
  123.  
  124. material = new THREE.ShaderMaterial({
  125.  
  126. uniforms: uniforms,
  127. vertexShader: shader.vertexShader,
  128. fragmentShader: shader.fragmentShader,
  129. side: THREE.BackSide,
  130. blending: THREE.AdditiveBlending,
  131. transparent: true
  132.  
  133. });
  134.  
  135. mesh = new THREE.Mesh(geometry, material);
  136. mesh.scale.set( 1.1, 1.1, 1.1 );
  137. scene.add(mesh);
  138.  
  139. geometry = new THREE.CubeGeometry(0.75, 0.75, 1);
  140. geometry.applyMatrix(new THREE.Matrix4().makeTranslation(0,0,-0.5));
  141.  
  142. point = new THREE.Mesh(geometry);
  143.  
  144. renderer = new THREE.WebGLRenderer({antialias: true});
  145. renderer.setSize(w, h);
  146.  
  147. renderer.domElement.style.position = 'absolute';
  148.  
  149. container.appendChild(renderer.domElement);
  150.  
  151. container.addEventListener('mousedown', onMouseDown, false);
  152.  
  153. container.addEventListener('mousewheel', onMouseWheel, false);
  154.  
  155. document.addEventListener('keydown', onDocumentKeyDown, false);
  156.  
  157. window.addEventListener('resize', onWindowResize, false);
  158.  
  159. container.addEventListener('mouseover', function() {
  160. overRenderer = true;
  161. }, false);
  162.  
  163. container.addEventListener('mouseout', function() {
  164. overRenderer = false;
  165. }, false);
  166. }
  167.  
  168. addData = function(data, opts) {
  169. var lat, lng, size, color, i, step, colorFnWrapper;
  170.  
  171. opts.animated = opts.animated || false;
  172. this.is_animated = opts.animated;
  173. opts.format = opts.format || 'magnitude'; // other option is 'legend'
  174. console.log(opts.format);
  175. if (opts.format === 'magnitude') {
  176. step = 3;
  177. colorFnWrapper = function(data, i) { return colorFn(data[i+2]); };
  178. } else if (opts.format === 'legend') {
  179. step = 4;
  180. colorFnWrapper = function(data, i) { return colorFn(data[i+3]); };
  181. } else {
  182. throw('error: format not supported: '+opts.format);
  183. }
  184.  
  185. if (opts.animated) {
  186. if (this._baseGeometry === undefined) {
  187. this._baseGeometry = new THREE.Geometry();
  188. for (i = 0; i < data.length; i += step) {
  189. lat = data[i];
  190. lng = data[i + 1];
  191. // size = data[i + 2];
  192. color = colorFnWrapper(data,i);
  193. size = 0;
  194. addPoint(lat, lng, size, color, this._baseGeometry);
  195. }
  196. }
  197. if(this._morphTargetId === undefined) {
  198. this._morphTargetId = 0;
  199. } else {
  200. this._morphTargetId += 1;
  201. }
  202. opts.name = opts.name || 'morphTarget'+this._morphTargetId;
  203. }
  204. var subgeo = new THREE.Geometry();
  205. for (i = 0; i < data.length; i += step) {
  206. lat = data[i];
  207. lng = data[i + 1];
  208. color = colorFnWrapper(data,i);
  209. size = data[i + 2];
  210. size = size*200;
  211. addPoint(lat, lng, size, color, subgeo);
  212. }
  213. if (opts.animated) {
  214. this._baseGeometry.morphTargets.push({'name': opts.name, vertices: subgeo.vertices});
  215. } else {
  216. this._baseGeometry = subgeo;
  217. }
  218.  
  219. };
  220.  
  221. function createPoints() {
  222. if (this._baseGeometry !== undefined) {
  223. if (this.is_animated === false) {
  224. this.points = new THREE.Mesh(this._baseGeometry, new THREE.MeshBasicMaterial({
  225. color: 0xffffff,
  226. vertexColors: THREE.FaceColors,
  227. morphTargets: false
  228. }));
  229. } else {
  230. if (this._baseGeometry.morphTargets.length < 8) {
  231. console.log('t l',this._baseGeometry.morphTargets.length);
  232. var padding = 8-this._baseGeometry.morphTargets.length;
  233. console.log('padding', padding);
  234. for(var i=0; i<=padding; i++) {
  235. console.log('padding',i);
  236. this._baseGeometry.morphTargets.push({'name': 'morphPadding'+i, vertices: this._baseGeometry.vertices});
  237. }
  238. }
  239. this.points = new THREE.Mesh(this._baseGeometry, new THREE.MeshBasicMaterial({
  240. color: 0xffffff,
  241. vertexColors: THREE.FaceColors,
  242. morphTargets: true
  243. }));
  244. }
  245. scene.add(this.points);
  246. }
  247. }
  248.  
  249. function addPoint(lat, lng, size, color, subgeo) {
  250.  
  251. var phi = (90 - lat) * Math.PI / 180;
  252. var theta = (180 - lng) * Math.PI / 180;
  253.  
  254. point.position.x = 200 * Math.sin(phi) * Math.cos(theta);
  255. point.position.y = 200 * Math.cos(phi);
  256. point.position.z = 200 * Math.sin(phi) * Math.sin(theta);
  257.  
  258. point.lookAt(mesh.position);
  259.  
  260. point.scale.z = Math.max( size, 0.1 ); // avoid non-invertible matrix
  261. point.updateMatrix();
  262.  
  263. for (var i = 0; i < point.geometry.faces.length; i++) {
  264.  
  265. point.geometry.faces[i].color = color;
  266.  
  267. }
  268.  
  269. THREE.GeometryUtils.merge(subgeo, point);
  270. }
  271.  
  272. function onMouseDown(event) {
  273. event.preventDefault();
  274.  
  275. container.addEventListener('mousemove', onMouseMove, false);
  276. container.addEventListener('mouseup', onMouseUp, false);
  277. container.addEventListener('mouseout', onMouseOut, false);
  278.  
  279. mouseOnDown.x = - event.clientX;
  280. mouseOnDown.y = event.clientY;
  281.  
  282. targetOnDown.x = target.x;
  283. targetOnDown.y = target.y;
  284.  
  285. container.style.cursor = 'move';
  286. }
  287.  
  288. function onMouseMove(event) {
  289. mouse.x = - event.clientX;
  290. mouse.y = event.clientY;
  291.  
  292. var zoomDamp = distance/1000;
  293.  
  294. target.x = targetOnDown.x + (mouse.x - mouseOnDown.x) * 0.005 * zoomDamp;
  295. target.y = targetOnDown.y + (mouse.y - mouseOnDown.y) * 0.005 * zoomDamp;
  296.  
  297. target.y = target.y > PI_HALF ? PI_HALF : target.y;
  298. target.y = target.y < - PI_HALF ? - PI_HALF : target.y;
  299. }
  300.  
  301. function onMouseUp(event) {
  302. container.removeEventListener('mousemove', onMouseMove, false);
  303. container.removeEventListener('mouseup', onMouseUp, false);
  304. container.removeEventListener('mouseout', onMouseOut, false);
  305. container.style.cursor = 'auto';
  306. }
  307.  
  308. function onMouseOut(event) {
  309. container.removeEventListener('mousemove', onMouseMove, false);
  310. container.removeEventListener('mouseup', onMouseUp, false);
  311. container.removeEventListener('mouseout', onMouseOut, false);
  312. }
  313.  
  314. function onMouseWheel(event) {
  315. event.preventDefault();
  316. if (overRenderer) {
  317. zoom(event.wheelDeltaY * 0.3);
  318. }
  319. return false;
  320. }
  321.  
  322. function onDocumentKeyDown(event) {
  323. switch (event.keyCode) {
  324. case 38:
  325. zoom(100);
  326. event.preventDefault();
  327. break;
  328. case 40:
  329. zoom(-100);
  330. event.preventDefault();
  331. break;
  332. }
  333. }
  334.  
  335. function onWindowResize( event ) {
  336. camera.aspect = window.innerWidth / window.innerHeight;
  337. camera.updateProjectionMatrix();
  338. renderer.setSize( window.innerWidth, window.innerHeight );
  339. }
  340.  
  341. function zoom(delta) {
  342. distanceTarget -= delta;
  343. distanceTarget = distanceTarget > 1000 ? 1000 : distanceTarget;
  344. distanceTarget = distanceTarget < 350 ? 350 : distanceTarget;
  345. }
  346.  
  347. function animate() {
  348. requestAnimationFrame(animate);
  349. render();
  350. }
  351.  
  352. function render() {
  353. zoom(curZoomSpeed);
  354.  
  355. rotation.x += (target.x - rotation.x) * 0.1;
  356. rotation.y += (target.y - rotation.y) * 0.1;
  357. distance += (distanceTarget - distance) * 0.3;
  358.  
  359. camera.position.x = distance * Math.sin(rotation.x) * Math.cos(rotation.y);
  360. camera.position.y = distance * Math.sin(rotation.y);
  361. camera.position.z = distance * Math.cos(rotation.x) * Math.cos(rotation.y);
  362.  
  363. camera.lookAt(mesh.position);
  364.  
  365. renderer.render(scene, camera);
  366. }
  367.  
  368. init();
  369. this.animate = animate;
  370.  
  371.  
  372. this.__defineGetter__('time', function() {
  373. return this._time || 0;
  374. });
  375.  
  376. this.__defineSetter__('time', function(t) {
  377. var validMorphs = [];
  378. var morphDict = this.points.morphTargetDictionary;
  379. for(var k in morphDict) {
  380. if(k.indexOf('morphPadding') < 0) {
  381. validMorphs.push(morphDict[k]);
  382. }
  383. }
  384. validMorphs.sort();
  385. var l = validMorphs.length-1;
  386. var scaledt = t*l+1;
  387. var index = Math.floor(scaledt);
  388. for (i=0;i<validMorphs.length;i++) {
  389. this.points.morphTargetInfluences[validMorphs[i]] = 0;
  390. }
  391. var lastIndex = index - 1;
  392. var leftover = scaledt - index;
  393. if (lastIndex >= 0) {
  394. this.points.morphTargetInfluences[lastIndex] = 1 - leftover;
  395. }
  396. this.points.morphTargetInfluences[index] = leftover;
  397. this._time = t;
  398. });
  399.  
  400. this.addData = addData;
  401. this.createPoints = createPoints;
  402. this.renderer = renderer;
  403. this.scene = scene;
  404.  
  405. return this;
  406.  
  407. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement