UNPKG

three-globe

Version:

Globe data visualization as a ThreeJS reusable 3D object

1,360 lines (1,314 loc) 225 kB
import { Mesh, BackSide, BufferAttribute, ShaderMaterial, Color, TextureLoader, SRGBColorSpace, SphereGeometry, MeshPhongMaterial, Group, LineSegments, LineBasicMaterial, CylinderGeometry, Matrix4, Object3D, BufferGeometry, MeshLambertMaterial, Vector3, Line, NormalBlending, TubeGeometry, CubicBezierCurve3, Curve, DoubleSide, MeshBasicMaterial, CircleGeometry, Euler, Points, PointsMaterial, BoxGeometry, Camera, Vector2 } from 'three'; import Kapsule from 'kapsule'; import { Tween, Easing, Group as Group$1 } from '@tweenjs/tween.js'; import SlippyMap from 'three-slippy-map-globe'; import GeoJsonGeometry from 'three-geojson-geometry'; import { geoGraticule10, geoDistance as geoDistance$1, geoInterpolate } from 'd3-geo'; import * as _bfg from 'three/examples/jsm/utils/BufferGeometryUtils.js'; import accessorFn from 'accessor-fn'; import { color } from 'd3-color'; import tinyColor from 'tinycolor2'; import DataBindMapper from 'data-bind-mapper'; import _FrameTicker from 'frame-ticker'; import { scaleLinear, scaleQuantize } from 'd3-scale'; import ConicPolygonGeometry from 'three-conic-polygon-geometry'; import indexBy from 'index-array-by'; import { latLngToCell, cellToLatLng, cellToBoundary, polygonToCells } from 'h3-js'; import { interpolateTurbo } from 'd3-scale-chromatic'; import { sum, max } from 'd3-array'; import { StorageInstancedBufferAttribute, WebGPURenderer } from 'three/webgpu'; import * as tsl from 'three/tsl'; import { Line2 } from 'three/examples/jsm/lines/Line2.js'; import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry.js'; import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial.js'; import { interpolateArray } from 'd3-interpolate'; import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry.js'; import { Font } from 'three/examples/jsm/loaders/FontLoader.js'; import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer.js'; function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } function _arrayWithHoles(r) { if (Array.isArray(r)) return r; } function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); } function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); } function _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; } function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); } function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; } function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); } function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); } function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } function _classPrivateFieldGet2(s, a) { return s.get(_assertClassBrand(s, a)); } function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); } function _classPrivateFieldSet2(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; } function _construct(t, e, r) { if (_isNativeReflectConstruct()) return Reflect.construct.apply(null, arguments); var o = [null]; o.push.apply(o, e); var p = new (t.bind.apply(t, o))(); return p; } function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || false, o.configurable = true, "value" in o && (o.writable = true), Object.defineProperty(e, _toPropertyKey(o.key), o); } } function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), Object.defineProperty(e, "prototype", { writable: false }), e; } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e; } function _get() { return _get = "undefined" != typeof Reflect && Reflect.get ? Reflect.get.bind() : function (e, t, r) { var p = _superPropBase(e, t); if (p) { var n = Object.getOwnPropertyDescriptor(p, t); return n.get ? n.get.call(arguments.length < 3 ? e : r) : n.value; } }, _get.apply(null, arguments); } function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); } function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: true, configurable: true } }), Object.defineProperty(t, "prototype", { writable: false }), e && _setPrototypeOf(t, e); } function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function () { return !!t; })(); } function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); } function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = true, o = false; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = true, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread2(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), true).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; } function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; } function _possibleConstructorReturn(t, e) { if (e && ("object" == typeof e || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return _assertThisInitialized(t); } function _regeneratorRuntime() { _regeneratorRuntime = function () { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: true, configurable: true, writable: true }), t[e]; } try { define({}, ""); } catch (t) { define = function (t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == typeof h && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function (t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: true }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(true); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = false, next; return next.value = t, next.done = true, next; }; return i.next = i; } } throw new TypeError(typeof e + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: true }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: true }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = false, next; } return next.done = true, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function (e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = false, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function () { this.done = true; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function (e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, true); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, true); } else { if (!u) throw Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function (t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function (t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function (t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function (t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw Error("illegal catch attempt"); }, delegateYield: function (e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; } function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); } function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); } function _superPropBase(t, o) { for (; !{}.hasOwnProperty.call(t, o) && null !== (t = _getPrototypeOf(t));); return t; } function _superPropGet(t, o, e, r) { var p = _get(_getPrototypeOf(t.prototype ), o, e); return "function" == typeof p ? function (t) { return p.apply(e, t); } : p; } function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } var _materialDispose = function materialDispose(material) { if (material instanceof Array) { material.forEach(_materialDispose); } else { if (material.map) { material.map.dispose(); } material.dispose(); } }; var _deallocate = function deallocate(obj) { if (obj.geometry) { obj.geometry.dispose(); } if (obj.material) { _materialDispose(obj.material); } if (obj.texture) { obj.texture.dispose(); } if (obj.children) { obj.children.forEach(_deallocate); } }; var emptyObject = function emptyObject(obj) { if (obj && obj.children) while (obj.children.length) { var childObj = obj.children[0]; obj.remove(childObj); _deallocate(childObj); } }; function linkKapsule (kapsulePropName, kapsuleType) { var dummyK = new kapsuleType(); // To extract defaults return { linkProp: function linkProp(prop) { // link property config return { "default": dummyK[prop](), onChange: function onChange(v, state) { state[kapsulePropName][prop](v); }, triggerUpdate: false }; }, linkMethod: function linkMethod(method) { // link method pass-through return function (state) { var kapsuleInstance = state[kapsulePropName]; for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } var returnVal = kapsuleInstance[method].apply(kapsuleInstance, args); return returnVal === kapsuleInstance ? this // chain based on the parent object, not the inner kapsule : returnVal; }; } }; } var GLOBE_RADIUS = 100; function getGlobeRadius() { return GLOBE_RADIUS; } function polar2Cartesian(lat, lng) { var relAltitude = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; var phi = (90 - lat) * Math.PI / 180; var theta = (90 - lng) * Math.PI / 180; var r = GLOBE_RADIUS * (1 + relAltitude); var phiSin = Math.sin(phi); return { x: r * phiSin * Math.cos(theta), y: r * Math.cos(phi), z: r * phiSin * Math.sin(theta) }; } function cartesian2Polar(_ref) { var x = _ref.x, y = _ref.y, z = _ref.z; var r = Math.sqrt(x * x + y * y + z * z); var phi = Math.acos(y / r); var theta = Math.atan2(z, x); return { lat: 90 - phi * 180 / Math.PI, lng: 90 - theta * 180 / Math.PI - (theta < -Math.PI / 2 ? 360 : 0), // keep within [-180, 180] boundaries altitude: r / GLOBE_RADIUS - 1 }; } function deg2Rad$1(deg) { return deg * Math.PI / 180; } var THREE$i = window.THREE ? window.THREE // Prefer consumption from global THREE, if exists : { BackSide: BackSide, BufferAttribute: BufferAttribute, Color: Color, Mesh: Mesh, ShaderMaterial: ShaderMaterial }; var vertexShader = "\nuniform float hollowRadius;\n\nvarying vec3 vVertexWorldPosition;\nvarying vec3 vVertexNormal;\nvarying float vCameraDistanceToObjCenter;\nvarying float vVertexAngularDistanceToHollowRadius;\n\nvoid main() { \n vVertexNormal\t= normalize(normalMatrix * normal);\n vVertexWorldPosition = (modelMatrix * vec4(position, 1.0)).xyz;\n \n vec4 objCenterViewPosition = modelViewMatrix * vec4(0.0, 0.0, 0.0, 1.0);\n vCameraDistanceToObjCenter = length(objCenterViewPosition);\n \n float edgeAngle = atan(hollowRadius / vCameraDistanceToObjCenter);\n float vertexAngle = acos(dot(normalize(modelViewMatrix * vec4(position, 1.0)), normalize(objCenterViewPosition)));\n vVertexAngularDistanceToHollowRadius = vertexAngle - edgeAngle;\n\n gl_Position\t= projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}"; var fragmentShader = "\nuniform vec3 color;\nuniform float coefficient;\nuniform float power;\nuniform float hollowRadius;\n\nvarying vec3 vVertexNormal;\nvarying vec3 vVertexWorldPosition;\nvarying float vCameraDistanceToObjCenter;\nvarying float vVertexAngularDistanceToHollowRadius;\n\nvoid main() {\n if (vCameraDistanceToObjCenter < hollowRadius) discard; // inside the hollowRadius\n if (vVertexAngularDistanceToHollowRadius < 0.0) discard; // frag position is within the hollow radius\n\n vec3 worldCameraToVertex = vVertexWorldPosition - cameraPosition;\n vec3 viewCameraToVertex\t= (viewMatrix * vec4(worldCameraToVertex, 0.0)).xyz;\n viewCameraToVertex = normalize(viewCameraToVertex);\n float intensity\t= pow(\n coefficient + dot(vVertexNormal, viewCameraToVertex),\n power\n );\n gl_FragColor = vec4(color, intensity);\n}"; // Based off: http://stemkoski.blogspot.fr/2013/07/shaders-in-threejs-glow-and-halo.html function createGlowMaterial(coefficient, color, power, hollowRadius) { return new THREE$i.ShaderMaterial({ depthWrite: false, transparent: true, vertexShader: vertexShader, fragmentShader: fragmentShader, uniforms: { coefficient: { value: coefficient }, color: { value: new THREE$i.Color(color) }, power: { value: power }, hollowRadius: { value: hollowRadius } } }); } function createGlowGeometry(geometry, size) { var glowGeometry = geometry.clone(); // Resize vertex positions according to normals var position = new Float32Array(geometry.attributes.position.count * 3); for (var idx = 0, len = position.length; idx < len; idx++) { var normal = geometry.attributes.normal.array[idx]; var curPos = geometry.attributes.position.array[idx]; position[idx] = curPos + normal * size; } glowGeometry.setAttribute('position', new THREE$i.BufferAttribute(position, 3)); return glowGeometry; } var GlowMesh = /*#__PURE__*/function (_THREE$Mesh) { function GlowMesh(geometry) { var _this; var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, _ref$color = _ref.color, color = _ref$color === void 0 ? 'gold' : _ref$color, _ref$size = _ref.size, size = _ref$size === void 0 ? 2 : _ref$size, _ref$coefficient = _ref.coefficient, coefficient = _ref$coefficient === void 0 ? 0.5 : _ref$coefficient, _ref$power = _ref.power, power = _ref$power === void 0 ? 1 : _ref$power, _ref$hollowRadius = _ref.hollowRadius, hollowRadius = _ref$hollowRadius === void 0 ? 0 : _ref$hollowRadius, _ref$backside = _ref.backside, backside = _ref$backside === void 0 ? true : _ref$backside; _classCallCheck(this, GlowMesh); _this = _callSuper(this, GlowMesh); var glowGeometry = createGlowGeometry(geometry, size); var glowMaterial = createGlowMaterial(coefficient, color, power, hollowRadius); backside && (glowMaterial.side = THREE$i.BackSide); _this.geometry = glowGeometry; _this.material = glowMaterial; return _this; } _inherits(GlowMesh, _THREE$Mesh); return _createClass(GlowMesh); }(THREE$i.Mesh); var THREE$h = window.THREE ? window.THREE // Prefer consumption from global THREE, if exists : { Color: Color, Group: Group, LineBasicMaterial: LineBasicMaterial, LineSegments: LineSegments, Mesh: Mesh, MeshPhongMaterial: MeshPhongMaterial, SphereGeometry: SphereGeometry, SRGBColorSpace: SRGBColorSpace, TextureLoader: TextureLoader }; // var GlobeLayerKapsule = Kapsule({ props: { globeImageUrl: {}, bumpImageUrl: {}, showGlobe: { "default": true, onChange: function onChange(showGlobe, state) { state.globeGroup.visible = !!showGlobe; }, triggerUpdate: false }, showGraticules: { "default": false, onChange: function onChange(showGraticules, state) { state.graticulesObj.visible = !!showGraticules; }, triggerUpdate: false }, showAtmosphere: { "default": true, onChange: function onChange(showAtmosphere, state) { state.atmosphereObj && (state.atmosphereObj.visible = !!showAtmosphere); }, triggerUpdate: false }, atmosphereColor: { "default": 'lightskyblue' }, atmosphereAltitude: { "default": 0.15 }, globeTileEngineUrl: { onChange: function onChange(v, state) { state.tileEngine.tileUrl = v; } }, globeTileEngineMaxLevel: { "default": 17, onChange: function onChange(v, state) { state.tileEngine.maxLevel = v; }, triggerUpdate: false }, updatePov: { onChange: function onChange(v, state) { state.tileEngine.updatePov(v); }, triggerUpdate: false }, onReady: { "default": function _default() {}, triggerUpdate: false } }, methods: { globeMaterial: function globeMaterial(state, _globeMaterial) { if (_globeMaterial !== undefined) { state.globeObj.material = _globeMaterial || state.defaultGlobeMaterial; return this; } return state.globeObj.material; }, _destructor: function _destructor(state) { emptyObject(state.globeObj); emptyObject(state.tileEngine); emptyObject(state.graticulesObj); } }, stateInit: function stateInit() { // create globe var globeGeometry = new THREE$h.SphereGeometry(GLOBE_RADIUS, 75, 75); var defaultGlobeMaterial = new THREE$h.MeshPhongMaterial({ color: 0x000000 }); var globeObj = new THREE$h.Mesh(globeGeometry, defaultGlobeMaterial); globeObj.rotation.y = -Math.PI / 2; // face prime meridian along Z axis // Create empty tile engine var tileEngine = new SlippyMap(GLOBE_RADIUS); // Group including globe and tile engine var globeGroup = new THREE$h.Group(); globeGroup.__globeObjType = 'globe'; // Add object type globeGroup.add(globeObj); globeGroup.add(tileEngine); // create graticules var graticulesObj = new THREE$h.LineSegments(new GeoJsonGeometry(geoGraticule10(), GLOBE_RADIUS, 2), new THREE$h.LineBasicMaterial({ color: 'lightgrey', transparent: true, opacity: 0.1 })); return { globeGroup: globeGroup, globeObj: globeObj, graticulesObj: graticulesObj, defaultGlobeMaterial: defaultGlobeMaterial, tileEngine: tileEngine }; }, init: function init(threeObj, state) { // Clear the scene emptyObject(threeObj); // Main three object to manipulate state.scene = threeObj; state.scene.add(state.globeGroup); // add globe state.scene.add(state.graticulesObj); // add graticules state.ready = false; }, update: function update(state, changedProps) { var globeMaterial = state.globeObj.material; // Hide globeObj if it's representing tiles state.tileEngine.visible = !(state.globeObj.visible = !state.globeTileEngineUrl); if (changedProps.hasOwnProperty('globeImageUrl')) { if (!state.globeImageUrl) { // Black globe if no image !globeMaterial.color && (globeMaterial.color = new THREE$h.Color(0x000000)); } else { new THREE$h.TextureLoader().load(state.globeImageUrl, function (texture) { texture.colorSpace = THREE$h.SRGBColorSpace; globeMaterial.map = texture; globeMaterial.color = null; globeMaterial.needsUpdate = true; // ready when first globe image finishes loading (asynchronously to allow 1 frame to load texture) !state.ready && (state.ready = true) && setTimeout(state.onReady); }); } } if (changedProps.hasOwnProperty('bumpImageUrl')) { if (!state.bumpImageUrl) { globeMaterial.bumpMap = null; globeMaterial.needsUpdate = true; } else { state.bumpImageUrl && new THREE$h.TextureLoader().load(state.bumpImageUrl, function (texture) { globeMaterial.bumpMap = texture; globeMaterial.needsUpdate = true; }); } } if (changedProps.hasOwnProperty('atmosphereColor') || changedProps.hasOwnProperty('atmosphereAltitude')) { if (state.atmosphereObj) { // recycle previous atmosphere object state.scene.remove(state.atmosphereObj); emptyObject(state.atmosphereObj); } if (state.atmosphereColor && state.atmosphereAltitude) { var obj = state.atmosphereObj = new GlowMesh(state.globeObj.geometry, { color: state.atmosphereColor, size: GLOBE_RADIUS * state.atmosphereAltitude, hollowRadius: GLOBE_RADIUS, coefficient: 0.1, power: 3.5 // dispersion }); obj.visible = !!state.showAtmosphere; obj.__globeObjType = 'atmosphere'; // Add object type state.scene.add(obj); } } if (!state.ready && (!state.globeImageUrl || state.globeTileEngineUrl)) { // ready immediately if there's no globe image state.ready = true; state.onReady(); } } }); var colorStr2Hex = function colorStr2Hex(str) { return isNaN(str) ? parseInt(tinyColor(str).toHex(), 16) : str; }; var colorAlpha = function colorAlpha(str) { return str && isNaN(str) ? color(str).opacity : 1; }; var color2ShaderArr = function color2ShaderArr(str) { var includeAlpha = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; var sRGBColorSpace = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; var color; var alpha = 1; var rgbaMatch = /^rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d.eE+-]+)\s*\)$/.exec(str.trim().toLowerCase()); if (rgbaMatch) { var _rgbaMatch$slice = rgbaMatch.slice(1), _rgbaMatch$slice2 = _slicedToArray(_rgbaMatch$slice, 4), r = _rgbaMatch$slice2[0], g = _rgbaMatch$slice2[1], b = _rgbaMatch$slice2[2], a = _rgbaMatch$slice2[3]; color = new Color("rgb(".concat(+r, ",").concat(+g, ",").concat(+b, ")")); alpha = Math.min(+a, 1); } else { color = new Color(str); } sRGBColorSpace && color.convertLinearToSRGB(); // vertexColors expects linear, but shaders expect sRGB var rgbArr = color.toArray(); return includeAlpha ? [].concat(_toConsumableArray(rgbArr), [alpha]) : rgbArr; }; function setMaterialOpacity(material, opacity, depthWrite) { material.opacity = opacity; material.transparent = opacity < 1; material.depthWrite = opacity >= 1 ; // depthWrite=false recommended for transparent materials, to prevent transparency issues https://discourse.threejs.org/t/threejs-and-the-transparent-problem/11553/31 return material; } var THREE$g = window.THREE ? window.THREE // Prefer consumption from global THREE, if exists : { BufferAttribute: BufferAttribute }; function array2BufferAttr(data) { var itemSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; var ArrayClass = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : Float32Array; if (itemSize === 1) { // edge case handle for improved performance return new THREE$g.BufferAttribute(new ArrayClass(data), itemSize); } var ba = new THREE$g.BufferAttribute(new ArrayClass(data.length * itemSize), itemSize); for (var idx = 0, l = data.length; idx < l; idx++) { ba.set(data[idx], idx * itemSize); } return ba; } function bufferAttr2Array(ba) { var itemSize = ba.itemSize; var res = []; for (var i = 0; i < ba.count; i++) { res.push(ba.array.slice(i * itemSize, (i + 1) * itemSize)); } return res; } var _dataBindAttr = /*#__PURE__*/new WeakMap(); var _objBindAttr = /*#__PURE__*/new WeakMap(); var _removeDelay = /*#__PURE__*/new WeakMap(); var ThreeDigest = /*#__PURE__*/function (_DataBindMapper) { function ThreeDigest(scene) { var _this; var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, _ref$dataBindAttr = _ref.dataBindAttr, dataBindAttr = _ref$dataBindAttr === void 0 ? '__data' : _ref$dataBindAttr, _ref$objBindAttr = _ref.objBindAttr, objBindAttr = _ref$objBindAttr === void 0 ? '__threeObj' : _ref$objBindAttr, _ref$removeDelay = _ref.removeDelay, removeDelay = _ref$removeDelay === void 0 ? 0 : _ref$removeDelay; _classCallCheck(this, ThreeDigest); _this = _callSuper(this, ThreeDigest); _defineProperty(_this, "scene", void 0); _classPrivateFieldInitSpec(_this, _dataBindAttr, void 0); _classPrivateFieldInitSpec(_this, _objBindAttr, void 0); _classPrivateFieldInitSpec(_this, _removeDelay, void 0); _this.scene = scene; _classPrivateFieldSet2(_dataBindAttr, _this, dataBindAttr); _classPrivateFieldSet2(_objBindAttr, _this, objBindAttr); _classPrivateFieldSet2(_removeDelay, _this, removeDelay); _this.onRemoveObj(function () {}); return _this; } _inherits(ThreeDigest, _DataBindMapper); return _createClass(ThreeDigest, [{ key: "onCreateObj", value: function onCreateObj(fn) { var _this2 = this; _superPropGet(ThreeDigest, "onCreateObj", this)([function (d) { var obj = fn(d); d[_classPrivateFieldGet2(_objBindAttr, _this2)] = obj; obj[_classPrivateFieldGet2(_dataBindAttr, _this2)] = d; _this2.scene.add(obj); return obj; }]); return this; } }, { key: "onRemoveObj", value: function onRemoveObj(fn) { var _this3 = this; _superPropGet(ThreeDigest, "onRemoveObj", this)([function (obj, dId) { var d = _superPropGet(ThreeDigest, "getData", _this3)([obj]); fn(obj, dId); var removeFn = function removeFn() { _this3.scene.remove(obj); emptyObject(obj); delete d[_classPrivateFieldGet2(_objBindAttr, _this3)]; }; _classPrivateFieldGet2(_removeDelay, _this3) ? setTimeout(removeFn, _classPrivateFieldGet2(_removeDelay, _this3)) : removeFn(); }]); return this; } }]); }(DataBindMapper); var THREE$f = window.THREE ? window.THREE // Prefer consumption from global THREE, if exists : { BufferGeometry: BufferGeometry, CylinderGeometry: CylinderGeometry, Matrix4: Matrix4, Mesh: Mesh, MeshLambertMaterial: MeshLambertMaterial, Object3D: Object3D, Vector3: Vector3 }; var bfg$2 = Object.assign({}, _bfg); var BufferGeometryUtils$2 = bfg$2.BufferGeometryUtils || bfg$2; // var PointsLayerKapsule = Kapsule({ props: { pointsData: { "default": [] }, pointLat: { "default": 'lat' }, pointLng: { "default": 'lng' }, pointColor: { "default": function _default() { return '#ffffaa'; } }, pointAltitude: { "default": 0.1 }, // in units of globe radius pointRadius: { "default": 0.25 }, // in deg pointResolution: { "default": 12, triggerUpdate: false }, // how many slice segments in the cylinder's circumference pointsMerge: { "default": false }, // boolean. Whether to merge all points into a single mesh for rendering performance pointsTransitionDuration: { "default": 1000, triggerUpdate: false } // ms }, init: function init(threeObj, state, _ref) { var tweenGroup = _ref.tweenGroup; // Clear the scene emptyObject(threeObj); // Main three object to manipulate state.scene = threeObj; state.tweenGroup = tweenGroup; state.dataMapper = new ThreeDigest(threeObj, { objBindAttr: '__threeObjPoint' }); }, update: function update(state, changedProps) { // Data accessors var latAccessor = accessorFn(state.pointLat); var lngAccessor = accessorFn(state.pointLng); var altitudeAccessor = accessorFn(state.pointAltitude); var radiusAccessor = accessorFn(state.pointRadius); var colorAccessor = accessorFn(state.pointColor); // shared geometry var pointGeometry = new THREE$f.CylinderGeometry(1, 1, 1, state.pointResolution); pointGeometry.applyMatrix4(new THREE$f.Matrix4().makeRotationX(Math.PI / 2)); pointGeometry.applyMatrix4(new THREE$f.Matrix4().makeTranslation(0, 0, -0.5)); var pxPerDeg = 2 * Math.PI * GLOBE_RADIUS / 360; var pointMaterials = {}; // indexed by color if (!state.pointsMerge && changedProps.hasOwnProperty('pointsMerge')) { emptyObject(state.scene); // Empty trailing merged objects } state.dataMapper.scene = state.pointsMerge ? new THREE$f.Object3D() : state.scene; // use fake scene if merging points state.dataMapper.onCreateObj(createObj).onUpdateObj(updateObj).digest(state.pointsData); if (state.pointsMerge) { // merge points into a single mesh var pointsGeometry = !state.pointsData.length ? new THREE$f.BufferGeometry() : (BufferGeometryUtils$2.mergeGeometries || BufferGeometryUtils$2.mergeBufferGeometries)(state.pointsData.map(function (d) { var obj = state.dataMapper.getObj(d); var geom = obj.geometry.clone(); // apply mesh world transform to vertices obj.updateMatrix(); geom.applyMatrix4(obj.matrix); // color vertices var color = color2ShaderArr(colorAccessor(d)); geom.setAttribute('color', array2BufferAttr(Array(geom.getAttribute('position').count).fill(color), 4)); return geom; })); var points = new THREE$f.Mesh(pointsGeometry, new THREE$f.MeshLambertMaterial({ color: 0xffffff, transparent: true, vertexColors: true })); points.__globeObjType = 'points'; // Add object type points.__data = state.pointsData; // Attach obj data state.dataMapper.clear(); // Unbind merged points emptyObject(state.scene); state.scene.add(points); } // function createObj() { var obj = new THREE$f.Mesh(pointGeometry); obj.__globeObjType = 'point'; // Add object type return obj; } function updateObj(obj, d) { var applyUpdate = function applyUpdate(td) { var _obj$__currentTargetD = obj.__currentTargetD = td, r = _obj$__currentTargetD.r, alt = _obj$__currentTargetD.alt, lat = _obj$__currentTargetD.lat, lng = _obj$__currentTargetD.lng; // position cylinder ground Object.assign(obj.position, polar2Cartesian(lat, lng)); // orientate outwards var globeCenter = state.pointsMerge ? new THREE$f.Vector3(0, 0, 0) : state.scene.localToWorld(new THREE$f.Vector3(0, 0, 0)); // translate from local to world coords obj.lookAt(globeCenter); // scale radius and altitude obj.scale.x = obj.scale.y = Math.min(30, r) * pxPerDeg; obj.scale.z = Math.max(alt * GLOBE_RADIUS, 0.1); // avoid non-invertible matrix }; var targetD = { alt: +altitudeAccessor(d), r: +radiusAccessor(d), lat: +latAccessor(d), lng: +lngAccessor(d) }; var currentTargetD = obj.__currentTargetD || Object.assign({}, targetD, { alt: -1e-3 }); if (Object.keys(targetD).some(function (k) { return currentTargetD[k] !== targetD[k]; })) { if (state.pointsMerge || !state.pointsTransitionDuration || state.pointsTransitionDuration < 0) { // set final position applyUpdate(targetD); } else { // animate state.tweenGroup.add(new Tween(currentTargetD).to(targetD, state.pointsTransitionDuration).easing(Easing.Quadratic.InOut).onUpdate(applyUpdate).start()); } } if (!state.pointsMerge) { // Update materials on individual points var color = colorAccessor(d); var opacity = color ? colorAlpha(color) : 0; var showCyl = !!opacity; obj.visible = showCyl; if (showCyl) { if (!pointMaterials.hasOwnProperty(color)) { pointMaterials[color] = new THREE$f.MeshLambertMaterial({ color: colorStr2Hex(color), transparent: opacity < 1, opacity: opacity }); } obj.material = pointMaterials[color]; } } } } }); var dashedLineShaders = function dashedLineShaders() { return { uniforms: { // dash param defaults, all relative to full length dashOffset: { value: 0 }, dashSize: { value: 1 }, gapSize: { value: 0 }, dashTranslate: { value: 0 } // used for animating the dash }, vertexShader: "\n uniform float dashTranslate; \n\n attribute vec4 color;\n varying vec4 vColor;\n \n attribute float relDistance;\n varying float vRelDistance;\n\n void main() {\n // pass through colors and distances\n vColor = color;\n vRelDistance = relDistance + dashTranslate;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n ", fragmentShader: "\n uniform float dashOffset; \n uniform float dashSize;\n uniform float gapSize; \n \n varying vec4 vColor;\n varying float vRelDistance;\n \n void main() {\n // ignore pixels in the gap\n if (vRelDistance < dashOffset) discard;\n if (mod(vRelDistance - dashOffset, dashSize + gapSize) > dashSize) discard;\n \n // set px color: [r, g, b, a], interpolated between vertices \n gl_FragColor = vColor; \n }\n " }; }; var invisibleUndergroundShaderExtend = function invisibleUndergroundShaderExtend(shader) { shader.uniforms.surfaceRadius = { type: 'float', value: 0 }; shader.vertexShader = ('attribute float surfaceRadius;\nvarying float vSurfaceRadius;\nvarying vec3 vPos;\n' + shader.vertexShader).replace('void main() {', ['void main() {', 'vSurfaceRadius = surfaceRadius;', 'vPos = position;'].join('\n')); shader.fragmentShader = ('uniform float surfaceRadius;\nvarying float vSurfaceRadius;\nvarying vec3 vPos;\n' + shader.fragmentShader).replace('void main() {', ['void main() {', 'if (length(vPos) < max(surfaceRadius, vSurfaceRadius)) discard;'].join('\n')); return shader; }; var setRadiusShaderExtend = function setRadiusShaderExtend(shader) { shader.vertexShader = "\n attribute float r;\n \n const float PI = 3.1415926535897932384626433832795;\n float toRad(in float a) {\n return a * PI / 180.0;\n }\n \n vec3 Polar2Cartesian(in vec3 c) { // [lat, lng, r]\n float phi = toRad(90.0 - c.x);\n float theta = toRad(90.0 - c.y);\n float r = c.z;\n return vec3( // x,y,z\n r * sin(phi) * cos(theta),\n r * cos(phi),\n r * sin(phi) * sin(theta)\n );\n }\n \n vec2 Cartesian2Polar(in vec3 p) {\n float r = sqrt(p.x * p.x + p.y * p.y + p.z * p.z);\n float phi = acos(p.y / r);\n float theta = atan(p.z, p.x);\n return vec2( // lat,lng\n 90.0 - phi * 180.0 / PI,\n 90.0 - theta * 180.0 / PI - (theta < -PI / 2.0 ? 360.0 : 0.0)\n );\n }\n ".concat(shader.vertexShader.replace('}', " \n vec3 pos = Polar2Cartesian(vec3(Cartesian2Polar(position), r));\n gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);\n }\n "), "\n "); return shader; }; // var applyShaderExtensionToMaterial = function applyShaderExtensionToMaterial(material, extensionFn) { material.onBeforeCompile = function (shader) { material.userData.shader = extensionFn(shader); }; return material; }; var setExtendedMaterialUniforms = function setExtendedMaterialUniforms(material) { var uniformsFn = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function (u) { return u; }; if (material.userData.shader) { uniformsFn(material.userData.shader.uniforms); } else { var curFn = material.onBeforeCompile; material.onBeforeCompile = function (shader) { curFn(shader); uniformsFn(shader.uniforms); }; } }; var _excluded = ["stroke"]; var THREE$e = window.THREE ? window.THREE // Prefer consumption from global THREE, if exists : { BufferGeometry: BufferGeometry, CubicBezierCurve3: CubicBezierCurve3, Curve: Curve, Group: Group, Line: Line, Mesh: Mesh, NormalBlending: NormalBlending, ShaderMaterial: ShaderMaterial, TubeGeometry: TubeGeometry, Vector3: Vector3 }; var FrameTicker$2 = _FrameTicker["default"] || _FrameTicker; // var ArcsLayerKapsule = Kapsule({ props: { arcsData: { "default": [] }, arcStartLat: { "default": 'startLat' }, arcStartLng: { "default": 'startLng' }, arcEndLat: { "default": 'endLat' }, arcEndLng: { "default": 'endLng' }, arcColor: { "default": function _default() { return '#ffffaa'; } }, // single color, array of colors or color interpolation fn arcAltitude: {}, // in units of globe radius arcAltitudeAutoScale: { "default": 0.5 }, // scale altitude proportional to great-arc distance between the two points arcStroke: {}, // in deg arcCurveResolution: { "default": 64, triggerUpdate: false }, // how many straight segments in the curve arcCircularResolution: { "default": 6, triggerUpdate: false }, // how many slice segments in the tube's circumference arcDashLength: { "default": 1 }, // in units of line length arcDashGap: { "default": 0