UNPKG

three-globe

Version:

Globe data visualization as a ThreeJS reusable 3D object

1,365 lines (1,319 loc) 224 kB
import { Mesh, BackSide, BufferAttribute, ShaderMaterial, Color, TextureLoader, SRGBColorSpace, SphereGeometry, MeshPhongMaterial, Group, LineSegments, LineBasicMaterial, CylinderGeometry, Matrix4, Object3D, BufferGeometry, MeshLambertMaterial, Vector3, ShaderChunk, 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 r; }; var t, r = {}, e = Object.prototype, n = e.hasOwnProperty, o = "function" == typeof Symbol ? Symbol : {}, i = o.iterator || "@@iterator", a = o.asyncIterator || "@@asyncIterator", u = o.toStringTag || "@@toStringTag"; function c(t, r, e, n) { return Object.defineProperty(t, r, { value: e, enumerable: !n, configurable: !n, writable: !n }); } try { c({}, ""); } catch (t) { c = function (t, r, e) { return t[r] = e; }; } function h(r, e, n, o) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype); return c(a, "_invoke", function (r, e, n) { var o = 1; return function (i, a) { if (3 === o) throw Error("Generator is already running"); if (4 === o) { if ("throw" === i) throw a; return { value: t, done: true }; } for (n.method = i, n.arg = a;;) { var u = n.delegate; if (u) { var c = d(u, n); if (c) { if (c === f) continue; return c; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (1 === o) throw o = 4, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = 3; var h = s(r, e, n); if ("normal" === h.type) { if (o = n.done ? 4 : 2, h.arg === f) continue; return { value: h.arg, done: n.done }; } "throw" === h.type && (o = 4, n.method = "throw", n.arg = h.arg); } }; }(r, n, new Context(o || [])), true), a; } function s(t, r, e) { try { return { type: "normal", arg: t.call(r, e) }; } catch (t) { return { type: "throw", arg: t }; } } r.wrap = h; var f = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var l = {}; c(l, i, function () { return this; }); var p = Object.getPrototypeOf, y = p && p(p(x([]))); y && y !== e && n.call(y, i) && (l = y); var v = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(l); function g(t) { ["next", "throw", "return"].forEach(function (r) { c(t, r, function (t) { return this._invoke(r, t); }); }); } function AsyncIterator(t, r) { function e(o, i, a, u) { var c = s(t[o], t, i); if ("throw" !== c.type) { var h = c.arg, f = h.value; return f && "object" == typeof f && n.call(f, "__await") ? r.resolve(f.__await).then(function (t) { e("next", t, a, u); }, function (t) { e("throw", t, a, u); }) : r.resolve(f).then(function (t) { h.value = t, a(h); }, function (t) { return e("throw", t, a, u); }); } u(c.arg); } var o; c(this, "_invoke", function (t, n) { function i() { return new r(function (r, o) { e(t, n, r, o); }); } return o = o ? o.then(i, i) : i(); }, true); } function d(r, e) { var n = e.method, o = r.i[n]; if (o === t) return e.delegate = null, "throw" === n && r.i.return && (e.method = "return", e.arg = t, d(r, e), "throw" === e.method) || "return" !== n && (e.method = "throw", e.arg = new TypeError("The iterator does not provide a '" + n + "' method")), f; var i = s(o, r.i, e.arg); if ("throw" === i.type) return e.method = "throw", e.arg = i.arg, e.delegate = null, f; var a = i.arg; return a ? a.done ? (e[r.r] = a.value, e.next = r.n, "return" !== e.method && (e.method = "next", e.arg = t), e.delegate = null, f) : a : (e.method = "throw", e.arg = new TypeError("iterator result is not an object"), e.delegate = null, f); } function w(t) { this.tryEntries.push(t); } function m(r) { var e = r[4] || {}; e.type = "normal", e.arg = t, r[4] = e; } function Context(t) { this.tryEntries = [[-1]], t.forEach(w, this), this.reset(true); } function x(r) { if (null != r) { var e = r[i]; if (e) return e.call(r); if ("function" == typeof r.next) return r; if (!isNaN(r.length)) { var o = -1, a = function e() { for (; ++o < r.length;) if (n.call(r, o)) return e.value = r[o], e.done = false, e; return e.value = t, e.done = true, e; }; return a.next = a; } } throw new TypeError(typeof r + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, c(v, "constructor", GeneratorFunctionPrototype), c(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = c(GeneratorFunctionPrototype, u, "GeneratorFunction"), r.isGeneratorFunction = function (t) { var r = "function" == typeof t && t.constructor; return !!r && (r === GeneratorFunction || "GeneratorFunction" === (r.displayName || r.name)); }, r.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, c(t, u, "GeneratorFunction")), t.prototype = Object.create(v), t; }, r.awrap = function (t) { return { __await: t }; }, g(AsyncIterator.prototype), c(AsyncIterator.prototype, a, function () { return this; }), r.AsyncIterator = AsyncIterator, r.async = function (t, e, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(h(t, e, n, o), i); return r.isGeneratorFunction(e) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, g(v), c(v, u, "Generator"), c(v, i, function () { return this; }), c(v, "toString", function () { return "[object Generator]"; }), r.keys = function (t) { var r = Object(t), e = []; for (var n in r) e.unshift(n); return function t() { for (; e.length;) if ((n = e.pop()) in r) return t.value = n, t.done = false, t; return t.done = true, t; }; }, r.values = x, Context.prototype = { constructor: Context, reset: function (r) { if (this.prev = this.next = 0, this.sent = this._sent = t, this.done = false, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(m), !r) for (var e in this) "t" === e.charAt(0) && n.call(this, e) && !isNaN(+e.slice(1)) && (this[e] = t); }, stop: function () { this.done = true; var t = this.tryEntries[0][4]; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function (r) { if (this.done) throw r; var e = this; function n(t) { a.type = "throw", a.arg = r, e.next = t; } for (var o = e.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i[4], u = this.prev, c = i[1], h = i[2]; if (-1 === i[0]) return n("end"), false; if (!c && !h) throw Error("try statement without catch or finally"); if (null != i[0] && i[0] <= u) { if (u < c) return this.method = "next", this.arg = t, n(c), true; if (u < h) return n(h), false; } } }, abrupt: function (t, r) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var n = this.tryEntries[e]; if (n[0] > -1 && n[0] <= this.prev && this.prev < n[2]) { var o = n; break; } } o && ("break" === t || "continue" === t) && o[0] <= r && r <= o[2] && (o = null); var i = o ? o[4] : {}; return i.type = t, i.arg = r, o ? (this.method = "next", this.next = o[2], f) : this.complete(i); }, complete: function (t, r) { 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 && r && (this.next = r), f; }, finish: function (t) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var e = this.tryEntries[r]; if (e[2] === t) return this.complete(e[4], e[3]), m(e), f; } }, catch: function (t) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var e = this.tryEntries[r]; if (e[0] === t) { var n = e[4]; if ("throw" === n.type) { var o = n.arg; m(e); } return o; } } throw Error("illegal catch attempt"); }, delegateYield: function (r, e, n) { return this.delegate = { i: x(r), r: e, n: n }, "next" === this.method && (this.arg = t), f; } }, r; } 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 ".concat(ShaderChunk.common, "\n ").concat(ShaderChunk.logdepthbuf_pars_vertex, "\n \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 ").concat(ShaderChunk.logdepthbuf_vertex, "\n }\n "), fragmentShader: "\n ".concat(ShaderChunk.logdepthbuf_pars_fragment, "\n\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 ").concat(ShaderChunk.logdepthbuf_fragment, "\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 }, arcDashInitialGap: { "default": 0 }, arcDashAnimateTime: { "default": 0 }, // ms arcsTransitionDuration: { "default": 1000, triggerUpdate: false } // ms }, methods: { pauseAnimation: function pauseAnimation(state) { var _state$ticker; (_state$ticker = state.ticker) === null || _state$ticker === void 0 || _state$ticker.pause(); }, resumeAnimation: function resumeAnimation(state) { var _state$ticker2; (_state$ticker2 = state.ticker) === null || _state$ticker2 === void 0 || _state$ticker2.resume(); }, _destructor: function _destructor(state) { var _state$ticker3; state.sharedMaterial.dispose(); (_state$ticker3 = state.ticker) === null || _state$ticker3 === void 0 || _state$ticker3.dispose(); } }, stateInit: function stateInit(_ref) { var tweenGroup = _ref.tweenGroup; return { tweenGroup: tweenGroup, ticker: new FrameTicker$2(), sharedMaterial: new THREE$e.ShaderMaterial(_objectSpread2(_objectSpread2({}, dashedLineShaders()), {}, { transparent: true, blending: THREE$e.NormalBlending }))