(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("echarts"));
else if(typeof define === 'function' && define.amd)
define(["echarts"], factory);
else if(typeof exports === 'object')
exports["echarts-gl"] = factory(require("echarts"));
else
root["echarts-gl"] = factory(root["echarts"]);
})(this, function(__WEBPACK_EXTERNAL_MODULE_0__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 99);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE_0__;
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global) {/**
* @fileoverview gl-matrix - High performance matrix and vector operations
* @author Brandon Jones
* @author Colin MacKenzie IV
* @version 2.2.2
*/
/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
(function(_global) {
"use strict";
var shim = {};
if (false) {
if(typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
shim.exports = {};
define(function() {
return shim.exports;
});
} else {
// gl-matrix lives in a browser, define its namespaces in global
shim.exports = typeof(window) !== 'undefined' ? window : _global;
}
}
else {
// gl-matrix lives in commonjs, define its namespaces in exports
shim.exports = exports;
}
(function(exports) {
/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
var g = typeof window === 'undefined' ? global : window;
var GLMAT_EPSILON = g.GLMAT_EPSILON;
if(GLMAT_EPSILON == null) {
GLMAT_EPSILON = 0.000001;
}
// Use Array instead of Float32Array. It seems to be much faster and higher precision.
var GLMAT_ARRAY_TYPE = g.GLMAT_ARRAY_TYPE || Array;
// if(!GLMAT_ARRAY_TYPE) {
// GLMAT_ARRAY_TYPE = (typeof Float32Array !== 'undefined') ? Float32Array : Array;
// }
var GLMAT_RANDOM = g.GLMAT_RANDOM;
if(!GLMAT_RANDOM) {
GLMAT_RANDOM = Math.random;
}
/**
* @class Common utilities
* @name glMatrix
*/
var glMatrix = {};
/**
* Sets the type of array used when creating new vectors and matrices
*
* @param {Type} type Array type, such as Float32Array or Array
*/
glMatrix.setMatrixArrayType = function(type) {
GLMAT_ARRAY_TYPE = type;
}
if(typeof(exports) !== 'undefined') {
exports.glMatrix = glMatrix;
}
var degree = Math.PI / 180;
/**
* Convert Degree To Radian
*
* @param {Number} Angle in Degrees
*/
glMatrix.toRadian = function(a){
return a * degree;
}
;
/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/**
* @class 2 Dimensional Vector
* @name vec2
*/
var vec2 = {};
/**
* Creates a new, empty vec2
*
* @returns {vec2} a new 2D vector
*/
vec2.create = function() {
var out = new GLMAT_ARRAY_TYPE(2);
out[0] = 0;
out[1] = 0;
return out;
};
/**
* Creates a new vec2 initialized with values from an existing vector
*
* @param {vec2} a vector to clone
* @returns {vec2} a new 2D vector
*/
vec2.clone = function(a) {
var out = new GLMAT_ARRAY_TYPE(2);
out[0] = a[0];
out[1] = a[1];
return out;
};
/**
* Creates a new vec2 initialized with the given values
*
* @param {Number} x X component
* @param {Number} y Y component
* @returns {vec2} a new 2D vector
*/
vec2.fromValues = function(x, y) {
var out = new GLMAT_ARRAY_TYPE(2);
out[0] = x;
out[1] = y;
return out;
};
/**
* Copy the values from one vec2 to another
*
* @param {vec2} out the receiving vector
* @param {vec2} a the source vector
* @returns {vec2} out
*/
vec2.copy = function(out, a) {
out[0] = a[0];
out[1] = a[1];
return out;
};
/**
* Set the components of a vec2 to the given values
*
* @param {vec2} out the receiving vector
* @param {Number} x X component
* @param {Number} y Y component
* @returns {vec2} out
*/
vec2.set = function(out, x, y) {
out[0] = x;
out[1] = y;
return out;
};
/**
* Adds two vec2's
*
* @param {vec2} out the receiving vector
* @param {vec2} a the first operand
* @param {vec2} b the second operand
* @returns {vec2} out
*/
vec2.add = function(out, a, b) {
out[0] = a[0] + b[0];
out[1] = a[1] + b[1];
return out;
};
/**
* Subtracts vector b from vector a
*
* @param {vec2} out the receiving vector
* @param {vec2} a the first operand
* @param {vec2} b the second operand
* @returns {vec2} out
*/
vec2.subtract = function(out, a, b) {
out[0] = a[0] - b[0];
out[1] = a[1] - b[1];
return out;
};
/**
* Alias for {@link vec2.subtract}
* @function
*/
vec2.sub = vec2.subtract;
/**
* Multiplies two vec2's
*
* @param {vec2} out the receiving vector
* @param {vec2} a the first operand
* @param {vec2} b the second operand
* @returns {vec2} out
*/
vec2.multiply = function(out, a, b) {
out[0] = a[0] * b[0];
out[1] = a[1] * b[1];
return out;
};
/**
* Alias for {@link vec2.multiply}
* @function
*/
vec2.mul = vec2.multiply;
/**
* Divides two vec2's
*
* @param {vec2} out the receiving vector
* @param {vec2} a the first operand
* @param {vec2} b the second operand
* @returns {vec2} out
*/
vec2.divide = function(out, a, b) {
out[0] = a[0] / b[0];
out[1] = a[1] / b[1];
return out;
};
/**
* Alias for {@link vec2.divide}
* @function
*/
vec2.div = vec2.divide;
/**
* Returns the minimum of two vec2's
*
* @param {vec2} out the receiving vector
* @param {vec2} a the first operand
* @param {vec2} b the second operand
* @returns {vec2} out
*/
vec2.min = function(out, a, b) {
out[0] = Math.min(a[0], b[0]);
out[1] = Math.min(a[1], b[1]);
return out;
};
/**
* Returns the maximum of two vec2's
*
* @param {vec2} out the receiving vector
* @param {vec2} a the first operand
* @param {vec2} b the second operand
* @returns {vec2} out
*/
vec2.max = function(out, a, b) {
out[0] = Math.max(a[0], b[0]);
out[1] = Math.max(a[1], b[1]);
return out;
};
/**
* Scales a vec2 by a scalar number
*
* @param {vec2} out the receiving vector
* @param {vec2} a the vector to scale
* @param {Number} b amount to scale the vector by
* @returns {vec2} out
*/
vec2.scale = function(out, a, b) {
out[0] = a[0] * b;
out[1] = a[1] * b;
return out;
};
/**
* Adds two vec2's after scaling the second operand by a scalar value
*
* @param {vec2} out the receiving vector
* @param {vec2} a the first operand
* @param {vec2} b the second operand
* @param {Number} scale the amount to scale b by before adding
* @returns {vec2} out
*/
vec2.scaleAndAdd = function(out, a, b, scale) {
out[0] = a[0] + (b[0] * scale);
out[1] = a[1] + (b[1] * scale);
return out;
};
/**
* Calculates the euclidian distance between two vec2's
*
* @param {vec2} a the first operand
* @param {vec2} b the second operand
* @returns {Number} distance between a and b
*/
vec2.distance = function(a, b) {
var x = b[0] - a[0],
y = b[1] - a[1];
return Math.sqrt(x*x + y*y);
};
/**
* Alias for {@link vec2.distance}
* @function
*/
vec2.dist = vec2.distance;
/**
* Calculates the squared euclidian distance between two vec2's
*
* @param {vec2} a the first operand
* @param {vec2} b the second operand
* @returns {Number} squared distance between a and b
*/
vec2.squaredDistance = function(a, b) {
var x = b[0] - a[0],
y = b[1] - a[1];
return x*x + y*y;
};
/**
* Alias for {@link vec2.squaredDistance}
* @function
*/
vec2.sqrDist = vec2.squaredDistance;
/**
* Calculates the length of a vec2
*
* @param {vec2} a vector to calculate length of
* @returns {Number} length of a
*/
vec2.length = function (a) {
var x = a[0],
y = a[1];
return Math.sqrt(x*x + y*y);
};
/**
* Alias for {@link vec2.length}
* @function
*/
vec2.len = vec2.length;
/**
* Calculates the squared length of a vec2
*
* @param {vec2} a vector to calculate squared length of
* @returns {Number} squared length of a
*/
vec2.squaredLength = function (a) {
var x = a[0],
y = a[1];
return x*x + y*y;
};
/**
* Alias for {@link vec2.squaredLength}
* @function
*/
vec2.sqrLen = vec2.squaredLength;
/**
* Negates the components of a vec2
*
* @param {vec2} out the receiving vector
* @param {vec2} a vector to negate
* @returns {vec2} out
*/
vec2.negate = function(out, a) {
out[0] = -a[0];
out[1] = -a[1];
return out;
};
/**
* Returns the inverse of the components of a vec2
*
* @param {vec2} out the receiving vector
* @param {vec2} a vector to invert
* @returns {vec2} out
*/
vec2.inverse = function(out, a) {
out[0] = 1.0 / a[0];
out[1] = 1.0 / a[1];
return out;
};
/**
* Normalize a vec2
*
* @param {vec2} out the receiving vector
* @param {vec2} a vector to normalize
* @returns {vec2} out
*/
vec2.normalize = function(out, a) {
var x = a[0],
y = a[1];
var len = x*x + y*y;
if (len > 0) {
//TODO: evaluate use of glm_invsqrt here?
len = 1 / Math.sqrt(len);
out[0] = a[0] * len;
out[1] = a[1] * len;
}
return out;
};
/**
* Calculates the dot product of two vec2's
*
* @param {vec2} a the first operand
* @param {vec2} b the second operand
* @returns {Number} dot product of a and b
*/
vec2.dot = function (a, b) {
return a[0] * b[0] + a[1] * b[1];
};
/**
* Computes the cross product of two vec2's
* Note that the cross product must by definition produce a 3D vector
*
* @param {vec3} out the receiving vector
* @param {vec2} a the first operand
* @param {vec2} b the second operand
* @returns {vec3} out
*/
vec2.cross = function(out, a, b) {
var z = a[0] * b[1] - a[1] * b[0];
out[0] = out[1] = 0;
out[2] = z;
return out;
};
/**
* Performs a linear interpolation between two vec2's
*
* @param {vec2} out the receiving vector
* @param {vec2} a the first operand
* @param {vec2} b the second operand
* @param {Number} t interpolation amount between the two inputs
* @returns {vec2} out
*/
vec2.lerp = function (out, a, b, t) {
var ax = a[0],
ay = a[1];
out[0] = ax + t * (b[0] - ax);
out[1] = ay + t * (b[1] - ay);
return out;
};
/**
* Generates a random vector with the given scale
*
* @param {vec2} out the receiving vector
* @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned
* @returns {vec2} out
*/
vec2.random = function (out, scale) {
scale = scale || 1.0;
var r = GLMAT_RANDOM() * 2.0 * Math.PI;
out[0] = Math.cos(r) * scale;
out[1] = Math.sin(r) * scale;
return out;
};
/**
* Transforms the vec2 with a mat2
*
* @param {vec2} out the receiving vector
* @param {vec2} a the vector to transform
* @param {mat2} m matrix to transform with
* @returns {vec2} out
*/
vec2.transformMat2 = function(out, a, m) {
var x = a[0],
y = a[1];
out[0] = m[0] * x + m[2] * y;
out[1] = m[1] * x + m[3] * y;
return out;
};
/**
* Transforms the vec2 with a mat2d
*
* @param {vec2} out the receiving vector
* @param {vec2} a the vector to transform
* @param {mat2d} m matrix to transform with
* @returns {vec2} out
*/
vec2.transformMat2d = function(out, a, m) {
var x = a[0],
y = a[1];
out[0] = m[0] * x + m[2] * y + m[4];
out[1] = m[1] * x + m[3] * y + m[5];
return out;
};
/**
* Transforms the vec2 with a mat3
* 3rd vector component is implicitly '1'
*
* @param {vec2} out the receiving vector
* @param {vec2} a the vector to transform
* @param {mat3} m matrix to transform with
* @returns {vec2} out
*/
vec2.transformMat3 = function(out, a, m) {
var x = a[0],
y = a[1];
out[0] = m[0] * x + m[3] * y + m[6];
out[1] = m[1] * x + m[4] * y + m[7];
return out;
};
/**
* Transforms the vec2 with a mat4
* 3rd vector component is implicitly '0'
* 4th vector component is implicitly '1'
*
* @param {vec2} out the receiving vector
* @param {vec2} a the vector to transform
* @param {mat4} m matrix to transform with
* @returns {vec2} out
*/
vec2.transformMat4 = function(out, a, m) {
var x = a[0],
y = a[1];
out[0] = m[0] * x + m[4] * y + m[12];
out[1] = m[1] * x + m[5] * y + m[13];
return out;
};
/**
* Perform some operation over an array of vec2s.
*
* @param {Array} a the array of vectors to iterate over
* @param {Number} stride Number of elements between the start of each vec2. If 0 assumes tightly packed
* @param {Number} offset Number of elements to skip at the beginning of the array
* @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array
* @param {Function} fn Function to call for each vector in the array
* @param {Object} [arg] additional argument to pass to fn
* @returns {Array} a
* @function
*/
vec2.forEach = (function() {
var vec = vec2.create();
return function(a, stride, offset, count, fn, arg) {
var i, l;
if(!stride) {
stride = 2;
}
if(!offset) {
offset = 0;
}
if(count) {
l = Math.min((count * stride) + offset, a.length);
} else {
l = a.length;
}
for(i = offset; i < l; i += stride) {
vec[0] = a[i]; vec[1] = a[i+1];
fn(vec, vec, arg);
a[i] = vec[0]; a[i+1] = vec[1];
}
return a;
};
})();
/**
* Returns a string representation of a vector
*
* @param {vec2} vec vector to represent as a string
* @returns {String} string representation of the vector
*/
vec2.str = function (a) {
return 'vec2(' + a[0] + ', ' + a[1] + ')';
};
if(typeof(exports) !== 'undefined') {
exports.vec2 = vec2;
}
;
/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/**
* @class 3 Dimensional Vector
* @name vec3
*/
var vec3 = {};
/**
* Creates a new, empty vec3
*
* @returns {vec3} a new 3D vector
*/
vec3.create = function() {
var out = new GLMAT_ARRAY_TYPE(3);
out[0] = 0;
out[1] = 0;
out[2] = 0;
return out;
};
/**
* Creates a new vec3 initialized with values from an existing vector
*
* @param {vec3} a vector to clone
* @returns {vec3} a new 3D vector
*/
vec3.clone = function(a) {
var out = new GLMAT_ARRAY_TYPE(3);
out[0] = a[0];
out[1] = a[1];
out[2] = a[2];
return out;
};
/**
* Creates a new vec3 initialized with the given values
*
* @param {Number} x X component
* @param {Number} y Y component
* @param {Number} z Z component
* @returns {vec3} a new 3D vector
*/
vec3.fromValues = function(x, y, z) {
var out = new GLMAT_ARRAY_TYPE(3);
out[0] = x;
out[1] = y;
out[2] = z;
return out;
};
/**
* Copy the values from one vec3 to another
*
* @param {vec3} out the receiving vector
* @param {vec3} a the source vector
* @returns {vec3} out
*/
vec3.copy = function(out, a) {
out[0] = a[0];
out[1] = a[1];
out[2] = a[2];
return out;
};
/**
* Set the components of a vec3 to the given values
*
* @param {vec3} out the receiving vector
* @param {Number} x X component
* @param {Number} y Y component
* @param {Number} z Z component
* @returns {vec3} out
*/
vec3.set = function(out, x, y, z) {
out[0] = x;
out[1] = y;
out[2] = z;
return out;
};
/**
* Adds two vec3's
*
* @param {vec3} out the receiving vector
* @param {vec3} a the first operand
* @param {vec3} b the second operand
* @returns {vec3} out
*/
vec3.add = function(out, a, b) {
out[0] = a[0] + b[0];
out[1] = a[1] + b[1];
out[2] = a[2] + b[2];
return out;
};
/**
* Subtracts vector b from vector a
*
* @param {vec3} out the receiving vector
* @param {vec3} a the first operand
* @param {vec3} b the second operand
* @returns {vec3} out
*/
vec3.subtract = function(out, a, b) {
out[0] = a[0] - b[0];
out[1] = a[1] - b[1];
out[2] = a[2] - b[2];
return out;
};
/**
* Alias for {@link vec3.subtract}
* @function
*/
vec3.sub = vec3.subtract;
/**
* Multiplies two vec3's
*
* @param {vec3} out the receiving vector
* @param {vec3} a the first operand
* @param {vec3} b the second operand
* @returns {vec3} out
*/
vec3.multiply = function(out, a, b) {
out[0] = a[0] * b[0];
out[1] = a[1] * b[1];
out[2] = a[2] * b[2];
return out;
};
/**
* Alias for {@link vec3.multiply}
* @function
*/
vec3.mul = vec3.multiply;
/**
* Divides two vec3's
*
* @param {vec3} out the receiving vector
* @param {vec3} a the first operand
* @param {vec3} b the second operand
* @returns {vec3} out
*/
vec3.divide = function(out, a, b) {
out[0] = a[0] / b[0];
out[1] = a[1] / b[1];
out[2] = a[2] / b[2];
return out;
};
/**
* Alias for {@link vec3.divide}
* @function
*/
vec3.div = vec3.divide;
/**
* Returns the minimum of two vec3's
*
* @param {vec3} out the receiving vector
* @param {vec3} a the first operand
* @param {vec3} b the second operand
* @returns {vec3} out
*/
vec3.min = function(out, a, b) {
out[0] = Math.min(a[0], b[0]);
out[1] = Math.min(a[1], b[1]);
out[2] = Math.min(a[2], b[2]);
return out;
};
/**
* Returns the maximum of two vec3's
*
* @param {vec3} out the receiving vector
* @param {vec3} a the first operand
* @param {vec3} b the second operand
* @returns {vec3} out
*/
vec3.max = function(out, a, b) {
out[0] = Math.max(a[0], b[0]);
out[1] = Math.max(a[1], b[1]);
out[2] = Math.max(a[2], b[2]);
return out;
};
/**
* Scales a vec3 by a scalar number
*
* @param {vec3} out the receiving vector
* @param {vec3} a the vector to scale
* @param {Number} b amount to scale the vector by
* @returns {vec3} out
*/
vec3.scale = function(out, a, b) {
out[0] = a[0] * b;
out[1] = a[1] * b;
out[2] = a[2] * b;
return out;
};
/**
* Adds two vec3's after scaling the second operand by a scalar value
*
* @param {vec3} out the receiving vector
* @param {vec3} a the first operand
* @param {vec3} b the second operand
* @param {Number} scale the amount to scale b by before adding
* @returns {vec3} out
*/
vec3.scaleAndAdd = function(out, a, b, scale) {
out[0] = a[0] + (b[0] * scale);
out[1] = a[1] + (b[1] * scale);
out[2] = a[2] + (b[2] * scale);
return out;
};
/**
* Calculates the euclidian distance between two vec3's
*
* @param {vec3} a the first operand
* @param {vec3} b the second operand
* @returns {Number} distance between a and b
*/
vec3.distance = function(a, b) {
var x = b[0] - a[0],
y = b[1] - a[1],
z = b[2] - a[2];
return Math.sqrt(x*x + y*y + z*z);
};
/**
* Alias for {@link vec3.distance}
* @function
*/
vec3.dist = vec3.distance;
/**
* Calculates the squared euclidian distance between two vec3's
*
* @param {vec3} a the first operand
* @param {vec3} b the second operand
* @returns {Number} squared distance between a and b
*/
vec3.squaredDistance = function(a, b) {
var x = b[0] - a[0],
y = b[1] - a[1],
z = b[2] - a[2];
return x*x + y*y + z*z;
};
/**
* Alias for {@link vec3.squaredDistance}
* @function
*/
vec3.sqrDist = vec3.squaredDistance;
/**
* Calculates the length of a vec3
*
* @param {vec3} a vector to calculate length of
* @returns {Number} length of a
*/
vec3.length = function (a) {
var x = a[0],
y = a[1],
z = a[2];
return Math.sqrt(x*x + y*y + z*z);
};
/**
* Alias for {@link vec3.length}
* @function
*/
vec3.len = vec3.length;
/**
* Calculates the squared length of a vec3
*
* @param {vec3} a vector to calculate squared length of
* @returns {Number} squared length of a
*/
vec3.squaredLength = function (a) {
var x = a[0],
y = a[1],
z = a[2];
return x*x + y*y + z*z;
};
/**
* Alias for {@link vec3.squaredLength}
* @function
*/
vec3.sqrLen = vec3.squaredLength;
/**
* Negates the components of a vec3
*
* @param {vec3} out the receiving vector
* @param {vec3} a vector to negate
* @returns {vec3} out
*/
vec3.negate = function(out, a) {
out[0] = -a[0];
out[1] = -a[1];
out[2] = -a[2];
return out;
};
/**
* Returns the inverse of the components of a vec3
*
* @param {vec3} out the receiving vector
* @param {vec3} a vector to invert
* @returns {vec3} out
*/
vec3.inverse = function(out, a) {
out[0] = 1.0 / a[0];
out[1] = 1.0 / a[1];
out[2] = 1.0 / a[2];
return out;
};
/**
* Normalize a vec3
*
* @param {vec3} out the receiving vector
* @param {vec3} a vector to normalize
* @returns {vec3} out
*/
vec3.normalize = function(out, a) {
var x = a[0],
y = a[1],
z = a[2];
var len = x*x + y*y + z*z;
if (len > 0) {
//TODO: evaluate use of glm_invsqrt here?
len = 1 / Math.sqrt(len);
out[0] = a[0] * len;
out[1] = a[1] * len;
out[2] = a[2] * len;
}
return out;
};
/**
* Calculates the dot product of two vec3's
*
* @param {vec3} a the first operand
* @param {vec3} b the second operand
* @returns {Number} dot product of a and b
*/
vec3.dot = function (a, b) {
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
};
/**
* Computes the cross product of two vec3's
*
* @param {vec3} out the receiving vector
* @param {vec3} a the first operand
* @param {vec3} b the second operand
* @returns {vec3} out
*/
vec3.cross = function(out, a, b) {
var ax = a[0], ay = a[1], az = a[2],
bx = b[0], by = b[1], bz = b[2];
out[0] = ay * bz - az * by;
out[1] = az * bx - ax * bz;
out[2] = ax * by - ay * bx;
return out;
};
/**
* Performs a linear interpolation between two vec3's
*
* @param {vec3} out the receiving vector
* @param {vec3} a the first operand
* @param {vec3} b the second operand
* @param {Number} t interpolation amount between the two inputs
* @returns {vec3} out
*/
vec3.lerp = function (out, a, b, t) {
var ax = a[0],
ay = a[1],
az = a[2];
out[0] = ax + t * (b[0] - ax);
out[1] = ay + t * (b[1] - ay);
out[2] = az + t * (b[2] - az);
return out;
};
/**
* Generates a random vector with the given scale
*
* @param {vec3} out the receiving vector
* @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned
* @returns {vec3} out
*/
vec3.random = function (out, scale) {
scale = scale || 1.0;
var r = GLMAT_RANDOM() * 2.0 * Math.PI;
var z = (GLMAT_RANDOM() * 2.0) - 1.0;
var zScale = Math.sqrt(1.0-z*z) * scale;
out[0] = Math.cos(r) * zScale;
out[1] = Math.sin(r) * zScale;
out[2] = z * scale;
return out;
};
/**
* Transforms the vec3 with a mat4.
* 4th vector component is implicitly '1'
*
* @param {vec3} out the receiving vector
* @param {vec3} a the vector to transform
* @param {mat4} m matrix to transform with
* @returns {vec3} out
*/
vec3.transformMat4 = function(out, a, m) {
var x = a[0], y = a[1], z = a[2],
w = m[3] * x + m[7] * y + m[11] * z + m[15];
w = w || 1.0;
out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w;
out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w;
out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w;
return out;
};
/**
* Transforms the vec3 with a mat3.
*
* @param {vec3} out the receiving vector
* @param {vec3} a the vector to transform
* @param {mat4} m the 3x3 matrix to transform with
* @returns {vec3} out
*/
vec3.transformMat3 = function(out, a, m) {
var x = a[0], y = a[1], z = a[2];
out[0] = x * m[0] + y * m[3] + z * m[6];
out[1] = x * m[1] + y * m[4] + z * m[7];
out[2] = x * m[2] + y * m[5] + z * m[8];
return out;
};
/**
* Transforms the vec3 with a quat
*
* @param {vec3} out the receiving vector
* @param {vec3} a the vector to transform
* @param {quat} q quaternion to transform with
* @returns {vec3} out
*/
vec3.transformQuat = function(out, a, q) {
// benchmarks: http://jsperf.com/quaternion-transform-vec3-implementations
var x = a[0], y = a[1], z = a[2],
qx = q[0], qy = q[1], qz = q[2], qw = q[3],
// calculate quat * vec
ix = qw * x + qy * z - qz * y,
iy = qw * y + qz * x - qx * z,
iz = qw * z + qx * y - qy * x,
iw = -qx * x - qy * y - qz * z;
// calculate result * inverse quat
out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy;
out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;
out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;
return out;
};
/**
* Rotate a 3D vector around the x-axis
* @param {vec3} out The receiving vec3
* @param {vec3} a The vec3 point to rotate
* @param {vec3} b The origin of the rotation
* @param {Number} c The angle of rotation
* @returns {vec3} out
*/
vec3.rotateX = function(out, a, b, c){
var p = [], r=[];
//Translate point to the origin
p[0] = a[0] - b[0];
p[1] = a[1] - b[1];
p[2] = a[2] - b[2];
//perform rotation
r[0] = p[0];
r[1] = p[1]*Math.cos(c) - p[2]*Math.sin(c);
r[2] = p[1]*Math.sin(c) + p[2]*Math.cos(c);
//translate to correct position
out[0] = r[0] + b[0];
out[1] = r[1] + b[1];
out[2] = r[2] + b[2];
return out;
};
/**
* Rotate a 3D vector around the y-axis
* @param {vec3} out The receiving vec3
* @param {vec3} a The vec3 point to rotate
* @param {vec3} b The origin of the rotation
* @param {Number} c The angle of rotation
* @returns {vec3} out
*/
vec3.rotateY = function(out, a, b, c){
var p = [], r=[];
//Translate point to the origin
p[0] = a[0] - b[0];
p[1] = a[1] - b[1];
p[2] = a[2] - b[2];
//perform rotation
r[0] = p[2]*Math.sin(c) + p[0]*Math.cos(c);
r[1] = p[1];
r[2] = p[2]*Math.cos(c) - p[0]*Math.sin(c);
//translate to correct position
out[0] = r[0] + b[0];
out[1] = r[1] + b[1];
out[2] = r[2] + b[2];
return out;
};
/**
* Rotate a 3D vector around the z-axis
* @param {vec3} out The receiving vec3
* @param {vec3} a The vec3 point to rotate
* @param {vec3} b The origin of the rotation
* @param {Number} c The angle of rotation
* @returns {vec3} out
*/
vec3.rotateZ = function(out, a, b, c){
var p = [], r=[];
//Translate point to the origin
p[0] = a[0] - b[0];
p[1] = a[1] - b[1];
p[2] = a[2] - b[2];
//perform rotation
r[0] = p[0]*Math.cos(c) - p[1]*Math.sin(c);
r[1] = p[0]*Math.sin(c) + p[1]*Math.cos(c);
r[2] = p[2];
//translate to correct position
out[0] = r[0] + b[0];
out[1] = r[1] + b[1];
out[2] = r[2] + b[2];
return out;
};
/**
* Perform some operation over an array of vec3s.
*
* @param {Array} a the array of vectors to iterate over
* @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed
* @param {Number} offset Number of elements to skip at the beginning of the array
* @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array
* @param {Function} fn Function to call for each vector in the array
* @param {Object} [arg] additional argument to pass to fn
* @returns {Array} a
* @function
*/
vec3.forEach = (function() {
var vec = vec3.create();
return function(a, stride, offset, count, fn, arg) {
var i, l;
if(!stride) {
stride = 3;
}
if(!offset) {
offset = 0;
}
if(count) {
l = Math.min((count * stride) + offset, a.length);
} else {
l = a.length;
}
for(i = offset; i < l; i += stride) {
vec[0] = a[i]; vec[1] = a[i+1]; vec[2] = a[i+2];
fn(vec, vec, arg);
a[i] = vec[0]; a[i+1] = vec[1]; a[i+2] = vec[2];
}
return a;
};
})();
/**
* Get the angle between two 3D vectors
* @param {vec3} a The first operand
* @param {vec3} b The second operand
* @returns {Number} The angle in radians
*/
vec3.angle = function(a, b) {
var tempA = vec3.fromValues(a[0], a[1], a[2]);
var tempB = vec3.fromValues(b[0], b[1], b[2]);
vec3.normalize(tempA, tempA);
vec3.normalize(tempB, tempB);
var cosine = vec3.dot(tempA, tempB);
if(cosine > 1.0){
return 0;
} else {
return Math.acos(cosine);
}
};
/**
* Returns a string representation of a vector
*
* @param {vec3} vec vector to represent as a string
* @returns {String} string representation of the vector
*/
vec3.str = function (a) {
return 'vec3(' + a[0] + ', ' + a[1] + ', ' + a[2] + ')';
};
if(typeof(exports) !== 'undefined') {
exports.vec3 = vec3;
}
;
/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/**
* @class 4 Dimensional Vector
* @name vec4
*/
var vec4 = {};
/**
* Creates a new, empty vec4
*
* @returns {vec4} a new 4D vector
*/
vec4.create = function() {
var out = new GLMAT_ARRAY_TYPE(4);
out[0] = 0;
out[1] = 0;
out[2] = 0;
out[3] = 0;
return out;
};
/**
* Creates a new vec4 initialized with values from an existing vector
*
* @param {vec4} a vector to clone
* @returns {vec4} a new 4D vector
*/
vec4.clone = function(a) {
var out = new GLMAT_ARRAY_TYPE(4);
out[0] = a[0];
out[1] = a[1];
out[2] = a[2];
out[3] = a[3];
return out;
};
/**
* Creates a new vec4 initialized with the given values
*
* @param {Number} x X component
* @param {Number} y Y component
* @param {Number} z Z component
* @param {Number} w W component
* @returns {vec4} a new 4D vector
*/
vec4.fromValues = function(x, y, z, w) {
var out = new GLMAT_ARRAY_TYPE(4);
out[0] = x;
out[1] = y;
out[2] = z;
out[3] = w;
return out;
};
/**
* Copy the values from one vec4 to another
*
* @param {vec4} out the receiving vector
* @param {vec4} a the source vector
* @returns {vec4} out
*/
vec4.copy = function(out, a) {
out[0] = a[0];
out[1] = a[1];
out[2] = a[2];
out[3] = a[3];
return out;
};
/**
* Set the components of a vec4 to the given values
*
* @param {vec4} out the receiving vector
* @param {Number} x X component
* @param {Number} y Y component
* @param {Number} z Z component
* @param {Number} w W component
* @returns {vec4} out
*/
vec4.set = function(out, x, y, z, w) {
out[0] = x;
out[1] = y;
out[2] = z;
out[3] = w;
return out;
};
/**
* Adds two vec4's
*
* @param {vec4} out the receiving vector
* @param {vec4} a the first operand
* @param {vec4} b the second operand
* @returns {vec4} out
*/
vec4.add = function(out, a, b) {
out[0] = a[0] + b[0];
out[1] = a[1] + b[1];
out[2] = a[2] + b[2];
out[3] = a[3] + b[3];
return out;
};
/**
* Subtracts vector b from vector a
*
* @param {vec4} out the receiving vector
* @param {vec4} a the first operand
* @param {vec4} b the second operand
* @returns {vec4} out
*/
vec4.subtract = function(out, a, b) {
out[0] = a[0] - b[0];
out[1] = a[1] - b[1];
out[2] = a[2] - b[2];
out[3] = a[3] - b[3];
return out;
};
/**
* Alias for {@link vec4.subtract}
* @function
*/
vec4.sub = vec4.subtract;
/**
* Multiplies two vec4's
*
* @param {vec4} out the receiving vector
* @param {vec4} a the first operand
* @param {vec4} b the second operand
* @returns {vec4} out
*/
vec4.multiply = function(out, a, b) {
out[0] = a[0] * b[0];
out[1] = a[1] * b[1];
out[2] = a[2] * b[2];
out[3] = a[3] * b[3];
return out;
};
/**
* Alias for {@link vec4.multiply}
* @function
*/
vec4.mul = vec4.multiply;
/**
* Divides two vec4's
*
* @param {vec4} out the receiving vector
* @param {vec4} a the first operand
* @param {vec4} b the second operand
* @returns {vec4} out
*/
vec4.divide = function(out, a, b) {
out[0] = a[0] / b[0];
out[1] = a[1] / b[1];
out[2] = a[2] / b[2];
out[3] = a[3] / b[3];
return out;
};
/**
* Alias for {@link vec4.divide}
* @function
*/
vec4.div = vec4.divide;
/**
* Returns the minimum of two vec4's
*
* @param {vec4} out the receiving vector
* @param {vec4} a the first operand
* @param {vec4} b the second operand
* @returns {vec4} out
*/
vec4.min = function(out, a, b) {
out[0] = Math.min(a[0], b[0]);
out[1] = Math.min(a[1], b[1]);
out[2] = Math.min(a[2], b[2]);
out[3] = Math.min(a[3], b[3]);
return out;
};
/**
* Returns the maximum of two vec4's
*
* @param {vec4} out the receiving vector
* @param {vec4} a the first operand
* @param {vec4} b the second operand
* @returns {vec4} out
*/
vec4.max = function(out, a, b) {
out[0] = Math.max(a[0], b[0]);
out[1] = Math.max(a[1], b[1]);
out[2] = Math.max(a[2], b[2]);
out[3] = Math.max(a[3], b[3]);
return out;
};
/**
* Scales a vec4 by a scalar number
*
* @param {vec4} out the receiving vector
* @param {vec4} a the vector to scale
* @param {Number} b amount to scale the vector by
* @returns {vec4} out
*/
vec4.scale = function(out, a, b) {
out[0] = a[0] * b;
out[1] = a[1] * b;
out[2] = a[2] * b;
out[3] = a[3] * b;
return out;
};
/**
* Adds two vec4's after scaling the second operand by a scalar value
*
* @param {vec4} out the receiving vector
* @param {vec4} a the first operand
* @param {vec4} b the second operand
* @param {Number} scale the amount to scale b by before adding
* @returns {vec4} out
*/
vec4.scaleAndAdd = function(out, a, b, scale) {
out[0] = a[0] + (b[0] * scale);
out[1] = a[1] + (b[1] * scale);
out[2] = a[2] + (b[2] * scale);
out[3] = a[3] + (b[3] * scale);
return out;
};
/**
* Calculates the euclidian distance between two vec4's
*
* @param {vec4} a the first operand
* @param {vec4} b the second operand
* @returns {Number} distance between a and b
*/
vec4.distance = function(a, b) {
var x = b[0] - a[0],
y = b[1] - a[1],
z = b[2] - a[2],
w = b[3] - a[3];
return Math.sqrt(x*x + y*y + z*z + w*w);
};
/**
* Alias for {@link vec4.distance}
* @function
*/
vec4.dist = vec4.distance;
/**
* Calculates the squared euclidian distance between two vec4's
*
* @param {vec4} a the first operand
* @param {vec4} b the second operand
* @returns {Number} squared distance between a and b
*/
vec4.squaredDistance = function(a, b) {
var x = b[0] - a[0],
y = b[1] - a[1],
z = b[2] - a[2],
w = b[3] - a[3];
return x*x + y*y + z*z + w*w;
};
/**
* Alias for {@link vec4.squaredDistance}
* @function
*/
vec4.sqrDist = vec4.squaredDistance;
/**
* Calculates the length of a vec4
*
* @param {vec4} a vector to calculate length of
* @returns {Number} length of a
*/
vec4.length = function (a) {
var x = a[0],
y = a[1],
z = a[2],
w = a[3];
return Math.sqrt(x*x + y*y + z*z + w*w);
};
/**
* Alias for {@link vec4.length}
* @function
*/
vec4.len = vec4.length;
/**
* Calculates the squared length of a vec4
*
* @param {vec4} a vector to calculate squared length of
* @returns {Number} squared length of a
*/
vec4.squaredLength = function (a) {
var x = a[0],
y = a[1],
z = a[2],
w = a[3];
return x*x + y*y + z*z + w*w;
};
/**
* Alias for {@link vec4.squaredLength}
* @function
*/
vec4.sqrLen = vec4.squaredLength;
/**
* Negates the components of a vec4
*
* @param {vec4} out the receiving vector
* @param {vec4} a vector to negate
* @returns {vec4} out
*/
vec4.negate = function(out, a) {
out[0] = -a[0];
out[1] = -a[1];
out[2] = -a[2];
out[3] = -a[3];
return out;
};
/**
* Returns the inverse of the components of a vec4
*
* @param {vec4} out the receiving vector
* @param {vec4} a vector to invert
* @returns {vec4} out
*/
vec4.inverse = function(out, a) {
out[0] = 1.0 / a[0];
out[1] = 1.0 / a[1];
out[2] = 1.0 / a[2];
out[3] = 1.0 / a[3];
return out;
};
/**
* Normalize a vec4
*
* @param {vec4} out the receiving vector
* @param {vec4} a vector to normalize
* @returns {vec4} out
*/
vec4.normalize = function(out, a) {
var x = a[0],
y = a[1],
z = a[2],
w = a[3];
var len = x*x + y*y + z*z + w*w;
if (len > 0) {
len = 1 / Math.sqrt(len);
out[0] = a[0] * len;
out[1] = a[1] * len;
out[2] = a[2] * len;
out[3] = a[3] * len;
}
return out;
};
/**
* Calculates the dot product of two vec4's
*
* @param {vec4} a the first operand
* @param {vec4} b the second operand
* @returns {Number} dot product of a and b
*/
vec4.dot = function (a, b) {
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
};
/**
* Performs a linear interpolation between two vec4's
*
* @param {vec4} out the receiving vector
* @param {vec4} a the first operand
* @param {vec4} b the second operand
* @param {Number} t interpolation amount between the two inputs
* @returns {vec4} out
*/
vec4.lerp = function (out, a, b, t) {
var ax = a[0],
ay = a[1],
az = a[2],
aw = a[3];
out[0] = ax + t * (b[0] - ax);
out[1] = ay + t * (b[1] - ay);
out[2] = az + t * (b[2] - az);
out[3] = aw + t * (b[3] - aw);
return out;
};
/**
* Generates a random vector with the given scale
*
* @param {vec4} out the receiving vector
* @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned
* @returns {vec4} out
*/
vec4.random = function (out, scale) {
scale = scale || 1.0;
//TODO: This is a pretty awful way of doing this. Find something better.
out[0] = GLMAT_RANDOM();
out[1] = GLMAT_RANDOM();
out[2] = GLMAT_RANDOM();
out[3] = GLMAT_RANDOM();
vec4.normalize(out, out);
vec4.scale(out, out, scale);
return out;
};
/**
* Transforms the vec4 with a mat4.
*
* @param {vec4} out the receiving vector
* @param {vec4} a the vector to transform
* @param {mat4} m matrix to transform with
* @returns {vec4} out
*/
vec4.transformMat4 = function(out, a, m) {
var x = a[0], y = a[1], z = a[2], w = a[3];
out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w;
out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w;
out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w;
out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w;
return out;
};
/**
* Transforms the vec4 with a quat
*
* @param {vec4} out the receiving vector
* @param {vec4} a the vector to transform
* @param {quat} q quaternion to transform with
* @returns {vec4} out
*/
vec4.transformQuat = function(out, a, q) {
var x = a[0], y = a[1], z = a[2],
qx = q[0], qy = q[1], qz = q[2], qw = q[3],
// calculate quat * vec
ix = qw * x + qy * z - qz * y,
iy = qw * y + qz * x - qx * z,
iz = qw * z + qx * y - qy * x,
iw = -qx * x - qy * y - qz * z;
// calculate result * inverse quat
out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy;
out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;
out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;
return out;
};
/**
* Perform some operation over an array of vec4s.
*
* @param {Array} a the array of vectors to iterate over
* @param {Number} stride Number of elements between the start of each vec4. If 0 assumes tightly packed
* @param {Number} offset Number of elements to skip at the beginning of the array
* @param {Number} count Number of vec4s to iterate over. If 0 iterates over entire array
* @param {Function} fn Function to call for each vector in the array
* @param {Object} [arg] additional argument to pass to fn
* @returns {Array} a
* @function
*/
vec4.forEach = (function() {
var vec = vec4.create();
return function(a, stride, offset, count, fn, arg) {
var i, l;
if(!stride) {
stride = 4;
}
if(!offset) {
offset = 0;
}
if(count) {
l = Math.min((count * stride) + offset, a.length);
} else {
l = a.length;
}
for(i = offset; i < l; i += stride) {
vec[0] = a[i]; vec[1] = a[i+1]; vec[2] = a[i+2]; vec[3] = a[i+3];
fn(vec, vec, arg);
a[i] = vec[0]; a[i+1] = vec[1]; a[i+2] = vec[2]; a[i+3] = vec[3];
}
return a;
};
})();
/**
* Returns a string representation of a vector
*
* @param {vec4} vec vector to represent as a string
* @returns {String} string representation of the vector
*/
vec4.str = function (a) {
return 'vec4(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')';
};
if(typeof(exports) !== 'undefined') {
exports.vec4 = vec4;
}
;
/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/**
* @class 2x2 Matrix
* @name mat2
*/
var mat2 = {};
/**
* Creates a new identity mat2
*
* @returns {mat2} a new 2x2 matrix
*/
mat2.create = function() {
var out = new GLMAT_ARRAY_TYPE(4);
out[0] = 1;
out[1] = 0;
out[2] = 0;
out[3] = 1;
return out;
};
/**
* Creates a new mat2 initialized with values from an existing matrix
*
* @param {mat2} a matrix to clone
* @returns {mat2} a new 2x2 matrix
*/
mat2.clone = function(a) {
var out = new GLMAT_ARRAY_TYPE(4);
out[0] = a[0];
out[1] = a[1];
out[2] = a[2];
out[3] = a[3];
return out;
};
/**
* Copy the values from one mat2 to another
*
* @param {mat2} out the receiving matrix
* @param {mat2} a the source matrix
* @returns {mat2} out
*/
mat2.copy = function(out, a) {
out[0] = a[0];
out[1] = a[1];
out[2] = a[2];
out[3] = a[3];
return out;
};
/**
* Set a mat2 to the identity matrix
*
* @param {mat2} out the receiving matrix
* @returns {mat2} out
*/
mat2.identity = function(out) {
out[0] = 1;
out[1] = 0;
out[2] = 0;
out[3] = 1;
return out;
};
/**
* Transpose the values of a mat2
*
* @param {mat2} out the receiving matrix
* @param {mat2} a the source matrix
* @returns {mat2} out
*/
mat2.transpose = function(out, a) {
// If we are transposing ourselves we can skip a few steps but have to cache some values
if (out === a) {
var a1 = a[1];
out[1] = a[2];
out[2] = a1;
} else {
out[0] = a[0];
out[1] = a[2];
out[2] = a[1];
out[3] = a[3];
}
return out;
};
/**
* Inverts a mat2
*
* @param {mat2} out the receiving matrix
* @param {mat2} a the source matrix
* @returns {mat2} out
*/
mat2.invert = function(out, a) {
var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3],
// Calculate the determinant
det = a0 * a3 - a2 * a1;
if (!det) {
return null;
}
det = 1.0 / det;
out[0] = a3 * det;
out[1] = -a1 * det;
out[2] = -a2 * det;
out[3] = a0 * det;
return out;
};
/**
* Calculates the adjugate of a mat2
*
* @param {mat2} out the receiving matrix
* @param {mat2} a the source matrix
* @returns {mat2} out
*/
mat2.adjoint = function(out, a) {
// Caching this value is nessecary if out == a
var a0 = a[0];
out[0] = a[3];
out[1] = -a[1];
out[2] = -a[2];
out[3] = a0;
return out;
};
/**
* Calculates the determinant of a mat2
*
* @param {mat2} a the source matrix
* @returns {Number} determinant of a
*/
mat2.determinant = function (a) {
return a[0] * a[3] - a[2] * a[1];
};
/**
* Multiplies two mat2's
*
* @param {mat2} out the receiving matrix
* @param {mat2} a the first operand
* @param {mat2} b the second operand
* @returns {mat2} out
*/
mat2.multiply = function (out, a, b) {
var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3];
var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3];
out[0] = a0 * b0 + a2 * b1;
out[1] = a1 * b0 + a3 * b1;
out[2] = a0 * b2 + a2 * b3;
out[3] = a1 * b2 + a3 * b3;
return out;
};
/**
* Alias for {@link mat2.multiply}
* @function
*/
mat2.mul = mat2.multiply;
/**
* Rotates a mat2 by the given angle
*
* @param {mat2} out the receiving matrix
* @param {mat2} a the matrix to rotate
* @param {Number} rad the angle to rotate the matrix by
* @returns {mat2} out
*/
mat2.rotate = function (out, a, rad) {
var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3],
s = Math.sin(rad),
c = Math.cos(rad);
out[0] = a0 * c + a2 * s;
out[1] = a1 * c + a3 * s;
out[2] = a0 * -s + a2 * c;
out[3] = a1 * -s + a3 * c;
return out;
};
/**
* Scales the mat2 by the dimensions in the given vec2
*
* @param {mat2} out the receiving matrix
* @param {mat2} a the matrix to rotate
* @param {vec2} v the vec2 to scale the matrix by
* @returns {mat2} out
**/
mat2.scale = function(out, a, v) {
var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3],
v0 = v[0], v1 = v[1];
out[0] = a0 * v0;
out[1] = a1 * v0;
out[2] = a2 * v1;
out[3] = a3 * v1;
return out;
};
/**
* Returns a string representation of a mat2
*
* @param {mat2} mat matrix to represent as a string
* @returns {String} string representation of the matrix
*/
mat2.str = function (a) {
return 'mat2(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')';
};
/**
* Returns Frobenius norm of a mat2
*
* @param {mat2} a the matrix to calculate Frobenius norm of
* @returns {Number} Frobenius norm
*/
mat2.frob = function (a) {
return(Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2)))
};
/**
* Returns L, D and U matrices (Lower triangular, Diagonal and Upper triangular) by factorizing the input matrix
* @param {mat2} L the lower triangular matrix
* @param {mat2} D the diagonal matrix
* @param {mat2} U the upper triangular matrix
* @param {mat2} a the input matrix to factorize
*/
mat2.LDU = function (L, D, U, a) {
L[2] = a[2]/a[0];
U[0] = a[0];
U[1] = a[1];
U[3] = a[3] - L[2] * U[1];
return [L, D, U];
};
if(typeof(exports) !== 'undefined') {
exports.mat2 = mat2;
}
;
/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/**
* @class 2x3 Matrix
* @name mat2d
*
* @description
* A mat2d contains six elements defined as:
*
* [a, c, tx,
* b, d, ty]
*
* This is a short form for the 3x3 matrix:
*
* [a, c, tx,
* b, d, ty,
* 0, 0, 1]
*
* The last row is ignored so the array is shorter and operations are faster.
*/
var mat2d = {};
/**
* Creates a new identity mat2d
*
* @returns {mat2d} a new 2x3 matrix
*/
mat2d.create = function() {
var out = new GLMAT_ARRAY_TYPE(6);
out[0] = 1;
out[1] = 0;
out[2] = 0;
out[3] = 1;
out[4] = 0;
out[5] = 0;
return out;
};
/**
* Creates a new mat2d initialized with values from an existing matrix
*
* @param {mat2d} a matrix to clone
* @returns {mat2d} a new 2x3 matrix
*/
mat2d.clone = function(a) {
var out = new GLMAT_ARRAY_TYPE(6);
out[0] = a[0];
out[1] = a[1];
out[2] = a[2];
out[3] = a[3];
out[4] = a[4];
out[5] = a[5];
return out;
};
/**
* Copy the values from one mat2d to another
*
* @param {mat2d} out the receiving matrix
* @param {mat2d} a the source matrix
* @returns {mat2d} out
*/
mat2d.copy = function(out, a) {
out[0] = a[0];
out[1] = a[1];
out[2] = a[2];
out[3] = a[3];
out[4] = a[4];
out[5] = a[5];
return out;
};
/**
* Set a mat2d to the identity matrix
*
* @param {mat2d} out the receiving matrix
* @returns {mat2d} out
*/
mat2d.identity = function(out) {
out[0] = 1;
out[1] = 0;
out[2] = 0;
out[3] = 1;
out[4] = 0;
out[5] = 0;
return out;
};
/**
* Inverts a mat2d
*
* @param {mat2d} out the receiving matrix
* @param {mat2d} a the source matrix
* @returns {mat2d} out
*/
mat2d.invert = function(out, a) {
var aa = a[0], ab = a[1], ac = a[2], ad = a[3],
atx = a[4], aty = a[5];
var det = aa * ad - ab * ac;
if(!det){
return null;
}
det = 1.0 / det;
out[0] = ad * det;
out[1] = -ab * det;
out[2] = -ac * det;
out[3] = aa * det;
out[4] = (ac * aty - ad * atx) * det;
out[5] = (ab * atx - aa * aty) * det;
return out;
};
/**
* Calculates the determinant of a mat2d
*
* @param {mat2d} a the source matrix
* @returns {Number} determinant of a
*/
mat2d.determinant = function (a) {
return a[0] * a[3] - a[1] * a[2];
};
/**
* Multiplies two mat2d's
*
* @param {mat2d} out the receiving matrix
* @param {mat2d} a the first operand
* @param {mat2d} b the second operand
* @returns {mat2d} out
*/
mat2d.multiply = function (out, a, b) {
var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5],
b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4], b5 = b[5];
out[0] = a0 * b0 + a2 * b1;
out[1] = a1 * b0 + a3 * b1;
out[2] = a0 * b2 + a2 * b3;
out[3] = a1 * b2 + a3 * b3;
out[4] = a0 * b4 + a2 * b5 + a4;
out[5] = a1 * b4 + a3 * b5 + a5;
return out;
};
/**
* Alias for {@link mat2d.multiply}
* @function
*/
mat2d.mul = mat2d.multiply;
/**
* Rotates a mat2d by the given angle
*
* @param {mat2d} out the receiving matrix
* @param {mat2d} a the matrix to rotate
* @param {Number} rad the angle to rotate the matrix by
* @returns {mat2d} out
*/
mat2d.rotate = function (out, a, rad) {
var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5],
s = Math.sin(rad),
c = Math.cos(rad);
out[0] = a0 * c + a2 * s;
out[1] = a1 * c + a3 * s;
out[2] = a0 * -s + a2 * c;
out[3] = a1 * -s + a3 * c;
out[4] = a4;
out[5] = a5;
return out;
};
/**
* Scales the mat2d by the dimensions in the given vec2
*
* @param {mat2d} out the receiving matrix
* @param {mat2d} a the matrix to translate
* @param {vec2} v the vec2 to scale the matrix by
* @returns {mat2d} out
**/
mat2d.scale = function(out, a, v) {
var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5],
v0 = v[0], v1 = v[1];
out[0] = a0 * v0;
out[1] = a1 * v0;
out[2] = a2 * v1;
out[3] = a3 * v1;
out[4] = a4;
out[5] = a5;
return out;
};
/**
* Translates the mat2d by the dimensions in the given vec2
*
* @param {mat2d} out the receiving matrix
* @param {mat2d} a the matrix to translate
* @param {vec2} v the vec2 to translate the matrix by
* @returns {mat2d} out
**/
mat2d.translate = function(out, a, v) {
var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5],
v0 = v[0], v1 = v[1];
out[0] = a0;
out[1] = a1;
out[2] = a2;
out[3] = a3;
out[4] = a0 * v0 + a2 * v1 + a4;
out[5] = a1 * v0 + a3 * v1 + a5;
return out;
};
/**
* Returns a string representation of a mat2d
*
* @param {mat2d} a matrix to represent as a string
* @returns {String} string representation of the matrix
*/
mat2d.str = function (a) {
return 'mat2d(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' +
a[3] + ', ' + a[4] + ', ' + a[5] + ')';
};
/**
* Returns Frobenius norm of a mat2d
*
* @param {mat2d} a the matrix to calculate Frobenius norm of
* @returns {Number} Frobenius norm
*/
mat2d.frob = function (a) {
return(Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + 1))
};
if(typeof(exports) !== 'undefined') {
exports.mat2d = mat2d;
}
;
/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/**
* @class 3x3 Matrix
* @name mat3
*/
var mat3 = {};
/**
* Creates a new identity mat3
*
* @returns {mat3} a new 3x3 matrix
*/
mat3.create = function() {
var out = new GLMAT_ARRAY_TYPE(9);
out[0] = 1;
out[1] = 0;
out[2] = 0;
out[3] = 0;
out[4] = 1;
out[5] = 0;
out[6] = 0;
out[7] = 0;
out[8] = 1;
return out;
};
/**
* Copies the upper-left 3x3 values into the given mat3.
*
* @param {mat3} out the receiving 3x3 matrix
* @param {mat4} a the source 4x4 matrix
* @returns {mat3} out
*/
mat3.fromMat4 = function(out, a) {
out[0] = a[0];
out[1] = a[1];
out[2] = a[2];
out[3] = a[4];
out[4] = a[5];
out[5] = a[6];
out[6] = a[8];
out[7] = a[9];
out[8] = a[10];
return out;
};
/**
* Creates a new mat3 initialized with values from an existing matrix
*
* @param {mat3} a matrix to clone
* @returns {mat3} a new 3x3 matrix
*/
mat3.clone = function(a) {
var out = new GLMAT_ARRAY_TYPE(9);
out[0] = a[0];
out[1] = a[1];
out[2] = a[2];
out[3] = a[3];
out[4] = a[4];
out[5] = a[5];
out[6] = a[6];
out[7] = a[7];
out[8] = a[8];
return out;
};
/**
* Copy the values from one mat3 to another
*
* @param {mat3} out the receiving matrix
* @param {mat3} a the source matrix
* @returns {mat3} out
*/
mat3.copy = function(out, a) {
out[0] = a[0];
out[1] = a[1];
out[2] = a[2];
out[3] = a[3];
out[4] = a[4];
out[5] = a[5];
out[6] = a[6];
out[7] = a[7];
out[8] = a[8];
return out;
};
/**
* Set a mat3 to the identity matrix
*
* @param {mat3} out the receiving matrix
* @returns {mat3} out
*/
mat3.identity = function(out) {
out[0] = 1;
out[1] = 0;
out[2] = 0;
out[3] = 0;
out[4] = 1;
out[5] = 0;
out[6] = 0;
out[7] = 0;
out[8] = 1;
return out;
};
/**
* Transpose the values of a mat3
*
* @param {mat3} out the receiving matrix
* @param {mat3} a the source matrix
* @returns {mat3} out
*/
mat3.transpose = function(out, a) {
// If we are transposing ourselves we can skip a few steps but have to cache some values
if (out === a) {
var a01 = a[1], a02 = a[2], a12 = a[5];
out[1] = a[3];
out[2] = a[6];
out[3] = a01;
out[5] = a[7];
out[6] = a02;
out[7] = a12;
} else {
out[0] = a[0];
out[1] = a[3];
out[2] = a[6];
out[3] = a[1];
out[4] = a[4];
out[5] = a[7];
out[6] = a[2];
out[7] = a[5];
out[8] = a[8];
}
return out;
};
/**
* Inverts a mat3
*
* @param {mat3} out the receiving matrix
* @param {mat3} a the source matrix
* @returns {mat3} out
*/
mat3.invert = function(out, a) {
var a00 = a[0], a01 = a[1], a02 = a[2],
a10 = a[3], a11 = a[4], a12 = a[5],
a20 = a[6], a21 = a[7], a22 = a[8],
b01 = a22 * a11 - a12 * a21,
b11 = -a22 * a10 + a12 * a20,
b21 = a21 * a10 - a11 * a20,
// Calculate the determinant
det = a00 * b01 + a01 * b11 + a02 * b21;
if (!det) {
return null;
}
det = 1.0 / det;
out[0] = b01 * det;
out[1] = (-a22 * a01 + a02 * a21) * det;
out[2] = (a12 * a01 - a02 * a11) * det;
out[3] = b11 * det;
out[4] = (a22 * a00 - a02 * a20) * det;
out[5] = (-a12 * a00 + a02 * a10) * det;
out[6] = b21 * det;
out[7] = (-a21 * a00 + a01 * a20) * det;
out[8] = (a11 * a00 - a01 * a10) * det;
return out;
};
/**
* Calculates the adjugate of a mat3
*
* @param {mat3} out the receiving matrix
* @param {mat3} a the source matrix
* @returns {mat3} out
*/
mat3.adjoint = function(out, a) {
var a00 = a[0], a01 = a[1], a02 = a[2],
a10 = a[3], a11 = a[4], a12 = a[5],
a20 = a[6], a21 = a[7], a22 = a[8];
out[0] = (a11 * a22 - a12 * a21);
out[1] = (a02 * a21 - a01 * a22);
out[2] = (a01 * a12 - a02 * a11);
out[3] = (a12 * a20 - a10 * a22);
out[4] = (a00 * a22 - a02 * a20);
out[5] = (a02 * a10 - a00 * a12);
out[6] = (a10 * a21 - a11 * a20);
out[7] = (a01 * a20 - a00 * a21);
out[8] = (a00 * a11 - a01 * a10);
return out;
};
/**
* Calculates the determinant of a mat3
*
* @param {mat3} a the source matrix
* @returns {Number} determinant of a
*/
mat3.determinant = function (a) {
var a00 = a[0], a01 = a[1], a02 = a[2],
a10 = a[3], a11 = a[4], a12 = a[5],
a20 = a[6], a21 = a[7], a22 = a[8];
return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20);
};
/**
* Multiplies two mat3's
*
* @param {mat3} out the receiving matrix
* @param {mat3} a the first operand
* @param {mat3} b the second operand
* @returns {mat3} out
*/
mat3.multiply = function (out, a, b) {
var a00 = a[0], a01 = a[1], a02 = a[2],
a10 = a[3], a11 = a[4], a12 = a[5],
a20 = a[6], a21 = a[7], a22 = a[8],
b00 = b[0], b01 = b[1], b02 = b[2],
b10 = b[3], b11 = b[4], b12 = b[5],
b20 = b[6], b21 = b[7], b22 = b[8];
out[0] = b00 * a00 + b01 * a10 + b02 * a20;
out[1] = b00 * a01 + b01 * a11 + b02 * a21;
out[2] = b00 * a02 + b01 * a12 + b02 * a22;
out[3] = b10 * a00 + b11 * a10 + b12 * a20;
out[4] = b10 * a01 + b11 * a11 + b12 * a21;
out[5] = b10 * a02 + b11 * a12 + b12 * a22;
out[6] = b20 * a00 + b21 * a10 + b22 * a20;
out[7] = b20 * a01 + b21 * a11 + b22 * a21;
out[8] = b20 * a02 + b21 * a12 + b22 * a22;
return out;
};
/**
* Alias for {@link mat3.multiply}
* @function
*/
mat3.mul = mat3.multiply;
/**
* Translate a mat3 by the given vector
*
* @param {mat3} out the receiving matrix
* @param {mat3} a the matrix to translate
* @param {vec2} v vector to translate by
* @returns {mat3} out
*/
mat3.translate = function(out, a, v) {
var a00 = a[0], a01 = a[1], a02 = a[2],
a10 = a[3], a11 = a[4], a12 = a[5],
a20 = a[6], a21 = a[7], a22 = a[8],
x = v[0], y = v[1];
out[0] = a00;
out[1] = a01;
out[2] = a02;
out[3] = a10;
out[4] = a11;
out[5] = a12;
out[6] = x * a00 + y * a10 + a20;
out[7] = x * a01 + y * a11 + a21;
out[8] = x * a02 + y * a12 + a22;
return out;
};
/**
* Rotates a mat3 by the given angle
*
* @param {mat3} out the receiving matrix
* @param {mat3} a the matrix to rotate
* @param {Number} rad the angle to rotate the matrix by
* @returns {mat3} out
*/
mat3.rotate = function (out, a, rad) {
var a00 = a[0], a01 = a[1], a02 = a[2],
a10 = a[3], a11 = a[4], a12 = a[5],
a20 = a[6], a21 = a[7], a22 = a[8],
s = Math.sin(rad),
c = Math.cos(rad);
out[0] = c * a00 + s * a10;
out[1] = c * a01 + s * a11;
out[2] = c * a02 + s * a12;
out[3] = c * a10 - s * a00;
out[4] = c * a11 - s * a01;
out[5] = c * a12 - s * a02;
out[6] = a20;
out[7] = a21;
out[8] = a22;
return out;
};
/**
* Scales the mat3 by the dimensions in the given vec2
*
* @param {mat3} out the receiving matrix
* @param {mat3} a the matrix to rotate
* @param {vec2} v the vec2 to scale the matrix by
* @returns {mat3} out
**/
mat3.scale = function(out, a, v) {
var x = v[0], y = v[1];
out[0] = x * a[0];
out[1] = x * a[1];
out[2] = x * a[2];
out[3] = y * a[3];
out[4] = y * a[4];
out[5] = y * a[5];
out[6] = a[6];
out[7] = a[7];
out[8] = a[8];
return out;
};
/**
* Copies the values from a mat2d into a mat3
*
* @param {mat3} out the receiving matrix
* @param {mat2d} a the matrix to copy
* @returns {mat3} out
**/
mat3.fromMat2d = function(out, a) {
out[0] = a[0];
out[1] = a[1];
out[2] = 0;
out[3] = a[2];
out[4] = a[3];
out[5] = 0;
out[6] = a[4];
out[7] = a[5];
out[8] = 1;
return out;
};
/**
* Calculates a 3x3 matrix from the given quaternion
*
* @param {mat3} out mat3 receiving operation result
* @param {quat} q Quaternion to create matrix from
*
* @returns {mat3} out
*/
mat3.fromQuat = function (out, q) {
var x = q[0], y = q[1], z = q[2], w = q[3],
x2 = x + x,
y2 = y + y,
z2 = z + z,
xx = x * x2,
yx = y * x2,
yy = y * y2,
zx = z * x2,
zy = z * y2,
zz = z * z2,
wx = w * x2,
wy = w * y2,
wz = w * z2;
out[0] = 1 - yy - zz;
out[3] = yx - wz;
out[6] = zx + wy;
out[1] = yx + wz;
out[4] = 1 - xx - zz;
out[7] = zy - wx;
out[2] = zx - wy;
out[5] = zy + wx;
out[8] = 1 - xx - yy;
return out;
};
/**
* Calculates a 3x3 normal matrix (transpose inverse) from the 4x4 matrix
*
* @param {mat3} out mat3 receiving operation result
* @param {mat4} a Mat4 to derive the normal matrix from
*
* @returns {mat3} out
*/
mat3.normalFromMat4 = function (out, a) {
var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15],
b00 = a00 * a11 - a01 * a10,
b01 = a00 * a12 - a02 * a10,
b02 = a00 * a13 - a03 * a10,
b03 = a01 * a12 - a02 * a11,
b04 = a01 * a13 - a03 * a11,
b05 = a02 * a13 - a03 * a12,
b06 = a20 * a31 - a21 * a30,
b07 = a20 * a32 - a22 * a30,
b08 = a20 * a33 - a23 * a30,
b09 = a21 * a32 - a22 * a31,
b10 = a21 * a33 - a23 * a31,
b11 = a22 * a33 - a23 * a32,
// Calculate the determinant
det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
if (!det) {
return null;
}
det = 1.0 / det;
out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
out[1] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
out[2] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
out[3] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
out[4] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
out[5] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
out[6] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
out[7] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
out[8] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
return out;
};
/**
* Returns a string representation of a mat3
*
* @param {mat3} mat matrix to represent as a string
* @returns {String} string representation of the matrix
*/
mat3.str = function (a) {
return 'mat3(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' +
a[3] + ', ' + a[4] + ', ' + a[5] + ', ' +
a[6] + ', ' + a[7] + ', ' + a[8] + ')';
};
/**
* Returns Frobenius norm of a mat3
*
* @param {mat3} a the matrix to calculate Frobenius norm of
* @returns {Number} Frobenius norm
*/
mat3.frob = function (a) {
return(Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + Math.pow(a[6], 2) + Math.pow(a[7], 2) + Math.pow(a[8], 2)))
};
if(typeof(exports) !== 'undefined') {
exports.mat3 = mat3;
}
;
/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/**
* @class 4x4 Matrix
* @name mat4
*/
var mat4 = {};
/**
* Creates a new identity mat4
*
* @returns {mat4} a new 4x4 matrix
*/
mat4.create = function() {
var out = new GLMAT_ARRAY_TYPE(16);
out[0] = 1;
out[1] = 0;
out[2] = 0;
out[3] = 0;
out[4] = 0;
out[5] = 1;
out[6] = 0;
out[7] = 0;
out[8] = 0;
out[9] = 0;
out[10] = 1;
out[11] = 0;
out[12] = 0;
out[13] = 0;
out[14] = 0;
out[15] = 1;
return out;
};
/**
* Creates a new mat4 initialized with values from an existing matrix
*
* @param {mat4} a matrix to clone
* @returns {mat4} a new 4x4 matrix
*/
mat4.clone = function(a) {
var out = new GLMAT_ARRAY_TYPE(16);
out[0] = a[0];
out[1] = a[1];
out[2] = a[2];
out[3] = a[3];
out[4] = a[4];
out[5] = a[5];
out[6] = a[6];
out[7] = a[7];
out[8] = a[8];
out[9] = a[9];
out[10] = a[10];
out[11] = a[11];
out[12] = a[12];
out[13] = a[13];
out[14] = a[14];
out[15] = a[15];
return out;
};
/**
* Copy the values from one mat4 to another
*
* @param {mat4} out the receiving matrix
* @param {mat4} a the source matrix
* @returns {mat4} out
*/
mat4.copy = function(out, a) {
out[0] = a[0];
out[1] = a[1];
out[2] = a[2];
out[3] = a[3];
out[4] = a[4];
out[5] = a[5];
out[6] = a[6];
out[7] = a[7];
out[8] = a[8];
out[9] = a[9];
out[10] = a[10];
out[11] = a[11];
out[12] = a[12];
out[13] = a[13];
out[14] = a[14];
out[15] = a[15];
return out;
};
/**
* Set a mat4 to the identity matrix
*
* @param {mat4} out the receiving matrix
* @returns {mat4} out
*/
mat4.identity = function(out) {
out[0] = 1;
out[1] = 0;
out[2] = 0;
out[3] = 0;
out[4] = 0;
out[5] = 1;
out[6] = 0;
out[7] = 0;
out[8] = 0;
out[9] = 0;
out[10] = 1;
out[11] = 0;
out[12] = 0;
out[13] = 0;
out[14] = 0;
out[15] = 1;
return out;
};
/**
* Transpose the values of a mat4
*
* @param {mat4} out the receiving matrix
* @param {mat4} a the source matrix
* @returns {mat4} out
*/
mat4.transpose = function(out, a) {
// If we are transposing ourselves we can skip a few steps but have to cache some values
if (out === a) {
var a01 = a[1], a02 = a[2], a03 = a[3],
a12 = a[6], a13 = a[7],
a23 = a[11];
out[1] = a[4];
out[2] = a[8];
out[3] = a[12];
out[4] = a01;
out[6] = a[9];
out[7] = a[13];
out[8] = a02;
out[9] = a12;
out[11] = a[14];
out[12] = a03;
out[13] = a13;
out[14] = a23;
} else {
out[0] = a[0];
out[1] = a[4];
out[2] = a[8];
out[3] = a[12];
out[4] = a[1];
out[5] = a[5];
out[6] = a[9];
out[7] = a[13];
out[8] = a[2];
out[9] = a[6];
out[10] = a[10];
out[11] = a[14];
out[12] = a[3];
out[13] = a[7];
out[14] = a[11];
out[15] = a[15];
}
return out;
};
/**
* Inverts a mat4
*
* @param {mat4} out the receiving matrix
* @param {mat4} a the source matrix
* @returns {mat4} out
*/
mat4.invert = function(out, a) {
var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15],
b00 = a00 * a11 - a01 * a10,
b01 = a00 * a12 - a02 * a10,
b02 = a00 * a13 - a03 * a10,
b03 = a01 * a12 - a02 * a11,
b04 = a01 * a13 - a03 * a11,
b05 = a02 * a13 - a03 * a12,
b06 = a20 * a31 - a21 * a30,
b07 = a20 * a32 - a22 * a30,
b08 = a20 * a33 - a23 * a30,
b09 = a21 * a32 - a22 * a31,
b10 = a21 * a33 - a23 * a31,
b11 = a22 * a33 - a23 * a32,
// Calculate the determinant
det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
if (!det) {
return null;
}
det = 1.0 / det;
out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;
out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;
out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;
out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;
out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;
out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;
out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;
return out;
};
/**
* Calculates the adjugate of a mat4
*
* @param {mat4} out the receiving matrix
* @param {mat4} a the source matrix
* @returns {mat4} out
*/
mat4.adjoint = function(out, a) {
var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
out[0] = (a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) + a31 * (a12 * a23 - a13 * a22));
out[1] = -(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) + a31 * (a02 * a23 - a03 * a22));
out[2] = (a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) + a31 * (a02 * a13 - a03 * a12));
out[3] = -(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) + a21 * (a02 * a13 - a03 * a12));
out[4] = -(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) + a30 * (a12 * a23 - a13 * a22));
out[5] = (a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) + a30 * (a02 * a23 - a03 * a22));
out[6] = -(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) + a30 * (a02 * a13 - a03 * a12));
out[7] = (a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) + a20 * (a02 * a13 - a03 * a12));
out[8] = (a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) + a30 * (a11 * a23 - a13 * a21));
out[9] = -(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) + a30 * (a01 * a23 - a03 * a21));
out[10] = (a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) + a30 * (a01 * a13 - a03 * a11));
out[11] = -(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) + a20 * (a01 * a13 - a03 * a11));
out[12] = -(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) + a30 * (a11 * a22 - a12 * a21));
out[13] = (a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) + a30 * (a01 * a22 - a02 * a21));
out[14] = -(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) + a30 * (a01 * a12 - a02 * a11));
out[15] = (a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) + a20 * (a01 * a12 - a02 * a11));
return out;
};
/**
* Calculates the determinant of a mat4
*
* @param {mat4} a the source matrix
* @returns {Number} determinant of a
*/
mat4.determinant = function (a) {
var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15],
b00 = a00 * a11 - a01 * a10,
b01 = a00 * a12 - a02 * a10,
b02 = a00 * a13 - a03 * a10,
b03 = a01 * a12 - a02 * a11,
b04 = a01 * a13 - a03 * a11,
b05 = a02 * a13 - a03 * a12,
b06 = a20 * a31 - a21 * a30,
b07 = a20 * a32 - a22 * a30,
b08 = a20 * a33 - a23 * a30,
b09 = a21 * a32 - a22 * a31,
b10 = a21 * a33 - a23 * a31,
b11 = a22 * a33 - a23 * a32;
// Calculate the determinant
return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
};
/**
* Multiplies two mat4's
*
* @param {mat4} out the receiving matrix
* @param {mat4} a the first operand
* @param {mat4} b the second operand
* @returns {mat4} out
*/
mat4.multiply = function (out, a, b) {
var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
// Cache only the current line of the second matrix
var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3];
out[0] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
out[1] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
out[2] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
out[3] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
b0 = b[4]; b1 = b[5]; b2 = b[6]; b3 = b[7];
out[4] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
out[5] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
out[6] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
out[7] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
b0 = b[8]; b1 = b[9]; b2 = b[10]; b3 = b[11];
out[8] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
out[9] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
out[10] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
out[11] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
b0 = b[12]; b1 = b[13]; b2 = b[14]; b3 = b[15];
out[12] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
out[13] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
out[14] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
out[15] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
return out;
};
/**
* Multiplies two affine mat4's
* Add by https://github.com/pissang
* @param {mat4} out the receiving matrix
* @param {mat4} a the first operand
* @param {mat4} b the second operand
* @returns {mat4} out
*/
mat4.multiplyAffine = function (out, a, b) {
var a00 = a[0], a01 = a[1], a02 = a[2],
a10 = a[4], a11 = a[5], a12 = a[6],
a20 = a[8], a21 = a[9], a22 = a[10],
a30 = a[12], a31 = a[13], a32 = a[14];
// Cache only the current line of the second matrix
var b0 = b[0], b1 = b[1], b2 = b[2];
out[0] = b0*a00 + b1*a10 + b2*a20;
out[1] = b0*a01 + b1*a11 + b2*a21;
out[2] = b0*a02 + b1*a12 + b2*a22;
// out[3] = 0;
b0 = b[4]; b1 = b[5]; b2 = b[6];
out[4] = b0*a00 + b1*a10 + b2*a20;
out[5] = b0*a01 + b1*a11 + b2*a21;
out[6] = b0*a02 + b1*a12 + b2*a22;
// out[7] = 0;
b0 = b[8]; b1 = b[9]; b2 = b[10];
out[8] = b0*a00 + b1*a10 + b2*a20;
out[9] = b0*a01 + b1*a11 + b2*a21;
out[10] = b0*a02 + b1*a12 + b2*a22;
// out[11] = 0;
b0 = b[12]; b1 = b[13]; b2 = b[14];
out[12] = b0*a00 + b1*a10 + b2*a20 + a30;
out[13] = b0*a01 + b1*a11 + b2*a21 + a31;
out[14] = b0*a02 + b1*a12 + b2*a22 + a32;
// out[15] = 1;
return out;
};
/**
* Alias for {@link mat4.multiply}
* @function
*/
mat4.mul = mat4.multiply;
/**
* Alias for {@link mat4.multiplyAffine}
* @function
*/
mat4.mulAffine = mat4.multiplyAffine;
/**
* Translate a mat4 by the given vector
*
* @param {mat4} out the receiving matrix
* @param {mat4} a the matrix to translate
* @param {vec3} v vector to translate by
* @returns {mat4} out
*/
mat4.translate = function (out, a, v) {
var x = v[0], y = v[1], z = v[2],
a00, a01, a02, a03,
a10, a11, a12, a13,
a20, a21, a22, a23;
if (a === out) {
out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];
out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];
out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];
out[15] = a[3] * x + a[7] * y + a[11] * z + a[15];
} else {
a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3];
a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7];
a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11];
out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a03;
out[4] = a10; out[5] = a11; out[6] = a12; out[7] = a13;
out[8] = a20; out[9] = a21; out[10] = a22; out[11] = a23;
out[12] = a00 * x + a10 * y + a20 * z + a[12];
out[13] = a01 * x + a11 * y + a21 * z + a[13];
out[14] = a02 * x + a12 * y + a22 * z + a[14];
out[15] = a03 * x + a13 * y + a23 * z + a[15];
}
return out;
};
/**
* Scales the mat4 by the dimensions in the given vec3
*
* @param {mat4} out the receiving matrix
* @param {mat4} a the matrix to scale
* @param {vec3} v the vec3 to scale the matrix by
* @returns {mat4} out
**/
mat4.scale = function(out, a, v) {
var x = v[0], y = v[1], z = v[2];
out[0] = a[0] * x;
out[1] = a[1] * x;
out[2] = a[2] * x;
out[3] = a[3] * x;
out[4] = a[4] * y;
out[5] = a[5] * y;
out[6] = a[6] * y;
out[7] = a[7] * y;
out[8] = a[8] * z;
out[9] = a[9] * z;
out[10] = a[10] * z;
out[11] = a[11] * z;
out[12] = a[12];
out[13] = a[13];
out[14] = a[14];
out[15] = a[15];
return out;
};
/**
* Rotates a mat4 by the given angle
*
* @param {mat4} out the receiving matrix
* @param {mat4} a the matrix to rotate
* @param {Number} rad the angle to rotate the matrix by
* @param {vec3} axis the axis to rotate around
* @returns {mat4} out
*/
mat4.rotate = function (out, a, rad, axis) {
var x = axis[0], y = axis[1], z = axis[2],
len = Math.sqrt(x * x + y * y + z * z),
s, c, t,
a00, a01, a02, a03,
a10, a11, a12, a13,
a20, a21, a22, a23,
b00, b01, b02,
b10, b11, b12,
b20, b21, b22;
if (Math.abs(len) < GLMAT_EPSILON) { return null; }
len = 1 / len;
x *= len;
y *= len;
z *= len;
s = Math.sin(rad);
c = Math.cos(rad);
t = 1 - c;
a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3];
a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7];
a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11];
// Construct the elements of the rotation matrix
b00 = x * x * t + c; b01 = y * x * t + z * s; b02 = z * x * t - y * s;
b10 = x * y * t - z * s; b11 = y * y * t + c; b12 = z * y * t + x * s;
b20 = x * z * t + y * s; b21 = y * z * t - x * s; b22 = z * z * t + c;
// Perform rotation-specific matrix multiplication
out[0] = a00 * b00 + a10 * b01 + a20 * b02;
out[1] = a01 * b00 + a11 * b01 + a21 * b02;
out[2] = a02 * b00 + a12 * b01 + a22 * b02;
out[3] = a03 * b00 + a13 * b01 + a23 * b02;
out[4] = a00 * b10 + a10 * b11 + a20 * b12;
out[5] = a01 * b10 + a11 * b11 + a21 * b12;
out[6] = a02 * b10 + a12 * b11 + a22 * b12;
out[7] = a03 * b10 + a13 * b11 + a23 * b12;
out[8] = a00 * b20 + a10 * b21 + a20 * b22;
out[9] = a01 * b20 + a11 * b21 + a21 * b22;
out[10] = a02 * b20 + a12 * b21 + a22 * b22;
out[11] = a03 * b20 + a13 * b21 + a23 * b22;
if (a !== out) { // If the source and destination differ, copy the unchanged last row
out[12] = a[12];
out[13] = a[13];
out[14] = a[14];
out[15] = a[15];
}
return out;
};
/**
* Rotates a matrix by the given angle around the X axis
*
* @param {mat4} out the receiving matrix
* @param {mat4} a the matrix to rotate
* @param {Number} rad the angle to rotate the matrix by
* @returns {mat4} out
*/
mat4.rotateX = function (out, a, rad) {
var s = Math.sin(rad),
c = Math.cos(rad),
a10 = a[4],
a11 = a[5],
a12 = a[6],
a13 = a[7],
a20 = a[8],
a21 = a[9],
a22 = a[10],
a23 = a[11];
if (a !== out) { // If the source and destination differ, copy the unchanged rows
out[0] = a[0];
out[1] = a[1];
out[2] = a[2];
out[3] = a[3];
out[12] = a[12];
out[13] = a[13];
out[14] = a[14];
out[15] = a[15];
}
// Perform axis-specific matrix multiplication
out[4] = a10 * c + a20 * s;
out[5] = a11 * c + a21 * s;
out[6] = a12 * c + a22 * s;
out[7] = a13 * c + a23 * s;
out[8] = a20 * c - a10 * s;
out[9] = a21 * c - a11 * s;
out[10] = a22 * c - a12 * s;
out[11] = a23 * c - a13 * s;
return out;
};
/**
* Rotates a matrix by the given angle around the Y axis
*
* @param {mat4} out the receiving matrix
* @param {mat4} a the matrix to rotate
* @param {Number} rad the angle to rotate the matrix by
* @returns {mat4} out
*/
mat4.rotateY = function (out, a, rad) {
var s = Math.sin(rad),
c = Math.cos(rad),
a00 = a[0],
a01 = a[1],
a02 = a[2],
a03 = a[3],
a20 = a[8],
a21 = a[9],
a22 = a[10],
a23 = a[11];
if (a !== out) { // If the source and destination differ, copy the unchanged rows
out[4] = a[4];
out[5] = a[5];
out[6] = a[6];
out[7] = a[7];
out[12] = a[12];
out[13] = a[13];
out[14] = a[14];
out[15] = a[15];
}
// Perform axis-specific matrix multiplication
out[0] = a00 * c - a20 * s;
out[1] = a01 * c - a21 * s;
out[2] = a02 * c - a22 * s;
out[3] = a03 * c - a23 * s;
out[8] = a00 * s + a20 * c;
out[9] = a01 * s + a21 * c;
out[10] = a02 * s + a22 * c;
out[11] = a03 * s + a23 * c;
return out;
};
/**
* Rotates a matrix by the given angle around the Z axis
*
* @param {mat4} out the receiving matrix
* @param {mat4} a the matrix to rotate
* @param {Number} rad the angle to rotate the matrix by
* @returns {mat4} out
*/
mat4.rotateZ = function (out, a, rad) {
var s = Math.sin(rad),
c = Math.cos(rad),
a00 = a[0],
a01 = a[1],
a02 = a[2],
a03 = a[3],
a10 = a[4],
a11 = a[5],
a12 = a[6],
a13 = a[7];
if (a !== out) { // If the source and destination differ, copy the unchanged last row
out[8] = a[8];
out[9] = a[9];
out[10] = a[10];
out[11] = a[11];
out[12] = a[12];
out[13] = a[13];
out[14] = a[14];
out[15] = a[15];
}
// Perform axis-specific matrix multiplication
out[0] = a00 * c + a10 * s;
out[1] = a01 * c + a11 * s;
out[2] = a02 * c + a12 * s;
out[3] = a03 * c + a13 * s;
out[4] = a10 * c - a00 * s;
out[5] = a11 * c - a01 * s;
out[6] = a12 * c - a02 * s;
out[7] = a13 * c - a03 * s;
return out;
};
/**
* Creates a matrix from a quaternion rotation and vector translation
* This is equivalent to (but much faster than):
*
* mat4.identity(dest);
* mat4.translate(dest, vec);
* var quatMat = mat4.create();
* quat4.toMat4(quat, quatMat);
* mat4.multiply(dest, quatMat);
*
* @param {mat4} out mat4 receiving operation result
* @param {quat4} q Rotation quaternion
* @param {vec3} v Translation vector
* @returns {mat4} out
*/
mat4.fromRotationTranslation = function (out, q, v) {
// Quaternion math
var x = q[0], y = q[1], z = q[2], w = q[3],
x2 = x + x,
y2 = y + y,
z2 = z + z,
xx = x * x2,
xy = x * y2,
xz = x * z2,
yy = y * y2,
yz = y * z2,
zz = z * z2,
wx = w * x2,
wy = w * y2,
wz = w * z2;
out[0] = 1 - (yy + zz);
out[1] = xy + wz;
out[2] = xz - wy;
out[3] = 0;
out[4] = xy - wz;
out[5] = 1 - (xx + zz);
out[6] = yz + wx;
out[7] = 0;
out[8] = xz + wy;
out[9] = yz - wx;
out[10] = 1 - (xx + yy);
out[11] = 0;
out[12] = v[0];
out[13] = v[1];
out[14] = v[2];
out[15] = 1;
return out;
};
mat4.fromQuat = function (out, q) {
var x = q[0], y = q[1], z = q[2], w = q[3],
x2 = x + x,
y2 = y + y,
z2 = z + z,
xx = x * x2,
yx = y * x2,
yy = y * y2,
zx = z * x2,
zy = z * y2,
zz = z * z2,
wx = w * x2,
wy = w * y2,
wz = w * z2;
out[0] = 1 - yy - zz;
out[1] = yx + wz;
out[2] = zx - wy;
out[3] = 0;
out[4] = yx - wz;
out[5] = 1 - xx - zz;
out[6] = zy + wx;
out[7] = 0;
out[8] = zx + wy;
out[9] = zy - wx;
out[10] = 1 - xx - yy;
out[11] = 0;
out[12] = 0;
out[13] = 0;
out[14] = 0;
out[15] = 1;
return out;
};
/**
* Generates a frustum matrix with the given bounds
*
* @param {mat4} out mat4 frustum matrix will be written into
* @param {Number} left Left bound of the frustum
* @param {Number} right Right bound of the frustum
* @param {Number} bottom Bottom bound of the frustum
* @param {Number} top Top bound of the frustum
* @param {Number} near Near bound of the frustum
* @param {Number} far Far bound of the frustum
* @returns {mat4} out
*/
mat4.frustum = function (out, left, right, bottom, top, near, far) {
var rl = 1 / (right - left),
tb = 1 / (top - bottom),
nf = 1 / (near - far);
out[0] = (near * 2) * rl;
out[1] = 0;
out[2] = 0;
out[3] = 0;
out[4] = 0;
out[5] = (near * 2) * tb;
out[6] = 0;
out[7] = 0;
out[8] = (right + left) * rl;
out[9] = (top + bottom) * tb;
out[10] = (far + near) * nf;
out[11] = -1;
out[12] = 0;
out[13] = 0;
out[14] = (far * near * 2) * nf;
out[15] = 0;
return out;
};
/**
* Generates a perspective projection matrix with the given bounds
*
* @param {mat4} out mat4 frustum matrix will be written into
* @param {number} fovy Vertical field of view in radians
* @param {number} aspect Aspect ratio. typically viewport width/height
* @param {number} near Near bound of the frustum
* @param {number} far Far bound of the frustum
* @returns {mat4} out
*/
mat4.perspective = function (out, fovy, aspect, near, far) {
var f = 1.0 / Math.tan(fovy / 2),
nf = 1 / (near - far);
out[0] = f / aspect;
out[1] = 0;
out[2] = 0;
out[3] = 0;
out[4] = 0;
out[5] = f;
out[6] = 0;
out[7] = 0;
out[8] = 0;
out[9] = 0;
out[10] = (far + near) * nf;
out[11] = -1;
out[12] = 0;
out[13] = 0;
out[14] = (2 * far * near) * nf;
out[15] = 0;
return out;
};
/**
* Generates a orthogonal projection matrix with the given bounds
*
* @param {mat4} out mat4 frustum matrix will be written into
* @param {number} left Left bound of the frustum
* @param {number} right Right bound of the frustum
* @param {number} bottom Bottom bound of the frustum
* @param {number} top Top bound of the frustum
* @param {number} near Near bound of the frustum
* @param {number} far Far bound of the frustum
* @returns {mat4} out
*/
mat4.ortho = function (out, left, right, bottom, top, near, far) {
var lr = 1 / (left - right),
bt = 1 / (bottom - top),
nf = 1 / (near - far);
out[0] = -2 * lr;
out[1] = 0;
out[2] = 0;
out[3] = 0;
out[4] = 0;
out[5] = -2 * bt;
out[6] = 0;
out[7] = 0;
out[8] = 0;
out[9] = 0;
out[10] = 2 * nf;
out[11] = 0;
out[12] = (left + right) * lr;
out[13] = (top + bottom) * bt;
out[14] = (far + near) * nf;
out[15] = 1;
return out;
};
/**
* Generates a look-at matrix with the given eye position, focal point, and up axis
*
* @param {mat4} out mat4 frustum matrix will be written into
* @param {vec3} eye Position of the viewer
* @param {vec3} center Point the viewer is looking at
* @param {vec3} up vec3 pointing up
* @returns {mat4} out
*/
mat4.lookAt = function (out, eye, center, up) {
var x0, x1, x2, y0, y1, y2, z0, z1, z2, len,
eyex = eye[0],
eyey = eye[1],
eyez = eye[2],
upx = up[0],
upy = up[1],
upz = up[2],
centerx = center[0],
centery = center[1],
centerz = center[2];
if (Math.abs(eyex - centerx) < GLMAT_EPSILON &&
Math.abs(eyey - centery) < GLMAT_EPSILON &&
Math.abs(eyez - centerz) < GLMAT_EPSILON) {
return mat4.identity(out);
}
z0 = eyex - centerx;
z1 = eyey - centery;
z2 = eyez - centerz;
len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2);
z0 *= len;
z1 *= len;
z2 *= len;
x0 = upy * z2 - upz * z1;
x1 = upz * z0 - upx * z2;
x2 = upx * z1 - upy * z0;
len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2);
if (!len) {
x0 = 0;
x1 = 0;
x2 = 0;
} else {
len = 1 / len;
x0 *= len;
x1 *= len;
x2 *= len;
}
y0 = z1 * x2 - z2 * x1;
y1 = z2 * x0 - z0 * x2;
y2 = z0 * x1 - z1 * x0;
len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2);
if (!len) {
y0 = 0;
y1 = 0;
y2 = 0;
} else {
len = 1 / len;
y0 *= len;
y1 *= len;
y2 *= len;
}
out[0] = x0;
out[1] = y0;
out[2] = z0;
out[3] = 0;
out[4] = x1;
out[5] = y1;
out[6] = z1;
out[7] = 0;
out[8] = x2;
out[9] = y2;
out[10] = z2;
out[11] = 0;
out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez);
out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez);
out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez);
out[15] = 1;
return out;
};
/**
* Returns a string representation of a mat4
*
* @param {mat4} mat matrix to represent as a string
* @returns {String} string representation of the matrix
*/
mat4.str = function (a) {
return 'mat4(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ', ' +
a[4] + ', ' + a[5] + ', ' + a[6] + ', ' + a[7] + ', ' +
a[8] + ', ' + a[9] + ', ' + a[10] + ', ' + a[11] + ', ' +
a[12] + ', ' + a[13] + ', ' + a[14] + ', ' + a[15] + ')';
};
/**
* Returns Frobenius norm of a mat4
*
* @param {mat4} a the matrix to calculate Frobenius norm of
* @returns {Number} Frobenius norm
*/
mat4.frob = function (a) {
return(Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + Math.pow(a[6], 2) + Math.pow(a[7], 2) + Math.pow(a[8], 2) + Math.pow(a[9], 2) + Math.pow(a[10], 2) + Math.pow(a[11], 2) + Math.pow(a[12], 2) + Math.pow(a[13], 2) + Math.pow(a[14], 2) + Math.pow(a[15], 2) ))
};
if(typeof(exports) !== 'undefined') {
exports.mat4 = mat4;
}
;
/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/**
* @class Quaternion
* @name quat
*/
var quat = {};
/**
* Creates a new identity quat
*
* @returns {quat} a new quaternion
*/
quat.create = function() {
var out = new GLMAT_ARRAY_TYPE(4);
out[0] = 0;
out[1] = 0;
out[2] = 0;
out[3] = 1;
return out;
};
/**
* Sets a quaternion to represent the shortest rotation from one
* vector to another.
*
* Both vectors are assumed to be unit length.
*
* @param {quat} out the receiving quaternion.
* @param {vec3} a the initial vector
* @param {vec3} b the destination vector
* @returns {quat} out
*/
quat.rotationTo = (function() {
var tmpvec3 = vec3.create();
var xUnitVec3 = vec3.fromValues(1,0,0);
var yUnitVec3 = vec3.fromValues(0,1,0);
return function(out, a, b) {
var dot = vec3.dot(a, b);
if (dot < -0.999999) {
vec3.cross(tmpvec3, xUnitVec3, a);
if (vec3.length(tmpvec3) < 0.000001)
vec3.cross(tmpvec3, yUnitVec3, a);
vec3.normalize(tmpvec3, tmpvec3);
quat.setAxisAngle(out, tmpvec3, Math.PI);
return out;
} else if (dot > 0.999999) {
out[0] = 0;
out[1] = 0;
out[2] = 0;
out[3] = 1;
return out;
} else {
vec3.cross(tmpvec3, a, b);
out[0] = tmpvec3[0];
out[1] = tmpvec3[1];
out[2] = tmpvec3[2];
out[3] = 1 + dot;
return quat.normalize(out, out);
}
};
})();
/**
* Sets the specified quaternion with values corresponding to the given
* axes. Each axis is a vec3 and is expected to be unit length and
* perpendicular to all other specified axes.
*
* @param {vec3} view the vector representing the viewing direction
* @param {vec3} right the vector representing the local "right" direction
* @param {vec3} up the vector representing the local "up" direction
* @returns {quat} out
*/
quat.setAxes = (function() {
var matr = mat3.create();
return function(out, view, right, up) {
matr[0] = right[0];
matr[3] = right[1];
matr[6] = right[2];
matr[1] = up[0];
matr[4] = up[1];
matr[7] = up[2];
matr[2] = -view[0];
matr[5] = -view[1];
matr[8] = -view[2];
return quat.normalize(out, quat.fromMat3(out, matr));
};
})();
/**
* Creates a new quat initialized with values from an existing quaternion
*
* @param {quat} a quaternion to clone
* @returns {quat} a new quaternion
* @function
*/
quat.clone = vec4.clone;
/**
* Creates a new quat initialized with the given values
*
* @param {Number} x X component
* @param {Number} y Y component
* @param {Number} z Z component
* @param {Number} w W component
* @returns {quat} a new quaternion
* @function
*/
quat.fromValues = vec4.fromValues;
/**
* Copy the values from one quat to another
*
* @param {quat} out the receiving quaternion
* @param {quat} a the source quaternion
* @returns {quat} out
* @function
*/
quat.copy = vec4.copy;
/**
* Set the components of a quat to the given values
*
* @param {quat} out the receiving quaternion
* @param {Number} x X component
* @param {Number} y Y component
* @param {Number} z Z component
* @param {Number} w W component
* @returns {quat} out
* @function
*/
quat.set = vec4.set;
/**
* Set a quat to the identity quaternion
*
* @param {quat} out the receiving quaternion
* @returns {quat} out
*/
quat.identity = function(out) {
out[0] = 0;
out[1] = 0;
out[2] = 0;
out[3] = 1;
return out;
};
/**
* Sets a quat from the given angle and rotation axis,
* then returns it.
*
* @param {quat} out the receiving quaternion
* @param {vec3} axis the axis around which to rotate
* @param {Number} rad the angle in radians
* @returns {quat} out
**/
quat.setAxisAngle = function(out, axis, rad) {
rad = rad * 0.5;
var s = Math.sin(rad);
out[0] = s * axis[0];
out[1] = s * axis[1];
out[2] = s * axis[2];
out[3] = Math.cos(rad);
return out;
};
/**
* Adds two quat's
*
* @param {quat} out the receiving quaternion
* @param {quat} a the first operand
* @param {quat} b the second operand
* @returns {quat} out
* @function
*/
quat.add = vec4.add;
/**
* Multiplies two quat's
*
* @param {quat} out the receiving quaternion
* @param {quat} a the first operand
* @param {quat} b the second operand
* @returns {quat} out
*/
quat.multiply = function(out, a, b) {
var ax = a[0], ay = a[1], az = a[2], aw = a[3],
bx = b[0], by = b[1], bz = b[2], bw = b[3];
out[0] = ax * bw + aw * bx + ay * bz - az * by;
out[1] = ay * bw + aw * by + az * bx - ax * bz;
out[2] = az * bw + aw * bz + ax * by - ay * bx;
out[3] = aw * bw - ax * bx - ay * by - az * bz;
return out;
};
/**
* Alias for {@link quat.multiply}
* @function
*/
quat.mul = quat.multiply;
/**
* Scales a quat by a scalar number
*
* @param {quat} out the receiving vector
* @param {quat} a the vector to scale
* @param {Number} b amount to scale the vector by
* @returns {quat} out
* @function
*/
quat.scale = vec4.scale;
/**
* Rotates a quaternion by the given angle about the X axis
*
* @param {quat} out quat receiving operation result
* @param {quat} a quat to rotate
* @param {number} rad angle (in radians) to rotate
* @returns {quat} out
*/
quat.rotateX = function (out, a, rad) {
rad *= 0.5;
var ax = a[0], ay = a[1], az = a[2], aw = a[3],
bx = Math.sin(rad), bw = Math.cos(rad);
out[0] = ax * bw + aw * bx;
out[1] = ay * bw + az * bx;
out[2] = az * bw - ay * bx;
out[3] = aw * bw - ax * bx;
return out;
};
/**
* Rotates a quaternion by the given angle about the Y axis
*
* @param {quat} out quat receiving operation result
* @param {quat} a quat to rotate
* @param {number} rad angle (in radians) to rotate
* @returns {quat} out
*/
quat.rotateY = function (out, a, rad) {
rad *= 0.5;
var ax = a[0], ay = a[1], az = a[2], aw = a[3],
by = Math.sin(rad), bw = Math.cos(rad);
out[0] = ax * bw - az * by;
out[1] = ay * bw + aw * by;
out[2] = az * bw + ax * by;
out[3] = aw * bw - ay * by;
return out;
};
/**
* Rotates a quaternion by the given angle about the Z axis
*
* @param {quat} out quat receiving operation result
* @param {quat} a quat to rotate
* @param {number} rad angle (in radians) to rotate
* @returns {quat} out
*/
quat.rotateZ = function (out, a, rad) {
rad *= 0.5;
var ax = a[0], ay = a[1], az = a[2], aw = a[3],
bz = Math.sin(rad), bw = Math.cos(rad);
out[0] = ax * bw + ay * bz;
out[1] = ay * bw - ax * bz;
out[2] = az * bw + aw * bz;
out[3] = aw * bw - az * bz;
return out;
};
/**
* Calculates the W component of a quat from the X, Y, and Z components.
* Assumes that quaternion is 1 unit in length.
* Any existing W component will be ignored.
*
* @param {quat} out the receiving quaternion
* @param {quat} a quat to calculate W component of
* @returns {quat} out
*/
quat.calculateW = function (out, a) {
var x = a[0], y = a[1], z = a[2];
out[0] = x;
out[1] = y;
out[2] = z;
out[3] = Math.sqrt(Math.abs(1.0 - x * x - y * y - z * z));
return out;
};
/**
* Calculates the dot product of two quat's
*
* @param {quat} a the first operand
* @param {quat} b the second operand
* @returns {Number} dot product of a and b
* @function
*/
quat.dot = vec4.dot;
/**
* Performs a linear interpolation between two quat's
*
* @param {quat} out the receiving quaternion
* @param {quat} a the first operand
* @param {quat} b the second operand
* @param {Number} t interpolation amount between the two inputs
* @returns {quat} out
* @function
*/
quat.lerp = vec4.lerp;
/**
* Performs a spherical linear interpolation between two quat
*
* @param {quat} out the receiving quaternion
* @param {quat} a the first operand
* @param {quat} b the second operand
* @param {Number} t interpolation amount between the two inputs
* @returns {quat} out
*/
quat.slerp = function (out, a, b, t) {
// benchmarks:
// http://jsperf.com/quaternion-slerp-implementations
var ax = a[0], ay = a[1], az = a[2], aw = a[3],
bx = b[0], by = b[1], bz = b[2], bw = b[3];
var omega, cosom, sinom, scale0, scale1;
// calc cosine
cosom = ax * bx + ay * by + az * bz + aw * bw;
// adjust signs (if necessary)
if ( cosom < 0.0 ) {
cosom = -cosom;
bx = - bx;
by = - by;
bz = - bz;
bw = - bw;
}
// calculate coefficients
if ( (1.0 - cosom) > 0.000001 ) {
// standard case (slerp)
omega = Math.acos(cosom);
sinom = Math.sin(omega);
scale0 = Math.sin((1.0 - t) * omega) / sinom;
scale1 = Math.sin(t * omega) / sinom;
} else {
// "from" and "to" quaternions are very close
// ... so we can do a linear interpolation
scale0 = 1.0 - t;
scale1 = t;
}
// calculate final values
out[0] = scale0 * ax + scale1 * bx;
out[1] = scale0 * ay + scale1 * by;
out[2] = scale0 * az + scale1 * bz;
out[3] = scale0 * aw + scale1 * bw;
return out;
};
/**
* Calculates the inverse of a quat
*
* @param {quat} out the receiving quaternion
* @param {quat} a quat to calculate inverse of
* @returns {quat} out
*/
quat.invert = function(out, a) {
var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3],
dot = a0*a0 + a1*a1 + a2*a2 + a3*a3,
invDot = dot ? 1.0/dot : 0;
// TODO: Would be faster to return [0,0,0,0] immediately if dot == 0
out[0] = -a0*invDot;
out[1] = -a1*invDot;
out[2] = -a2*invDot;
out[3] = a3*invDot;
return out;
};
/**
* Calculates the conjugate of a quat
* If the quaternion is normalized, this function is faster than quat.inverse and produces the same result.
*
* @param {quat} out the receiving quaternion
* @param {quat} a quat to calculate conjugate of
* @returns {quat} out
*/
quat.conjugate = function (out, a) {
out[0] = -a[0];
out[1] = -a[1];
out[2] = -a[2];
out[3] = a[3];
return out;
};
/**
* Calculates the length of a quat
*
* @param {quat} a vector to calculate length of
* @returns {Number} length of a
* @function
*/
quat.length = vec4.length;
/**
* Alias for {@link quat.length}
* @function
*/
quat.len = quat.length;
/**
* Calculates the squared length of a quat
*
* @param {quat} a vector to calculate squared length of
* @returns {Number} squared length of a
* @function
*/
quat.squaredLength = vec4.squaredLength;
/**
* Alias for {@link quat.squaredLength}
* @function
*/
quat.sqrLen = quat.squaredLength;
/**
* Normalize a quat
*
* @param {quat} out the receiving quaternion
* @param {quat} a quaternion to normalize
* @returns {quat} out
* @function
*/
quat.normalize = vec4.normalize;
/**
* Creates a quaternion from the given 3x3 rotation matrix.
*
* NOTE: The resultant quaternion is not normalized, so you should be sure
* to renormalize the quaternion yourself where necessary.
*
* @param {quat} out the receiving quaternion
* @param {mat3} m rotation matrix
* @returns {quat} out
* @function
*/
quat.fromMat3 = function(out, m) {
// Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes
// article "Quaternion Calculus and Fast Animation".
var fTrace = m[0] + m[4] + m[8];
var fRoot;
if ( fTrace > 0.0 ) {
// |w| > 1/2, may as well choose w > 1/2
fRoot = Math.sqrt(fTrace + 1.0); // 2w
out[3] = 0.5 * fRoot;
fRoot = 0.5/fRoot; // 1/(4w)
out[0] = (m[5]-m[7])*fRoot;
out[1] = (m[6]-m[2])*fRoot;
out[2] = (m[1]-m[3])*fRoot;
} else {
// |w| <= 1/2
var i = 0;
if ( m[4] > m[0] )
i = 1;
if ( m[8] > m[i*3+i] )
i = 2;
var j = (i+1)%3;
var k = (i+2)%3;
fRoot = Math.sqrt(m[i*3+i]-m[j*3+j]-m[k*3+k] + 1.0);
out[i] = 0.5 * fRoot;
fRoot = 0.5 / fRoot;
out[3] = (m[j*3+k] - m[k*3+j]) * fRoot;
out[j] = (m[j*3+i] + m[i*3+j]) * fRoot;
out[k] = (m[k*3+i] + m[i*3+k]) * fRoot;
}
return out;
};
/**
* Returns a string representation of a quatenion
*
* @param {quat} vec vector to represent as a string
* @returns {String} string representation of the vector
*/
quat.str = function (a) {
return 'quat(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')';
};
if(typeof(exports) !== 'undefined') {
exports.quat = quat;
}
;
})(shim.exports);
})(this);
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(63)))
/***/ }),
/* 2 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_Mesh__ = __webpack_require__(31);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_Renderer__ = __webpack_require__(46);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_claygl_src_Material__ = __webpack_require__(17);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_claygl_src_Node__ = __webpack_require__(30);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_claygl_src_Geometry__ = __webpack_require__(13);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_8_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9_claygl_src_Scene__ = __webpack_require__(32);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10_zrender_lib_core_LRU__ = __webpack_require__(53);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10_zrender_lib_core_LRU___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_10_zrender_lib_core_LRU__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11_claygl_src_util_texture__ = __webpack_require__(54);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__EChartsSurface__ = __webpack_require__(116);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_13_claygl_src_light_AmbientCubemap__ = __webpack_require__(117);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_14_claygl_src_light_AmbientSH__ = __webpack_require__(122);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_15_claygl_src_util_sh__ = __webpack_require__(123);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_16__retrieve__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_17_claygl_src_geometry_Sphere__ = __webpack_require__(69);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_18_claygl_src_geometry_Plane__ = __webpack_require__(37);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_19_claygl_src_geometry_Cube__ = __webpack_require__(71);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_20_claygl_src_light_Ambient__ = __webpack_require__(125);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_21_claygl_src_light_Directional__ = __webpack_require__(126);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_22_claygl_src_light_Point__ = __webpack_require__(127);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_23_claygl_src_light_Spot__ = __webpack_require__(128);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_24_claygl_src_camera_Perspective__ = __webpack_require__(36);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_25_claygl_src_camera_Orthographic__ = __webpack_require__(33);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_26_claygl_src_math_Vector2__ = __webpack_require__(23);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_27_claygl_src_math_Vector3__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_28_claygl_src_math_Vector4__ = __webpack_require__(129);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_29_claygl_src_math_Quaternion__ = __webpack_require__(50);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_30_claygl_src_math_Matrix2__ = __webpack_require__(130);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_31_claygl_src_math_Matrix2d__ = __webpack_require__(131);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_32_claygl_src_math_Matrix3__ = __webpack_require__(132);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_33_claygl_src_math_Matrix4__ = __webpack_require__(7);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_34_claygl_src_math_Plane__ = __webpack_require__(68);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_35_claygl_src_math_Ray__ = __webpack_require__(49);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_36_claygl_src_math_BoundingBox__ = __webpack_require__(15);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_37_claygl_src_math_Frustum__ = __webpack_require__(52);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_38__animatableMixin__ = __webpack_require__(133);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_39_claygl_src_shader_source_util_glsl_js__ = __webpack_require__(138);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_40_claygl_src_shader_source_prez_glsl_js__ = __webpack_require__(65);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_41__shader_common_glsl_js__ = __webpack_require__(139);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_42__shader_color_glsl_js__ = __webpack_require__(140);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_43__shader_lambert_glsl_js__ = __webpack_require__(141);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_44__shader_realistic_glsl_js__ = __webpack_require__(142);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_45__shader_hatching_glsl_js__ = __webpack_require__(143);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_46__shader_shadow_glsl_js__ = __webpack_require__(144);
// Math
// Some common shaders
__WEBPACK_IMPORTED_MODULE_8_echarts_lib_echarts___default.a.util.extend(__WEBPACK_IMPORTED_MODULE_6_claygl_src_Node__["a" /* default */].prototype, __WEBPACK_IMPORTED_MODULE_38__animatableMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].import(__WEBPACK_IMPORTED_MODULE_39_claygl_src_shader_source_util_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].import(__WEBPACK_IMPORTED_MODULE_40_claygl_src_shader_source_prez_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].import(__WEBPACK_IMPORTED_MODULE_41__shader_common_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].import(__WEBPACK_IMPORTED_MODULE_42__shader_color_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].import(__WEBPACK_IMPORTED_MODULE_43__shader_lambert_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].import(__WEBPACK_IMPORTED_MODULE_44__shader_realistic_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].import(__WEBPACK_IMPORTED_MODULE_45__shader_hatching_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].import(__WEBPACK_IMPORTED_MODULE_46__shader_shadow_glsl_js__["a" /* default */]);
function isValueNone(value) {
return !value || value === 'none';
}
function isValueImage(value) {
return value instanceof HTMLCanvasElement
|| value instanceof HTMLImageElement
|| value instanceof Image;
}
function isECharts(value) {
return value.getZr && value.setOption;
}
// Overwrite addToScene and removeFromScene
var oldAddToScene = __WEBPACK_IMPORTED_MODULE_9_claygl_src_Scene__["a" /* default */].prototype.addToScene;
var oldRemoveFromScene = __WEBPACK_IMPORTED_MODULE_9_claygl_src_Scene__["a" /* default */].prototype.removeFromScene;
__WEBPACK_IMPORTED_MODULE_9_claygl_src_Scene__["a" /* default */].prototype.addToScene = function (node) {
oldAddToScene.call(this, node);
if (this.__zr) {
var zr = this.__zr;
node.traverse(function (child) {
child.__zr = zr;
if (child.addAnimatorsToZr) {
child.addAnimatorsToZr(zr);
}
});
}
};
__WEBPACK_IMPORTED_MODULE_9_claygl_src_Scene__["a" /* default */].prototype.removeFromScene = function (node) {
oldRemoveFromScene.call(this, node);
node.traverse(function (child) {
var zr = child.__zr;
child.__zr = null;
if (zr && child.removeAnimatorsFromZr) {
child.removeAnimatorsFromZr(zr);
}
});
};
/**
* @param {string} textureName
* @param {string|HTMLImageElement|HTMLCanvasElement} imgValue
* @param {module:echarts/ExtensionAPI} api
* @param {Object} [textureOpts]
*/
__WEBPACK_IMPORTED_MODULE_5_claygl_src_Material__["a" /* default */].prototype.setTextureImage = function (textureName, imgValue, api, textureOpts) {
if (!this.shader) {
return;
}
var zr = api.getZr();
var material = this;
var texture;
material.autoUpdateTextureStatus = false;
// disableTexture first
material.disableTexture(textureName);
if (!isValueNone(imgValue)) {
texture = graphicGL.loadTexture(imgValue, api, textureOpts, function (texture) {
material.enableTexture(textureName);
zr && zr.refresh();
});
// Set texture immediately for other code to verify if have this texture.
material.set(textureName, texture);
}
return texture;
};
var graphicGL = {};
graphicGL.Renderer = __WEBPACK_IMPORTED_MODULE_1_claygl_src_Renderer__["a" /* default */];
graphicGL.Node = __WEBPACK_IMPORTED_MODULE_6_claygl_src_Node__["a" /* default */];
graphicGL.Mesh = __WEBPACK_IMPORTED_MODULE_0_claygl_src_Mesh__["a" /* default */];
graphicGL.Shader = __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */];
graphicGL.Material = __WEBPACK_IMPORTED_MODULE_5_claygl_src_Material__["a" /* default */];
graphicGL.Texture = __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__["a" /* default */];
graphicGL.Texture2D = __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__["a" /* default */];
// Geometries
graphicGL.Geometry = __WEBPACK_IMPORTED_MODULE_7_claygl_src_Geometry__["a" /* default */];
graphicGL.SphereGeometry = __WEBPACK_IMPORTED_MODULE_17_claygl_src_geometry_Sphere__["a" /* default */];
graphicGL.PlaneGeometry = __WEBPACK_IMPORTED_MODULE_18_claygl_src_geometry_Plane__["a" /* default */];
graphicGL.CubeGeometry = __WEBPACK_IMPORTED_MODULE_19_claygl_src_geometry_Cube__["a" /* default */];
// Lights
graphicGL.AmbientLight = __WEBPACK_IMPORTED_MODULE_20_claygl_src_light_Ambient__["a" /* default */];
graphicGL.DirectionalLight = __WEBPACK_IMPORTED_MODULE_21_claygl_src_light_Directional__["a" /* default */];
graphicGL.PointLight = __WEBPACK_IMPORTED_MODULE_22_claygl_src_light_Point__["a" /* default */];
graphicGL.SpotLight = __WEBPACK_IMPORTED_MODULE_23_claygl_src_light_Spot__["a" /* default */];
// Cameras
graphicGL.PerspectiveCamera = __WEBPACK_IMPORTED_MODULE_24_claygl_src_camera_Perspective__["a" /* default */];
graphicGL.OrthographicCamera = __WEBPACK_IMPORTED_MODULE_25_claygl_src_camera_Orthographic__["a" /* default */];
// Math
graphicGL.Vector2 = __WEBPACK_IMPORTED_MODULE_26_claygl_src_math_Vector2__["a" /* default */];
graphicGL.Vector3 = __WEBPACK_IMPORTED_MODULE_27_claygl_src_math_Vector3__["a" /* default */];
graphicGL.Vector4 = __WEBPACK_IMPORTED_MODULE_28_claygl_src_math_Vector4__["a" /* default */];
graphicGL.Quaternion = __WEBPACK_IMPORTED_MODULE_29_claygl_src_math_Quaternion__["a" /* default */];
graphicGL.Matrix2 = __WEBPACK_IMPORTED_MODULE_30_claygl_src_math_Matrix2__["a" /* default */];
graphicGL.Matrix2d = __WEBPACK_IMPORTED_MODULE_31_claygl_src_math_Matrix2d__["a" /* default */];
graphicGL.Matrix3 = __WEBPACK_IMPORTED_MODULE_32_claygl_src_math_Matrix3__["a" /* default */];
graphicGL.Matrix4 = __WEBPACK_IMPORTED_MODULE_33_claygl_src_math_Matrix4__["a" /* default */];
graphicGL.Plane = __WEBPACK_IMPORTED_MODULE_34_claygl_src_math_Plane__["a" /* default */];
graphicGL.Ray = __WEBPACK_IMPORTED_MODULE_35_claygl_src_math_Ray__["a" /* default */];
graphicGL.BoundingBox = __WEBPACK_IMPORTED_MODULE_36_claygl_src_math_BoundingBox__["a" /* default */];
graphicGL.Frustum = __WEBPACK_IMPORTED_MODULE_37_claygl_src_math_Frustum__["a" /* default */];
// Texture utilities
var blankImage = __WEBPACK_IMPORTED_MODULE_11_claygl_src_util_texture__["a" /* default */].createBlank('rgba(255,255,255,0)').image;
function nearestPowerOfTwo(val) {
return Math.pow(2, Math.round(Math.log(val) / Math.LN2));
}
function convertTextureToPowerOfTwo(texture) {
if ((texture.wrapS === __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__["a" /* default */].REPEAT || texture.wrapT === __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__["a" /* default */].REPEAT)
&& texture.image
) {
// var canvas = document.createElement('canvas');
var width = nearestPowerOfTwo(texture.width);
var height = nearestPowerOfTwo(texture.height);
if (width !== texture.width || height !== texture.height) {
var canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext('2d');
ctx.drawImage(texture.image, 0, 0, width, height);
texture.image = canvas;
}
}
}
/**
* @param {string|HTMLImageElement|HTMLCanvasElement} imgValue
* @param {module:echarts/ExtensionAPI} api
* @param {Object} [textureOpts]
* @param {Function} cb
*/
// TODO Promise, test
graphicGL.loadTexture = function (imgValue, api, textureOpts, cb) {
if (typeof textureOpts === 'function') {
cb = textureOpts;
textureOpts = {};
}
textureOpts = textureOpts || {};
var keys = Object.keys(textureOpts).sort();
var prefix = '';
for (var i = 0; i < keys.length; i++) {
prefix += keys[i] + '_' + textureOpts[keys[i]] + '_';
}
var textureCache = api.__textureCache = api.__textureCache || new __WEBPACK_IMPORTED_MODULE_10_zrender_lib_core_LRU___default.a(20);
if (isECharts(imgValue)) {
var id = imgValue.__textureid__;
var textureObj = textureCache.get(prefix + id);
if (!textureObj) {
var surface = new __WEBPACK_IMPORTED_MODULE_12__EChartsSurface__["a" /* default */](imgValue);
surface.onupdate = function () {
api.getZr().refresh();
};
textureObj = {
texture: surface.getTexture()
};
for (var i = 0; i < keys.length; i++) {
textureObj.texture[keys[i]] = textureOpts[keys[i]];
}
id = imgValue.__textureid__ || '__ecgl_ec__' + textureObj.texture.__uid__;
imgValue.__textureid__ = id;
textureCache.put(prefix + id, textureObj);
cb && cb(textureObj.texture);
}
else {
textureObj.texture.surface.setECharts(imgValue);
cb && cb(textureObj.texture);
}
return textureObj.texture;
}
else if (isValueImage(imgValue)) {
var id = imgValue.__textureid__;
var textureObj = textureCache.get(prefix + id);
if (!textureObj) {
textureObj = {
texture: new graphicGL.Texture2D({
image: imgValue
})
};
for (var i = 0; i < keys.length; i++) {
textureObj.texture[keys[i]] = textureOpts[keys[i]];
}
id = imgValue.__textureid__ || '__ecgl_image__' + textureObj.texture.__uid__;
imgValue.__textureid__ = id;
textureCache.put(prefix + id, textureObj);
convertTextureToPowerOfTwo(textureObj.texture);
// TODO Next tick?
cb && cb(textureObj.texture);
}
return textureObj.texture;
}
else {
var textureObj = textureCache.get(prefix + imgValue);
if (textureObj) {
if (textureObj.callbacks) {
// Add to pending callbacks
textureObj.callbacks.push(cb);
}
else {
// TODO Next tick?
cb && cb(textureObj.texture);
}
}
else {
// Maybe base64
if (imgValue.match(/.hdr$|^data:application\/octet-stream/)) {
textureObj = {
callbacks: [cb]
};
var texture = __WEBPACK_IMPORTED_MODULE_11_claygl_src_util_texture__["a" /* default */].loadTexture(imgValue, {
exposure: textureOpts.exposure,
fileType: 'hdr'
}, function () {
texture.dirty();
textureObj.callbacks.forEach(function (cb) {
cb && cb(texture);
});
textureObj.callbacks = null;
});
textureObj.texture = texture;
textureCache.put(prefix + imgValue, textureObj);
}
else {
var texture = new graphicGL.Texture2D({
image: new Image()
});
for (var i = 0; i < keys.length; i++) {
texture[keys[i]] = textureOpts[keys[i]];
}
textureObj = {
texture: texture,
callbacks: [cb]
};
var originalImage = texture.image;
originalImage.onload = function () {
texture.image = originalImage;
convertTextureToPowerOfTwo(texture);
texture.dirty();
textureObj.callbacks.forEach(function (cb) {
cb && cb(texture);
});
textureObj.callbacks = null;
};
originalImage.src = imgValue;
// Use blank image as place holder.
texture.image = blankImage;
textureCache.put(prefix + imgValue, textureObj);
}
}
return textureObj.texture;
}
};
/**
* Create ambientCubemap and ambientSH light. respectively to have specular and diffuse light
* @return {Object} { specular, diffuse }
*/
graphicGL.createAmbientCubemap = function (opt, renderer, api, cb) {
opt = opt || {};
var textureUrl = opt.texture;
var exposure = __WEBPACK_IMPORTED_MODULE_16__retrieve__["a" /* default */].firstNotNull(opt.exposure, 1.0);
var ambientCubemap = new __WEBPACK_IMPORTED_MODULE_13_claygl_src_light_AmbientCubemap__["a" /* default */]({
intensity: __WEBPACK_IMPORTED_MODULE_16__retrieve__["a" /* default */].firstNotNull(opt.specularIntensity, 1.0)
});
var ambientSH = new __WEBPACK_IMPORTED_MODULE_14_claygl_src_light_AmbientSH__["a" /* default */]({
intensity: __WEBPACK_IMPORTED_MODULE_16__retrieve__["a" /* default */].firstNotNull(opt.diffuseIntensity, 1.0),
coefficients: [0.844, 0.712, 0.691, -0.037, 0.083, 0.167, 0.343, 0.288, 0.299, -0.041, -0.021, -0.009, -0.003, -0.041, -0.064, -0.011, -0.007, -0.004, -0.031, 0.034, 0.081, -0.060, -0.049, -0.060, 0.046, 0.056, 0.050]
});
ambientCubemap.cubemap = graphicGL.loadTexture(textureUrl, api, {
exposure: exposure
}, function () {
// TODO Performance when multiple view
ambientCubemap.cubemap.flipY = false;
if (true) {
var time = Date.now();
}
ambientCubemap.prefilter(renderer, 32);
if (true) {
var dTime = Date.now() - time;
console.log('Prefilter environment map: ' + dTime + 'ms');
}
ambientSH.coefficients = __WEBPACK_IMPORTED_MODULE_15_claygl_src_util_sh__["a" /* default */].projectEnvironmentMap(renderer, ambientCubemap.cubemap, {
lod: 1
});
cb && cb();
// TODO Refresh ?
});
return {
specular: ambientCubemap,
diffuse: ambientSH
};
};
/**
* Create a blank texture for placeholder
*/
graphicGL.createBlankTexture = __WEBPACK_IMPORTED_MODULE_11_claygl_src_util_texture__["a" /* default */].createBlank;
/**
* If value is image
* @param {*}
* @return {boolean}
*/
graphicGL.isImage = isValueImage;
graphicGL.additiveBlend = function (gl) {
gl.blendEquation(gl.FUNC_ADD);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
};
/**
* @param {string|Array.} colorStr
* @param {Array.} [rgba]
* @return {Array.} rgba
*/
graphicGL.parseColor = function (colorStr, rgba) {
if (colorStr instanceof Array) {
if (!rgba) {
rgba = [];
}
// Color has been parsed.
rgba[0] = colorStr[0];
rgba[1] = colorStr[1];
rgba[2] = colorStr[2];
if (colorStr.length > 3) {
rgba[3] = colorStr[3];
}
else {
rgba[3] = 1;
}
return rgba;
}
rgba = __WEBPACK_IMPORTED_MODULE_8_echarts_lib_echarts___default.a.color.parse(colorStr || '#000', rgba) || [0, 0, 0, 0];
rgba[0] /= 255;
rgba[1] /= 255;
rgba[2] /= 255;
return rgba;
};
/**
* Convert alpha beta rotation to direction.
* @param {number} alpha
* @param {number} beta
* @return {Array.}
*/
graphicGL.directionFromAlphaBeta = function (alpha, beta) {
var theta = alpha / 180 * Math.PI + Math.PI / 2;
var phi = -beta / 180 * Math.PI + Math.PI / 2;
var dir = [];
var r = Math.sin(theta);
dir[0] = r * Math.cos(phi);
dir[1] = -Math.cos(theta);
dir[2] = r * Math.sin(phi);
return dir;
};
/**
* Get shadow resolution from shadowQuality configuration
*/
graphicGL.getShadowResolution = function (shadowQuality) {
var shadowResolution = 1024;
switch (shadowQuality) {
case 'low':
shadowResolution = 512;
break;
case 'medium':
break;
case 'high':
shadowResolution = 2048;
break;
case 'ultra':
shadowResolution = 4096;
break;
}
return shadowResolution;
};
/**
* Shading utilities
*/
graphicGL.COMMON_SHADERS = ['lambert', 'color', 'realistic', 'hatching'];
/**
* Create shader including vertex and fragment
* @param {string} prefix.
*/
graphicGL.createShader = function (prefix) {
var vertexShaderStr = __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].source(prefix + '.vertex');
var fragmentShaderStr = __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].source(prefix + '.fragment');
if (!vertexShaderStr) {
console.error('Vertex shader of \'%s\' not exits', prefix);
}
if (!fragmentShaderStr) {
console.error('Fragment shader of \'%s\' not exits', prefix);
}
var shader = new __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */](vertexShaderStr, fragmentShaderStr);
shader.name = prefix;
return shader;
};
graphicGL.createMaterial = function (prefix, defines) {
if (!(defines instanceof Array)) {
defines = [defines];
}
var shader = graphicGL.createShader(prefix);
var material = new __WEBPACK_IMPORTED_MODULE_5_claygl_src_Material__["a" /* default */]({
shader: shader
});
defines.forEach(function (defineName) {
if (typeof defineName === 'string') {
material.define(defineName);
}
});
return material;
};
/**
* Set material from model.
* @param {clay.Material} material
* @param {module:echarts/model/Model} model
* @param {module:echarts/ExtensionAPI} api
*/
graphicGL.setMaterialFromModel = function (shading, material, model, api) {
material.autoUpdateTextureStatus = false;
var materialModel = model.getModel(shading + 'Material');
var detailTexture = materialModel.get('detailTexture');
var uvRepeat = __WEBPACK_IMPORTED_MODULE_16__retrieve__["a" /* default */].firstNotNull(materialModel.get('textureTiling'), 1.0);
var uvOffset = __WEBPACK_IMPORTED_MODULE_16__retrieve__["a" /* default */].firstNotNull(materialModel.get('textureOffset'), 0.0);
if (typeof uvRepeat === 'number') {
uvRepeat = [uvRepeat, uvRepeat];
}
if (typeof uvOffset === 'number') {
uvOffset = [uvOffset, uvOffset];
}
var repeatParam = (uvRepeat[0] > 1 || uvRepeat[1] > 1) ? graphicGL.Texture.REPEAT : graphicGL.Texture.CLAMP_TO_EDGE;
var textureOpt = {
anisotropic: 8,
wrapS: repeatParam,
wrapT: repeatParam
};
if (shading === 'realistic') {
var roughness = materialModel.get('roughness');
var metalness = materialModel.get('metalness');
if (metalness != null) {
// Try to treat as a texture, TODO More check
if (isNaN(metalness)) {
material.setTextureImage('metalnessMap', metalness, api, textureOpt);
metalness = __WEBPACK_IMPORTED_MODULE_16__retrieve__["a" /* default */].firstNotNull(materialModel.get('metalnessAdjust'), 0.5);
}
}
else {
// Default metalness.
metalness = 0;
}
if (roughness != null) {
// Try to treat as a texture, TODO More check
if (isNaN(roughness)) {
material.setTextureImage('roughnessMap', roughness, api, textureOpt);
roughness = __WEBPACK_IMPORTED_MODULE_16__retrieve__["a" /* default */].firstNotNull(materialModel.get('roughnessAdjust'), 0.5);
}
}
else {
// Default roughness.
roughness = 0.5;
}
var normalTextureVal = materialModel.get('normalTexture');
material.setTextureImage('detailMap', detailTexture, api, textureOpt);
material.setTextureImage('normalMap', normalTextureVal, api, textureOpt);
material.set({
roughness: roughness,
metalness: metalness,
detailUvRepeat: uvRepeat,
detailUvOffset: uvOffset
});
// var normalTexture = material.get('normalMap');
// if (normalTexture) {
// PENDING
// normalTexture.format = Texture.SRGB;
// }
}
else if (shading === 'lambert') {
material.setTextureImage('detailMap', detailTexture, api, textureOpt);
material.set({
detailUvRepeat: uvRepeat,
detailUvOffset: uvOffset
});
}
else if (shading === 'color') {
material.setTextureImage('detailMap', detailTexture, api, textureOpt);
material.set({
detailUvRepeat: uvRepeat,
detailUvOffset: uvOffset
});
}
else if (shading === 'hatching') {
var tams = materialModel.get('hatchingTextures') || [];
if (tams.length < 6) {
if (true) {
console.error('Invalid hatchingTextures.');
}
}
for (var i = 0; i < 6; i++) {
material.setTextureImage('hatch' + (i + 1), tams[i], api, {
anisotropic: 8,
wrapS: graphicGL.Texture.REPEAT,
wrapT: graphicGL.Texture.REPEAT
});
}
material.set({
detailUvRepeat: uvRepeat,
detailUvOffset: uvOffset
});
}
};
graphicGL.updateVertexAnimation = function (
mappingAttributes, previousMesh, currentMesh, seriesModel
) {
var enableAnimation = seriesModel.get('animation');
var duration = seriesModel.get('animationDurationUpdate');
var easing = seriesModel.get('animationEasingUpdate');
var shadowDepthMaterial = currentMesh.shadowDepthMaterial;
if (enableAnimation && previousMesh && duration > 0
// Only animate when bar count are not changed
&& previousMesh.geometry.vertexCount === currentMesh.geometry.vertexCount
) {
currentMesh.material.define('vertex', 'VERTEX_ANIMATION');
currentMesh.ignorePreZ = true;
if (shadowDepthMaterial) {
shadowDepthMaterial.define('vertex', 'VERTEX_ANIMATION');
}
for (var i = 0; i < mappingAttributes.length; i++) {
currentMesh.geometry.attributes[mappingAttributes[i][0]].value =
previousMesh.geometry.attributes[mappingAttributes[i][1]].value;
}
currentMesh.geometry.dirty();
currentMesh.__percent = 0;
currentMesh.material.set('percent', 0);
currentMesh.stopAnimation();
currentMesh.animate()
.when(duration, {
__percent: 1
})
.during(function () {
currentMesh.material.set('percent', currentMesh.__percent);
if (shadowDepthMaterial) {
shadowDepthMaterial.set('percent', currentMesh.__percent);
}
})
.done(function () {
currentMesh.ignorePreZ = false;
currentMesh.material.undefine('vertex', 'VERTEX_ANIMATION');
if (shadowDepthMaterial) {
shadowDepthMaterial.undefine('vertex', 'VERTEX_ANIMATION');
}
})
.start(easing);
}
else {
currentMesh.material.undefine('vertex', 'VERTEX_ANIMATION');
if (shadowDepthMaterial) {
shadowDepthMaterial.undefine('vertex', 'VERTEX_ANIMATION');
}
}
};
/* harmony default export */ __webpack_exports__["a"] = (graphicGL);
/***/ }),
/* 3 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
var retrieve = {
firstNotNull: function () {
for (var i = 0, len = arguments.length; i < len; i++) {
if (arguments[i] != null) {
return arguments[i];
}
}
},
/**
* @param {module:echarts/data/List} data
* @param {Object} payload Contains dataIndex (means rawIndex) / dataIndexInside / name
* each of which can be Array or primary type.
* @return {number|Array.} dataIndex If not found, return undefined/null.
*/
queryDataIndex: function (data, payload) {
if (payload.dataIndexInside != null) {
return payload.dataIndexInside;
}
else if (payload.dataIndex != null) {
return __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.isArray(payload.dataIndex)
? __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.map(payload.dataIndex, function (value) {
return data.indexOfRawIndex(value);
})
: data.indexOfRawIndex(payload.dataIndex);
}
else if (payload.name != null) {
return __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.isArray(payload.name)
? __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.map(payload.name, function (value) {
return data.indexOfName(value);
})
: data.indexOfName(payload.name);
}
}
};
/* harmony default export */ __webpack_exports__["a"] = (retrieve);
/***/ }),
/* 4 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0__dep_glmatrix__);
var vec3 = __WEBPACK_IMPORTED_MODULE_0__dep_glmatrix___default.a.vec3;
/**
* @constructor
* @alias clay.Vector3
* @param {number} x
* @param {number} y
* @param {number} z
*/
var Vector3 = function(x, y, z) {
x = x || 0;
y = y || 0;
z = z || 0;
/**
* Storage of Vector3, read and write of x, y, z will change the values in array
* All methods also operate on the array instead of x, y, z components
* @name array
* @type {Float32Array}
* @memberOf clay.Vector3#
*/
this.array = vec3.fromValues(x, y, z);
/**
* Dirty flag is used by the Node to determine
* if the matrix is updated to latest
* @name _dirty
* @type {boolean}
* @memberOf clay.Vector3#
*/
this._dirty = true;
};
Vector3.prototype = {
constructor: Vector3,
/**
* Add b to self
* @param {clay.Vector3} b
* @return {clay.Vector3}
*/
add: function (b) {
vec3.add(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Set x, y and z components
* @param {number} x
* @param {number} y
* @param {number} z
* @return {clay.Vector3}
*/
set: function (x, y, z) {
this.array[0] = x;
this.array[1] = y;
this.array[2] = z;
this._dirty = true;
return this;
},
/**
* Set x, y and z components from array
* @param {Float32Array|number[]} arr
* @return {clay.Vector3}
*/
setArray: function (arr) {
this.array[0] = arr[0];
this.array[1] = arr[1];
this.array[2] = arr[2];
this._dirty = true;
return this;
},
/**
* Clone a new Vector3
* @return {clay.Vector3}
*/
clone: function () {
return new Vector3(this.x, this.y, this.z);
},
/**
* Copy from b
* @param {clay.Vector3} b
* @return {clay.Vector3}
*/
copy: function (b) {
vec3.copy(this.array, b.array);
this._dirty = true;
return this;
},
/**
* Cross product of self and b, written to a Vector3 out
* @param {clay.Vector3} a
* @param {clay.Vector3} b
* @return {clay.Vector3}
*/
cross: function (a, b) {
vec3.cross(this.array, a.array, b.array);
this._dirty = true;
return this;
},
/**
* Alias for distance
* @param {clay.Vector3} b
* @return {number}
*/
dist: function (b) {
return vec3.dist(this.array, b.array);
},
/**
* Distance between self and b
* @param {clay.Vector3} b
* @return {number}
*/
distance: function (b) {
return vec3.distance(this.array, b.array);
},
/**
* Alias for divide
* @param {clay.Vector3} b
* @return {clay.Vector3}
*/
div: function (b) {
vec3.div(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Divide self by b
* @param {clay.Vector3} b
* @return {clay.Vector3}
*/
divide: function (b) {
vec3.divide(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Dot product of self and b
* @param {clay.Vector3} b
* @return {number}
*/
dot: function (b) {
return vec3.dot(this.array, b.array);
},
/**
* Alias of length
* @return {number}
*/
len: function () {
return vec3.len(this.array);
},
/**
* Calculate the length
* @return {number}
*/
length: function () {
return vec3.length(this.array);
},
/**
* Linear interpolation between a and b
* @param {clay.Vector3} a
* @param {clay.Vector3} b
* @param {number} t
* @return {clay.Vector3}
*/
lerp: function (a, b, t) {
vec3.lerp(this.array, a.array, b.array, t);
this._dirty = true;
return this;
},
/**
* Minimum of self and b
* @param {clay.Vector3} b
* @return {clay.Vector3}
*/
min: function (b) {
vec3.min(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Maximum of self and b
* @param {clay.Vector3} b
* @return {clay.Vector3}
*/
max: function (b) {
vec3.max(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Alias for multiply
* @param {clay.Vector3} b
* @return {clay.Vector3}
*/
mul: function (b) {
vec3.mul(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Mutiply self and b
* @param {clay.Vector3} b
* @return {clay.Vector3}
*/
multiply: function (b) {
vec3.multiply(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Negate self
* @return {clay.Vector3}
*/
negate: function () {
vec3.negate(this.array, this.array);
this._dirty = true;
return this;
},
/**
* Normalize self
* @return {clay.Vector3}
*/
normalize: function () {
vec3.normalize(this.array, this.array);
this._dirty = true;
return this;
},
/**
* Generate random x, y, z components with a given scale
* @param {number} scale
* @return {clay.Vector3}
*/
random: function (scale) {
vec3.random(this.array, scale);
this._dirty = true;
return this;
},
/**
* Scale self
* @param {number} scale
* @return {clay.Vector3}
*/
scale: function (s) {
vec3.scale(this.array, this.array, s);
this._dirty = true;
return this;
},
/**
* Scale b and add to self
* @param {clay.Vector3} b
* @param {number} scale
* @return {clay.Vector3}
*/
scaleAndAdd: function (b, s) {
vec3.scaleAndAdd(this.array, this.array, b.array, s);
this._dirty = true;
return this;
},
/**
* Alias for squaredDistance
* @param {clay.Vector3} b
* @return {number}
*/
sqrDist: function (b) {
return vec3.sqrDist(this.array, b.array);
},
/**
* Squared distance between self and b
* @param {clay.Vector3} b
* @return {number}
*/
squaredDistance: function (b) {
return vec3.squaredDistance(this.array, b.array);
},
/**
* Alias for squaredLength
* @return {number}
*/
sqrLen: function () {
return vec3.sqrLen(this.array);
},
/**
* Squared length of self
* @return {number}
*/
squaredLength: function () {
return vec3.squaredLength(this.array);
},
/**
* Alias for subtract
* @param {clay.Vector3} b
* @return {clay.Vector3}
*/
sub: function (b) {
vec3.sub(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Subtract b from self
* @param {clay.Vector3} b
* @return {clay.Vector3}
*/
subtract: function (b) {
vec3.subtract(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Transform self with a Matrix3 m
* @param {clay.Matrix3} m
* @return {clay.Vector3}
*/
transformMat3: function (m) {
vec3.transformMat3(this.array, this.array, m.array);
this._dirty = true;
return this;
},
/**
* Transform self with a Matrix4 m
* @param {clay.Matrix4} m
* @return {clay.Vector3}
*/
transformMat4: function (m) {
vec3.transformMat4(this.array, this.array, m.array);
this._dirty = true;
return this;
},
/**
* Transform self with a Quaternion q
* @param {clay.Quaternion} q
* @return {clay.Vector3}
*/
transformQuat: function (q) {
vec3.transformQuat(this.array, this.array, q.array);
this._dirty = true;
return this;
},
/**
* Trasnform self into projection space with m
* @param {clay.Matrix4} m
* @return {clay.Vector3}
*/
applyProjection: function (m) {
var v = this.array;
m = m.array;
// Perspective projection
if (m[15] === 0) {
var w = -1 / v[2];
v[0] = m[0] * v[0] * w;
v[1] = m[5] * v[1] * w;
v[2] = (m[10] * v[2] + m[14]) * w;
}
else {
v[0] = m[0] * v[0] + m[12];
v[1] = m[5] * v[1] + m[13];
v[2] = m[10] * v[2] + m[14];
}
this._dirty = true;
return this;
},
eulerFromQuat: function(q, order) {
Vector3.eulerFromQuat(this, q, order);
},
eulerFromMat3: function (m, order) {
Vector3.eulerFromMat3(this, m, order);
},
toString: function() {
return '[' + Array.prototype.join.call(this.array, ',') + ']';
},
toArray: function () {
return Array.prototype.slice.call(this.array);
}
};
var defineProperty = Object.defineProperty;
// Getter and Setter
if (defineProperty) {
var proto = Vector3.prototype;
/**
* @name x
* @type {number}
* @memberOf clay.Vector3
* @instance
*/
defineProperty(proto, 'x', {
get: function () {
return this.array[0];
},
set: function (value) {
this.array[0] = value;
this._dirty = true;
}
});
/**
* @name y
* @type {number}
* @memberOf clay.Vector3
* @instance
*/
defineProperty(proto, 'y', {
get: function () {
return this.array[1];
},
set: function (value) {
this.array[1] = value;
this._dirty = true;
}
});
/**
* @name z
* @type {number}
* @memberOf clay.Vector3
* @instance
*/
defineProperty(proto, 'z', {
get: function () {
return this.array[2];
},
set: function (value) {
this.array[2] = value;
this._dirty = true;
}
});
}
// Supply methods that are not in place
/**
* @param {clay.Vector3} out
* @param {clay.Vector3} a
* @param {clay.Vector3} b
* @return {clay.Vector3}
*/
Vector3.add = function(out, a, b) {
vec3.add(out.array, a.array, b.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector3} out
* @param {number} x
* @param {number} y
* @param {number} z
* @return {clay.Vector3}
*/
Vector3.set = function(out, x, y, z) {
vec3.set(out.array, x, y, z);
out._dirty = true;
};
/**
* @param {clay.Vector3} out
* @param {clay.Vector3} b
* @return {clay.Vector3}
*/
Vector3.copy = function(out, b) {
vec3.copy(out.array, b.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector3} out
* @param {clay.Vector3} a
* @param {clay.Vector3} b
* @return {clay.Vector3}
*/
Vector3.cross = function(out, a, b) {
vec3.cross(out.array, a.array, b.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector3} a
* @param {clay.Vector3} b
* @return {number}
*/
Vector3.dist = function(a, b) {
return vec3.distance(a.array, b.array);
};
/**
* @function
* @param {clay.Vector3} a
* @param {clay.Vector3} b
* @return {number}
*/
Vector3.distance = Vector3.dist;
/**
* @param {clay.Vector3} out
* @param {clay.Vector3} a
* @param {clay.Vector3} b
* @return {clay.Vector3}
*/
Vector3.div = function(out, a, b) {
vec3.divide(out.array, a.array, b.array);
out._dirty = true;
return out;
};
/**
* @function
* @param {clay.Vector3} out
* @param {clay.Vector3} a
* @param {clay.Vector3} b
* @return {clay.Vector3}
*/
Vector3.divide = Vector3.div;
/**
* @param {clay.Vector3} a
* @param {clay.Vector3} b
* @return {number}
*/
Vector3.dot = function(a, b) {
return vec3.dot(a.array, b.array);
};
/**
* @param {clay.Vector3} a
* @return {number}
*/
Vector3.len = function(b) {
return vec3.length(b.array);
};
// Vector3.length = Vector3.len;
/**
* @param {clay.Vector3} out
* @param {clay.Vector3} a
* @param {clay.Vector3} b
* @param {number} t
* @return {clay.Vector3}
*/
Vector3.lerp = function(out, a, b, t) {
vec3.lerp(out.array, a.array, b.array, t);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector3} out
* @param {clay.Vector3} a
* @param {clay.Vector3} b
* @return {clay.Vector3}
*/
Vector3.min = function(out, a, b) {
vec3.min(out.array, a.array, b.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector3} out
* @param {clay.Vector3} a
* @param {clay.Vector3} b
* @return {clay.Vector3}
*/
Vector3.max = function(out, a, b) {
vec3.max(out.array, a.array, b.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector3} out
* @param {clay.Vector3} a
* @param {clay.Vector3} b
* @return {clay.Vector3}
*/
Vector3.mul = function(out, a, b) {
vec3.multiply(out.array, a.array, b.array);
out._dirty = true;
return out;
};
/**
* @function
* @param {clay.Vector3} out
* @param {clay.Vector3} a
* @param {clay.Vector3} b
* @return {clay.Vector3}
*/
Vector3.multiply = Vector3.mul;
/**
* @param {clay.Vector3} out
* @param {clay.Vector3} a
* @return {clay.Vector3}
*/
Vector3.negate = function(out, a) {
vec3.negate(out.array, a.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector3} out
* @param {clay.Vector3} a
* @return {clay.Vector3}
*/
Vector3.normalize = function(out, a) {
vec3.normalize(out.array, a.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector3} out
* @param {number} scale
* @return {clay.Vector3}
*/
Vector3.random = function(out, scale) {
vec3.random(out.array, scale);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector3} out
* @param {clay.Vector3} a
* @param {number} scale
* @return {clay.Vector3}
*/
Vector3.scale = function(out, a, scale) {
vec3.scale(out.array, a.array, scale);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector3} out
* @param {clay.Vector3} a
* @param {clay.Vector3} b
* @param {number} scale
* @return {clay.Vector3}
*/
Vector3.scaleAndAdd = function(out, a, b, scale) {
vec3.scaleAndAdd(out.array, a.array, b.array, scale);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector3} a
* @param {clay.Vector3} b
* @return {number}
*/
Vector3.sqrDist = function(a, b) {
return vec3.sqrDist(a.array, b.array);
};
/**
* @function
* @param {clay.Vector3} a
* @param {clay.Vector3} b
* @return {number}
*/
Vector3.squaredDistance = Vector3.sqrDist;
/**
* @param {clay.Vector3} a
* @return {number}
*/
Vector3.sqrLen = function(a) {
return vec3.sqrLen(a.array);
};
/**
* @function
* @param {clay.Vector3} a
* @return {number}
*/
Vector3.squaredLength = Vector3.sqrLen;
/**
* @param {clay.Vector3} out
* @param {clay.Vector3} a
* @param {clay.Vector3} b
* @return {clay.Vector3}
*/
Vector3.sub = function(out, a, b) {
vec3.subtract(out.array, a.array, b.array);
out._dirty = true;
return out;
};
/**
* @function
* @param {clay.Vector3} out
* @param {clay.Vector3} a
* @param {clay.Vector3} b
* @return {clay.Vector3}
*/
Vector3.subtract = Vector3.sub;
/**
* @param {clay.Vector3} out
* @param {clay.Vector3} a
* @param {Matrix3} m
* @return {clay.Vector3}
*/
Vector3.transformMat3 = function(out, a, m) {
vec3.transformMat3(out.array, a.array, m.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector3} out
* @param {clay.Vector3} a
* @param {clay.Matrix4} m
* @return {clay.Vector3}
*/
Vector3.transformMat4 = function(out, a, m) {
vec3.transformMat4(out.array, a.array, m.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector3} out
* @param {clay.Vector3} a
* @param {clay.Quaternion} q
* @return {clay.Vector3}
*/
Vector3.transformQuat = function(out, a, q) {
vec3.transformQuat(out.array, a.array, q.array);
out._dirty = true;
return out;
};
function clamp(val, min, max) {
return val < min ? min : (val > max ? max : val);
}
var atan2 = Math.atan2;
var asin = Math.asin;
var abs = Math.abs;
/**
* Convert quaternion to euler angle
* Quaternion must be normalized
* From three.js
*/
Vector3.eulerFromQuat = function (out, q, order) {
out._dirty = true;
q = q.array;
var target = out.array;
var x = q[0], y = q[1], z = q[2], w = q[3];
var x2 = x * x;
var y2 = y * y;
var z2 = z * z;
var w2 = w * w;
var order = (order || 'XYZ').toUpperCase();
switch (order) {
case 'XYZ':
target[0] = atan2(2 * (x * w - y * z), (w2 - x2 - y2 + z2));
target[1] = asin(clamp(2 * (x * z + y * w), - 1, 1));
target[2] = atan2(2 * (z * w - x * y), (w2 + x2 - y2 - z2));
break;
case 'YXZ':
target[0] = asin(clamp(2 * (x * w - y * z), - 1, 1));
target[1] = atan2(2 * (x * z + y * w), (w2 - x2 - y2 + z2));
target[2] = atan2(2 * (x * y + z * w), (w2 - x2 + y2 - z2));
break;
case 'ZXY':
target[0] = asin(clamp(2 * (x * w + y * z), - 1, 1));
target[1] = atan2(2 * (y * w - z * x), (w2 - x2 - y2 + z2));
target[2] = atan2(2 * (z * w - x * y), (w2 - x2 + y2 - z2));
break;
case 'ZYX':
target[0] = atan2(2 * (x * w + z * y), (w2 - x2 - y2 + z2));
target[1] = asin(clamp(2 * (y * w - x * z), - 1, 1));
target[2] = atan2(2 * (x * y + z * w), (w2 + x2 - y2 - z2));
break;
case 'YZX':
target[0] = atan2(2 * (x * w - z * y), (w2 - x2 + y2 - z2));
target[1] = atan2(2 * (y * w - x * z), (w2 + x2 - y2 - z2));
target[2] = asin(clamp(2 * (x * y + z * w), - 1, 1));
break;
case 'XZY':
target[0] = atan2(2 * (x * w + y * z), (w2 - x2 + y2 - z2));
target[1] = atan2(2 * (x * z + y * w), (w2 + x2 - y2 - z2));
target[2] = asin(clamp(2 * (z * w - x * y), - 1, 1));
break;
default:
console.warn('Unkown order: ' + order);
}
return out;
};
/**
* Convert rotation matrix to euler angle
* from three.js
*/
Vector3.eulerFromMat3 = function (out, m, order) {
// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
var te = m.array;
var m11 = te[0], m12 = te[3], m13 = te[6];
var m21 = te[1], m22 = te[4], m23 = te[7];
var m31 = te[2], m32 = te[5], m33 = te[8];
var target = out.array;
var order = (order || 'XYZ').toUpperCase();
switch (order) {
case 'XYZ':
target[1] = asin(clamp(m13, -1, 1));
if (abs(m13) < 0.99999) {
target[0] = atan2(-m23, m33);
target[2] = atan2(-m12, m11);
}
else {
target[0] = atan2(m32, m22);
target[2] = 0;
}
break;
case 'YXZ':
target[0] = asin(-clamp(m23, -1, 1));
if (abs(m23) < 0.99999) {
target[1] = atan2(m13, m33);
target[2] = atan2(m21, m22);
}
else {
target[1] = atan2(-m31, m11);
target[2] = 0;
}
break;
case 'ZXY':
target[0] = asin(clamp(m32, -1, 1));
if (abs(m32) < 0.99999) {
target[1] = atan2(-m31, m33);
target[2] = atan2(-m12, m22);
}
else {
target[1] = 0;
target[2] = atan2(m21, m11);
}
break;
case 'ZYX':
target[1] = asin(-clamp(m31, -1, 1));
if (abs(m31) < 0.99999) {
target[0] = atan2(m32, m33);
target[2] = atan2(m21, m11);
}
else {
target[0] = 0;
target[2] = atan2(-m12, m22);
}
break;
case 'YZX':
target[2] = asin(clamp(m21, -1, 1));
if (abs(m21) < 0.99999) {
target[0] = atan2(-m23, m22);
target[1] = atan2(-m31, m11);
}
else {
target[0] = 0;
target[1] = atan2(m13, m33);
}
break;
case 'XZY':
target[2] = asin(-clamp(m12, -1, 1));
if (abs(m12) < 0.99999) {
target[0] = atan2(m32, m22);
target[1] = atan2(m13, m11);
}
else {
target[0] = atan2(-m23, m33);
target[1] = 0;
}
break;
default:
console.warn('Unkown order: ' + order);
}
out._dirty = true;
return out;
};
// TODO return new.
/**
* @type {clay.Vector3}
*/
Vector3.POSITIVE_X = new Vector3(1, 0, 0);
/**
* @type {clay.Vector3}
*/
Vector3.NEGATIVE_X = new Vector3(-1, 0, 0);
/**
* @type {clay.Vector3}
*/
Vector3.POSITIVE_Y = new Vector3(0, 1, 0);
/**
* @type {clay.Vector3}
*/
Vector3.NEGATIVE_Y = new Vector3(0, -1, 0);
/**
* @type {clay.Vector3}
*/
Vector3.POSITIVE_Z = new Vector3(0, 0, 1);
/**
* @type {clay.Vector3}
*/
Vector3.NEGATIVE_Z = new Vector3(0, 0, -1);
/**
* @type {clay.Vector3}
*/
Vector3.UP = new Vector3(0, 1, 0);
/**
* @type {clay.Vector3}
*/
Vector3.ZERO = new Vector3(0, 0, 0);
/* harmony default export */ __webpack_exports__["a"] = (Vector3);
/***/ }),
/* 5 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Texture__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_glenum__ = __webpack_require__(11);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__math_util__ = __webpack_require__(67);
var isPowerOfTwo = __WEBPACK_IMPORTED_MODULE_2__math_util__["a" /* default */].isPowerOfTwo;
function nearestPowerOfTwo(val) {
return Math.pow(2, Math.round(Math.log(val) / Math.LN2));
}
function convertTextureToPowerOfTwo(texture, canvas) {
// var canvas = document.createElement('canvas');
var width = nearestPowerOfTwo(texture.width);
var height = nearestPowerOfTwo(texture.height);
canvas = canvas || document.createElement('canvas');
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext('2d');
ctx.drawImage(texture.image, 0, 0, width, height);
return canvas;
}
/**
* @constructor clay.Texture2D
* @extends clay.Texture
*
* @example
* ...
* var mat = new clay.Material({
* shader: clay.shader.library.get('clay.phong', 'diffuseMap')
* });
* var diffuseMap = new clay.Texture2D();
* diffuseMap.load('assets/textures/diffuse.jpg');
* mat.set('diffuseMap', diffuseMap);
* ...
* diffuseMap.success(function () {
* // Wait for the diffuse texture loaded
* animation.on('frame', function (frameTime) {
* renderer.render(scene, camera);
* });
* });
*/
var Texture2D = __WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].extend(function () {
return /** @lends clay.Texture2D# */ {
/**
* @type {?HTMLImageElement|HTMLCanvasElemnet}
*/
image: null,
/**
* Pixels data. Will be ignored if image is set.
* @type {?Uint8Array|Float32Array}
*/
pixels: null,
/**
* @type {Array.}
* @example
* [{
* image: mipmap0,
* pixels: null
* }, {
* image: mipmap1,
* pixels: null
* }, ....]
*/
mipmaps: [],
/**
* If convert texture to power-of-two
* @type {boolean}
*/
convertToPOT: false
};
}, {
textureType: 'texture2D',
update: function (renderer) {
var _gl = renderer.gl;
_gl.bindTexture(_gl.TEXTURE_2D, this._cache.get('webgl_texture'));
this.updateCommon(renderer);
var glFormat = this.format;
var glType = this.type;
// Convert to pot is only available when using image/canvas/video element.
var convertToPOT = !!(this.convertToPOT
&& !this.mipmaps.length && this.image
&& (this.wrapS === __WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].REPEAT || this.wrapT === __WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].REPEAT)
&& this.NPOT
);
_gl.texParameteri(_gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, convertToPOT ? this.wrapS : this.getAvailableWrapS());
_gl.texParameteri(_gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, convertToPOT ? this.wrapT : this.getAvailableWrapT());
_gl.texParameteri(_gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, convertToPOT ? this.magFilter : this.getAvailableMagFilter());
_gl.texParameteri(_gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, convertToPOT ? this.minFilter : this.getAvailableMinFilter());
var anisotropicExt = renderer.getGLExtension('EXT_texture_filter_anisotropic');
if (anisotropicExt && this.anisotropic > 1) {
_gl.texParameterf(_gl.TEXTURE_2D, anisotropicExt.TEXTURE_MAX_ANISOTROPY_EXT, this.anisotropic);
}
// Fallback to float type if browser don't have half float extension
if (glType === 36193) {
var halfFloatExt = renderer.getGLExtension('OES_texture_half_float');
if (!halfFloatExt) {
glType = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].FLOAT;
}
}
if (this.mipmaps.length) {
var width = this.width;
var height = this.height;
for (var i = 0; i < this.mipmaps.length; i++) {
var mipmap = this.mipmaps[i];
this._updateTextureData(_gl, mipmap, i, width, height, glFormat, glType, false);
width /= 2;
height /= 2;
}
}
else {
this._updateTextureData(_gl, this, 0, this.width, this.height, glFormat, glType, convertToPOT);
if (this.useMipmap && (!this.NPOT || convertToPOT)) {
_gl.generateMipmap(_gl.TEXTURE_2D);
}
}
_gl.bindTexture(_gl.TEXTURE_2D, null);
},
_updateTextureData: function (_gl, data, level, width, height, glFormat, glType, convertToPOT) {
if (data.image) {
var imgData = data.image;
if (convertToPOT) {
this._potCanvas = convertTextureToPowerOfTwo(this, this._potCanvas);
imgData = this._potCanvas;
}
_gl.texImage2D(_gl.TEXTURE_2D, level, glFormat, glFormat, glType, imgData);
}
else {
// Can be used as a blank texture when writing render to texture(RTT)
if (
glFormat <= __WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].COMPRESSED_RGBA_S3TC_DXT5_EXT
&& glFormat >= __WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].COMPRESSED_RGB_S3TC_DXT1_EXT
) {
_gl.compressedTexImage2D(_gl.TEXTURE_2D, level, glFormat, width, height, 0, data.pixels);
}
else {
// Is a render target if pixels is null
_gl.texImage2D(_gl.TEXTURE_2D, level, glFormat, width, height, 0, glFormat, glType, data.pixels);
}
}
},
/**
* @param {clay.Renderer} renderer
* @memberOf clay.Texture2D.prototype
*/
generateMipmap: function (renderer) {
var _gl = renderer.gl;
if (this.useMipmap && !this.NPOT) {
_gl.bindTexture(_gl.TEXTURE_2D, this._cache.get('webgl_texture'));
_gl.generateMipmap(_gl.TEXTURE_2D);
}
},
isPowerOfTwo: function () {
return isPowerOfTwo(this.width) && isPowerOfTwo(this.height);
},
isRenderable: function () {
if (this.image) {
return this.image.nodeName === 'CANVAS'
|| this.image.nodeName === 'VIDEO'
|| this.image.complete;
}
else {
return !!(this.width && this.height);
}
},
bind: function (renderer) {
renderer.gl.bindTexture(renderer.gl.TEXTURE_2D, this.getWebGLTexture(renderer));
},
unbind: function (renderer) {
renderer.gl.bindTexture(renderer.gl.TEXTURE_2D, null);
},
load: function (src, crossOrigin) {
var image = new Image();
if (crossOrigin) {
image.crossOrigin = crossOrigin;
}
var self = this;
image.onload = function () {
self.dirty();
self.trigger('success', self);
image.onload = null;
};
image.onerror = function () {
self.trigger('error', self);
image.onerror = null;
};
image.src = src;
this.image = image;
return this;
}
});
Object.defineProperty(Texture2D.prototype, 'width', {
get: function () {
if (this.image) {
return this.image.width;
}
return this._width;
},
set: function (value) {
if (this.image) {
console.warn('Texture from image can\'t set width');
}
else {
if (this._width !== value) {
this.dirty();
}
this._width = value;
}
}
});
Object.defineProperty(Texture2D.prototype, 'height', {
get: function () {
if (this.image) {
return this.image.height;
}
return this._height;
},
set: function (value) {
if (this.image) {
console.warn('Texture from image can\'t set height');
}
else {
if (this._height !== value) {
this.dirty();
}
this._height = value;
}
}
});
/* harmony default export */ __webpack_exports__["a"] = (Texture2D);
/***/ }),
/* 6 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_Base__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_glenum__ = __webpack_require__(11);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__core_Cache__ = __webpack_require__(48);
/**
* Base class for all textures like compressed texture, texture2d, texturecube
* TODO mapping
*/
/**
* @constructor
* @alias clay.Texture
* @extends clay.core.Base
*/
var Texture = __WEBPACK_IMPORTED_MODULE_0__core_Base__["a" /* default */].extend( /** @lends clay.Texture# */ {
/**
* Texture width, readonly when the texture source is image
* @type {number}
*/
width: 512,
/**
* Texture height, readonly when the texture source is image
* @type {number}
*/
height: 512,
/**
* Texel data type.
* Possible values:
* + {@link clay.Texture.UNSIGNED_BYTE}
* + {@link clay.Texture.HALF_FLOAT}
* + {@link clay.Texture.FLOAT}
* + {@link clay.Texture.UNSIGNED_INT_24_8_WEBGL}
* + {@link clay.Texture.UNSIGNED_INT}
* @type {number}
*/
type: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].UNSIGNED_BYTE,
/**
* Format of texel data
* Possible values:
* + {@link clay.Texture.RGBA}
* + {@link clay.Texture.DEPTH_COMPONENT}
* + {@link clay.Texture.DEPTH_STENCIL}
* @type {number}
*/
format: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].RGBA,
/**
* Texture wrap. Default to be REPEAT.
* Possible values:
* + {@link clay.Texture.CLAMP_TO_EDGE}
* + {@link clay.Texture.REPEAT}
* + {@link clay.Texture.MIRRORED_REPEAT}
* @type {number}
*/
wrapS: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].REPEAT,
/**
* Texture wrap. Default to be REPEAT.
* Possible values:
* + {@link clay.Texture.CLAMP_TO_EDGE}
* + {@link clay.Texture.REPEAT}
* + {@link clay.Texture.MIRRORED_REPEAT}
* @type {number}
*/
wrapT: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].REPEAT,
/**
* Possible values:
* + {@link clay.Texture.NEAREST}
* + {@link clay.Texture.LINEAR}
* + {@link clay.Texture.NEAREST_MIPMAP_NEAREST}
* + {@link clay.Texture.LINEAR_MIPMAP_NEAREST}
* + {@link clay.Texture.NEAREST_MIPMAP_LINEAR}
* + {@link clay.Texture.LINEAR_MIPMAP_LINEAR}
* @type {number}
*/
minFilter: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINEAR_MIPMAP_LINEAR,
/**
* Possible values:
* + {@link clay.Texture.NEAREST}
* + {@link clay.Texture.LINEAR}
* @type {number}
*/
magFilter: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINEAR,
/**
* If enable mimap.
* @type {boolean}
*/
useMipmap: true,
/**
* Anisotropic filtering, enabled if value is larger than 1
* @see https://developer.mozilla.org/en-US/docs/Web/API/EXT_texture_filter_anisotropic
* @type {number}
*/
anisotropic: 1,
// pixelStorei parameters, not available when texture is used as render target
// http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml
/**
* If flip in y axis for given image source
* @type {boolean}
* @default true
*/
flipY: true,
/**
* A flag to indicate if texture source is sRGB
*/
sRGB: true,
/**
* @type {number}
* @default 4
*/
unpackAlignment: 4,
/**
* @type {boolean}
* @default false
*/
premultiplyAlpha: false,
/**
* Dynamic option for texture like video
* @type {boolean}
*/
dynamic: false,
NPOT: false,
// PENDING
// Init it here to avoid deoptimization when it's assigned in application dynamically
__used: 0
}, function () {
this._cache = new __WEBPACK_IMPORTED_MODULE_2__core_Cache__["a" /* default */]();
},
/** @lends clay.Texture.prototype */
{
getWebGLTexture: function (renderer) {
var _gl = renderer.gl;
var cache = this._cache;
cache.use(renderer.__uid__);
if (cache.miss('webgl_texture')) {
// In a new gl context, create new texture and set dirty true
cache.put('webgl_texture', _gl.createTexture());
}
if (this.dynamic) {
this.update(renderer);
}
else if (cache.isDirty()) {
this.update(renderer);
cache.fresh();
}
return cache.get('webgl_texture');
},
bind: function () {},
unbind: function () {},
/**
* Mark texture is dirty and update in the next frame
*/
dirty: function () {
if (this._cache) {
this._cache.dirtyAll();
}
},
update: function (renderer) {},
// Update the common parameters of texture
updateCommon: function (renderer) {
var _gl = renderer.gl;
_gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, this.flipY);
_gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this.premultiplyAlpha);
_gl.pixelStorei(_gl.UNPACK_ALIGNMENT, this.unpackAlignment);
// Use of none-power of two texture
// http://www.khronos.org/webgl/wiki/WebGL_and_OpenGL_Differences
if (this.format === __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].DEPTH_COMPONENT) {
this.useMipmap = false;
}
var sRGBExt = renderer.getGLExtension('EXT_sRGB');
// Fallback
if (this.format === Texture.SRGB && !sRGBExt) {
this.format = Texture.RGB;
}
if (this.format === Texture.SRGB_ALPHA && !sRGBExt) {
this.format = Texture.RGBA;
}
this.NPOT = !this.isPowerOfTwo();
},
getAvailableWrapS: function () {
if (this.NPOT) {
return __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].CLAMP_TO_EDGE;
}
return this.wrapS;
},
getAvailableWrapT: function () {
if (this.NPOT) {
return __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].CLAMP_TO_EDGE;
}
return this.wrapT;
},
getAvailableMinFilter: function () {
var minFilter = this.minFilter;
if (this.NPOT || !this.useMipmap) {
if (minFilter === __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].NEAREST_MIPMAP_NEAREST ||
minFilter === __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].NEAREST_MIPMAP_LINEAR
) {
return __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].NEAREST;
}
else if (minFilter === __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINEAR_MIPMAP_LINEAR ||
minFilter === __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINEAR_MIPMAP_NEAREST
) {
return __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINEAR;
}
else {
return minFilter;
}
}
else {
return minFilter;
}
},
getAvailableMagFilter: function () {
return this.magFilter;
},
nextHighestPowerOfTwo: function (x) {
--x;
for (var i = 1; i < 32; i <<= 1) {
x = x | x >> i;
}
return x + 1;
},
/**
* @param {clay.Renderer} renderer
*/
dispose: function (renderer) {
var cache = this._cache;
cache.use(renderer.__uid__);
var webglTexture = cache.get('webgl_texture');
if (webglTexture){
renderer.gl.deleteTexture(webglTexture);
}
cache.deleteContext(renderer.__uid__);
},
/**
* Test if image of texture is valid and loaded.
* @return {boolean}
*/
isRenderable: function () {},
/**
* Test if texture size is power of two
* @return {boolean}
*/
isPowerOfTwo: function () {}
});
Object.defineProperty(Texture.prototype, 'width', {
get: function () {
return this._width;
},
set: function (value) {
this._width = value;
}
});
Object.defineProperty(Texture.prototype, 'height', {
get: function () {
return this._height;
},
set: function (value) {
this._height = value;
}
});
/* DataType */
/**
* @type {number}
*/
Texture.BYTE = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].BYTE;
/**
* @type {number}
*/
Texture.UNSIGNED_BYTE = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].UNSIGNED_BYTE;
/**
* @type {number}
*/
Texture.SHORT = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].SHORT;
/**
* @type {number}
*/
Texture.UNSIGNED_SHORT = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].UNSIGNED_SHORT;
/**
* @type {number}
*/
Texture.INT = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].INT;
/**
* @type {number}
*/
Texture.UNSIGNED_INT = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].UNSIGNED_INT;
/**
* @type {number}
*/
Texture.FLOAT = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].FLOAT;
/**
* @type {number}
*/
Texture.HALF_FLOAT = 0x8D61;
/**
* UNSIGNED_INT_24_8_WEBGL for WEBGL_depth_texture extension
* @type {number}
*/
Texture.UNSIGNED_INT_24_8_WEBGL = 34042;
/* PixelFormat */
/**
* @type {number}
*/
Texture.DEPTH_COMPONENT = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].DEPTH_COMPONENT;
/**
* @type {number}
*/
Texture.DEPTH_STENCIL = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].DEPTH_STENCIL;
/**
* @type {number}
*/
Texture.ALPHA = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].ALPHA;
/**
* @type {number}
*/
Texture.RGB = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].RGB;
/**
* @type {number}
*/
Texture.RGBA = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].RGBA;
/**
* @type {number}
*/
Texture.LUMINANCE = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LUMINANCE;
/**
* @type {number}
*/
Texture.LUMINANCE_ALPHA = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LUMINANCE_ALPHA;
/**
* @see https://www.khronos.org/registry/webgl/extensions/EXT_sRGB/
* @type {number}
*/
Texture.SRGB = 0x8C40;
/**
* @see https://www.khronos.org/registry/webgl/extensions/EXT_sRGB/
* @type {number}
*/
Texture.SRGB_ALPHA = 0x8C42;
/* Compressed Texture */
Texture.COMPRESSED_RGB_S3TC_DXT1_EXT = 0x83F0;
Texture.COMPRESSED_RGBA_S3TC_DXT1_EXT = 0x83F1;
Texture.COMPRESSED_RGBA_S3TC_DXT3_EXT = 0x83F2;
Texture.COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3;
/* TextureMagFilter */
/**
* @type {number}
*/
Texture.NEAREST = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].NEAREST;
/**
* @type {number}
*/
Texture.LINEAR = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINEAR;
/* TextureMinFilter */
/**
* @type {number}
*/
Texture.NEAREST_MIPMAP_NEAREST = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].NEAREST_MIPMAP_NEAREST;
/**
* @type {number}
*/
Texture.LINEAR_MIPMAP_NEAREST = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINEAR_MIPMAP_NEAREST;
/**
* @type {number}
*/
Texture.NEAREST_MIPMAP_LINEAR = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].NEAREST_MIPMAP_LINEAR;
/**
* @type {number}
*/
Texture.LINEAR_MIPMAP_LINEAR = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINEAR_MIPMAP_LINEAR;
/* TextureWrapMode */
/**
* @type {number}
*/
Texture.REPEAT = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].REPEAT;
/**
* @type {number}
*/
Texture.CLAMP_TO_EDGE = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].CLAMP_TO_EDGE;
/**
* @type {number}
*/
Texture.MIRRORED_REPEAT = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].MIRRORED_REPEAT;
/* harmony default export */ __webpack_exports__["a"] = (Texture);
/***/ }),
/* 7 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0__dep_glmatrix__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Vector3__ = __webpack_require__(4);
var mat4 = __WEBPACK_IMPORTED_MODULE_0__dep_glmatrix___default.a.mat4;
var vec3 = __WEBPACK_IMPORTED_MODULE_0__dep_glmatrix___default.a.vec3;
var mat3 = __WEBPACK_IMPORTED_MODULE_0__dep_glmatrix___default.a.mat3;
var quat = __WEBPACK_IMPORTED_MODULE_0__dep_glmatrix___default.a.quat;
/**
* @constructor
* @alias clay.Matrix4
*/
var Matrix4 = function() {
this._axisX = new __WEBPACK_IMPORTED_MODULE_1__Vector3__["a" /* default */]();
this._axisY = new __WEBPACK_IMPORTED_MODULE_1__Vector3__["a" /* default */]();
this._axisZ = new __WEBPACK_IMPORTED_MODULE_1__Vector3__["a" /* default */]();
/**
* Storage of Matrix4
* @name array
* @type {Float32Array}
* @memberOf clay.Matrix4#
*/
this.array = mat4.create();
/**
* @name _dirty
* @type {boolean}
* @memberOf clay.Matrix4#
*/
this._dirty = true;
};
Matrix4.prototype = {
constructor: Matrix4,
/**
* Set components from array
* @param {Float32Array|number[]} arr
*/
setArray: function (arr) {
for (var i = 0; i < this.array.length; i++) {
this.array[i] = arr[i];
}
this._dirty = true;
return this;
},
/**
* Calculate the adjugate of self, in-place
* @return {clay.Matrix4}
*/
adjoint: function() {
mat4.adjoint(this.array, this.array);
this._dirty = true;
return this;
},
/**
* Clone a new Matrix4
* @return {clay.Matrix4}
*/
clone: function() {
return (new Matrix4()).copy(this);
},
/**
* Copy from b
* @param {clay.Matrix4} b
* @return {clay.Matrix4}
*/
copy: function(a) {
mat4.copy(this.array, a.array);
this._dirty = true;
return this;
},
/**
* Calculate matrix determinant
* @return {number}
*/
determinant: function() {
return mat4.determinant(this.array);
},
/**
* Set upper 3x3 part from quaternion
* @param {clay.Quaternion} q
* @return {clay.Matrix4}
*/
fromQuat: function(q) {
mat4.fromQuat(this.array, q.array);
this._dirty = true;
return this;
},
/**
* Set from a quaternion rotation and a vector translation
* @param {clay.Quaternion} q
* @param {clay.Vector3} v
* @return {clay.Matrix4}
*/
fromRotationTranslation: function(q, v) {
mat4.fromRotationTranslation(this.array, q.array, v.array);
this._dirty = true;
return this;
},
/**
* Set from Matrix2d, it is used when converting a 2d shape to 3d space.
* In 3d space it is equivalent to ranslate on xy plane and rotate about z axis
* @param {clay.Matrix2d} m2d
* @return {clay.Matrix4}
*/
fromMat2d: function(m2d) {
Matrix4.fromMat2d(this, m2d);
return this;
},
/**
* Set from frustum bounds
* @param {number} left
* @param {number} right
* @param {number} bottom
* @param {number} top
* @param {number} near
* @param {number} far
* @return {clay.Matrix4}
*/
frustum: function (left, right, bottom, top, near, far) {
mat4.frustum(this.array, left, right, bottom, top, near, far);
this._dirty = true;
return this;
},
/**
* Set to a identity matrix
* @return {clay.Matrix4}
*/
identity: function() {
mat4.identity(this.array);
this._dirty = true;
return this;
},
/**
* Invert self
* @return {clay.Matrix4}
*/
invert: function() {
mat4.invert(this.array, this.array);
this._dirty = true;
return this;
},
/**
* Set as a matrix with the given eye position, focal point, and up axis
* @param {clay.Vector3} eye
* @param {clay.Vector3} center
* @param {clay.Vector3} up
* @return {clay.Matrix4}
*/
lookAt: function(eye, center, up) {
mat4.lookAt(this.array, eye.array, center.array, up.array);
this._dirty = true;
return this;
},
/**
* Alias for mutiply
* @param {clay.Matrix4} b
* @return {clay.Matrix4}
*/
mul: function(b) {
mat4.mul(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Alias for multiplyLeft
* @param {clay.Matrix4} a
* @return {clay.Matrix4}
*/
mulLeft: function(a) {
mat4.mul(this.array, a.array, this.array);
this._dirty = true;
return this;
},
/**
* Multiply self and b
* @param {clay.Matrix4} b
* @return {clay.Matrix4}
*/
multiply: function(b) {
mat4.multiply(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Multiply a and self, a is on the left
* @param {clay.Matrix3} a
* @return {clay.Matrix3}
*/
multiplyLeft: function(a) {
mat4.multiply(this.array, a.array, this.array);
this._dirty = true;
return this;
},
/**
* Set as a orthographic projection matrix
* @param {number} left
* @param {number} right
* @param {number} bottom
* @param {number} top
* @param {number} near
* @param {number} far
* @return {clay.Matrix4}
*/
ortho: function(left, right, bottom, top, near, far) {
mat4.ortho(this.array, left, right, bottom, top, near, far);
this._dirty = true;
return this;
},
/**
* Set as a perspective projection matrix
* @param {number} fovy
* @param {number} aspect
* @param {number} near
* @param {number} far
* @return {clay.Matrix4}
*/
perspective: function(fovy, aspect, near, far) {
mat4.perspective(this.array, fovy, aspect, near, far);
this._dirty = true;
return this;
},
/**
* Rotate self by rad about axis.
* Equal to right-multiply a rotaion matrix
* @param {number} rad
* @param {clay.Vector3} axis
* @return {clay.Matrix4}
*/
rotate: function(rad, axis) {
mat4.rotate(this.array, this.array, rad, axis.array);
this._dirty = true;
return this;
},
/**
* Rotate self by a given radian about X axis.
* Equal to right-multiply a rotaion matrix
* @param {number} rad
* @return {clay.Matrix4}
*/
rotateX: function(rad) {
mat4.rotateX(this.array, this.array, rad);
this._dirty = true;
return this;
},
/**
* Rotate self by a given radian about Y axis.
* Equal to right-multiply a rotaion matrix
* @param {number} rad
* @return {clay.Matrix4}
*/
rotateY: function(rad) {
mat4.rotateY(this.array, this.array, rad);
this._dirty = true;
return this;
},
/**
* Rotate self by a given radian about Z axis.
* Equal to right-multiply a rotaion matrix
* @param {number} rad
* @return {clay.Matrix4}
*/
rotateZ: function(rad) {
mat4.rotateZ(this.array, this.array, rad);
this._dirty = true;
return this;
},
/**
* Scale self by s
* Equal to right-multiply a scale matrix
* @param {clay.Vector3} s
* @return {clay.Matrix4}
*/
scale: function(v) {
mat4.scale(this.array, this.array, v.array);
this._dirty = true;
return this;
},
/**
* Translate self by v.
* Equal to right-multiply a translate matrix
* @param {clay.Vector3} v
* @return {clay.Matrix4}
*/
translate: function(v) {
mat4.translate(this.array, this.array, v.array);
this._dirty = true;
return this;
},
/**
* Transpose self, in-place.
* @return {clay.Matrix2}
*/
transpose: function() {
mat4.transpose(this.array, this.array);
this._dirty = true;
return this;
},
/**
* Decompose a matrix to SRT
* @param {clay.Vector3} [scale]
* @param {clay.Quaternion} rotation
* @param {clay.Vector} position
* @see http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.matrix.decompose.aspx
*/
decomposeMatrix: (function() {
var x = vec3.create();
var y = vec3.create();
var z = vec3.create();
var m3 = mat3.create();
return function(scale, rotation, position) {
var el = this.array;
vec3.set(x, el[0], el[1], el[2]);
vec3.set(y, el[4], el[5], el[6]);
vec3.set(z, el[8], el[9], el[10]);
var sx = vec3.length(x);
var sy = vec3.length(y);
var sz = vec3.length(z);
// if determine is negative, we need to invert one scale
var det = this.determinant();
if (det < 0) {
sx = -sx;
}
if (scale) {
scale.set(sx, sy, sz);
}
position.set(el[12], el[13], el[14]);
mat3.fromMat4(m3, el);
// Not like mat4, mat3 in glmatrix seems to be row-based
// Seems fixed in gl-matrix 2.2.2
// https://github.com/toji/gl-matrix/issues/114
// mat3.transpose(m3, m3);
m3[0] /= sx;
m3[1] /= sx;
m3[2] /= sx;
m3[3] /= sy;
m3[4] /= sy;
m3[5] /= sy;
m3[6] /= sz;
m3[7] /= sz;
m3[8] /= sz;
quat.fromMat3(rotation.array, m3);
quat.normalize(rotation.array, rotation.array);
rotation._dirty = true;
position._dirty = true;
};
})(),
toString: function() {
return '[' + Array.prototype.join.call(this.array, ',') + ']';
},
toArray: function () {
return Array.prototype.slice.call(this.array);
}
};
var defineProperty = Object.defineProperty;
if (defineProperty) {
var proto = Matrix4.prototype;
/**
* Z Axis of local transform
* @name z
* @type {clay.Vector3}
* @memberOf clay.Matrix4
* @instance
*/
defineProperty(proto, 'z', {
get: function () {
var el = this.array;
this._axisZ.set(el[8], el[9], el[10]);
return this._axisZ;
},
set: function (v) {
// TODO Here has a problem
// If only set an item of vector will not work
var el = this.array;
v = v.array;
el[8] = v[0];
el[9] = v[1];
el[10] = v[2];
this._dirty = true;
}
});
/**
* Y Axis of local transform
* @name y
* @type {clay.Vector3}
* @memberOf clay.Matrix4
* @instance
*/
defineProperty(proto, 'y', {
get: function () {
var el = this.array;
this._axisY.set(el[4], el[5], el[6]);
return this._axisY;
},
set: function (v) {
var el = this.array;
v = v.array;
el[4] = v[0];
el[5] = v[1];
el[6] = v[2];
this._dirty = true;
}
});
/**
* X Axis of local transform
* @name x
* @type {clay.Vector3}
* @memberOf clay.Matrix4
* @instance
*/
defineProperty(proto, 'x', {
get: function () {
var el = this.array;
this._axisX.set(el[0], el[1], el[2]);
return this._axisX;
},
set: function (v) {
var el = this.array;
v = v.array;
el[0] = v[0];
el[1] = v[1];
el[2] = v[2];
this._dirty = true;
}
})
}
/**
* @param {clay.Matrix4} out
* @param {clay.Matrix4} a
* @return {clay.Matrix4}
*/
Matrix4.adjoint = function(out, a) {
mat4.adjoint(out.array, a.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix4} out
* @param {clay.Matrix4} a
* @return {clay.Matrix4}
*/
Matrix4.copy = function(out, a) {
mat4.copy(out.array, a.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix4} a
* @return {number}
*/
Matrix4.determinant = function(a) {
return mat4.determinant(a.array);
};
/**
* @param {clay.Matrix4} out
* @return {clay.Matrix4}
*/
Matrix4.identity = function(out) {
mat4.identity(out.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix4} out
* @param {number} left
* @param {number} right
* @param {number} bottom
* @param {number} top
* @param {number} near
* @param {number} far
* @return {clay.Matrix4}
*/
Matrix4.ortho = function(out, left, right, bottom, top, near, far) {
mat4.ortho(out.array, left, right, bottom, top, near, far);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix4} out
* @param {number} fovy
* @param {number} aspect
* @param {number} near
* @param {number} far
* @return {clay.Matrix4}
*/
Matrix4.perspective = function(out, fovy, aspect, near, far) {
mat4.perspective(out.array, fovy, aspect, near, far);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix4} out
* @param {clay.Vector3} eye
* @param {clay.Vector3} center
* @param {clay.Vector3} up
* @return {clay.Matrix4}
*/
Matrix4.lookAt = function(out, eye, center, up) {
mat4.lookAt(out.array, eye.array, center.array, up.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix4} out
* @param {clay.Matrix4} a
* @return {clay.Matrix4}
*/
Matrix4.invert = function(out, a) {
mat4.invert(out.array, a.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix4} out
* @param {clay.Matrix4} a
* @param {clay.Matrix4} b
* @return {clay.Matrix4}
*/
Matrix4.mul = function(out, a, b) {
mat4.mul(out.array, a.array, b.array);
out._dirty = true;
return out;
};
/**
* @function
* @param {clay.Matrix4} out
* @param {clay.Matrix4} a
* @param {clay.Matrix4} b
* @return {clay.Matrix4}
*/
Matrix4.multiply = Matrix4.mul;
/**
* @param {clay.Matrix4} out
* @param {clay.Quaternion} q
* @return {clay.Matrix4}
*/
Matrix4.fromQuat = function(out, q) {
mat4.fromQuat(out.array, q.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix4} out
* @param {clay.Quaternion} q
* @param {clay.Vector3} v
* @return {clay.Matrix4}
*/
Matrix4.fromRotationTranslation = function(out, q, v) {
mat4.fromRotationTranslation(out.array, q.array, v.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix4} m4
* @param {clay.Matrix2d} m2d
* @return {clay.Matrix4}
*/
Matrix4.fromMat2d = function(m4, m2d) {
m4._dirty = true;
var m2d = m2d.array;
var m4 = m4.array;
m4[0] = m2d[0];
m4[4] = m2d[2];
m4[12] = m2d[4];
m4[1] = m2d[1];
m4[5] = m2d[3];
m4[13] = m2d[5];
return m4;
};
/**
* @param {clay.Matrix4} out
* @param {clay.Matrix4} a
* @param {number} rad
* @param {clay.Vector3} axis
* @return {clay.Matrix4}
*/
Matrix4.rotate = function(out, a, rad, axis) {
mat4.rotate(out.array, a.array, rad, axis.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix4} out
* @param {clay.Matrix4} a
* @param {number} rad
* @return {clay.Matrix4}
*/
Matrix4.rotateX = function(out, a, rad) {
mat4.rotateX(out.array, a.array, rad);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix4} out
* @param {clay.Matrix4} a
* @param {number} rad
* @return {clay.Matrix4}
*/
Matrix4.rotateY = function(out, a, rad) {
mat4.rotateY(out.array, a.array, rad);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix4} out
* @param {clay.Matrix4} a
* @param {number} rad
* @return {clay.Matrix4}
*/
Matrix4.rotateZ = function(out, a, rad) {
mat4.rotateZ(out.array, a.array, rad);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix4} out
* @param {clay.Matrix4} a
* @param {clay.Vector3} v
* @return {clay.Matrix4}
*/
Matrix4.scale = function(out, a, v) {
mat4.scale(out.array, a.array, v.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix4} out
* @param {clay.Matrix4} a
* @return {clay.Matrix4}
*/
Matrix4.transpose = function(out, a) {
mat4.transpose(out.array, a.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix4} out
* @param {clay.Matrix4} a
* @param {clay.Vector3} v
* @return {clay.Matrix4}
*/
Matrix4.translate = function(out, a, v) {
mat4.translate(out.array, a.array, v.array);
out._dirty = true;
return out;
};
/* harmony default export */ __webpack_exports__["a"] = (Matrix4);
/***/ }),
/* 8 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_util__ = __webpack_require__(20);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_vendor__ = __webpack_require__(18);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2__dep_glmatrix__);
/**
* Mainly do the parse and compile of shader string
* Support shader code chunk import and export
* Support shader semantics
* http://www.nvidia.com/object/using_sas.html
* https://github.com/KhronosGroup/collada2json/issues/45
*
* TODO: Use etpl or other string template engine
*/
var mat2 = __WEBPACK_IMPORTED_MODULE_2__dep_glmatrix___default.a.mat2;
var mat3 = __WEBPACK_IMPORTED_MODULE_2__dep_glmatrix___default.a.mat3;
var mat4 = __WEBPACK_IMPORTED_MODULE_2__dep_glmatrix___default.a.mat4;
var uniformRegex = /uniform\s+(bool|float|int|vec2|vec3|vec4|ivec2|ivec3|ivec4|mat2|mat3|mat4|sampler2D|samplerCube)\s+([\s\S]*?);/g;
var attributeRegex = /attribute\s+(float|int|vec2|vec3|vec4)\s+([\s\S]*?);/g;
var defineRegex = /#define\s+(\w+)?(\s+[\w-.]+)?\s*;?\s*\n/g;
var uniformTypeMap = {
'bool': '1i',
'int': '1i',
'sampler2D': 't',
'samplerCube': 't',
'float': '1f',
'vec2': '2f',
'vec3': '3f',
'vec4': '4f',
'ivec2': '2i',
'ivec3': '3i',
'ivec4': '4i',
'mat2': 'm2',
'mat3': 'm3',
'mat4': 'm4'
};
var uniformValueConstructor = {
'bool': function () { return true; },
'int': function () { return 0; },
'float': function () { return 0; },
'sampler2D': function () { return null; },
'samplerCube': function () { return null; },
'vec2': function () { return [0, 0]; },
'vec3': function () { return [0, 0, 0]; },
'vec4': function () { return [0, 0, 0, 0]; },
'ivec2': function () { return [0, 0]; },
'ivec3': function () { return [0, 0, 0]; },
'ivec4': function () { return [0, 0, 0, 0]; },
'mat2': function () { return mat2.create(); },
'mat3': function () { return mat3.create(); },
'mat4': function () { return mat4.create(); },
'array': function () { return []; }
};
var attributeSemantics = [
'POSITION',
'NORMAL',
'BINORMAL',
'TANGENT',
'TEXCOORD',
'TEXCOORD_0',
'TEXCOORD_1',
'COLOR',
// Skinning
// https://github.com/KhronosGroup/glTF/blob/master/specification/README.md#semantics
'JOINT',
'WEIGHT'
];
var uniformSemantics = [
'SKIN_MATRIX',
// Information about viewport
'VIEWPORT_SIZE',
'VIEWPORT',
'DEVICEPIXELRATIO',
// Window size for window relative coordinate
// https://www.opengl.org/sdk/docs/man/html/gl_FragCoord.xhtml
'WINDOW_SIZE',
// Infomation about camera
'NEAR',
'FAR',
// Time
'TIME'
];
var matrixSemantics = [
'WORLD',
'VIEW',
'PROJECTION',
'WORLDVIEW',
'VIEWPROJECTION',
'WORLDVIEWPROJECTION',
'WORLDINVERSE',
'VIEWINVERSE',
'PROJECTIONINVERSE',
'WORLDVIEWINVERSE',
'VIEWPROJECTIONINVERSE',
'WORLDVIEWPROJECTIONINVERSE',
'WORLDTRANSPOSE',
'VIEWTRANSPOSE',
'PROJECTIONTRANSPOSE',
'WORLDVIEWTRANSPOSE',
'VIEWPROJECTIONTRANSPOSE',
'WORLDVIEWPROJECTIONTRANSPOSE',
'WORLDINVERSETRANSPOSE',
'VIEWINVERSETRANSPOSE',
'PROJECTIONINVERSETRANSPOSE',
'WORLDVIEWINVERSETRANSPOSE',
'VIEWPROJECTIONINVERSETRANSPOSE',
'WORLDVIEWPROJECTIONINVERSETRANSPOSE'
];
var attributeSizeMap = {
// WebGL does not support integer attributes
'vec4': 4,
'vec3': 3,
'vec2': 2,
'float': 1
};
var shaderIDCache = {};
var shaderCodeCache = {};
function getShaderID(vertex, fragment) {
var key = 'vertex:' + vertex + 'fragment:' + fragment;
if (shaderIDCache[key]) {
return shaderIDCache[key];
}
var id = __WEBPACK_IMPORTED_MODULE_0__core_util__["a" /* default */].genGUID();
shaderIDCache[key] = id;
shaderCodeCache[id] = {
vertex: vertex,
fragment: fragment
};
return id;
}
function removeComment(code) {
return code.replace(/[ \t]*\/\/.*\n/g, '' ) // remove //
.replace(/[ \t]*\/\*[\s\S]*?\*\//g, '' ); // remove /* */
}
function logSyntaxError() {
console.error('Wrong uniform/attributes syntax');
}
function parseDeclarations(type, line) {
var speratorsRegexp = /[,=\(\):]/;
var tokens = line
// Convert `symbol: [1,2,3]` to `symbol: vec3(1,2,3)`
.replace(/:\s*\[\s*(.*)\s*\]/g, '=' + type + '($1)')
.replace(/\s+/g, '')
.split(/(?=[,=\(\):])/g);
var newTokens = [];
for (var i = 0; i < tokens.length; i++) {
if (tokens[i].match(speratorsRegexp)) {
newTokens.push(
tokens[i].charAt(0),
tokens[i].slice(1)
);
}
else {
newTokens.push(tokens[i]);
}
}
tokens = newTokens;
var TYPE_SYMBOL = 0;
var TYPE_ASSIGN = 1;
var TYPE_VEC = 2;
var TYPE_ARR = 3;
var TYPE_SEMANTIC = 4;
var TYPE_NORMAL = 5;
var opType = TYPE_SYMBOL;
var declarations = {};
var declarationValue = null;
var currentDeclaration;
addSymbol(tokens[0]);
function addSymbol(symbol) {
if (!symbol) {
logSyntaxError();
}
var arrResult = symbol.match(/\[(.*?)\]/);
currentDeclaration = symbol.replace(/\[(.*?)\]/, '');
declarations[currentDeclaration] = {};
if (arrResult) {
declarations[currentDeclaration].isArray = true;
declarations[currentDeclaration].arraySize = arrResult[1];
}
}
for (var i = 1; i < tokens.length; i++) {
var token = tokens[i];
if (!token) { // Empty token;
continue;
}
if (token === '=') {
if (opType !== TYPE_SYMBOL
&& opType !== TYPE_ARR) {
logSyntaxError();
break;
}
opType = TYPE_ASSIGN;
continue;
}
else if (token === ':') {
opType = TYPE_SEMANTIC;
continue;
}
else if (token === ',') {
if (opType === TYPE_VEC) {
if (!(declarationValue instanceof Array)) {
logSyntaxError();
break;
}
declarationValue.push(+tokens[++i]);
}
else {
opType = TYPE_NORMAL;
}
continue;
}
else if (token === ')') {
declarations[currentDeclaration].value = new __WEBPACK_IMPORTED_MODULE_1__core_vendor__["a" /* default */].Float32Array(declarationValue);
declarationValue = null;
opType = TYPE_NORMAL;
continue;
}
else if (token === '(') {
if (opType !== TYPE_VEC) {
logSyntaxError();
break;
}
if (!(declarationValue instanceof Array)) {
logSyntaxError();
break;
}
declarationValue.push(+tokens[++i]);
continue;
}
else if (token.indexOf('vec') >= 0) {
if (opType !== TYPE_ASSIGN
// Compatitable with old syntax `symbol: [1,2,3]`
&& opType !== TYPE_SEMANTIC) {
logSyntaxError();
break;
}
opType = TYPE_VEC;
declarationValue = [];
continue;
}
else if (opType === TYPE_ASSIGN) {
if (type === 'bool') {
declarations[currentDeclaration].value = token === 'true';
}
else {
declarations[currentDeclaration].value = parseFloat(token);
}
declarationValue = null;
continue;
}
else if (opType === TYPE_SEMANTIC) {
var semantic = token;
if (attributeSemantics.indexOf(semantic) >= 0
|| uniformSemantics.indexOf(semantic) >= 0
|| matrixSemantics.indexOf(semantic) >= 0
) {
declarations[currentDeclaration].semantic = semantic;
}
else if (semantic === 'ignore' || semantic === 'unconfigurable') {
declarations[currentDeclaration].ignore = true;
}
else {
// Try to parse as a default tvalue.
if (type === 'bool') {
declarations[currentDeclaration].value = semantic === 'true';
}
else {
declarations[currentDeclaration].value = parseFloat(semantic);
}
}
continue;
}
// treat as symbol.
addSymbol(token);
opType = TYPE_SYMBOL;
}
return declarations;
}
/**
* @constructor
* @extends clay.core.Base
* @alias clay.Shader
* @param {string} vertex
* @param {string} fragment
* @example
* // Create a phong shader
* var shader = new clay.Shader(
* clay.Shader.source('clay.standard.vertex'),
* clay.Shader.source('clay.standard.fragment')
* );
*/
function Shader(vertex, fragment) {
// First argument can be { vertex, fragment }
if (typeof vertex === 'object') {
fragment = vertex.fragment;
vertex = vertex.vertex;
}
vertex = removeComment(vertex);
fragment = removeComment(fragment);
this._shaderID = getShaderID(vertex, fragment);
this._vertexCode = Shader.parseImport(vertex);
this._fragmentCode = Shader.parseImport(fragment);
/**
* @readOnly
*/
this.attributeSemantics = {};
/**
* @readOnly
*/
this.matrixSemantics = {};
/**
* @readOnly
*/
this.uniformSemantics = {};
/**
* @readOnly
*/
this.matrixSemanticKeys = [];
/**
* @readOnly
*/
this.uniformTemplates = {};
/**
* @readOnly
*/
this.attributes = {};
/**
* @readOnly
*/
this.textures = {};
/**
* @readOnly
*/
this.vertexDefines = {};
/**
* @readOnly
*/
this.fragmentDefines = {};
this._parseAttributes();
this._parseUniforms();
this._parseDefines();
}
Shader.prototype = {
constructor: Shader,
// Create a new uniform instance for material
createUniforms: function () {
var uniforms = {};
for (var symbol in this.uniformTemplates){
var uniformTpl = this.uniformTemplates[symbol];
uniforms[symbol] = {
type: uniformTpl.type,
value: uniformTpl.value()
};
}
return uniforms;
},
_parseImport: function () {
this._vertexCode = Shader.parseImport(this.vertex);
this._fragmentCode = Shader.parseImport(this.fragment);
},
_addSemanticUniform: function (symbol, uniformType, semantic) {
// This case is only for SKIN_MATRIX
// TODO
if (attributeSemantics.indexOf(semantic) >= 0) {
this.attributeSemantics[semantic] = {
symbol: symbol,
type: uniformType
};
}
else if (matrixSemantics.indexOf(semantic) >= 0) {
var isTranspose = false;
var semanticNoTranspose = semantic;
if (semantic.match(/TRANSPOSE$/)) {
isTranspose = true;
semanticNoTranspose = semantic.slice(0, -9);
}
this.matrixSemantics[semantic] = {
symbol: symbol,
type: uniformType,
isTranspose: isTranspose,
semanticNoTranspose: semanticNoTranspose
};
}
else if (uniformSemantics.indexOf(semantic) >= 0) {
this.uniformSemantics[semantic] = {
symbol: symbol,
type: uniformType
};
}
},
_addMaterialUniform: function (symbol, type, uniformType, defaultValueFunc, isArray, materialUniforms) {
materialUniforms[symbol] = {
type: uniformType,
value: isArray ? uniformValueConstructor['array'] : (defaultValueFunc || uniformValueConstructor[type]),
semantic: null
};
},
_parseUniforms: function () {
var uniforms = {};
var self = this;
var shaderType = 'vertex';
this._uniformList = [];
this._vertexCode = this._vertexCode.replace(uniformRegex, _uniformParser);
shaderType = 'fragment';
this._fragmentCode = this._fragmentCode.replace(uniformRegex, _uniformParser);
self.matrixSemanticKeys = Object.keys(this.matrixSemantics);
function makeDefaultValueFunc(value) {
return value != null ? function () { return value; } : null;
}
function _uniformParser(str, type, content) {
var declaredUniforms = parseDeclarations(type, content);
var uniformMainStr = [];
for (var symbol in declaredUniforms) {
var uniformInfo = declaredUniforms[symbol];
var semantic = uniformInfo.semantic;
var tmpStr = symbol;
var uniformType = uniformTypeMap[type];
var defaultValueFunc = makeDefaultValueFunc(declaredUniforms[symbol].value);
if (declaredUniforms[symbol].isArray) {
tmpStr += '[' + declaredUniforms[symbol].arraySize + ']';
uniformType += 'v';
}
uniformMainStr.push(tmpStr);
self._uniformList.push(symbol);
if (!uniformInfo.ignore) {
if (type === 'sampler2D' || type === 'samplerCube') {
// Texture is default disabled
self.textures[symbol] = {
shaderType: shaderType,
type: type
};
}
if (semantic) {
// TODO Should not declare multiple symbols if have semantic.
self._addSemanticUniform(symbol, uniformType, semantic);
}
else {
self._addMaterialUniform(
symbol, type, uniformType, defaultValueFunc,
declaredUniforms[symbol].isArray, uniforms
);
}
}
}
return uniformMainStr.length > 0
? 'uniform ' + type + ' ' + uniformMainStr.join(',') + ';\n' : '';
}
this.uniformTemplates = uniforms;
},
_parseAttributes: function () {
var attributes = {};
var self = this;
this._vertexCode = this._vertexCode.replace(attributeRegex, _attributeParser);
function _attributeParser(str, type, content) {
var declaredAttributes = parseDeclarations(type, content);
var size = attributeSizeMap[type] || 1;
var attributeMainStr = [];
for (var symbol in declaredAttributes) {
var semantic = declaredAttributes[symbol].semantic;
attributes[symbol] = {
// TODO Can only be float
type: 'float',
size: size,
semantic: semantic || null
};
// TODO Should not declare multiple symbols if have semantic.
if (semantic) {
if (attributeSemantics.indexOf(semantic) < 0) {
throw new Error('Unkown semantic "' + semantic + '"');
}
else {
self.attributeSemantics[semantic] = {
symbol: symbol,
type: type
};
}
}
attributeMainStr.push(symbol);
}
return 'attribute ' + type + ' ' + attributeMainStr.join(',') + ';\n';
}
this.attributes = attributes;
},
_parseDefines: function () {
var self = this;
var shaderType = 'vertex';
this._vertexCode = this._vertexCode.replace(defineRegex, _defineParser);
shaderType = 'fragment';
this._fragmentCode = this._fragmentCode.replace(defineRegex, _defineParser);
function _defineParser(str, symbol, value) {
var defines = shaderType === 'vertex' ? self.vertexDefines : self.fragmentDefines;
if (!defines[symbol]) { // Haven't been defined by user
if (value === 'false') {
defines[symbol] = false;
}
else if (value === 'true') {
defines[symbol] = true;
}
else {
defines[symbol] = value
// If can parse to float
? (isNaN(parseFloat(value)) ? value.trim() : parseFloat(value))
: null;
}
}
return '';
}
},
/**
* Clone a new shader
* @return {clay.Shader}
*/
clone: function () {
var code = shaderCodeCache[this._shaderID];
var shader = new Shader(code.vertex, code.fragment);
return shader;
}
};
if (Object.defineProperty) {
Object.defineProperty(Shader.prototype, 'shaderID', {
get: function () {
return this._shaderID;
}
});
Object.defineProperty(Shader.prototype, 'vertex', {
get: function () {
return this._vertexCode;
}
});
Object.defineProperty(Shader.prototype, 'fragment', {
get: function () {
return this._fragmentCode;
}
});
Object.defineProperty(Shader.prototype, 'uniforms', {
get: function () {
return this._uniformList;
}
});
}
var importRegex = /(@import)\s*([0-9a-zA-Z_\-\.]*)/g;
Shader.parseImport = function (shaderStr) {
shaderStr = shaderStr.replace(importRegex, function (str, importSymbol, importName) {
var str = Shader.source(importName);
if (str) {
// Recursively parse
return Shader.parseImport(str);
}
else {
console.error('Shader chunk "' + importName + '" not existed in library');
return '';
}
});
return shaderStr;
};
var exportRegex = /(@export)\s*([0-9a-zA-Z_\-\.]*)\s*\n([\s\S]*?)@end/g;
/**
* Import shader source
* @param {string} shaderStr
* @memberOf clay.Shader
*/
Shader['import'] = function (shaderStr) {
shaderStr.replace(exportRegex, function (str, exportSymbol, exportName, code) {
var code = code.replace(/(^[\s\t\xa0\u3000]+)|([\u3000\xa0\s\t]+\x24)/g, '');
if (code) {
var parts = exportName.split('.');
var obj = Shader.codes;
var i = 0;
var key;
while (i < parts.length - 1) {
key = parts[i++];
if (!obj[key]) {
obj[key] = {};
}
obj = obj[key];
}
key = parts[i];
obj[key] = code;
}
return code;
});
};
/**
* Library to store all the loaded shader codes
* @type {Object}
* @readOnly
* @memberOf clay.Shader
*/
Shader.codes = {};
/**
* Get shader source
* @param {string} name
* @return {string}
*/
Shader.source = function (name) {
var parts = name.split('.');
var obj = Shader.codes;
var i = 0;
while (obj && i < parts.length) {
var key = parts[i++];
obj = obj[key];
}
if (typeof obj !== 'string') {
// FIXME Use default instead
console.error('Shader "' + name + '" not existed in library');
return '';
}
return obj;
};
/* harmony default export */ __webpack_exports__["a"] = (Shader);
/***/ }),
/* 9 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__mixin_extend__ = __webpack_require__(103);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__mixin_notifier__ = __webpack_require__(47);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util__ = __webpack_require__(20);
/**
* Base class of all objects
* @constructor
* @alias clay.core.Base
* @mixes clay.core.mixin.notifier
*/
var Base = function () {
/**
* @type {number}
*/
this.__uid__ = __WEBPACK_IMPORTED_MODULE_2__util__["a" /* default */].genGUID();
};
Base.__initializers__ = [
function (opts) {
__WEBPACK_IMPORTED_MODULE_2__util__["a" /* default */].extend(this, opts);
}
];
__WEBPACK_IMPORTED_MODULE_2__util__["a" /* default */].extend(Base, __WEBPACK_IMPORTED_MODULE_0__mixin_extend__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_2__util__["a" /* default */].extend(Base.prototype, __WEBPACK_IMPORTED_MODULE_1__mixin_notifier__["a" /* default */]);
/* harmony default export */ __webpack_exports__["a"] = (Base);
/***/ }),
/* 10 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_Base__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Texture__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__TextureCube__ = __webpack_require__(24);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__core_glenum__ = __webpack_require__(11);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__core_Cache__ = __webpack_require__(48);
var KEY_FRAMEBUFFER = 'framebuffer';
var KEY_RENDERBUFFER = 'renderbuffer';
var KEY_RENDERBUFFER_WIDTH = KEY_RENDERBUFFER + '_width';
var KEY_RENDERBUFFER_HEIGHT = KEY_RENDERBUFFER + '_height';
var KEY_RENDERBUFFER_ATTACHED = KEY_RENDERBUFFER + '_attached';
var KEY_DEPTHTEXTURE_ATTACHED = 'depthtexture_attached';
var GL_FRAMEBUFFER = __WEBPACK_IMPORTED_MODULE_3__core_glenum__["a" /* default */].FRAMEBUFFER;
var GL_RENDERBUFFER = __WEBPACK_IMPORTED_MODULE_3__core_glenum__["a" /* default */].RENDERBUFFER;
var GL_DEPTH_ATTACHMENT = __WEBPACK_IMPORTED_MODULE_3__core_glenum__["a" /* default */].DEPTH_ATTACHMENT;
var GL_COLOR_ATTACHMENT0 = __WEBPACK_IMPORTED_MODULE_3__core_glenum__["a" /* default */].COLOR_ATTACHMENT0;
/**
* @constructor clay.FrameBuffer
* @extends clay.core.Base
*/
var FrameBuffer = __WEBPACK_IMPORTED_MODULE_0__core_Base__["a" /* default */].extend(
/** @lends clay.FrameBuffer# */
{
/**
* If use depth buffer
* @type {boolean}
*/
depthBuffer: true,
/**
* @type {Object}
*/
viewport: null,
_width: 0,
_height: 0,
_textures: null,
_boundRenderer: null,
}, function () {
// Use cache
this._cache = new __WEBPACK_IMPORTED_MODULE_4__core_Cache__["a" /* default */]();
this._textures = {};
},
/**@lends clay.FrameBuffer.prototype. */
{
/**
* Get attached texture width
* {number}
*/
// FIXME Can't use before #bind
getTextureWidth: function () {
return this._width;
},
/**
* Get attached texture height
* {number}
*/
getTextureHeight: function () {
return this._height;
},
/**
* Bind the framebuffer to given renderer before rendering
* @param {clay.Renderer} renderer
*/
bind: function (renderer) {
if (renderer.__currentFrameBuffer) {
// Already bound
if (renderer.__currentFrameBuffer === this) {
return;
}
console.warn('Renderer already bound with another framebuffer. Unbind it first');
}
renderer.__currentFrameBuffer = this;
var _gl = renderer.gl;
_gl.bindFramebuffer(GL_FRAMEBUFFER, this._getFrameBufferGL(renderer));
this._boundRenderer = renderer;
var cache = this._cache;
cache.put('viewport', renderer.viewport);
var hasTextureAttached = false;
var width;
var height;
for (var attachment in this._textures) {
hasTextureAttached = true;
var obj = this._textures[attachment];
if (obj) {
// TODO Do width, height checking, make sure size are same
width = obj.texture.width;
height = obj.texture.height;
// Attach textures
this._doAttach(renderer, obj.texture, attachment, obj.target);
}
}
this._width = width;
this._height = height;
if (!hasTextureAttached && this.depthBuffer) {
console.error('Must attach texture before bind, or renderbuffer may have incorrect width and height.')
}
if (this.viewport) {
renderer.setViewport(this.viewport);
}
else {
renderer.setViewport(0, 0, width, height, 1);
}
var attachedTextures = cache.get('attached_textures');
if (attachedTextures) {
for (var attachment in attachedTextures) {
if (!this._textures[attachment]) {
var target = attachedTextures[attachment];
this._doDetach(_gl, attachment, target);
}
}
}
if (!cache.get(KEY_DEPTHTEXTURE_ATTACHED) && this.depthBuffer) {
// Create a new render buffer
if (cache.miss(KEY_RENDERBUFFER)) {
cache.put(KEY_RENDERBUFFER, _gl.createRenderbuffer());
}
var renderbuffer = cache.get(KEY_RENDERBUFFER);
if (width !== cache.get(KEY_RENDERBUFFER_WIDTH)
|| height !== cache.get(KEY_RENDERBUFFER_HEIGHT)) {
_gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
_gl.renderbufferStorage(GL_RENDERBUFFER, _gl.DEPTH_COMPONENT16, width, height);
cache.put(KEY_RENDERBUFFER_WIDTH, width);
cache.put(KEY_RENDERBUFFER_HEIGHT, height);
_gl.bindRenderbuffer(GL_RENDERBUFFER, null);
}
if (!cache.get(KEY_RENDERBUFFER_ATTACHED)) {
_gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffer);
cache.put(KEY_RENDERBUFFER_ATTACHED, true);
}
}
},
/**
* Unbind the frame buffer after rendering
* @param {clay.Renderer} renderer
*/
unbind: function (renderer) {
// Remove status record on renderer
renderer.__currentFrameBuffer = null;
var _gl = renderer.gl;
_gl.bindFramebuffer(GL_FRAMEBUFFER, null);
this._boundRenderer = null;
this._cache.use(renderer.__uid__);
var viewport = this._cache.get('viewport');
// Reset viewport;
if (viewport) {
renderer.setViewport(viewport);
}
this.updateMipmap(renderer);
},
// Because the data of texture is changed over time,
// Here update the mipmaps of texture each time after rendered;
updateMipmap: function (renderer) {
var _gl = renderer.gl;
for (var attachment in this._textures) {
var obj = this._textures[attachment];
if (obj) {
var texture = obj.texture;
// FIXME some texture format can't generate mipmap
if (!texture.NPOT && texture.useMipmap
&& texture.minFilter === __WEBPACK_IMPORTED_MODULE_1__Texture__["a" /* default */].LINEAR_MIPMAP_LINEAR) {
var target = texture.textureType === 'textureCube' ? __WEBPACK_IMPORTED_MODULE_3__core_glenum__["a" /* default */].TEXTURE_CUBE_MAP : __WEBPACK_IMPORTED_MODULE_3__core_glenum__["a" /* default */].TEXTURE_2D;
_gl.bindTexture(target, texture.getWebGLTexture(renderer));
_gl.generateMipmap(target);
_gl.bindTexture(target, null);
}
}
}
},
// 0x8CD5, 36053, FRAMEBUFFER_COMPLETE
// 0x8CD6, 36054, FRAMEBUFFER_INCOMPLETE_ATTACHMENT
// 0x8CD7, 36055, FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT
// 0x8CD9, 36057, FRAMEBUFFER_INCOMPLETE_DIMENSIONS
// 0x8CDD, 36061, FRAMEBUFFER_UNSUPPORTED
checkStatus: function (_gl) {
return _gl.checkFramebufferStatus(GL_FRAMEBUFFER);
},
_getFrameBufferGL: function (renderer) {
var cache = this._cache;
cache.use(renderer.__uid__);
if (cache.miss(KEY_FRAMEBUFFER)) {
cache.put(KEY_FRAMEBUFFER, renderer.gl.createFramebuffer());
}
return cache.get(KEY_FRAMEBUFFER);
},
/**
* Attach a texture(RTT) to the framebuffer
* @param {clay.Texture} texture
* @param {number} [attachment=gl.COLOR_ATTACHMENT0]
* @param {number} [target=gl.TEXTURE_2D]
*/
attach: function (texture, attachment, target) {
if (!texture.width) {
throw new Error('The texture attached to color buffer is not a valid.');
}
// TODO width and height check
// If the depth_texture extension is enabled, developers
// Can attach a depth texture to the depth buffer
// http://blog.tojicode.com/2012/07/using-webgldepthtexture.html
attachment = attachment || GL_COLOR_ATTACHMENT0;
target = target || __WEBPACK_IMPORTED_MODULE_3__core_glenum__["a" /* default */].TEXTURE_2D;
var boundRenderer = this._boundRenderer;
var _gl = boundRenderer && boundRenderer.gl;
var attachedTextures;
if (_gl) {
var cache = this._cache;
cache.use(boundRenderer.__uid__);
attachedTextures = cache.get('attached_textures');
}
// Check if texture attached
var previous = this._textures[attachment];
if (previous && previous.target === target
&& previous.texture === texture
&& (attachedTextures && attachedTextures[attachment] != null)
) {
return;
}
var canAttach = true;
if (boundRenderer) {
canAttach = this._doAttach(boundRenderer, texture, attachment, target);
// Set viewport again incase attached to different size textures.
if (!this.viewport) {
boundRenderer.setViewport(0, 0, texture.width, texture.height, 1);
}
}
if (canAttach) {
this._textures[attachment] = this._textures[attachment] || {};
this._textures[attachment].texture = texture;
this._textures[attachment].target = target;
}
},
_doAttach: function (renderer, texture, attachment, target) {
var _gl = renderer.gl;
// Make sure texture is always updated
// Because texture width or height may be changed and in this we can't be notified
// FIXME awkward;
var webglTexture = texture.getWebGLTexture(renderer);
// Assume cache has been used.
var attachedTextures = this._cache.get('attached_textures');
if (attachedTextures && attachedTextures[attachment]) {
var obj = attachedTextures[attachment];
// Check if texture and target not changed
if (obj.texture === texture && obj.target === target) {
return;
}
}
attachment = +attachment;
var canAttach = true;
if (attachment === GL_DEPTH_ATTACHMENT || attachment === __WEBPACK_IMPORTED_MODULE_3__core_glenum__["a" /* default */].DEPTH_STENCIL_ATTACHMENT) {
var extension = renderer.getGLExtension('WEBGL_depth_texture');
if (!extension) {
console.error('Depth texture is not supported by the browser');
canAttach = false;
}
if (texture.format !== __WEBPACK_IMPORTED_MODULE_3__core_glenum__["a" /* default */].DEPTH_COMPONENT
&& texture.format !== __WEBPACK_IMPORTED_MODULE_3__core_glenum__["a" /* default */].DEPTH_STENCIL
) {
console.error('The texture attached to depth buffer is not a valid.');
canAttach = false;
}
// Dispose render buffer created previous
if (canAttach) {
var renderbuffer = this._cache.get(KEY_RENDERBUFFER);
if (renderbuffer) {
_gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, null);
_gl.deleteRenderbuffer(renderbuffer);
this._cache.put(KEY_RENDERBUFFER, false);
}
this._cache.put(KEY_RENDERBUFFER_ATTACHED, false);
this._cache.put(KEY_DEPTHTEXTURE_ATTACHED, true);
}
}
// Mipmap level can only be 0
_gl.framebufferTexture2D(GL_FRAMEBUFFER, attachment, target, webglTexture, 0);
if (!attachedTextures) {
attachedTextures = {};
this._cache.put('attached_textures', attachedTextures);
}
attachedTextures[attachment] = attachedTextures[attachment] || {};
attachedTextures[attachment].texture = texture;
attachedTextures[attachment].target = target;
return canAttach;
},
_doDetach: function (_gl, attachment, target) {
// Detach a texture from framebuffer
// https://github.com/KhronosGroup/WebGL/blob/master/conformance-suites/1.0.0/conformance/framebuffer-test.html#L145
_gl.framebufferTexture2D(GL_FRAMEBUFFER, attachment, target, null, 0);
// Assume cache has been used.
var attachedTextures = this._cache.get('attached_textures');
if (attachedTextures && attachedTextures[attachment]) {
attachedTextures[attachment] = null;
}
if (attachment === GL_DEPTH_ATTACHMENT || attachment === __WEBPACK_IMPORTED_MODULE_3__core_glenum__["a" /* default */].DEPTH_STENCIL_ATTACHMENT) {
this._cache.put(KEY_DEPTHTEXTURE_ATTACHED, false);
}
},
/**
* Detach a texture
* @param {number} [attachment=gl.COLOR_ATTACHMENT0]
* @param {number} [target=gl.TEXTURE_2D]
*/
detach: function (attachment, target) {
// TODO depth extension check ?
this._textures[attachment] = null;
if (this._boundRenderer) {
var cache = this._cache;
cache.use(this._boundRenderer.__uid__);
this._doDetach(this._boundRenderer.gl, attachment, target);
}
},
/**
* Dispose
* @param {WebGLRenderingContext} _gl
*/
dispose: function (renderer) {
var _gl = renderer.gl;
var cache = this._cache;
cache.use(renderer.__uid__);
var renderBuffer = cache.get(KEY_RENDERBUFFER);
if (renderBuffer) {
_gl.deleteRenderbuffer(renderBuffer);
}
var frameBuffer = cache.get(KEY_FRAMEBUFFER);
if (frameBuffer) {
_gl.deleteFramebuffer(frameBuffer);
}
cache.deleteContext(renderer.__uid__);
// Clear cache for reusing
this._textures = {};
}
});
FrameBuffer.DEPTH_ATTACHMENT = GL_DEPTH_ATTACHMENT;
FrameBuffer.COLOR_ATTACHMENT0 = GL_COLOR_ATTACHMENT0;
FrameBuffer.STENCIL_ATTACHMENT = __WEBPACK_IMPORTED_MODULE_3__core_glenum__["a" /* default */].STENCIL_ATTACHMENT;
FrameBuffer.DEPTH_STENCIL_ATTACHMENT = __WEBPACK_IMPORTED_MODULE_3__core_glenum__["a" /* default */].DEPTH_STENCIL_ATTACHMENT;
/* harmony default export */ __webpack_exports__["a"] = (FrameBuffer);
/***/ }),
/* 11 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/**
* @namespace clay.core.glenum
* @see http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14
*/
/* harmony default export */ __webpack_exports__["a"] = ({
/* ClearBufferMask */
DEPTH_BUFFER_BIT : 0x00000100,
STENCIL_BUFFER_BIT : 0x00000400,
COLOR_BUFFER_BIT : 0x00004000,
/* BeginMode */
POINTS : 0x0000,
LINES : 0x0001,
LINE_LOOP : 0x0002,
LINE_STRIP : 0x0003,
TRIANGLES : 0x0004,
TRIANGLE_STRIP : 0x0005,
TRIANGLE_FAN : 0x0006,
/* AlphaFunction (not supported in ES20) */
/* NEVER */
/* LESS */
/* EQUAL */
/* LEQUAL */
/* GREATER */
/* NOTEQUAL */
/* GEQUAL */
/* ALWAYS */
/* BlendingFactorDest */
ZERO : 0,
ONE : 1,
SRC_COLOR : 0x0300,
ONE_MINUS_SRC_COLOR : 0x0301,
SRC_ALPHA : 0x0302,
ONE_MINUS_SRC_ALPHA : 0x0303,
DST_ALPHA : 0x0304,
ONE_MINUS_DST_ALPHA : 0x0305,
/* BlendingFactorSrc */
/* ZERO */
/* ONE */
DST_COLOR : 0x0306,
ONE_MINUS_DST_COLOR : 0x0307,
SRC_ALPHA_SATURATE : 0x0308,
/* SRC_ALPHA */
/* ONE_MINUS_SRC_ALPHA */
/* DST_ALPHA */
/* ONE_MINUS_DST_ALPHA */
/* BlendEquationSeparate */
FUNC_ADD : 0x8006,
BLEND_EQUATION : 0x8009,
BLEND_EQUATION_RGB : 0x8009, /* same as BLEND_EQUATION */
BLEND_EQUATION_ALPHA : 0x883D,
/* BlendSubtract */
FUNC_SUBTRACT : 0x800A,
FUNC_REVERSE_SUBTRACT : 0x800B,
/* Separate Blend Functions */
BLEND_DST_RGB : 0x80C8,
BLEND_SRC_RGB : 0x80C9,
BLEND_DST_ALPHA : 0x80CA,
BLEND_SRC_ALPHA : 0x80CB,
CONSTANT_COLOR : 0x8001,
ONE_MINUS_CONSTANT_COLOR : 0x8002,
CONSTANT_ALPHA : 0x8003,
ONE_MINUS_CONSTANT_ALPHA : 0x8004,
BLEND_COLOR : 0x8005,
/* Buffer Objects */
ARRAY_BUFFER : 0x8892,
ELEMENT_ARRAY_BUFFER : 0x8893,
ARRAY_BUFFER_BINDING : 0x8894,
ELEMENT_ARRAY_BUFFER_BINDING : 0x8895,
STREAM_DRAW : 0x88E0,
STATIC_DRAW : 0x88E4,
DYNAMIC_DRAW : 0x88E8,
BUFFER_SIZE : 0x8764,
BUFFER_USAGE : 0x8765,
CURRENT_VERTEX_ATTRIB : 0x8626,
/* CullFaceMode */
FRONT : 0x0404,
BACK : 0x0405,
FRONT_AND_BACK : 0x0408,
/* DepthFunction */
/* NEVER */
/* LESS */
/* EQUAL */
/* LEQUAL */
/* GREATER */
/* NOTEQUAL */
/* GEQUAL */
/* ALWAYS */
/* EnableCap */
/* TEXTURE_2D */
CULL_FACE : 0x0B44,
BLEND : 0x0BE2,
DITHER : 0x0BD0,
STENCIL_TEST : 0x0B90,
DEPTH_TEST : 0x0B71,
SCISSOR_TEST : 0x0C11,
POLYGON_OFFSET_FILL : 0x8037,
SAMPLE_ALPHA_TO_COVERAGE : 0x809E,
SAMPLE_COVERAGE : 0x80A0,
/* ErrorCode */
NO_ERROR : 0,
INVALID_ENUM : 0x0500,
INVALID_VALUE : 0x0501,
INVALID_OPERATION : 0x0502,
OUT_OF_MEMORY : 0x0505,
/* FrontFaceDirection */
CW : 0x0900,
CCW : 0x0901,
/* GetPName */
LINE_WIDTH : 0x0B21,
ALIASED_POINT_SIZE_RANGE : 0x846D,
ALIASED_LINE_WIDTH_RANGE : 0x846E,
CULL_FACE_MODE : 0x0B45,
FRONT_FACE : 0x0B46,
DEPTH_RANGE : 0x0B70,
DEPTH_WRITEMASK : 0x0B72,
DEPTH_CLEAR_VALUE : 0x0B73,
DEPTH_FUNC : 0x0B74,
STENCIL_CLEAR_VALUE : 0x0B91,
STENCIL_FUNC : 0x0B92,
STENCIL_FAIL : 0x0B94,
STENCIL_PASS_DEPTH_FAIL : 0x0B95,
STENCIL_PASS_DEPTH_PASS : 0x0B96,
STENCIL_REF : 0x0B97,
STENCIL_VALUE_MASK : 0x0B93,
STENCIL_WRITEMASK : 0x0B98,
STENCIL_BACK_FUNC : 0x8800,
STENCIL_BACK_FAIL : 0x8801,
STENCIL_BACK_PASS_DEPTH_FAIL : 0x8802,
STENCIL_BACK_PASS_DEPTH_PASS : 0x8803,
STENCIL_BACK_REF : 0x8CA3,
STENCIL_BACK_VALUE_MASK : 0x8CA4,
STENCIL_BACK_WRITEMASK : 0x8CA5,
VIEWPORT : 0x0BA2,
SCISSOR_BOX : 0x0C10,
/* SCISSOR_TEST */
COLOR_CLEAR_VALUE : 0x0C22,
COLOR_WRITEMASK : 0x0C23,
UNPACK_ALIGNMENT : 0x0CF5,
PACK_ALIGNMENT : 0x0D05,
MAX_TEXTURE_SIZE : 0x0D33,
MAX_VIEWPORT_DIMS : 0x0D3A,
SUBPIXEL_BITS : 0x0D50,
RED_BITS : 0x0D52,
GREEN_BITS : 0x0D53,
BLUE_BITS : 0x0D54,
ALPHA_BITS : 0x0D55,
DEPTH_BITS : 0x0D56,
STENCIL_BITS : 0x0D57,
POLYGON_OFFSET_UNITS : 0x2A00,
/* POLYGON_OFFSET_FILL */
POLYGON_OFFSET_FACTOR : 0x8038,
TEXTURE_BINDING_2D : 0x8069,
SAMPLE_BUFFERS : 0x80A8,
SAMPLES : 0x80A9,
SAMPLE_COVERAGE_VALUE : 0x80AA,
SAMPLE_COVERAGE_INVERT : 0x80AB,
/* GetTextureParameter */
/* TEXTURE_MAG_FILTER */
/* TEXTURE_MIN_FILTER */
/* TEXTURE_WRAP_S */
/* TEXTURE_WRAP_T */
COMPRESSED_TEXTURE_FORMATS : 0x86A3,
/* HintMode */
DONT_CARE : 0x1100,
FASTEST : 0x1101,
NICEST : 0x1102,
/* HintTarget */
GENERATE_MIPMAP_HINT : 0x8192,
/* DataType */
BYTE : 0x1400,
UNSIGNED_BYTE : 0x1401,
SHORT : 0x1402,
UNSIGNED_SHORT : 0x1403,
INT : 0x1404,
UNSIGNED_INT : 0x1405,
FLOAT : 0x1406,
/* PixelFormat */
DEPTH_COMPONENT : 0x1902,
ALPHA : 0x1906,
RGB : 0x1907,
RGBA : 0x1908,
LUMINANCE : 0x1909,
LUMINANCE_ALPHA : 0x190A,
/* PixelType */
/* UNSIGNED_BYTE */
UNSIGNED_SHORT_4_4_4_4 : 0x8033,
UNSIGNED_SHORT_5_5_5_1 : 0x8034,
UNSIGNED_SHORT_5_6_5 : 0x8363,
/* Shaders */
FRAGMENT_SHADER : 0x8B30,
VERTEX_SHADER : 0x8B31,
MAX_VERTEX_ATTRIBS : 0x8869,
MAX_VERTEX_UNIFORM_VECTORS : 0x8DFB,
MAX_VARYING_VECTORS : 0x8DFC,
MAX_COMBINED_TEXTURE_IMAGE_UNITS : 0x8B4D,
MAX_VERTEX_TEXTURE_IMAGE_UNITS : 0x8B4C,
MAX_TEXTURE_IMAGE_UNITS : 0x8872,
MAX_FRAGMENT_UNIFORM_VECTORS : 0x8DFD,
SHADER_TYPE : 0x8B4F,
DELETE_STATUS : 0x8B80,
LINK_STATUS : 0x8B82,
VALIDATE_STATUS : 0x8B83,
ATTACHED_SHADERS : 0x8B85,
ACTIVE_UNIFORMS : 0x8B86,
ACTIVE_ATTRIBUTES : 0x8B89,
SHADING_LANGUAGE_VERSION : 0x8B8C,
CURRENT_PROGRAM : 0x8B8D,
/* StencilFunction */
NEVER : 0x0200,
LESS : 0x0201,
EQUAL : 0x0202,
LEQUAL : 0x0203,
GREATER : 0x0204,
NOTEQUAL : 0x0205,
GEQUAL : 0x0206,
ALWAYS : 0x0207,
/* StencilOp */
/* ZERO */
KEEP : 0x1E00,
REPLACE : 0x1E01,
INCR : 0x1E02,
DECR : 0x1E03,
INVERT : 0x150A,
INCR_WRAP : 0x8507,
DECR_WRAP : 0x8508,
/* StringName */
VENDOR : 0x1F00,
RENDERER : 0x1F01,
VERSION : 0x1F02,
/* TextureMagFilter */
NEAREST : 0x2600,
LINEAR : 0x2601,
/* TextureMinFilter */
/* NEAREST */
/* LINEAR */
NEAREST_MIPMAP_NEAREST : 0x2700,
LINEAR_MIPMAP_NEAREST : 0x2701,
NEAREST_MIPMAP_LINEAR : 0x2702,
LINEAR_MIPMAP_LINEAR : 0x2703,
/* TextureParameterName */
TEXTURE_MAG_FILTER : 0x2800,
TEXTURE_MIN_FILTER : 0x2801,
TEXTURE_WRAP_S : 0x2802,
TEXTURE_WRAP_T : 0x2803,
/* TextureTarget */
TEXTURE_2D : 0x0DE1,
TEXTURE : 0x1702,
TEXTURE_CUBE_MAP : 0x8513,
TEXTURE_BINDING_CUBE_MAP : 0x8514,
TEXTURE_CUBE_MAP_POSITIVE_X : 0x8515,
TEXTURE_CUBE_MAP_NEGATIVE_X : 0x8516,
TEXTURE_CUBE_MAP_POSITIVE_Y : 0x8517,
TEXTURE_CUBE_MAP_NEGATIVE_Y : 0x8518,
TEXTURE_CUBE_MAP_POSITIVE_Z : 0x8519,
TEXTURE_CUBE_MAP_NEGATIVE_Z : 0x851A,
MAX_CUBE_MAP_TEXTURE_SIZE : 0x851C,
/* TextureUnit */
TEXTURE0 : 0x84C0,
TEXTURE1 : 0x84C1,
TEXTURE2 : 0x84C2,
TEXTURE3 : 0x84C3,
TEXTURE4 : 0x84C4,
TEXTURE5 : 0x84C5,
TEXTURE6 : 0x84C6,
TEXTURE7 : 0x84C7,
TEXTURE8 : 0x84C8,
TEXTURE9 : 0x84C9,
TEXTURE10 : 0x84CA,
TEXTURE11 : 0x84CB,
TEXTURE12 : 0x84CC,
TEXTURE13 : 0x84CD,
TEXTURE14 : 0x84CE,
TEXTURE15 : 0x84CF,
TEXTURE16 : 0x84D0,
TEXTURE17 : 0x84D1,
TEXTURE18 : 0x84D2,
TEXTURE19 : 0x84D3,
TEXTURE20 : 0x84D4,
TEXTURE21 : 0x84D5,
TEXTURE22 : 0x84D6,
TEXTURE23 : 0x84D7,
TEXTURE24 : 0x84D8,
TEXTURE25 : 0x84D9,
TEXTURE26 : 0x84DA,
TEXTURE27 : 0x84DB,
TEXTURE28 : 0x84DC,
TEXTURE29 : 0x84DD,
TEXTURE30 : 0x84DE,
TEXTURE31 : 0x84DF,
ACTIVE_TEXTURE : 0x84E0,
/* TextureWrapMode */
REPEAT : 0x2901,
CLAMP_TO_EDGE : 0x812F,
MIRRORED_REPEAT : 0x8370,
/* Uniform Types */
FLOAT_VEC2 : 0x8B50,
FLOAT_VEC3 : 0x8B51,
FLOAT_VEC4 : 0x8B52,
INT_VEC2 : 0x8B53,
INT_VEC3 : 0x8B54,
INT_VEC4 : 0x8B55,
BOOL : 0x8B56,
BOOL_VEC2 : 0x8B57,
BOOL_VEC3 : 0x8B58,
BOOL_VEC4 : 0x8B59,
FLOAT_MAT2 : 0x8B5A,
FLOAT_MAT3 : 0x8B5B,
FLOAT_MAT4 : 0x8B5C,
SAMPLER_2D : 0x8B5E,
SAMPLER_CUBE : 0x8B60,
/* Vertex Arrays */
VERTEX_ATTRIB_ARRAY_ENABLED : 0x8622,
VERTEX_ATTRIB_ARRAY_SIZE : 0x8623,
VERTEX_ATTRIB_ARRAY_STRIDE : 0x8624,
VERTEX_ATTRIB_ARRAY_TYPE : 0x8625,
VERTEX_ATTRIB_ARRAY_NORMALIZED : 0x886A,
VERTEX_ATTRIB_ARRAY_POINTER : 0x8645,
VERTEX_ATTRIB_ARRAY_BUFFER_BINDING : 0x889F,
/* Shader Source */
COMPILE_STATUS : 0x8B81,
/* Shader Precision-Specified Types */
LOW_FLOAT : 0x8DF0,
MEDIUM_FLOAT : 0x8DF1,
HIGH_FLOAT : 0x8DF2,
LOW_INT : 0x8DF3,
MEDIUM_INT : 0x8DF4,
HIGH_INT : 0x8DF5,
/* Framebuffer Object. */
FRAMEBUFFER : 0x8D40,
RENDERBUFFER : 0x8D41,
RGBA4 : 0x8056,
RGB5_A1 : 0x8057,
RGB565 : 0x8D62,
DEPTH_COMPONENT16 : 0x81A5,
STENCIL_INDEX : 0x1901,
STENCIL_INDEX8 : 0x8D48,
DEPTH_STENCIL : 0x84F9,
RENDERBUFFER_WIDTH : 0x8D42,
RENDERBUFFER_HEIGHT : 0x8D43,
RENDERBUFFER_INTERNAL_FORMAT : 0x8D44,
RENDERBUFFER_RED_SIZE : 0x8D50,
RENDERBUFFER_GREEN_SIZE : 0x8D51,
RENDERBUFFER_BLUE_SIZE : 0x8D52,
RENDERBUFFER_ALPHA_SIZE : 0x8D53,
RENDERBUFFER_DEPTH_SIZE : 0x8D54,
RENDERBUFFER_STENCIL_SIZE : 0x8D55,
FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE : 0x8CD0,
FRAMEBUFFER_ATTACHMENT_OBJECT_NAME : 0x8CD1,
FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL : 0x8CD2,
FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE : 0x8CD3,
COLOR_ATTACHMENT0 : 0x8CE0,
DEPTH_ATTACHMENT : 0x8D00,
STENCIL_ATTACHMENT : 0x8D20,
DEPTH_STENCIL_ATTACHMENT : 0x821A,
NONE : 0,
FRAMEBUFFER_COMPLETE : 0x8CD5,
FRAMEBUFFER_INCOMPLETE_ATTACHMENT : 0x8CD6,
FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT : 0x8CD7,
FRAMEBUFFER_INCOMPLETE_DIMENSIONS : 0x8CD9,
FRAMEBUFFER_UNSUPPORTED : 0x8CDD,
FRAMEBUFFER_BINDING : 0x8CA6,
RENDERBUFFER_BINDING : 0x8CA7,
MAX_RENDERBUFFER_SIZE : 0x84E8,
INVALID_FRAMEBUFFER_OPERATION : 0x0506,
/* WebGL-specific enums */
UNPACK_FLIP_Y_WEBGL : 0x9240,
UNPACK_PREMULTIPLY_ALPHA_WEBGL : 0x9241,
CONTEXT_LOST_WEBGL : 0x9242,
UNPACK_COLORSPACE_CONVERSION_WEBGL : 0x9243,
BROWSER_DEFAULT_WEBGL : 0x9244,
});
/***/ }),
/* 12 */
/***/ (function(module, exports) {
/**
* @module zrender/core/util
*/
// 用于处理merge时无法遍历Date等对象的问题
var BUILTIN_OBJECT = {
'[object Function]': 1,
'[object RegExp]': 1,
'[object Date]': 1,
'[object Error]': 1,
'[object CanvasGradient]': 1,
'[object CanvasPattern]': 1,
// For node-canvas
'[object Image]': 1,
'[object Canvas]': 1
};
var TYPED_ARRAY = {
'[object Int8Array]': 1,
'[object Uint8Array]': 1,
'[object Uint8ClampedArray]': 1,
'[object Int16Array]': 1,
'[object Uint16Array]': 1,
'[object Int32Array]': 1,
'[object Uint32Array]': 1,
'[object Float32Array]': 1,
'[object Float64Array]': 1
};
var objToString = Object.prototype.toString;
var arrayProto = Array.prototype;
var nativeForEach = arrayProto.forEach;
var nativeFilter = arrayProto.filter;
var nativeSlice = arrayProto.slice;
var nativeMap = arrayProto.map;
var nativeReduce = arrayProto.reduce; // Avoid assign to an exported variable, for transforming to cjs.
var methods = {};
function $override(name, fn) {
// Clear ctx instance for different environment
if (name === 'createCanvas') {
_ctx = null;
}
methods[name] = fn;
}
/**
* Those data types can be cloned:
* Plain object, Array, TypedArray, number, string, null, undefined.
* Those data types will be assgined using the orginal data:
* BUILTIN_OBJECT
* Instance of user defined class will be cloned to a plain object, without
* properties in prototype.
* Other data types is not supported (not sure what will happen).
*
* Caution: do not support clone Date, for performance consideration.
* (There might be a large number of date in `series.data`).
* So date should not be modified in and out of echarts.
*
* @param {*} source
* @return {*} new
*/
function clone(source) {
if (source == null || typeof source != 'object') {
return source;
}
var result = source;
var typeStr = objToString.call(source);
if (typeStr === '[object Array]') {
if (!isPrimitive(source)) {
result = [];
for (var i = 0, len = source.length; i < len; i++) {
result[i] = clone(source[i]);
}
}
} else if (TYPED_ARRAY[typeStr]) {
if (!isPrimitive(source)) {
var Ctor = source.constructor;
if (source.constructor.from) {
result = Ctor.from(source);
} else {
result = new Ctor(source.length);
for (var i = 0, len = source.length; i < len; i++) {
result[i] = clone(source[i]);
}
}
}
} else if (!BUILTIN_OBJECT[typeStr] && !isPrimitive(source) && !isDom(source)) {
result = {};
for (var key in source) {
if (source.hasOwnProperty(key)) {
result[key] = clone(source[key]);
}
}
}
return result;
}
/**
* @memberOf module:zrender/core/util
* @param {*} target
* @param {*} source
* @param {boolean} [overwrite=false]
*/
function merge(target, source, overwrite) {
// We should escapse that source is string
// and enter for ... in ...
if (!isObject(source) || !isObject(target)) {
return overwrite ? clone(source) : target;
}
for (var key in source) {
if (source.hasOwnProperty(key)) {
var targetProp = target[key];
var sourceProp = source[key];
if (isObject(sourceProp) && isObject(targetProp) && !isArray(sourceProp) && !isArray(targetProp) && !isDom(sourceProp) && !isDom(targetProp) && !isBuiltInObject(sourceProp) && !isBuiltInObject(targetProp) && !isPrimitive(sourceProp) && !isPrimitive(targetProp)) {
// 如果需要递归覆盖,就递归调用merge
merge(targetProp, sourceProp, overwrite);
} else if (overwrite || !(key in target)) {
// 否则只处理overwrite为true,或者在目标对象中没有此属性的情况
// NOTE,在 target[key] 不存在的时候也是直接覆盖
target[key] = clone(source[key], true);
}
}
}
return target;
}
/**
* @param {Array} targetAndSources The first item is target, and the rests are source.
* @param {boolean} [overwrite=false]
* @return {*} target
*/
function mergeAll(targetAndSources, overwrite) {
var result = targetAndSources[0];
for (var i = 1, len = targetAndSources.length; i < len; i++) {
result = merge(result, targetAndSources[i], overwrite);
}
return result;
}
/**
* @param {*} target
* @param {*} source
* @memberOf module:zrender/core/util
*/
function extend(target, source) {
for (var key in source) {
if (source.hasOwnProperty(key)) {
target[key] = source[key];
}
}
return target;
}
/**
* @param {*} target
* @param {*} source
* @param {boolean} [overlay=false]
* @memberOf module:zrender/core/util
*/
function defaults(target, source, overlay) {
for (var key in source) {
if (source.hasOwnProperty(key) && (overlay ? source[key] != null : target[key] == null)) {
target[key] = source[key];
}
}
return target;
}
var createCanvas = function () {
return methods.createCanvas();
};
methods.createCanvas = function () {
return document.createElement('canvas');
}; // FIXME
var _ctx;
function getContext() {
if (!_ctx) {
// Use util.createCanvas instead of createCanvas
// because createCanvas may be overwritten in different environment
_ctx = createCanvas().getContext('2d');
}
return _ctx;
}
/**
* 查询数组中元素的index
* @memberOf module:zrender/core/util
*/
function indexOf(array, value) {
if (array) {
if (array.indexOf) {
return array.indexOf(value);
}
for (var i = 0, len = array.length; i < len; i++) {
if (array[i] === value) {
return i;
}
}
}
return -1;
}
/**
* 构造类继承关系
*
* @memberOf module:zrender/core/util
* @param {Function} clazz 源类
* @param {Function} baseClazz 基类
*/
function inherits(clazz, baseClazz) {
var clazzPrototype = clazz.prototype;
function F() {}
F.prototype = baseClazz.prototype;
clazz.prototype = new F();
for (var prop in clazzPrototype) {
clazz.prototype[prop] = clazzPrototype[prop];
}
clazz.prototype.constructor = clazz;
clazz.superClass = baseClazz;
}
/**
* @memberOf module:zrender/core/util
* @param {Object|Function} target
* @param {Object|Function} sorce
* @param {boolean} overlay
*/
function mixin(target, source, overlay) {
target = 'prototype' in target ? target.prototype : target;
source = 'prototype' in source ? source.prototype : source;
defaults(target, source, overlay);
}
/**
* Consider typed array.
* @param {Array|TypedArray} data
*/
function isArrayLike(data) {
if (!data) {
return;
}
if (typeof data == 'string') {
return false;
}
return typeof data.length == 'number';
}
/**
* 数组或对象遍历
* @memberOf module:zrender/core/util
* @param {Object|Array} obj
* @param {Function} cb
* @param {*} [context]
*/
function each(obj, cb, context) {
if (!(obj && cb)) {
return;
}
if (obj.forEach && obj.forEach === nativeForEach) {
obj.forEach(cb, context);
} else if (obj.length === +obj.length) {
for (var i = 0, len = obj.length; i < len; i++) {
cb.call(context, obj[i], i, obj);
}
} else {
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
cb.call(context, obj[key], key, obj);
}
}
}
}
/**
* 数组映射
* @memberOf module:zrender/core/util
* @param {Array} obj
* @param {Function} cb
* @param {*} [context]
* @return {Array}
*/
function map(obj, cb, context) {
if (!(obj && cb)) {
return;
}
if (obj.map && obj.map === nativeMap) {
return obj.map(cb, context);
} else {
var result = [];
for (var i = 0, len = obj.length; i < len; i++) {
result.push(cb.call(context, obj[i], i, obj));
}
return result;
}
}
/**
* @memberOf module:zrender/core/util
* @param {Array} obj
* @param {Function} cb
* @param {Object} [memo]
* @param {*} [context]
* @return {Array}
*/
function reduce(obj, cb, memo, context) {
if (!(obj && cb)) {
return;
}
if (obj.reduce && obj.reduce === nativeReduce) {
return obj.reduce(cb, memo, context);
} else {
for (var i = 0, len = obj.length; i < len; i++) {
memo = cb.call(context, memo, obj[i], i, obj);
}
return memo;
}
}
/**
* 数组过滤
* @memberOf module:zrender/core/util
* @param {Array} obj
* @param {Function} cb
* @param {*} [context]
* @return {Array}
*/
function filter(obj, cb, context) {
if (!(obj && cb)) {
return;
}
if (obj.filter && obj.filter === nativeFilter) {
return obj.filter(cb, context);
} else {
var result = [];
for (var i = 0, len = obj.length; i < len; i++) {
if (cb.call(context, obj[i], i, obj)) {
result.push(obj[i]);
}
}
return result;
}
}
/**
* 数组项查找
* @memberOf module:zrender/core/util
* @param {Array} obj
* @param {Function} cb
* @param {*} [context]
* @return {*}
*/
function find(obj, cb, context) {
if (!(obj && cb)) {
return;
}
for (var i = 0, len = obj.length; i < len; i++) {
if (cb.call(context, obj[i], i, obj)) {
return obj[i];
}
}
}
/**
* @memberOf module:zrender/core/util
* @param {Function} func
* @param {*} context
* @return {Function}
*/
function bind(func, context) {
var args = nativeSlice.call(arguments, 2);
return function () {
return func.apply(context, args.concat(nativeSlice.call(arguments)));
};
}
/**
* @memberOf module:zrender/core/util
* @param {Function} func
* @return {Function}
*/
function curry(func) {
var args = nativeSlice.call(arguments, 1);
return function () {
return func.apply(this, args.concat(nativeSlice.call(arguments)));
};
}
/**
* @memberOf module:zrender/core/util
* @param {*} value
* @return {boolean}
*/
function isArray(value) {
return objToString.call(value) === '[object Array]';
}
/**
* @memberOf module:zrender/core/util
* @param {*} value
* @return {boolean}
*/
function isFunction(value) {
return typeof value === 'function';
}
/**
* @memberOf module:zrender/core/util
* @param {*} value
* @return {boolean}
*/
function isString(value) {
return objToString.call(value) === '[object String]';
}
/**
* @memberOf module:zrender/core/util
* @param {*} value
* @return {boolean}
*/
function isObject(value) {
// Avoid a V8 JIT bug in Chrome 19-20.
// See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
var type = typeof value;
return type === 'function' || !!value && type == 'object';
}
/**
* @memberOf module:zrender/core/util
* @param {*} value
* @return {boolean}
*/
function isBuiltInObject(value) {
return !!BUILTIN_OBJECT[objToString.call(value)];
}
/**
* @memberOf module:zrender/core/util
* @param {*} value
* @return {boolean}
*/
function isTypedArray(value) {
return !!TYPED_ARRAY[objToString.call(value)];
}
/**
* @memberOf module:zrender/core/util
* @param {*} value
* @return {boolean}
*/
function isDom(value) {
return typeof value === 'object' && typeof value.nodeType === 'number' && typeof value.ownerDocument === 'object';
}
/**
* Whether is exactly NaN. Notice isNaN('a') returns true.
* @param {*} value
* @return {boolean}
*/
function eqNaN(value) {
return value !== value;
}
/**
* If value1 is not null, then return value1, otherwise judget rest of values.
* Low performance.
* @memberOf module:zrender/core/util
* @return {*} Final value
*/
function retrieve(values) {
for (var i = 0, len = arguments.length; i < len; i++) {
if (arguments[i] != null) {
return arguments[i];
}
}
}
function retrieve2(value0, value1) {
return value0 != null ? value0 : value1;
}
function retrieve3(value0, value1, value2) {
return value0 != null ? value0 : value1 != null ? value1 : value2;
}
/**
* @memberOf module:zrender/core/util
* @param {Array} arr
* @param {number} startIndex
* @param {number} endIndex
* @return {Array}
*/
function slice() {
return Function.call.apply(nativeSlice, arguments);
}
/**
* Normalize css liked array configuration
* e.g.
* 3 => [3, 3, 3, 3]
* [4, 2] => [4, 2, 4, 2]
* [4, 3, 2] => [4, 3, 2, 3]
* @param {number|Array.} val
* @return {Array.}
*/
function normalizeCssArray(val) {
if (typeof val === 'number') {
return [val, val, val, val];
}
var len = val.length;
if (len === 2) {
// vertical | horizontal
return [val[0], val[1], val[0], val[1]];
} else if (len === 3) {
// top | horizontal | bottom
return [val[0], val[1], val[2], val[1]];
}
return val;
}
/**
* @memberOf module:zrender/core/util
* @param {boolean} condition
* @param {string} message
*/
function assert(condition, message) {
if (!condition) {
throw new Error(message);
}
}
/**
* @memberOf module:zrender/core/util
* @param {string} str string to be trimed
* @return {string} trimed string
*/
function trim(str) {
if (str == null) {
return null;
} else if (typeof str.trim === 'function') {
return str.trim();
} else {
return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
}
}
var primitiveKey = '__ec_primitive__';
/**
* Set an object as primitive to be ignored traversing children in clone or merge
*/
function setAsPrimitive(obj) {
obj[primitiveKey] = true;
}
function isPrimitive(obj) {
return obj[primitiveKey];
}
/**
* @constructor
* @param {Object} obj Only apply `ownProperty`.
*/
function HashMap(obj) {
var isArr = isArray(obj);
var thisMap = this;
obj instanceof HashMap ? obj.each(visit) : obj && each(obj, visit);
function visit(value, key) {
isArr ? thisMap.set(value, key) : thisMap.set(key, value);
}
} // Add prefix to avoid conflict with Object.prototype.
HashMap.prototype = {
constructor: HashMap,
// Do not provide `has` method to avoid defining what is `has`.
// (We usually treat `null` and `undefined` as the same, different
// from ES6 Map).
get: function (key) {
return this.hasOwnProperty(key) ? this[key] : null;
},
set: function (key, value) {
// Comparing with invocation chaining, `return value` is more commonly
// used in this case: `var someVal = map.set('a', genVal());`
return this[key] = value;
},
// Although util.each can be performed on this hashMap directly, user
// should not use the exposed keys, who are prefixed.
each: function (cb, context) {
context !== void 0 && (cb = bind(cb, context));
for (var key in this) {
this.hasOwnProperty(key) && cb(this[key], key);
}
},
// Do not use this method if performance sensitive.
removeKey: function (key) {
delete this[key];
}
};
function createHashMap(obj) {
return new HashMap(obj);
}
function concatArray(a, b) {
var newArray = new a.constructor(a.length + b.length);
for (var i = 0; i < a.length; i++) {
newArray[i] = a[i];
}
var offset = a.length;
for (i = 0; i < b.length; i++) {
newArray[i + offset] = b[i];
}
return newArray;
}
function noop() {}
exports.$override = $override;
exports.clone = clone;
exports.merge = merge;
exports.mergeAll = mergeAll;
exports.extend = extend;
exports.defaults = defaults;
exports.createCanvas = createCanvas;
exports.getContext = getContext;
exports.indexOf = indexOf;
exports.inherits = inherits;
exports.mixin = mixin;
exports.isArrayLike = isArrayLike;
exports.each = each;
exports.map = map;
exports.reduce = reduce;
exports.filter = filter;
exports.find = find;
exports.bind = bind;
exports.curry = curry;
exports.isArray = isArray;
exports.isFunction = isFunction;
exports.isString = isString;
exports.isObject = isObject;
exports.isBuiltInObject = isBuiltInObject;
exports.isTypedArray = isTypedArray;
exports.isDom = isDom;
exports.eqNaN = eqNaN;
exports.retrieve = retrieve;
exports.retrieve2 = retrieve2;
exports.retrieve3 = retrieve3;
exports.slice = slice;
exports.normalizeCssArray = normalizeCssArray;
exports.assert = assert;
exports.trim = trim;
exports.setAsPrimitive = setAsPrimitive;
exports.isPrimitive = isPrimitive;
exports.createHashMap = createHashMap;
exports.concatArray = concatArray;
exports.noop = noop;
/***/ }),
/* 13 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_Base__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_glenum__ = __webpack_require__(11);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__core_Cache__ = __webpack_require__(48);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__core_vendor__ = __webpack_require__(18);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4__dep_glmatrix__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__math_BoundingBox__ = __webpack_require__(15);
var vec3 = __WEBPACK_IMPORTED_MODULE_4__dep_glmatrix___default.a.vec3;
var mat4 = __WEBPACK_IMPORTED_MODULE_4__dep_glmatrix___default.a.mat4;
var vec3Create = vec3.create;
var vec3Add = vec3.add;
var vec3Set = vec3.set;
function getArrayCtorByType (type) {
return ({
'byte': __WEBPACK_IMPORTED_MODULE_3__core_vendor__["a" /* default */].Int8Array,
'ubyte': __WEBPACK_IMPORTED_MODULE_3__core_vendor__["a" /* default */].Uint8Array,
'short': __WEBPACK_IMPORTED_MODULE_3__core_vendor__["a" /* default */].Int16Array,
'ushort': __WEBPACK_IMPORTED_MODULE_3__core_vendor__["a" /* default */].Uint16Array
})[type] || __WEBPACK_IMPORTED_MODULE_3__core_vendor__["a" /* default */].Float32Array;
}
function makeAttrKey(attrName) {
return 'attr_' + attrName;
}
/**
* Geometry attribute
* @alias clay.Geometry.Attribute
* @constructor
*/
function Attribute(name, type, size, semantic) {
/**
* Attribute name
* @type {string}
*/
this.name = name;
/**
* Attribute type
* Possible values:
* + `'byte'`
* + `'ubyte'`
* + `'short'`
* + `'ushort'`
* + `'float'` Most commonly used.
* @type {string}
*/
this.type = type;
/**
* Size of attribute component. 1 - 4.
* @type {number}
*/
this.size = size;
/**
* Semantic of this attribute.
* Possible values:
* + `'POSITION'`
* + `'NORMAL'`
* + `'BINORMAL'`
* + `'TANGENT'`
* + `'TEXCOORD'`
* + `'TEXCOORD_0'`
* + `'TEXCOORD_1'`
* + `'COLOR'`
* + `'JOINT'`
* + `'WEIGHT'`
*
* In shader, attribute with same semantic will be automatically mapped. For example:
* ```glsl
* attribute vec3 pos: POSITION
* ```
* will use the attribute value with semantic POSITION in geometry, no matter what name it used.
* @type {string}
*/
this.semantic = semantic || '';
/**
* Value of the attribute.
* @type {TypedArray}
*/
this.value = null;
// Init getter setter
switch (size) {
case 1:
this.get = function (idx) {
return this.value[idx];
};
this.set = function (idx, value) {
this.value[idx] = value;
};
// Copy from source to target
this.copy = function (target, source) {
this.value[target] = this.value[target];
};
break;
case 2:
this.get = function (idx, out) {
var arr = this.value;
out[0] = arr[idx * 2];
out[1] = arr[idx * 2 + 1];
return out;
};
this.set = function (idx, val) {
var arr = this.value;
arr[idx * 2] = val[0];
arr[idx * 2 + 1] = val[1];
};
this.copy = function (target, source) {
var arr = this.value;
source *= 2;
target *= 2;
arr[target] = arr[source];
arr[target + 1] = arr[source + 1];
};
break;
case 3:
this.get = function (idx, out) {
var idx3 = idx * 3;
var arr = this.value;
out[0] = arr[idx3];
out[1] = arr[idx3 + 1];
out[2] = arr[idx3 + 2];
return out;
};
this.set = function (idx, val) {
var idx3 = idx * 3;
var arr = this.value;
arr[idx3] = val[0];
arr[idx3 + 1] = val[1];
arr[idx3 + 2] = val[2];
};
this.copy = function (target, source) {
var arr = this.value;
source *= 3;
target *= 3;
arr[target] = arr[source];
arr[target + 1] = arr[source + 1];
arr[target + 2] = arr[source + 2];
};
break;
case 4:
this.get = function (idx, out) {
var arr = this.value;
var idx4 = idx * 4;
out[0] = arr[idx4];
out[1] = arr[idx4 + 1];
out[2] = arr[idx4 + 2];
out[3] = arr[idx4 + 3];
return out;
};
this.set = function (idx, val) {
var arr = this.value;
var idx4 = idx * 4;
arr[idx4] = val[0];
arr[idx4 + 1] = val[1];
arr[idx4 + 2] = val[2];
arr[idx4 + 3] = val[3];
};
this.copy = function (target, source) {
var arr = this.value;
source *= 4;
target *= 4;
// copyWithin is extremely slow
arr[target] = arr[source];
arr[target + 1] = arr[source + 1];
arr[target + 2] = arr[source + 2];
arr[target + 3] = arr[source + 3];
};
}
}
/**
* Set item value at give index. Second parameter val is number if size is 1
* @function
* @name clay.Geometry.Attribute#set
* @param {number} idx
* @param {number[]|number} val
* @example
* geometry.getAttribute('position').set(0, [1, 1, 1]);
*/
/**
* Get item value at give index. Second parameter out is no need if size is 1
* @function
* @name clay.Geometry.Attribute#set
* @param {number} idx
* @param {number[]} [out]
* @example
* geometry.getAttribute('position').get(0, out);
*/
/**
* Initialize attribute with given vertex count
* @param {number} nVertex
*/
Attribute.prototype.init = function (nVertex) {
if (!this.value || this.value.length != nVertex * this.size) {
var ArrayConstructor = getArrayCtorByType(this.type);
this.value = new ArrayConstructor(nVertex * this.size);
}
};
/**
* Initialize attribute with given array. Which can be 1 dimensional or 2 dimensional
* @param {Array} array
* @example
* geometry.getAttribute('position').fromArray(
* [-1, 0, 0, 1, 0, 0, 0, 1, 0]
* );
* geometry.getAttribute('position').fromArray(
* [ [-1, 0, 0], [1, 0, 0], [0, 1, 0] ]
* );
*/
Attribute.prototype.fromArray = function (array) {
var ArrayConstructor = getArrayCtorByType(this.type);
var value;
// Convert 2d array to flat
if (array[0] && (array[0].length)) {
var n = 0;
var size = this.size;
value = new ArrayConstructor(array.length * size);
for (var i = 0; i < array.length; i++) {
for (var j = 0; j < size; j++) {
value[n++] = array[i][j];
}
}
}
else {
value = new ArrayConstructor(array);
}
this.value = value;
};
Attribute.prototype.clone = function(copyValue) {
var ret = new Attribute(this.name, this.type, this.size, this.semantic);
// FIXME
if (copyValue) {
console.warn('todo');
}
return ret;
};
function AttributeBuffer(name, type, buffer, size, semantic) {
this.name = name;
this.type = type;
this.buffer = buffer;
this.size = size;
this.semantic = semantic;
// To be set in mesh
// symbol in the shader
this.symbol = '';
// Needs remove flag
this.needsRemove = false;
}
function IndicesBuffer(buffer) {
this.buffer = buffer;
this.count = 0;
}
/**
* Geometry in ClayGL contains vertex attributes of mesh. These vertex attributes will be finally provided to the {@link clay.Shader}.
* Different {@link clay.Shader} needs different attributes. Here is a list of attributes used in the builtin shaders.
*
* + position: `clay.basic`, `clay.lambert`, `clay.standard`
* + texcoord0: `clay.basic`, `clay.lambert`, `clay.standard`
* + color: `clay.basic`, `clay.lambert`, `clay.standard`
* + weight: `clay.basic`, `clay.lambert`, `clay.standard`
* + joint: `clay.basic`, `clay.lambert`, `clay.standard`
* + normal: `clay.lambert`, `clay.standard`
* + tangent: `clay.standard`
*
* #### Create a procedural geometry
*
* ClayGL provides a couple of builtin procedural geometries. Inlcuding:
*
* + {@link clay.geometry.Cube}
* + {@link clay.geometry.Sphere}
* + {@link clay.geometry.Plane}
* + {@link clay.geometry.Cylinder}
* + {@link clay.geometry.Cone}
* + {@link clay.geometry.ParametricSurface}
*
* It's simple to create a basic geometry with these classes.
*
```js
var sphere = new clay.geometry.Sphere({
radius: 2
});
```
*
* #### Create the geometry data by yourself
*
* Usually the vertex attributes data are created by the {@link clay.loader.GLTF} or procedural geometries like {@link clay.geometry.Sphere}.
* Besides these, you can create the data manually. Here is a simple example to create a triangle.
```js
var TRIANGLE_POSITIONS = [
[-0.5, -0.5, 0],
[0.5, -0.5, 0],
[0, 0.5, 0]
];
var geometry = new clay.StaticGeometry();
// Add triangle vertices to position attribute.
geometry.attributes.position.fromArray(TRIANGLE_POSITIONS);
```
* Then you can use the utility methods like `generateVertexNormals`, `generateTangents` to create the remaining necessary attributes.
*
*
* #### Use with custom shaders
*
* If you wan't to write custom shaders. Don't forget to add SEMANTICS to these attributes. For example
*
```glsl
uniform mat4 worldViewProjection : WORLDVIEWPROJECTION;
uniform mat4 worldInverseTranspose : WORLDINVERSETRANSPOSE;
uniform mat4 world : WORLD;
attribute vec3 position : POSITION;
attribute vec2 texcoord : TEXCOORD_0;
attribute vec3 normal : NORMAL;
```
* These `POSITION`, `TEXCOORD_0`, `NORMAL` are SEMANTICS which will map the attributes in shader to the attributes in the Geometry
*
* Available attributes SEMANTICS includes `POSITION`, `TEXCOORD_0`, `TEXCOORD_1` `NORMAL`, `TANGENT`, `COLOR`, `WEIGHT`, `JOINT`.
*
*
* @constructor clay.Geometry
* @extends clay.core.Base
*/
var Geometry = __WEBPACK_IMPORTED_MODULE_0__core_Base__["a" /* default */].extend(function () {
return /** @lends clay.Geometry# */ {
/**
* Attributes of geometry. Including:
* + `position`
* + `texcoord0`
* + `texcoord1`
* + `normal`
* + `tangent`
* + `color`
* + `weight`
* + `joint`
* + `barycentric`
*
* @type {Object.}
*/
attributes: {
position: new Attribute('position', 'float', 3, 'POSITION'),
texcoord0: new Attribute('texcoord0', 'float', 2, 'TEXCOORD_0'),
texcoord1: new Attribute('texcoord1', 'float', 2, 'TEXCOORD_1'),
normal: new Attribute('normal', 'float', 3, 'NORMAL'),
tangent: new Attribute('tangent', 'float', 4, 'TANGENT'),
color: new Attribute('color', 'float', 4, 'COLOR'),
// Skinning attributes
// Each vertex can be bind to 4 bones, because the
// sum of weights is 1, so the weights is stored in vec3 and the last
// can be calculated by 1-w.x-w.y-w.z
weight: new Attribute('weight', 'float', 3, 'WEIGHT'),
joint: new Attribute('joint', 'float', 4, 'JOINT'),
// For wireframe display
// http://codeflow.org/entries/2012/aug/02/easy-wireframe-display-with-barycentric-coordinates/
barycentric: new Attribute('barycentric', 'float', 3, null),
},
/**
* Calculated bounding box of geometry.
* @type {clay.BoundingBox}
*/
boundingBox: null,
/**
* Indices of geometry.
* @type {Uint16Array|Uint32Array}
*/
indices: null,
/**
* Is vertices data dynamically updated.
* Attributes value can't be changed after first render if dyanmic is false.
* @type {boolean}
*/
dynamic: true,
_enabledAttributes: null,
// PENDING
// Init it here to avoid deoptimization when it's assigned in application dynamically
__used: 0
};
}, function() {
// Use cache
this._cache = new __WEBPACK_IMPORTED_MODULE_2__core_Cache__["a" /* default */]();
this._attributeList = Object.keys(this.attributes);
this.__vaoCache = {};
},
/** @lends clay.Geometry.prototype */
{
/**
* Main attribute will be used to count vertex number
* @type {string}
*/
mainAttribute: 'position',
/**
* User defined picking algorithm instead of default
* triangle ray intersection
* x, y are NDC.
* ```typescript
* (x, y, renderer, camera, renderable, out) => boolean
* ```
* @type {?Function}
*/
pick: null,
/**
* User defined ray picking algorithm instead of default
* triangle ray intersection
* ```typescript
* (ray: clay.Ray, renderable: clay.Renderable, out: Array) => boolean
* ```
* @type {?Function}
*/
pickByRay: null,
/**
* Update boundingBox of Geometry
*/
updateBoundingBox: function () {
var bbox = this.boundingBox;
if (!bbox) {
bbox = this.boundingBox = new __WEBPACK_IMPORTED_MODULE_5__math_BoundingBox__["a" /* default */]();
}
var posArr = this.attributes.position.value;
if (posArr && posArr.length) {
var min = bbox.min;
var max = bbox.max;
var minArr = min.array;
var maxArr = max.array;
vec3.set(minArr, posArr[0], posArr[1], posArr[2]);
vec3.set(maxArr, posArr[0], posArr[1], posArr[2]);
for (var i = 3; i < posArr.length;) {
var x = posArr[i++];
var y = posArr[i++];
var z = posArr[i++];
if (x < minArr[0]) { minArr[0] = x; }
if (y < minArr[1]) { minArr[1] = y; }
if (z < minArr[2]) { minArr[2] = z; }
if (x > maxArr[0]) { maxArr[0] = x; }
if (y > maxArr[1]) { maxArr[1] = y; }
if (z > maxArr[2]) { maxArr[2] = z; }
}
min._dirty = true;
max._dirty = true;
}
},
/**
* Mark attributes and indices in geometry needs to update.
* Usually called after you change the data in attributes.
*/
dirty: function () {
var enabledAttributes = this.getEnabledAttributes();
for (var i = 0; i < enabledAttributes.length; i++) {
this.dirtyAttribute(enabledAttributes[i]);
}
this.dirtyIndices();
this._enabledAttributes = null;
this._cache.dirty('any');
},
/**
* Mark the indices needs to update.
*/
dirtyIndices: function () {
this._cache.dirtyAll('indices');
},
/**
* Mark the attributes needs to update.
* @param {string} [attrName]
*/
dirtyAttribute: function (attrName) {
this._cache.dirtyAll(makeAttrKey(attrName));
this._cache.dirtyAll('attributes');
},
/**
* Get indices of triangle at given index.
* @param {number} idx
* @param {Array.} out
* @return {Array.}
*/
getTriangleIndices: function (idx, out) {
if (idx < this.triangleCount && idx >= 0) {
if (!out) {
out = vec3Create();
}
var indices = this.indices;
out[0] = indices[idx * 3];
out[1] = indices[idx * 3 + 1];
out[2] = indices[idx * 3 + 2];
return out;
}
},
/**
* Set indices of triangle at given index.
* @param {number} idx
* @param {Array.} arr
*/
setTriangleIndices: function (idx, arr) {
var indices = this.indices;
indices[idx * 3] = arr[0];
indices[idx * 3 + 1] = arr[1];
indices[idx * 3 + 2] = arr[2];
},
isUseIndices: function () {
return !!this.indices;
},
/**
* Initialize indices from an array.
* @param {Array} array
*/
initIndicesFromArray: function (array) {
var value;
var ArrayConstructor = this.vertexCount > 0xffff
? __WEBPACK_IMPORTED_MODULE_3__core_vendor__["a" /* default */].Uint32Array : __WEBPACK_IMPORTED_MODULE_3__core_vendor__["a" /* default */].Uint16Array;
// Convert 2d array to flat
if (array[0] && (array[0].length)) {
var n = 0;
var size = 3;
value = new ArrayConstructor(array.length * size);
for (var i = 0; i < array.length; i++) {
for (var j = 0; j < size; j++) {
value[n++] = array[i][j];
}
}
}
else {
value = new ArrayConstructor(array);
}
this.indices = value;
},
/**
* Create a new attribute
* @param {string} name
* @param {string} type
* @param {number} size
* @param {string} [semantic]
*/
createAttribute: function (name, type, size, semantic) {
var attrib = new Attribute(name, type, size, semantic);
if (this.attributes[name]) {
this.removeAttribute(name);
}
this.attributes[name] = attrib;
this._attributeList.push(name);
return attrib;
},
/**
* Remove attribute
* @param {string} name
*/
removeAttribute: function (name) {
var attributeList = this._attributeList;
var idx = attributeList.indexOf(name);
if (idx >= 0) {
attributeList.splice(idx, 1);
delete this.attributes[name];
return true;
}
return false;
},
/**
* Get attribute
* @param {string} name
* @return {clay.Geometry.Attribute}
*/
getAttribute: function (name) {
return this.attributes[name];
},
/**
* Get enabled attributes name list
* Attribute which has the same vertex number with position is treated as a enabled attribute
* @return {string[]}
*/
getEnabledAttributes: function () {
var enabledAttributes = this._enabledAttributes;
var attributeList = this._attributeList;
// Cache
if (enabledAttributes) {
return enabledAttributes;
}
var result = [];
var nVertex = this.vertexCount;
for (var i = 0; i < attributeList.length; i++) {
var name = attributeList[i];
var attrib = this.attributes[name];
if (attrib.value) {
if (attrib.value.length === nVertex * attrib.size) {
result.push(name);
}
}
}
this._enabledAttributes = result;
return result;
},
getBufferChunks: function (renderer) {
var cache = this._cache;
cache.use(renderer.__uid__);
var isAttributesDirty = cache.isDirty('attributes');
var isIndicesDirty = cache.isDirty('indices');
if (isAttributesDirty || isIndicesDirty) {
this._updateBuffer(renderer.gl, isAttributesDirty, isIndicesDirty);
var enabledAttributes = this.getEnabledAttributes();
for (var i = 0; i < enabledAttributes.length; i++) {
cache.fresh(makeAttrKey(enabledAttributes[i]));
}
cache.fresh('attributes');
cache.fresh('indices');
}
cache.fresh('any');
return cache.get('chunks');
},
_updateBuffer: function (_gl, isAttributesDirty, isIndicesDirty) {
var cache = this._cache;
var chunks = cache.get('chunks');
var firstUpdate = false;
if (!chunks) {
chunks = [];
// Intialize
chunks[0] = {
attributeBuffers: [],
indicesBuffer: null
};
cache.put('chunks', chunks);
firstUpdate = true;
}
var chunk = chunks[0];
var attributeBuffers = chunk.attributeBuffers;
var indicesBuffer = chunk.indicesBuffer;
if (isAttributesDirty || firstUpdate) {
var attributeList = this.getEnabledAttributes();
var attributeBufferMap = {};
if (!firstUpdate) {
for (var i = 0; i < attributeBuffers.length; i++) {
attributeBufferMap[attributeBuffers[i].name] = attributeBuffers[i];
}
}
// FIXME If some attributes removed
for (var k = 0; k < attributeList.length; k++) {
var name = attributeList[k];
var attribute = this.attributes[name];
var bufferInfo;
if (!firstUpdate) {
bufferInfo = attributeBufferMap[name];
}
var buffer;
if (bufferInfo) {
buffer = bufferInfo.buffer;
}
else {
buffer = _gl.createBuffer();
}
if (cache.isDirty(makeAttrKey(name))) {
// Only update when they are dirty.
// TODO: Use BufferSubData?
_gl.bindBuffer(_gl.ARRAY_BUFFER, buffer);
_gl.bufferData(_gl.ARRAY_BUFFER, attribute.value, this.dynamic ? __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].DYNAMIC_DRAW : __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].STATIC_DRAW);
}
attributeBuffers[k] = new AttributeBuffer(name, attribute.type, buffer, attribute.size, attribute.semantic);
}
// Remove unused attributes buffers.
// PENDING
for (var i = k; i < attributeBuffers.length; i++) {
_gl.deleteBuffer(attributeBuffers[i].buffer);
}
attributeBuffers.length = k;
}
if (this.isUseIndices() && (isIndicesDirty || firstUpdate)) {
if (!indicesBuffer) {
indicesBuffer = new IndicesBuffer(_gl.createBuffer());
chunk.indicesBuffer = indicesBuffer;
}
indicesBuffer.count = this.indices.length;
_gl.bindBuffer(_gl.ELEMENT_ARRAY_BUFFER, indicesBuffer.buffer);
_gl.bufferData(_gl.ELEMENT_ARRAY_BUFFER, this.indices, this.dynamic ? __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].DYNAMIC_DRAW : __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].STATIC_DRAW);
}
},
/**
* Generate normals per vertex.
*/
generateVertexNormals: function () {
if (!this.vertexCount) {
return;
}
var indices = this.indices;
var attributes = this.attributes;
var positions = attributes.position.value;
var normals = attributes.normal.value;
if (!normals || normals.length !== positions.length) {
normals = attributes.normal.value = new __WEBPACK_IMPORTED_MODULE_3__core_vendor__["a" /* default */].Float32Array(positions.length);
}
else {
// Reset
for (var i = 0; i < normals.length; i++) {
normals[i] = 0;
}
}
var p1 = vec3Create();
var p2 = vec3Create();
var p3 = vec3Create();
var v21 = vec3Create();
var v32 = vec3Create();
var n = vec3Create();
var len = indices ? indices.length : this.vertexCount;
var i1, i2, i3;
for (var f = 0; f < len;) {
if (indices) {
i1 = indices[f++];
i2 = indices[f++];
i3 = indices[f++];
}
else {
i1 = f++;
i2 = f++;
i3 = f++;
}
vec3Set(p1, positions[i1*3], positions[i1*3+1], positions[i1*3+2]);
vec3Set(p2, positions[i2*3], positions[i2*3+1], positions[i2*3+2]);
vec3Set(p3, positions[i3*3], positions[i3*3+1], positions[i3*3+2]);
vec3.sub(v21, p1, p2);
vec3.sub(v32, p2, p3);
vec3.cross(n, v21, v32);
// Already be weighted by the triangle area
for (var i = 0; i < 3; i++) {
normals[i1*3+i] = normals[i1*3+i] + n[i];
normals[i2*3+i] = normals[i2*3+i] + n[i];
normals[i3*3+i] = normals[i3*3+i] + n[i];
}
}
for (var i = 0; i < normals.length;) {
vec3Set(n, normals[i], normals[i+1], normals[i+2]);
vec3.normalize(n, n);
normals[i++] = n[0];
normals[i++] = n[1];
normals[i++] = n[2];
}
this.dirty();
},
/**
* Generate normals per face.
*/
generateFaceNormals: function () {
if (!this.vertexCount) {
return;
}
if (!this.isUniqueVertex()) {
this.generateUniqueVertex();
}
var indices = this.indices;
var attributes = this.attributes;
var positions = attributes.position.value;
var normals = attributes.normal.value;
var p1 = vec3Create();
var p2 = vec3Create();
var p3 = vec3Create();
var v21 = vec3Create();
var v32 = vec3Create();
var n = vec3Create();
if (!normals) {
normals = attributes.normal.value = new Float32Array(positions.length);
}
var len = indices ? indices.length : this.vertexCount;
var i1, i2, i3;
for (var f = 0; f < len;) {
if (indices) {
i1 = indices[f++];
i2 = indices[f++];
i3 = indices[f++];
}
else {
i1 = f++;
i2 = f++;
i3 = f++;
}
vec3Set(p1, positions[i1*3], positions[i1*3+1], positions[i1*3+2]);
vec3Set(p2, positions[i2*3], positions[i2*3+1], positions[i2*3+2]);
vec3Set(p3, positions[i3*3], positions[i3*3+1], positions[i3*3+2]);
vec3.sub(v21, p1, p2);
vec3.sub(v32, p2, p3);
vec3.cross(n, v21, v32);
vec3.normalize(n, n);
for (var i = 0; i < 3; i++) {
normals[i1*3 + i] = n[i];
normals[i2*3 + i] = n[i];
normals[i3*3 + i] = n[i];
}
}
this.dirty();
},
/**
* Generate tangents attributes.
*/
generateTangents: function () {
if (!this.vertexCount) {
return;
}
var nVertex = this.vertexCount;
var attributes = this.attributes;
if (!attributes.tangent.value) {
attributes.tangent.value = new Float32Array(nVertex * 4);
}
var texcoords = attributes.texcoord0.value;
var positions = attributes.position.value;
var tangents = attributes.tangent.value;
var normals = attributes.normal.value;
if (!texcoords) {
console.warn('Geometry without texcoords can\'t generate tangents.');
return;
}
var tan1 = [];
var tan2 = [];
for (var i = 0; i < nVertex; i++) {
tan1[i] = [0.0, 0.0, 0.0];
tan2[i] = [0.0, 0.0, 0.0];
}
var sdir = [0.0, 0.0, 0.0];
var tdir = [0.0, 0.0, 0.0];
var indices = this.indices;
var len = indices ? indices.length : this.vertexCount;
var i1, i2, i3;
for (var i = 0; i < len;) {
if (indices) {
i1 = indices[i++];
i2 = indices[i++];
i3 = indices[i++];
}
else {
i1 = i++;
i2 = i++;
i3 = i++;
}
var st1s = texcoords[i1 * 2],
st2s = texcoords[i2 * 2],
st3s = texcoords[i3 * 2],
st1t = texcoords[i1 * 2 + 1],
st2t = texcoords[i2 * 2 + 1],
st3t = texcoords[i3 * 2 + 1],
p1x = positions[i1 * 3],
p2x = positions[i2 * 3],
p3x = positions[i3 * 3],
p1y = positions[i1 * 3 + 1],
p2y = positions[i2 * 3 + 1],
p3y = positions[i3 * 3 + 1],
p1z = positions[i1 * 3 + 2],
p2z = positions[i2 * 3 + 2],
p3z = positions[i3 * 3 + 2];
var x1 = p2x - p1x,
x2 = p3x - p1x,
y1 = p2y - p1y,
y2 = p3y - p1y,
z1 = p2z - p1z,
z2 = p3z - p1z;
var s1 = st2s - st1s,
s2 = st3s - st1s,
t1 = st2t - st1t,
t2 = st3t - st1t;
var r = 1.0 / (s1 * t2 - t1 * s2);
sdir[0] = (t2 * x1 - t1 * x2) * r;
sdir[1] = (t2 * y1 - t1 * y2) * r;
sdir[2] = (t2 * z1 - t1 * z2) * r;
tdir[0] = (s1 * x2 - s2 * x1) * r;
tdir[1] = (s1 * y2 - s2 * y1) * r;
tdir[2] = (s1 * z2 - s2 * z1) * r;
vec3Add(tan1[i1], tan1[i1], sdir);
vec3Add(tan1[i2], tan1[i2], sdir);
vec3Add(tan1[i3], tan1[i3], sdir);
vec3Add(tan2[i1], tan2[i1], tdir);
vec3Add(tan2[i2], tan2[i2], tdir);
vec3Add(tan2[i3], tan2[i3], tdir);
}
var tmp = vec3Create();
var nCrossT = vec3Create();
var n = vec3Create();
for (var i = 0; i < nVertex; i++) {
n[0] = normals[i * 3];
n[1] = normals[i * 3 + 1];
n[2] = normals[i * 3 + 2];
var t = tan1[i];
// Gram-Schmidt orthogonalize
vec3.scale(tmp, n, vec3.dot(n, t));
vec3.sub(tmp, t, tmp);
vec3.normalize(tmp, tmp);
// Calculate handedness.
vec3.cross(nCrossT, n, t);
tangents[i * 4] = tmp[0];
tangents[i * 4 + 1] = tmp[1];
tangents[i * 4 + 2] = tmp[2];
// PENDING can config ?
tangents[i * 4 + 3] = vec3.dot(nCrossT, tan2[i]) < 0.0 ? -1.0 : 1.0;
}
this.dirty();
},
/**
* If vertices are not shared by different indices.
*/
isUniqueVertex: function () {
if (this.isUseIndices()) {
return this.vertexCount === this.indices.length;
}
else {
return true;
}
},
/**
* Create a unique vertex for each index.
*/
generateUniqueVertex: function () {
if (!this.vertexCount || !this.indices) {
return;
}
if (this.indices.length > 0xffff) {
this.indices = new __WEBPACK_IMPORTED_MODULE_3__core_vendor__["a" /* default */].Uint32Array(this.indices);
}
var attributes = this.attributes;
var indices = this.indices;
var attributeNameList = this.getEnabledAttributes();
var oldAttrValues = {};
for (var a = 0; a < attributeNameList.length; a++) {
var name = attributeNameList[a];
oldAttrValues[name] = attributes[name].value;
attributes[name].init(this.indices.length);
}
var cursor = 0;
for (var i = 0; i < indices.length; i++) {
var ii = indices[i];
for (var a = 0; a < attributeNameList.length; a++) {
var name = attributeNameList[a];
var array = attributes[name].value;
var size = attributes[name].size;
for (var k = 0; k < size; k++) {
array[cursor * size + k] = oldAttrValues[name][ii * size + k];
}
}
indices[i] = cursor;
cursor++;
}
this.dirty();
},
/**
* Generate barycentric coordinates for wireframe draw.
*/
generateBarycentric: function () {
if (!this.vertexCount) {
return;
}
if (!this.isUniqueVertex()) {
this.generateUniqueVertex();
}
var attributes = this.attributes;
var array = attributes.barycentric.value;
var indices = this.indices;
// Already existed;
if (array && array.length === indices.length * 3) {
return;
}
array = attributes.barycentric.value = new Float32Array(indices.length * 3);
for (var i = 0; i < (indices ? indices.length : this.vertexCount / 3);) {
for (var j = 0; j < 3; j++) {
var ii = indices ? indices[i++] : (i * 3 + j);
array[ii * 3 + j] = 1;
}
}
this.dirty();
},
/**
* Apply transform to geometry attributes.
* @param {clay.Matrix4} matrix
*/
applyTransform: function (matrix) {
var attributes = this.attributes;
var positions = attributes.position.value;
var normals = attributes.normal.value;
var tangents = attributes.tangent.value;
matrix = matrix.array;
// Normal Matrix
var inverseTransposeMatrix = mat4.create();
mat4.invert(inverseTransposeMatrix, matrix);
mat4.transpose(inverseTransposeMatrix, inverseTransposeMatrix);
var vec3TransformMat4 = vec3.transformMat4;
var vec3ForEach = vec3.forEach;
vec3ForEach(positions, 3, 0, null, vec3TransformMat4, matrix);
if (normals) {
vec3ForEach(normals, 3, 0, null, vec3TransformMat4, inverseTransposeMatrix);
}
if (tangents) {
vec3ForEach(tangents, 4, 0, null, vec3TransformMat4, inverseTransposeMatrix);
}
if (this.boundingBox) {
this.updateBoundingBox();
}
},
/**
* Dispose geometry data in GL context.
* @param {clay.Renderer} renderer
*/
dispose: function (renderer) {
var cache = this._cache;
cache.use(renderer.__uid__);
var chunks = cache.get('chunks');
if (chunks) {
for (var c = 0; c < chunks.length; c++) {
var chunk = chunks[c];
for (var k = 0; k < chunk.attributeBuffers.length; k++) {
var attribs = chunk.attributeBuffers[k];
renderer.gl.deleteBuffer(attribs.buffer);
}
if (chunk.indicesBuffer) {
renderer.gl.deleteBuffer(chunk.indicesBuffer.buffer);
}
}
}
if (this.__vaoCache) {
var vaoExt = renderer.getGLExtension('OES_vertex_array_object');
for (var id in this.__vaoCache) {
var vao = this.__vaoCache[id].vao;
if (vao) {
vaoExt.deleteVertexArrayOES(vao);
}
}
}
this.__vaoCache = {};
cache.deleteContext(renderer.__uid__);
}
});
if (Object.defineProperty) {
/**
* @name clay.Geometry#vertexCount
* @type {number}
* @readOnly
*/
Object.defineProperty(Geometry.prototype, 'vertexCount', {
enumerable: false,
get: function () {
var mainAttribute = this.attributes[this.mainAttribute];
if (!mainAttribute || !mainAttribute.value) {
return 0;
}
return mainAttribute.value.length / mainAttribute.size;
}
});
/**
* @name clay.Geometry#triangleCount
* @type {number}
* @readOnly
*/
Object.defineProperty(Geometry.prototype, 'triangleCount', {
enumerable: false,
get: function () {
var indices = this.indices;
if (!indices) {
return 0;
}
else {
return indices.length / 3;
}
}
});
}
Geometry.STATIC_DRAW = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].STATIC_DRAW;
Geometry.DYNAMIC_DRAW = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].DYNAMIC_DRAW;
Geometry.STREAM_DRAW = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].STREAM_DRAW;
Geometry.AttributeBuffer = AttributeBuffer;
Geometry.IndicesBuffer = IndicesBuffer;
Geometry.Attribute = Attribute;
/* harmony default export */ __webpack_exports__["a"] = (Geometry);
/***/ }),
/* 14 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_Base__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__camera_Orthographic__ = __webpack_require__(33);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__geometry_Plane__ = __webpack_require__(37);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__Material__ = __webpack_require__(17);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__Mesh__ = __webpack_require__(31);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__core_glenum__ = __webpack_require__(11);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__shader_source_compositor_vertex_glsl_js__ = __webpack_require__(118);
__WEBPACK_IMPORTED_MODULE_3__Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_7__shader_source_compositor_vertex_glsl_js__["a" /* default */]);
var planeGeo = new __WEBPACK_IMPORTED_MODULE_2__geometry_Plane__["a" /* default */]();
var mesh = new __WEBPACK_IMPORTED_MODULE_5__Mesh__["a" /* default */]({
geometry: planeGeo,
frustumCulling: false
});
var camera = new __WEBPACK_IMPORTED_MODULE_1__camera_Orthographic__["a" /* default */]();
/**
* @constructor clay.compositor.Pass
* @extends clay.core.Base
*/
var Pass = __WEBPACK_IMPORTED_MODULE_0__core_Base__["a" /* default */].extend(function () {
return /** @lends clay.compositor.Pass# */ {
/**
* Fragment shader string
* @type {string}
*/
// PENDING shader or fragment ?
fragment : '',
/**
* @type {Object}
*/
outputs : null,
/**
* @type {clay.Material}
*/
material : null,
/**
* @type {Boolean}
*/
blendWithPrevious: false,
/**
* @type {Boolean}
*/
clearColor: false,
/**
* @type {Boolean}
*/
clearDepth: true
};
}, function() {
var shader = new __WEBPACK_IMPORTED_MODULE_3__Shader__["a" /* default */](__WEBPACK_IMPORTED_MODULE_3__Shader__["a" /* default */].source('clay.compositor.vertex'), this.fragment);
var material = new __WEBPACK_IMPORTED_MODULE_4__Material__["a" /* default */]({
shader: shader
});
material.enableTexturesAll();
this.material = material;
},
/** @lends clay.compositor.Pass.prototype */
{
/**
* @param {string} name
* @param {} value
*/
setUniform : function(name, value) {
this.material.setUniform(name, value);
},
/**
* @param {string} name
* @return {}
*/
getUniform : function(name) {
var uniform = this.material.uniforms[name];
if (uniform) {
return uniform.value;
}
},
/**
* @param {clay.Texture} texture
* @param {number} attachment
*/
attachOutput : function(texture, attachment) {
if (!this.outputs) {
this.outputs = {};
}
attachment = attachment || __WEBPACK_IMPORTED_MODULE_6__core_glenum__["a" /* default */].COLOR_ATTACHMENT0;
this.outputs[attachment] = texture;
},
/**
* @param {clay.Texture} texture
*/
detachOutput : function(texture) {
for (var attachment in this.outputs) {
if (this.outputs[attachment] === texture) {
this.outputs[attachment] = null;
}
}
},
bind : function(renderer, frameBuffer) {
if (this.outputs) {
for (var attachment in this.outputs) {
var texture = this.outputs[attachment];
if (texture) {
frameBuffer.attach(texture, attachment);
}
}
}
if (frameBuffer) {
frameBuffer.bind(renderer);
}
},
unbind : function(renderer, frameBuffer) {
frameBuffer.unbind(renderer);
},
/**
* @param {clay.Renderer} renderer
* @param {clay.FrameBuffer} [frameBuffer]
*/
render : function(renderer, frameBuffer) {
var _gl = renderer.gl;
if (frameBuffer) {
this.bind(renderer, frameBuffer);
// MRT Support in chrome
// https://www.khronos.org/registry/webgl/sdk/tests/conformance/extensions/ext-draw-buffers.html
var ext = renderer.getGLExtension('EXT_draw_buffers');
if (ext && this.outputs) {
var bufs = [];
for (var attachment in this.outputs) {
attachment = +attachment;
if (attachment >= _gl.COLOR_ATTACHMENT0 && attachment <= _gl.COLOR_ATTACHMENT0 + 8) {
bufs.push(attachment);
}
}
ext.drawBuffersEXT(bufs);
}
}
this.trigger('beforerender', this, renderer);
// FIXME Don't clear in each pass in default, let the color overwrite the buffer
// FIXME pixels may be discard
var clearBit = this.clearDepth ? _gl.DEPTH_BUFFER_BIT : 0;
_gl.depthMask(true);
if (this.clearColor) {
clearBit = clearBit | _gl.COLOR_BUFFER_BIT;
_gl.colorMask(true, true, true, true);
var cc = this.clearColor;
if (Array.isArray(cc)) {
_gl.clearColor(cc[0], cc[1], cc[2], cc[3]);
}
}
_gl.clear(clearBit);
if (this.blendWithPrevious) {
// Blend with previous rendered scene in the final output
// FIXME Configure blend.
// FIXME It will cause screen blink?
_gl.enable(_gl.BLEND);
this.material.transparent = true;
}
else {
_gl.disable(_gl.BLEND);
this.material.transparent = false;
}
this.renderQuad(renderer);
this.trigger('afterrender', this, renderer);
if (frameBuffer) {
this.unbind(renderer, frameBuffer);
}
},
/**
* Simply do quad rendering
*/
renderQuad: function (renderer) {
mesh.material = this.material;
renderer.renderPass([mesh], camera);
},
/**
* @param {clay.Renderer} renderer
*/
dispose: function (renderer) {}
});
/* harmony default export */ __webpack_exports__["a"] = (Pass);
/***/ }),
/* 15 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Vector3__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1__dep_glmatrix__);
var vec3 = __WEBPACK_IMPORTED_MODULE_1__dep_glmatrix___default.a.vec3;
var vec3Copy = vec3.copy;
var vec3Set = vec3.set;
/**
* Axis aligned bounding box
* @constructor
* @alias clay.BoundingBox
* @param {clay.Vector3} [min]
* @param {clay.Vector3} [max]
*/
var BoundingBox = function (min, max) {
/**
* Minimum coords of bounding box
* @type {clay.Vector3}
*/
this.min = min || new __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */](Infinity, Infinity, Infinity);
/**
* Maximum coords of bounding box
* @type {clay.Vector3}
*/
this.max = max || new __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */](-Infinity, -Infinity, -Infinity);
this.vertices = null;
};
BoundingBox.prototype = {
constructor: BoundingBox,
/**
* Update min and max coords from a vertices array
* @param {array} vertices
*/
updateFromVertices: function (vertices) {
if (vertices.length > 0) {
var min = this.min;
var max = this.max;
var minArr = min.array;
var maxArr = max.array;
vec3Copy(minArr, vertices[0]);
vec3Copy(maxArr, vertices[0]);
for (var i = 1; i < vertices.length; i++) {
var vertex = vertices[i];
if (vertex[0] < minArr[0]) { minArr[0] = vertex[0]; }
if (vertex[1] < minArr[1]) { minArr[1] = vertex[1]; }
if (vertex[2] < minArr[2]) { minArr[2] = vertex[2]; }
if (vertex[0] > maxArr[0]) { maxArr[0] = vertex[0]; }
if (vertex[1] > maxArr[1]) { maxArr[1] = vertex[1]; }
if (vertex[2] > maxArr[2]) { maxArr[2] = vertex[2]; }
}
min._dirty = true;
max._dirty = true;
}
},
/**
* Union operation with another bounding box
* @param {clay.BoundingBox} bbox
*/
union: function (bbox) {
var min = this.min;
var max = this.max;
vec3.min(min.array, min.array, bbox.min.array);
vec3.max(max.array, max.array, bbox.max.array);
min._dirty = true;
max._dirty = true;
return this;
},
/**
* Intersection operation with another bounding box
* @param {clay.BoundingBox} bbox
*/
intersection: function (bbox) {
var min = this.min;
var max = this.max;
vec3.max(min.array, min.array, bbox.min.array);
vec3.min(max.array, max.array, bbox.max.array);
min._dirty = true;
max._dirty = true;
return this;
},
/**
* If intersect with another bounding box
* @param {clay.BoundingBox} bbox
* @return {boolean}
*/
intersectBoundingBox: function (bbox) {
var _min = this.min.array;
var _max = this.max.array;
var _min2 = bbox.min.array;
var _max2 = bbox.max.array;
return ! (_min[0] > _max2[0] || _min[1] > _max2[1] || _min[2] > _max2[2]
|| _max[0] < _min2[0] || _max[1] < _min2[1] || _max[2] < _min2[2]);
},
/**
* If contain another bounding box entirely
* @param {clay.BoundingBox} bbox
* @return {boolean}
*/
containBoundingBox: function (bbox) {
var _min = this.min.array;
var _max = this.max.array;
var _min2 = bbox.min.array;
var _max2 = bbox.max.array;
return _min[0] <= _min2[0] && _min[1] <= _min2[1] && _min[2] <= _min2[2]
&& _max[0] >= _max2[0] && _max[1] >= _max2[1] && _max[2] >= _max2[2];
},
/**
* If contain point entirely
* @param {clay.Vector3} point
* @return {boolean}
*/
containPoint: function (p) {
var _min = this.min.array;
var _max = this.max.array;
var _p = p.array;
return _min[0] <= _p[0] && _min[1] <= _p[1] && _min[2] <= _p[2]
&& _max[0] >= _p[0] && _max[1] >= _p[1] && _max[2] >= _p[2];
},
/**
* If bounding box is finite
*/
isFinite: function () {
var _min = this.min.array;
var _max = this.max.array;
return isFinite(_min[0]) && isFinite(_min[1]) && isFinite(_min[2])
&& isFinite(_max[0]) && isFinite(_max[1]) && isFinite(_max[2]);
},
/**
* Apply an affine transform matrix to the bounding box
* @param {clay.Matrix4} matrix
*/
applyTransform: function (matrix) {
this.transformFrom(this, matrix);
},
/**
* Get from another bounding box and an affine transform matrix.
* @param {clay.BoundingBox} source
* @param {clay.Matrix4} matrix
*/
transformFrom: (function () {
// http://dev.theomader.com/transform-bounding-boxes/
var xa = vec3.create();
var xb = vec3.create();
var ya = vec3.create();
var yb = vec3.create();
var za = vec3.create();
var zb = vec3.create();
return function (source, matrix) {
var min = source.min.array;
var max = source.max.array;
var m = matrix.array;
xa[0] = m[0] * min[0]; xa[1] = m[1] * min[0]; xa[2] = m[2] * min[0];
xb[0] = m[0] * max[0]; xb[1] = m[1] * max[0]; xb[2] = m[2] * max[0];
ya[0] = m[4] * min[1]; ya[1] = m[5] * min[1]; ya[2] = m[6] * min[1];
yb[0] = m[4] * max[1]; yb[1] = m[5] * max[1]; yb[2] = m[6] * max[1];
za[0] = m[8] * min[2]; za[1] = m[9] * min[2]; za[2] = m[10] * min[2];
zb[0] = m[8] * max[2]; zb[1] = m[9] * max[2]; zb[2] = m[10] * max[2];
min = this.min.array;
max = this.max.array;
min[0] = Math.min(xa[0], xb[0]) + Math.min(ya[0], yb[0]) + Math.min(za[0], zb[0]) + m[12];
min[1] = Math.min(xa[1], xb[1]) + Math.min(ya[1], yb[1]) + Math.min(za[1], zb[1]) + m[13];
min[2] = Math.min(xa[2], xb[2]) + Math.min(ya[2], yb[2]) + Math.min(za[2], zb[2]) + m[14];
max[0] = Math.max(xa[0], xb[0]) + Math.max(ya[0], yb[0]) + Math.max(za[0], zb[0]) + m[12];
max[1] = Math.max(xa[1], xb[1]) + Math.max(ya[1], yb[1]) + Math.max(za[1], zb[1]) + m[13];
max[2] = Math.max(xa[2], xb[2]) + Math.max(ya[2], yb[2]) + Math.max(za[2], zb[2]) + m[14];
this.min._dirty = true;
this.max._dirty = true;
return this;
};
})(),
/**
* Apply a projection matrix to the bounding box
* @param {clay.Matrix4} matrix
*/
applyProjection: function (matrix) {
var min = this.min.array;
var max = this.max.array;
var m = matrix.array;
// min in min z
var v10 = min[0];
var v11 = min[1];
var v12 = min[2];
// max in min z
var v20 = max[0];
var v21 = max[1];
var v22 = min[2];
// max in max z
var v30 = max[0];
var v31 = max[1];
var v32 = max[2];
if (m[15] === 1) { // Orthographic projection
min[0] = m[0] * v10 + m[12];
min[1] = m[5] * v11 + m[13];
max[2] = m[10] * v12 + m[14];
max[0] = m[0] * v30 + m[12];
max[1] = m[5] * v31 + m[13];
min[2] = m[10] * v32 + m[14];
}
else {
var w = -1 / v12;
min[0] = m[0] * v10 * w;
min[1] = m[5] * v11 * w;
max[2] = (m[10] * v12 + m[14]) * w;
w = -1 / v22;
max[0] = m[0] * v20 * w;
max[1] = m[5] * v21 * w;
w = -1 / v32;
min[2] = (m[10] * v32 + m[14]) * w;
}
this.min._dirty = true;
this.max._dirty = true;
return this;
},
updateVertices: function () {
var vertices = this.vertices;
if (!vertices) {
// Cube vertices
vertices = [];
for (var i = 0; i < 8; i++) {
vertices[i] = vec3.fromValues(0, 0, 0);
}
/**
* Eight coords of bounding box
* @type {Float32Array[]}
*/
this.vertices = vertices;
}
var min = this.min.array;
var max = this.max.array;
//--- min z
// min x
vec3Set(vertices[0], min[0], min[1], min[2]);
vec3Set(vertices[1], min[0], max[1], min[2]);
// max x
vec3Set(vertices[2], max[0], min[1], min[2]);
vec3Set(vertices[3], max[0], max[1], min[2]);
//-- max z
vec3Set(vertices[4], min[0], min[1], max[2]);
vec3Set(vertices[5], min[0], max[1], max[2]);
vec3Set(vertices[6], max[0], min[1], max[2]);
vec3Set(vertices[7], max[0], max[1], max[2]);
return this;
},
/**
* Copy values from another bounding box
* @param {clay.BoundingBox} bbox
*/
copy: function (bbox) {
var min = this.min;
var max = this.max;
vec3Copy(min.array, bbox.min.array);
vec3Copy(max.array, bbox.max.array);
min._dirty = true;
max._dirty = true;
return this;
},
/**
* Clone a new bounding box
* @return {clay.BoundingBox}
*/
clone: function () {
var boundingBox = new BoundingBox();
boundingBox.copy(this);
return boundingBox;
}
};
/* harmony default export */ __webpack_exports__["a"] = (BoundingBox);
/***/ }),
/* 16 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = (function (seriesType, ecModel, api) {
return {
seriesType: seriesType,
reset: function (seriesModel, ecModel) {
var data = seriesModel.getData();
var opacityAccessPath = seriesModel.visualColorAccessPath.split('.');
opacityAccessPath[opacityAccessPath.length - 1] ='opacity';
var opacity = seriesModel.get(opacityAccessPath);
data.setVisual('opacity', opacity == null ? 1 : opacity);
function dataEach(data, idx) {
var itemModel = data.getItemModel(idx);
var opacity = itemModel.get(opacityAccessPath, true);
if (opacity != null) {
data.setItemVisual(idx, 'opacity', opacity);
}
}
return {
dataEach: data.hasItemOption ? dataEach : null
};
}
};
});
/***/ }),
/* 17 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_Base__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Texture__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__core_util__ = __webpack_require__(20);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__core_color__ = __webpack_require__(105);
var parseColor = __WEBPACK_IMPORTED_MODULE_3__core_color__["a" /* default */].parseToFloat;
var programKeyCache = {};
function getDefineCode(defines) {
var defineKeys = Object.keys(defines);
defineKeys.sort();
var defineStr = [];
// Custom Defines
for (var i = 0; i < defineKeys.length; i++) {
var key = defineKeys[i];
var value = defines[key];
if (value === null) {
defineStr.push(key);
}
else{
defineStr.push(key + ' ' + value.toString());
}
}
return defineStr.join('\n');
}
function getProgramKey(vertexDefines, fragmentDefines, enabledTextures) {
enabledTextures.sort();
var defineStr = [];
for (var i = 0; i < enabledTextures.length; i++) {
var symbol = enabledTextures[i];
defineStr.push(symbol);
}
var key = getDefineCode(vertexDefines) + '\n'
+ getDefineCode(fragmentDefines) + '\n'
+ defineStr.join('\n');
if (programKeyCache[key]) {
return programKeyCache[key];
}
var id = __WEBPACK_IMPORTED_MODULE_2__core_util__["a" /* default */].genGUID();
programKeyCache[key] = id;
return id;
}
/**
* Material defines the appearance of mesh surface, like `color`, `roughness`, `metalness`, etc.
* It contains a {@link clay.Shader} and corresponding uniforms.
*
* Here is a basic example to create a standard material
```js
var material = new clay.Material({
shader: new clay.Shader(
clay.Shader.source('clay.vertex'),
clay.Shader.source('clay.fragment')
)
});
```
* @constructor clay.Material
* @extends clay.core.Base
*/
var Material = __WEBPACK_IMPORTED_MODULE_0__core_Base__["a" /* default */].extend(function () {
return /** @lends clay.Material# */ {
/**
* @type {string}
*/
name: '',
/**
* @type {Object}
*/
// uniforms: null,
/**
* @type {clay.Shader}
*/
// shader: null,
/**
* @type {boolean}
*/
depthTest: true,
/**
* @type {boolean}
*/
depthMask: true,
/**
* @type {boolean}
*/
transparent: false,
/**
* Blend func is a callback function when the material
* have custom blending
* The gl context will be the only argument passed in tho the
* blend function
* Detail of blend function in WebGL:
* http://www.khronos.org/registry/gles/specs/2.0/es_full_spec_2.0.25.pdf
*
* Example :
* function(_gl) {
* _gl.blendEquation(_gl.FUNC_ADD);
* _gl.blendFunc(_gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA);
* }
*/
blend: null,
/**
* If update texture status automatically.
*/
autoUpdateTextureStatus: true,
uniforms: {},
vertexDefines: {},
fragmentDefines: {},
_textureStatus: {},
// shadowTransparentMap : null
// PENDING enable the uniform that only used in shader.
_enabledUniforms: null,
};
}, function () {
if (!this.name) {
this.name = 'MATERIAL_' + this.__uid__;
}
if (this.shader) {
// Keep status, mainly preset uniforms, vertexDefines and fragmentDefines
this.attachShader(this.shader, true);
}
},
/** @lends clay.Material.prototype */
{
precision: 'highp',
/**
* Set material uniform
* @example
* mat.setUniform('color', [1, 1, 1, 1]);
* @param {string} symbol
* @param {number|array|clay.Texture|ArrayBufferView} value
*/
setUniform: function (symbol, value) {
if (value === undefined) {
console.warn('Uniform value "' + symbol + '" is undefined');
}
var uniform = this.uniforms[symbol];
if (uniform) {
if (typeof value === 'string') {
// Try to parse as a color. Invalid color string will return null.
value = parseColor(value) || value;
}
uniform.value = value;
if (this.autoUpdateTextureStatus && uniform.type === 't') {
if (value) {
this.enableTexture(symbol);
}
else {
this.disableTexture(symbol);
}
}
}
},
/**
* @param {Object} obj
*/
setUniforms: function(obj) {
for (var key in obj) {
var val = obj[key];
this.setUniform(key, val);
}
},
/**
* @param {string} symbol
* @return {boolean}
*/
isUniformEnabled: function (symbol) {
return this._enabledUniforms.indexOf(symbol) >= 0;
},
getEnabledUniforms: function () {
return this._enabledUniforms;
},
getTextureUniforms: function () {
return this._textureUniforms;
},
/**
* Alias of setUniform and setUniforms
* @param {object|string} symbol
* @param {number|array|clay.Texture|ArrayBufferView} [value]
*/
set: function (symbol, value) {
if (typeof(symbol) === 'object') {
for (var key in symbol) {
var val = symbol[key];
this.setUniform(key, val);
}
}
else {
this.setUniform(symbol, value);
}
},
/**
* Get uniform value
* @param {string} symbol
* @return {number|array|clay.Texture|ArrayBufferView}
*/
get: function (symbol) {
var uniform = this.uniforms[symbol];
if (uniform) {
return uniform.value;
}
},
/**
* Attach a shader instance
* @param {clay.Shader} shader
* @param {boolean} keepStatus If try to keep uniform and texture
*/
attachShader: function(shader, keepStatus) {
var originalUniforms = this.uniforms;
// Ignore if uniform can use in shader.
this.uniforms = shader.createUniforms();
this.shader = shader;
var uniforms = this.uniforms;
this._enabledUniforms = Object.keys(uniforms);
// Make sure uniforms are set in same order to avoid texture slot wrong
this._enabledUniforms.sort();
this._textureUniforms = this._enabledUniforms.filter(function (uniformName) {
var type = this.uniforms[uniformName].type;
return type === 't' || type === 'tv';
}, this);
var originalVertexDefines = this.vertexDefines;
var originalFragmentDefines = this.fragmentDefines;
this.vertexDefines = __WEBPACK_IMPORTED_MODULE_2__core_util__["a" /* default */].clone(shader.vertexDefines);
this.fragmentDefines = __WEBPACK_IMPORTED_MODULE_2__core_util__["a" /* default */].clone(shader.fragmentDefines);
if (keepStatus) {
for (var symbol in originalUniforms) {
if (uniforms[symbol]) {
uniforms[symbol].value = originalUniforms[symbol].value;
}
}
__WEBPACK_IMPORTED_MODULE_2__core_util__["a" /* default */].defaults(this.vertexDefines, originalVertexDefines);
__WEBPACK_IMPORTED_MODULE_2__core_util__["a" /* default */].defaults(this.fragmentDefines, originalFragmentDefines);
}
var textureStatus = {};
for (var key in shader.textures) {
textureStatus[key] = {
shaderType: shader.textures[key].shaderType,
type: shader.textures[key].type,
enabled: (keepStatus && this._textureStatus[key]) ? this._textureStatus[key].enabled : false
};
}
this._textureStatus = textureStatus;
this._programKey = '';
},
/**
* Clone a new material and keep uniforms, shader will not be cloned
* @return {clay.Material}
*/
clone: function () {
var material = new this.constructor({
name: this.name,
shader: this.shader
});
for (var symbol in this.uniforms) {
material.uniforms[symbol].value = this.uniforms[symbol].value;
}
material.depthTest = this.depthTest;
material.depthMask = this.depthMask;
material.transparent = this.transparent;
material.blend = this.blend;
material.vertexDefines = __WEBPACK_IMPORTED_MODULE_2__core_util__["a" /* default */].clone(this.vertexDefines);
material.fragmentDefines = __WEBPACK_IMPORTED_MODULE_2__core_util__["a" /* default */].clone(this.fragmentDefines);
material.enableTexture(this.getEnabledTextures());
material.precision = this.precision;
return material;
},
/**
* Add a #define macro in shader code
* @param {string} shaderType Can be vertex, fragment or both
* @param {string} symbol
* @param {number} [val]
*/
define: function (shaderType, symbol, val) {
var vertexDefines = this.vertexDefines;
var fragmentDefines = this.fragmentDefines;
if (shaderType !== 'vertex' && shaderType !== 'fragment' && shaderType !== 'both'
&& arguments.length < 3
) {
// shaderType default to be 'both'
val = symbol;
symbol = shaderType;
shaderType = 'both';
}
val = val != null ? val : null;
if (shaderType === 'vertex' || shaderType === 'both') {
if (vertexDefines[symbol] !== val) {
vertexDefines[symbol] = val;
// Mark as dirty
this._programKey = '';
}
}
if (shaderType === 'fragment' || shaderType === 'both') {
if (fragmentDefines[symbol] !== val) {
fragmentDefines[symbol] = val;
if (shaderType !== 'both') {
this._programKey = '';
}
}
}
},
/**
* Remove a #define macro in shader code
* @param {string} shaderType Can be vertex, fragment or both
* @param {string} symbol
*/
undefine: function (shaderType, symbol) {
if (shaderType !== 'vertex' && shaderType !== 'fragment' && shaderType !== 'both'
&& arguments.length < 2
) {
// shaderType default to be 'both'
symbol = shaderType;
shaderType = 'both';
}
if (shaderType === 'vertex' || shaderType === 'both') {
if (this.isDefined('vertex', symbol)) {
delete this.vertexDefines[symbol];
// Mark as dirty
this._programKey = '';
}
}
if (shaderType === 'fragment' || shaderType === 'both') {
if (this.isDefined('fragment', symbol)) {
delete this.fragmentDefines[symbol];
if (shaderType !== 'both') {
this._programKey = '';
}
}
}
},
/**
* If macro is defined in shader.
* @param {string} shaderType Can be vertex, fragment or both
* @param {string} symbol
*/
isDefined: function (shaderType, symbol) {
// PENDING hasOwnProperty ?
switch (shaderType) {
case 'vertex':
return this.vertexDefines[symbol] !== undefined;
case 'fragment':
return this.fragmentDefines[symbol] !== undefined;
}
},
/**
* Get macro value defined in shader.
* @param {string} shaderType Can be vertex, fragment or both
* @param {string} symbol
*/
getDefine: function (shaderType, symbol) {
switch(shaderType) {
case 'vertex':
return this.vertexDefines[symbol];
case 'fragment':
return this.fragmentDefines[symbol];
}
},
/**
* Enable a texture, actually it will add a #define macro in the shader code
* For example, if texture symbol is diffuseMap, it will add a line `#define DIFFUSEMAP_ENABLED` in the shader code
* @param {string} symbol
*/
enableTexture: function (symbol) {
if (Array.isArray(symbol)) {
for (var i = 0; i < symbol.length; i++) {
this.enableTexture(symbol[i]);
}
return;
}
var status = this._textureStatus[symbol];
if (status) {
var isEnabled = status.enabled;
if (!isEnabled) {
status.enabled = true;
this._programKey = '';
}
}
},
/**
* Enable all textures used in the shader
*/
enableTexturesAll: function () {
var textureStatus = this._textureStatus;
for (var symbol in textureStatus) {
textureStatus[symbol].enabled = true;
}
this._programKey = '';
},
/**
* Disable a texture, it remove a #define macro in the shader
* @param {string} symbol
*/
disableTexture: function (symbol) {
if (Array.isArray(symbol)) {
for (var i = 0; i < symbol.length; i++) {
this.disableTexture(symbol[i]);
}
return;
}
var status = this._textureStatus[symbol];
if (status) {
var isDisabled = ! status.enabled;
if (!isDisabled) {
status.enabled = false;
this._programKey = '';
}
}
},
/**
* Disable all textures used in the shader
*/
disableTexturesAll: function () {
var textureStatus = this._textureStatus;
for (var symbol in textureStatus) {
textureStatus[symbol].enabled = false;
}
this._programKey = '';
},
/**
* If texture of given type is enabled.
* @param {string} symbol
* @return {boolean}
*/
isTextureEnabled: function (symbol) {
var textureStatus = this._textureStatus;
return !!textureStatus[symbol]
&& textureStatus[symbol].enabled;
},
/**
* Get all enabled textures
* @return {string[]}
*/
getEnabledTextures: function () {
var enabledTextures = [];
var textureStatus = this._textureStatus;
for (var symbol in textureStatus) {
if (textureStatus[symbol].enabled) {
enabledTextures.push(symbol);
}
}
return enabledTextures;
},
/**
* Mark defines are updated.
*/
dirtyDefines: function () {
this._programKey = '';
},
getProgramKey: function () {
if (!this._programKey) {
this._programKey = getProgramKey(
this.vertexDefines, this.fragmentDefines, this.getEnabledTextures()
);
}
return this._programKey;
}
});
/* harmony default export */ __webpack_exports__["a"] = (Material);
/***/ }),
/* 18 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
var supportWebGL = true;
try {
var canvas = document.createElement('canvas');
var gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
if (!gl) {
throw new Error();
}
} catch (e) {
supportWebGL = false;
}
var vendor = {};
/**
* If support WebGL
* @return {boolean}
*/
vendor.supportWebGL = function () {
return supportWebGL;
};
vendor.Int8Array = typeof Int8Array == 'undefined' ? Array : Int8Array;
vendor.Uint8Array = typeof Uint8Array == 'undefined' ? Array : Uint8Array;
vendor.Uint16Array = typeof Uint16Array == 'undefined' ? Array : Uint16Array;
vendor.Uint32Array = typeof Uint32Array == 'undefined' ? Array : Uint32Array;
vendor.Int16Array = typeof Int16Array == 'undefined' ? Array : Int16Array;
vendor.Float32Array = typeof Float32Array == 'undefined' ? Array : Float32Array;
vendor.Float64Array = typeof Float64Array == 'undefined' ? Array : Float64Array;
/* harmony default export */ __webpack_exports__["a"] = (vendor);
/***/ }),
/* 19 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_Scene__ = __webpack_require__(32);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_prePass_ShadowMap__ = __webpack_require__(165);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_camera_Perspective__ = __webpack_require__(36);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_claygl_src_camera_Orthographic__ = __webpack_require__(33);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_claygl_src_math_Matrix4__ = __webpack_require__(7);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_claygl_src_math_Vector3__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_claygl_src_math_Vector2__ = __webpack_require__(23);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8_claygl_src_core_mixin_notifier__ = __webpack_require__(47);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__effect_EffectCompositor__ = __webpack_require__(167);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__effect_TemporalSuperSampling__ = __webpack_require__(192);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__effect_halton__ = __webpack_require__(43);
/*
* @module echarts-gl/core/ViewGL
* @author Yi Shen(http://github.com/pissang)
*/
/**
* @constructor
* @alias module:echarts-gl/core/ViewGL
* @param {string} [projection='perspective']
*/
function ViewGL(projection) {
projection = projection || 'perspective';
/**
* @type {module:echarts-gl/core/LayerGL}
*/
this.layer = null;
/**
* @type {clay.Scene}
*/
this.scene = new __WEBPACK_IMPORTED_MODULE_1_claygl_src_Scene__["a" /* default */]();
/**
* @type {clay.Node}
*/
this.rootNode = this.scene;
this.viewport = {
x: 0, y: 0, width: 0, height: 0
};
this.setProjection(projection);
this._compositor = new __WEBPACK_IMPORTED_MODULE_9__effect_EffectCompositor__["a" /* default */]();
this._temporalSS = new __WEBPACK_IMPORTED_MODULE_10__effect_TemporalSuperSampling__["a" /* default */]();
this._shadowMapPass = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_prePass_ShadowMap__["a" /* default */]();
var pcfKernels = [];
var off = 0;
for (var i = 0; i < 30; i++) {
var pcfKernel = [];
for (var k = 0; k < 6; k++) {
pcfKernel.push(Object(__WEBPACK_IMPORTED_MODULE_11__effect_halton__["a" /* default */])(off, 2) * 4.0 - 2.0);
pcfKernel.push(Object(__WEBPACK_IMPORTED_MODULE_11__effect_halton__["a" /* default */])(off, 3) * 4.0 - 2.0);
off++;
}
pcfKernels.push(pcfKernel);
}
this._pcfKernels = pcfKernels;
this.scene.on('beforerender', function (renderer, scene, camera) {
if (this.needsTemporalSS()) {
this._temporalSS.jitterProjection(renderer, camera);
}
}, this);
}
/**
* Set camera type of group
* @param {string} cameraType 'perspective' | 'orthographic'
*/
ViewGL.prototype.setProjection = function (projection) {
var oldCamera = this.camera;
oldCamera && oldCamera.update();
if (projection === 'perspective') {
if (!(this.camera instanceof __WEBPACK_IMPORTED_MODULE_3_claygl_src_camera_Perspective__["a" /* default */])) {
this.camera = new __WEBPACK_IMPORTED_MODULE_3_claygl_src_camera_Perspective__["a" /* default */]();
if (oldCamera) {
this.camera.setLocalTransform(oldCamera.localTransform);
}
}
}
else {
if (!(this.camera instanceof __WEBPACK_IMPORTED_MODULE_4_claygl_src_camera_Orthographic__["a" /* default */])) {
this.camera = new __WEBPACK_IMPORTED_MODULE_4_claygl_src_camera_Orthographic__["a" /* default */]();
if (oldCamera) {
this.camera.setLocalTransform(oldCamera.localTransform);
}
}
}
// PENDING
this.camera.near = 0.1;
this.camera.far = 2000;
};
/**
* Set viewport of group
* @param {number} x Viewport left bottom x
* @param {number} y Viewport left bottom y
* @param {number} width Viewport height
* @param {number} height Viewport height
* @param {number} [dpr=1]
*/
ViewGL.prototype.setViewport = function (x, y, width, height, dpr) {
if (this.camera instanceof __WEBPACK_IMPORTED_MODULE_3_claygl_src_camera_Perspective__["a" /* default */]) {
this.camera.aspect = width / height;
}
dpr = dpr || 1;
this.viewport.x = x;
this.viewport.y = y;
this.viewport.width = width;
this.viewport.height = height;
this.viewport.devicePixelRatio = dpr;
// Source and output of compositor use high dpr texture.
// But the intermediate texture of bloom, dof effects use fixed 1.0 dpr
this._compositor.resize(width * dpr, height * dpr);
this._temporalSS.resize(width * dpr, height * dpr);
};
/**
* If contain screen point x, y
* @param {number} x offsetX
* @param {number} y offsetY
* @return {boolean}
*/
ViewGL.prototype.containPoint = function (x, y) {
var viewport = this.viewport;
var height = this.layer.renderer.getHeight();
// Flip y;
y = height - y;
return x >= viewport.x && y >= viewport.y
&& x <= viewport.x + viewport.width && y <= viewport.y + viewport.height;
};
/**
* Cast a ray
* @param {number} x offsetX
* @param {number} y offsetY
* @param {clay.math.Ray} out
* @return {clay.math.Ray}
*/
var ndc = new __WEBPACK_IMPORTED_MODULE_7_claygl_src_math_Vector2__["a" /* default */]();
ViewGL.prototype.castRay = function (x, y, out) {
var renderer = this.layer.renderer;
var oldViewport = renderer.viewport;
renderer.viewport = this.viewport;
renderer.screenToNDC(x, y, ndc);
this.camera.castRay(ndc, out);
renderer.viewport = oldViewport;
return out;
};
/**
* Prepare and update scene before render
*/
ViewGL.prototype.prepareRender = function () {
this.scene.update();
this.camera.update();
this.scene.updateLights();
var renderList = this.scene.updateRenderList(this.camera);
this._needsSortProgressively = false;
// If has any transparent mesh needs sort triangles progressively.
for (var i = 0; i < renderList.transparent.length; i++) {
var renderable = renderList.transparent[i];
var geometry = renderable.geometry;
if (geometry.needsSortVerticesProgressively && geometry.needsSortVerticesProgressively()) {
this._needsSortProgressively = true;
}
if (geometry.needsSortTrianglesProgressively && geometry.needsSortTrianglesProgressively()) {
this._needsSortProgressively = true;
}
}
this._frame = 0;
this._temporalSS.resetFrame();
// var lights = this.scene.getLights();
// for (var i = 0; i < lights.length; i++) {
// if (lights[i].cubemap) {
// if (this._compositor && this._compositor.isSSREnabled()) {
// lights[i].invisible = true;
// }
// else {
// lights[i].invisible = false;
// }
// }
// }
};
ViewGL.prototype.render = function (renderer, accumulating) {
this._doRender(renderer, accumulating, this._frame);
this._frame++;
};
ViewGL.prototype.needsAccumulate = function () {
return this.needsTemporalSS() || this._needsSortProgressively;
};
ViewGL.prototype.needsTemporalSS = function () {
var enableTemporalSS = this._enableTemporalSS;
if (enableTemporalSS === 'auto') {
enableTemporalSS = this._enablePostEffect;
}
return enableTemporalSS;
};
ViewGL.prototype.hasDOF = function () {
return this._enableDOF;
};
ViewGL.prototype.isAccumulateFinished = function () {
return this.needsTemporalSS() ? this._temporalSS.isFinished()
: (this._frame > 30);
};
ViewGL.prototype._doRender = function (renderer, accumulating, accumFrame) {
var scene = this.scene;
var camera = this.camera;
accumFrame = accumFrame || 0;
this._updateTransparent(renderer, scene, camera, accumFrame);
if (!accumulating) {
this._shadowMapPass.kernelPCF = this._pcfKernels[0];
// Not render shadowmap pass in accumulating frame.
this._shadowMapPass.render(renderer, scene, camera, true);
}
this._updateShadowPCFKernel(accumFrame);
// Shadowmap will set clear color.
var bgColor = renderer.clearColor;
renderer.gl.clearColor(bgColor[0], bgColor[1], bgColor[2], bgColor[3]);
if (this._enablePostEffect) {
// normal render also needs to be jittered when have edge pass.
if (this.needsTemporalSS()) {
this._temporalSS.jitterProjection(renderer, camera);
}
this._compositor.updateNormal(renderer, scene, camera, this._temporalSS.getFrame());
}
// Always update SSAO to make sure have correct ssaoMap status
this._updateSSAO(renderer, scene, camera, this._temporalSS.getFrame());
if (this._enablePostEffect) {
var frameBuffer = this._compositor.getSourceFrameBuffer();
frameBuffer.bind(renderer);
renderer.gl.clear(renderer.gl.DEPTH_BUFFER_BIT | renderer.gl.COLOR_BUFFER_BIT);
renderer.render(scene, camera, true, true);
frameBuffer.unbind(renderer);
if (this.needsTemporalSS() && accumulating) {
this._compositor.composite(renderer, scene, camera, this._temporalSS.getSourceFrameBuffer(), this._temporalSS.getFrame());
renderer.setViewport(this.viewport);
this._temporalSS.render(renderer);
}
else {
renderer.setViewport(this.viewport);
this._compositor.composite(renderer, scene, camera, null, 0);
}
}
else {
if (this.needsTemporalSS() && accumulating) {
var frameBuffer = this._temporalSS.getSourceFrameBuffer();
frameBuffer.bind(renderer);
renderer.saveClear();
renderer.clearBit = renderer.gl.DEPTH_BUFFER_BIT | renderer.gl.COLOR_BUFFER_BIT;
renderer.render(scene, camera, true, true);
renderer.restoreClear();
frameBuffer.unbind(renderer);
renderer.setViewport(this.viewport);
this._temporalSS.render(renderer);
}
else {
renderer.setViewport(this.viewport);
renderer.render(scene, camera, true, true);
}
}
// this._shadowMapPass.renderDebug(renderer);
// this._compositor._normalPass.renderDebug(renderer);
};
ViewGL.prototype._updateTransparent = function (renderer, scene, camera, frame) {
var v3 = new __WEBPACK_IMPORTED_MODULE_6_claygl_src_math_Vector3__["a" /* default */]();
var invWorldTransform = new __WEBPACK_IMPORTED_MODULE_5_claygl_src_math_Matrix4__["a" /* default */]();
var cameraWorldPosition = camera.getWorldPosition();
var transparentList = scene.getRenderList(camera).transparent;
// Sort transparent object.
for (var i = 0; i < transparentList.length; i++) {
var renderable = transparentList[i];
var geometry = renderable.geometry;
__WEBPACK_IMPORTED_MODULE_5_claygl_src_math_Matrix4__["a" /* default */].invert(invWorldTransform, renderable.worldTransform);
__WEBPACK_IMPORTED_MODULE_6_claygl_src_math_Vector3__["a" /* default */].transformMat4(v3, cameraWorldPosition, invWorldTransform);
if (geometry.needsSortTriangles && geometry.needsSortTriangles()) {
geometry.doSortTriangles(v3, frame);
}
if (geometry.needsSortVertices && geometry.needsSortVertices()) {
geometry.doSortVertices(v3, frame);
}
}
};
ViewGL.prototype._updateSSAO = function (renderer, scene, camera) {
var ifEnableSSAO = this._enableSSAO && this._enablePostEffect;
if (ifEnableSSAO) {
this._compositor.updateSSAO(renderer, scene, camera, this._temporalSS.getFrame());
}
var renderList = scene.getRenderList(camera);
for (var i = 0; i < renderList.opaque.length; i++) {
var renderable = renderList.opaque[i];
// PENDING
if (renderable.renderNormal) {
renderable.material[ifEnableSSAO ? 'enableTexture' : 'disableTexture']('ssaoMap');
}
if (ifEnableSSAO) {
renderable.material.set('ssaoMap', this._compositor.getSSAOTexture());
}
}
};
ViewGL.prototype._updateShadowPCFKernel = function (frame) {
var pcfKernel = this._pcfKernels[frame % this._pcfKernels.length];
var renderList = this.scene.getRenderList(this.camera);
var opaqueList = renderList.opaque;
for (var i = 0; i < opaqueList.length; i++) {
if (opaqueList[i].receiveShadow) {
opaqueList[i].material.set('pcfKernel', pcfKernel);
opaqueList[i].material.define('fragment', 'PCF_KERNEL_SIZE', pcfKernel.length / 2);
}
}
};
ViewGL.prototype.dispose = function (renderer) {
this._compositor.dispose(renderer.gl);
this._temporalSS.dispose(renderer.gl);
this._shadowMapPass.dispose(renderer);
};
/**
* @param {module:echarts/Model} Post effect model
*/
ViewGL.prototype.setPostEffect = function (postEffectModel, api) {
var compositor = this._compositor;
this._enablePostEffect = postEffectModel.get('enable');
var bloomModel = postEffectModel.getModel('bloom');
var edgeModel = postEffectModel.getModel('edge');
var dofModel = postEffectModel.getModel('DOF', postEffectModel.getModel('depthOfField'));
var ssaoModel = postEffectModel.getModel('SSAO', postEffectModel.getModel('screenSpaceAmbientOcclusion'));
var ssrModel = postEffectModel.getModel('SSR', postEffectModel.getModel('screenSpaceReflection'));
var fxaaModel = postEffectModel.getModel('FXAA');
var colorCorrModel = postEffectModel.getModel('colorCorrection');
bloomModel.get('enable') ? compositor.enableBloom() : compositor.disableBloom();
dofModel.get('enable') ? compositor.enableDOF() : compositor.disableDOF();
ssrModel.get('enable') ? compositor.enableSSR() : compositor.disableSSR();
colorCorrModel.get('enable') ? compositor.enableColorCorrection() : compositor.disableColorCorrection();
edgeModel.get('enable') ? compositor.enableEdge() : compositor.disableEdge();
fxaaModel.get('enable') ? compositor.enableFXAA() : compositor.disableFXAA();
this._enableDOF = dofModel.get('enable');
this._enableSSAO = ssaoModel.get('enable');
this._enableSSAO ? compositor.enableSSAO() : compositor.disableSSAO();
compositor.setBloomIntensity(bloomModel.get('intensity'));
compositor.setEdgeColor(edgeModel.get('color'));
compositor.setColorLookupTexture(colorCorrModel.get('lookupTexture'), api);
compositor.setExposure(colorCorrModel.get('exposure'));
['radius', 'quality', 'intensity'].forEach(function (name) {
compositor.setSSAOParameter(name, ssaoModel.get(name));
});
['quality', 'maxRoughness', 'physical'].forEach(function (name) {
compositor.setSSRParameter(name, ssrModel.get(name));
});
['quality', 'focalDistance', 'focalRange', 'blurRadius', 'fstop'].forEach(function (name) {
compositor.setDOFParameter(name, dofModel.get(name));
});
['brightness', 'contrast', 'saturation'].forEach(function (name) {
compositor.setColorCorrection(name, colorCorrModel.get(name));
});
};
ViewGL.prototype.setDOFFocusOnPoint = function (depth) {
if (this._enablePostEffect) {
if (depth > this.camera.far || depth < this.camera.near) {
return;
}
this._compositor.setDOFParameter('focalDistance', depth);
return true;
}
};
ViewGL.prototype.setTemporalSuperSampling = function (temporalSuperSamplingModel) {
this._enableTemporalSS = temporalSuperSamplingModel.get('enable');
};
ViewGL.prototype.isLinearSpace = function () {
return this._enablePostEffect;
};
ViewGL.prototype.setRootNode = function (rootNode) {
if (this.rootNode === rootNode) {
return;
}
var children = this.rootNode.children();
for (var i = 0; i < children.length; i++) {
rootNode.add(children[i]);
}
if (rootNode !== this.scene) {
this.scene.add(rootNode);
}
this.rootNode = rootNode;
};
// Proxies
ViewGL.prototype.add = function (node3D) {
this.rootNode.add(node3D);
};
ViewGL.prototype.remove = function (node3D) {
this.rootNode.remove(node3D);
};
ViewGL.prototype.removeAll = function (node3D) {
this.rootNode.removeAll(node3D);
};
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.extend(ViewGL.prototype, __WEBPACK_IMPORTED_MODULE_8_claygl_src_core_mixin_notifier__["a" /* default */]);
/* harmony default export */ __webpack_exports__["a"] = (ViewGL);
/***/ }),
/* 20 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
var guid = 0;
var ArrayProto = Array.prototype;
var nativeForEach = ArrayProto.forEach;
/**
* Util functions
* @namespace clay.core.util
*/
var util = {
/**
* Generate GUID
* @return {number}
* @memberOf clay.core.util
*/
genGUID: function () {
return ++guid;
},
/**
* Relative path to absolute path
* @param {string} path
* @param {string} basePath
* @return {string}
* @memberOf clay.core.util
*/
relative2absolute: function (path, basePath) {
if (!basePath || path.match(/^\//)) {
return path;
}
var pathParts = path.split('/');
var basePathParts = basePath.split('/');
var item = pathParts[0];
while(item === '.' || item === '..') {
if (item === '..') {
basePathParts.pop();
}
pathParts.shift();
item = pathParts[0];
}
return basePathParts.join('/') + '/' + pathParts.join('/');
},
/**
* Extend target with source
* @param {Object} target
* @param {Object} source
* @return {Object}
* @memberOf clay.core.util
*/
extend: function (target, source) {
if (source) {
for (var name in source) {
if (source.hasOwnProperty(name)) {
target[name] = source[name];
}
}
}
return target;
},
/**
* Extend properties to target if not exist.
* @param {Object} target
* @param {Object} source
* @return {Object}
* @memberOf clay.core.util
*/
defaults: function (target, source) {
if (source) {
for (var propName in source) {
if (target[propName] === undefined) {
target[propName] = source[propName];
}
}
}
return target;
},
/**
* Extend properties with a given property list to avoid for..in.. iteration.
* @param {Object} target
* @param {Object} source
* @param {Array.} propList
* @return {Object}
* @memberOf clay.core.util
*/
extendWithPropList: function (target, source, propList) {
if (source) {
for (var i = 0; i < propList.length; i++) {
var propName = propList[i];
target[propName] = source[propName];
}
}
return target;
},
/**
* Extend properties to target if not exist. With a given property list avoid for..in.. iteration.
* @param {Object} target
* @param {Object} source
* @param {Array.} propList
* @return {Object}
* @memberOf clay.core.util
*/
defaultsWithPropList: function (target, source, propList) {
if (source) {
for (var i = 0; i < propList.length; i++) {
var propName = propList[i];
if (target[propName] == null) {
target[propName] = source[propName];
}
}
}
return target;
},
/**
* @param {Object|Array} obj
* @param {Function} iterator
* @param {Object} [context]
* @memberOf clay.core.util
*/
each: function (obj, iterator, context) {
if (!(obj && iterator)) {
return;
}
if (obj.forEach && obj.forEach === nativeForEach) {
obj.forEach(iterator, context);
}
else if (obj.length === + obj.length) {
for (var i = 0, len = obj.length; i < len; i++) {
iterator.call(context, obj[i], i, obj);
}
}
else {
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
iterator.call(context, obj[key], key, obj);
}
}
}
},
/**
* Is object
* @param {} obj
* @return {boolean}
* @memberOf clay.core.util
*/
isObject: function (obj) {
return obj === Object(obj);
},
/**
* Is array ?
* @param {} obj
* @return {boolean}
* @memberOf clay.core.util
*/
isArray: function (obj) {
return Array.isArray(obj);
},
/**
* Is array like, which have a length property
* @param {} obj
* @return {boolean}
* @memberOf clay.core.util
*/
isArrayLike: function (obj) {
if (!obj) {
return false;
}
else {
return obj.length === + obj.length;
}
},
/**
* @param {} obj
* @return {}
* @memberOf clay.core.util
*/
clone: function (obj) {
if (!util.isObject(obj)) {
return obj;
}
else if (util.isArray(obj)) {
return obj.slice();
}
else if (util.isArrayLike(obj)) { // is typed array
var ret = new obj.constructor(obj.length);
for (var i = 0; i < obj.length; i++) {
ret[i] = obj[i];
}
return ret;
}
else {
return util.extend({}, obj);
}
}
};
/* harmony default export */ __webpack_exports__["a"] = (util);
/***/ }),
/* 21 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Node__ = __webpack_require__(30);
/**
* @constructor clay.Light
* @extends clay.Node
*/
var Light = __WEBPACK_IMPORTED_MODULE_0__Node__["a" /* default */].extend(function(){
return /** @lends clay.Light# */ {
/**
* Light RGB color
* @type {number[]}
*/
color: [1, 1, 1],
/**
* Light intensity
* @type {number}
*/
intensity: 1.0,
// Config for shadow map
/**
* If light cast shadow
* @type {boolean}
*/
castShadow: true,
/**
* Shadow map size
* @type {number}
*/
shadowResolution: 512,
/**
* Light group, shader with same `lightGroup` will be affected
*
* Only useful in forward rendering
* @type {number}
*/
group: 0
};
},
/** @lends clay.Light.prototype. */
{
/**
* Light type
* @type {string}
* @memberOf clay.Light#
*/
type: '',
/**
* @return {clay.Light}
* @memberOf clay.Light.prototype
*/
clone: function() {
var light = __WEBPACK_IMPORTED_MODULE_0__Node__["a" /* default */].prototype.clone.call(this);
light.color = Array.prototype.slice.call(this.color);
light.intensity = this.intensity;
light.castShadow = this.castShadow;
light.shadowResolution = this.shadowResolution;
return light;
}
});
/* harmony default export */ __webpack_exports__["a"] = (Light);
/***/ }),
/* 22 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__ = __webpack_require__(13);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__dynamicConvertMixin__ = __webpack_require__(34);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix__);
/**
* Lines geometry
* Use screen space projected lines lineWidth > MAX_LINE_WIDTH
* https://mattdesl.svbtle.com/drawing-lines-is-hard
* @module echarts-gl/util/geometry/LinesGeometry
* @author Yi Shen(http://github.com/pissang)
*/
var vec3 = __WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix___default.a.vec3;
// var CURVE_RECURSION_LIMIT = 8;
// var CURVE_COLLINEAR_EPSILON = 40;
var sampleLinePoints = [[0, 0], [1, 1]];
/**
* @constructor
* @alias module:echarts-gl/util/geometry/LinesGeometry
* @extends clay.Geometry
*/
var LinesGeometry = __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].extend(function () {
return {
segmentScale: 1,
dynamic: true,
/**
* Need to use mesh to expand lines if lineWidth > MAX_LINE_WIDTH
*/
useNativeLine: true,
attributes: {
position: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('position', 'float', 3, 'POSITION'),
positionPrev: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('positionPrev', 'float', 3),
positionNext: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('positionNext', 'float', 3),
prevPositionPrev: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('prevPositionPrev', 'float', 3),
prevPosition: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('prevPosition', 'float', 3),
prevPositionNext: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('prevPositionNext', 'float', 3),
offset: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('offset', 'float', 1),
color: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('color', 'float', 4, 'COLOR')
}
};
},
/** @lends module: echarts-gl/util/geometry/LinesGeometry.prototype */
{
/**
* Reset offset
*/
resetOffset: function () {
this._vertexOffset = 0;
this._triangleOffset = 0;
this._itemVertexOffsets = [];
},
/**
* @param {number} nVertex
*/
setVertexCount: function (nVertex) {
var attributes = this.attributes;
if (this.vertexCount !== nVertex) {
attributes.position.init(nVertex);
attributes.color.init(nVertex);
if (!this.useNativeLine) {
attributes.positionPrev.init(nVertex);
attributes.positionNext.init(nVertex);
attributes.offset.init(nVertex);
}
if (nVertex > 0xffff) {
if (this.indices instanceof Uint16Array) {
this.indices = new Uint32Array(this.indices);
}
}
else {
if (this.indices instanceof Uint32Array) {
this.indices = new Uint16Array(this.indices);
}
}
}
},
/**
* @param {number} nTriangle
*/
setTriangleCount: function (nTriangle) {
if (this.triangleCount !== nTriangle) {
if (nTriangle === 0) {
this.indices = null;
}
else {
this.indices = this.vertexCount > 0xffff ? new Uint32Array(nTriangle * 3) : new Uint16Array(nTriangle * 3);
}
}
},
_getCubicCurveApproxStep: function (p0, p1, p2, p3) {
var len = vec3.dist(p0, p1) + vec3.dist(p2, p1) + vec3.dist(p3, p2);
var step = 1 / (len + 1) * this.segmentScale;
return step;
},
/**
* Get vertex count of cubic curve
* @param {Array.} p0
* @param {Array.} p1
* @param {Array.} p2
* @param {Array.} p3
* @return number
*/
getCubicCurveVertexCount: function (p0, p1, p2, p3) {
var step = this._getCubicCurveApproxStep(p0, p1, p2, p3);
var segCount = Math.ceil(1 / step);
if (!this.useNativeLine) {
return segCount * 2 + 2;
}
else {
return segCount * 2;
}
},
/**
* Get face count of cubic curve
* @param {Array.} p0
* @param {Array.} p1
* @param {Array.} p2
* @param {Array.} p3
* @return number
*/
getCubicCurveTriangleCount: function (p0, p1, p2, p3) {
var step = this._getCubicCurveApproxStep(p0, p1, p2, p3);
var segCount = Math.ceil(1 / step);
if (!this.useNativeLine) {
return segCount * 2;
}
else {
return 0;
}
},
/**
* Get vertex count of line
* @return {number}
*/
getLineVertexCount: function () {
return this.getPolylineVertexCount(sampleLinePoints);
},
/**
* Get face count of line
* @return {number}
*/
getLineTriangleCount: function () {
return this.getPolylineTriangleCount(sampleLinePoints);
},
/**
* Get how many vertices will polyline take.
* @type {number|Array} points Can be a 1d/2d list of points, or a number of points amount.
* @return {number}
*/
getPolylineVertexCount: function (points) {
var pointsLen;
if (typeof points === 'number') {
pointsLen = points;
}
else {
var is2DArray = typeof points[0] !== 'number';
pointsLen = is2DArray ? points.length : (points.length / 3);
}
return !this.useNativeLine ? ((pointsLen - 1) * 2 + 2) : (pointsLen - 1) * 2;
},
/**
* Get how many triangles will polyline take.
* @type {number|Array} points Can be a 1d/2d list of points, or a number of points amount.
* @return {number}
*/
getPolylineTriangleCount: function (points) {
var pointsLen;
if (typeof points === 'number') {
pointsLen = points;
}
else {
var is2DArray = typeof points[0] !== 'number';
pointsLen = is2DArray ? points.length : (points.length / 3);
}
return !this.useNativeLine ? Math.max(pointsLen - 1, 0) * 2 : 0;
},
/**
* Add a cubic curve
* @param {Array.} p0
* @param {Array.} p1
* @param {Array.} p2
* @param {Array.} p3
* @param {Array.} color
* @param {number} [lineWidth=1]
*/
addCubicCurve: function (p0, p1, p2, p3, color, lineWidth) {
if (lineWidth == null) {
lineWidth = 1;
}
// incremental interpolation
// http://antigrain.com/research/bezier_interpolation/index.html#PAGE_BEZIER_INTERPOLATION
var x0 = p0[0], y0 = p0[1], z0 = p0[2];
var x1 = p1[0], y1 = p1[1], z1 = p1[2];
var x2 = p2[0], y2 = p2[1], z2 = p2[2];
var x3 = p3[0], y3 = p3[1], z3 = p3[2];
var step = this._getCubicCurveApproxStep(p0, p1, p2, p3);
var step2 = step * step;
var step3 = step2 * step;
var pre1 = 3.0 * step;
var pre2 = 3.0 * step2;
var pre4 = 6.0 * step2;
var pre5 = 6.0 * step3;
var tmp1x = x0 - x1 * 2.0 + x2;
var tmp1y = y0 - y1 * 2.0 + y2;
var tmp1z = z0 - z1 * 2.0 + z2;
var tmp2x = (x1 - x2) * 3.0 - x0 + x3;
var tmp2y = (y1 - y2) * 3.0 - y0 + y3;
var tmp2z = (z1 - z2) * 3.0 - z0 + z3;
var fx = x0;
var fy = y0;
var fz = z0;
var dfx = (x1 - x0) * pre1 + tmp1x * pre2 + tmp2x * step3;
var dfy = (y1 - y0) * pre1 + tmp1y * pre2 + tmp2y * step3;
var dfz = (z1 - z0) * pre1 + tmp1z * pre2 + tmp2z * step3;
var ddfx = tmp1x * pre4 + tmp2x * pre5;
var ddfy = tmp1y * pre4 + tmp2y * pre5;
var ddfz = tmp1z * pre4 + tmp2z * pre5;
var dddfx = tmp2x * pre5;
var dddfy = tmp2y * pre5;
var dddfz = tmp2z * pre5;
var t = 0;
var k = 0;
var segCount = Math.ceil(1 / step);
var points = new Float32Array((segCount + 1) * 3);
var points = [];
var offset = 0;
for (var k = 0; k < segCount + 1; k++) {
points[offset++] = fx;
points[offset++] = fy;
points[offset++] = fz;
fx += dfx; fy += dfy; fz += dfz;
dfx += ddfx; dfy += ddfy; dfz += ddfz;
ddfx += dddfx; ddfy += dddfy; ddfz += dddfz;
t += step;
if (t > 1) {
fx = dfx > 0 ? Math.min(fx, x3) : Math.max(fx, x3);
fy = dfy > 0 ? Math.min(fy, y3) : Math.max(fy, y3);
fz = dfz > 0 ? Math.min(fz, z3) : Math.max(fz, z3);
}
}
return this.addPolyline(points, color, lineWidth);
},
/**
* Add a straight line
* @param {Array.} p0
* @param {Array.} p1
* @param {Array.} color
* @param {number} [lineWidth=1]
*/
addLine: function (p0, p1, color, lineWidth) {
return this.addPolyline([p0, p1], color, lineWidth);
},
/**
* Add a straight line
* @param {Array. | Array.} points
* @param {Array. | Array.} color
* @param {number} [lineWidth=1]
* @param {number} [startOffset=0]
* @param {number} [pointsCount] Default to be amount of points in the first argument
*/
addPolyline: function (points, color, lineWidth, startOffset, pointsCount) {
if (!points.length) {
return;
}
var is2DArray = typeof points[0] !== 'number';
if (pointsCount == null) {
pointsCount = is2DArray ? points.length : points.length / 3;
}
if (pointsCount < 2) {
return;
}
if (startOffset == null) {
startOffset = 0;
}
if (lineWidth == null) {
lineWidth = 1;
}
this._itemVertexOffsets.push(this._vertexOffset);
var is2DArray = typeof points[0] !== 'number';
var notSharingColor = is2DArray
? typeof color[0] !== 'number'
: color.length / 4 === pointsCount;
var positionAttr = this.attributes.position;
var positionPrevAttr = this.attributes.positionPrev;
var positionNextAttr = this.attributes.positionNext;
var colorAttr = this.attributes.color;
var offsetAttr = this.attributes.offset;
var indices = this.indices;
var vertexOffset = this._vertexOffset;
var point;
var pointColor;
lineWidth = Math.max(lineWidth, 0.01);
for (var k = startOffset; k < pointsCount; k++) {
if (is2DArray) {
point = points[k];
if (notSharingColor) {
pointColor = color[k];
}
else {
pointColor = color;
}
}
else {
var k3 = k * 3;
point = point || [];
point[0] = points[k3];
point[1] = points[k3 + 1];
point[2] = points[k3 + 2];
if (notSharingColor) {
var k4 = k * 4;
pointColor = pointColor || [];
pointColor[0] = color[k4];
pointColor[1] = color[k4 + 1];
pointColor[2] = color[k4 + 2];
pointColor[3] = color[k4 + 3];
}
else {
pointColor = color;
}
}
if (!this.useNativeLine) {
if (k < pointsCount - 1) {
// Set to next two points
positionPrevAttr.set(vertexOffset + 2, point);
positionPrevAttr.set(vertexOffset + 3, point);
}
if (k > 0) {
// Set to previous two points
positionNextAttr.set(vertexOffset - 2, point);
positionNextAttr.set(vertexOffset - 1, point);
}
positionAttr.set(vertexOffset, point);
positionAttr.set(vertexOffset + 1, point);
colorAttr.set(vertexOffset, pointColor);
colorAttr.set(vertexOffset + 1, pointColor);
offsetAttr.set(vertexOffset, lineWidth / 2);
offsetAttr.set(vertexOffset + 1, -lineWidth / 2);
vertexOffset += 2;
}
else {
if (k > 1) {
positionAttr.copy(vertexOffset, vertexOffset - 1);
colorAttr.copy(vertexOffset, vertexOffset - 1);
vertexOffset++;
}
}
if (!this.useNativeLine) {
if (k > 0) {
var idx3 = this._triangleOffset * 3;
var indices = this.indices;
// 0-----2
// 1-----3
// 0->1->2, 1->3->2
indices[idx3] = vertexOffset - 4;
indices[idx3 + 1] = vertexOffset - 3;
indices[idx3 + 2] = vertexOffset - 2;
indices[idx3 + 3] = vertexOffset - 3;
indices[idx3 + 4] = vertexOffset - 1;
indices[idx3 + 5] = vertexOffset - 2;
this._triangleOffset += 2;
}
}
else {
colorAttr.set(vertexOffset, pointColor);
positionAttr.set(vertexOffset, point);
vertexOffset++;
}
}
if (!this.useNativeLine) {
var start = this._vertexOffset;
var end = this._vertexOffset + pointsCount * 2;
positionPrevAttr.copy(start, start + 2);
positionPrevAttr.copy(start + 1, start + 3);
positionNextAttr.copy(end - 1, end - 3);
positionNextAttr.copy(end - 2, end - 4);
}
this._vertexOffset = vertexOffset;
return this._vertexOffset;
},
/**
* Set color of single line.
*/
setItemColor: function (idx, color) {
var startOffset = this._itemVertexOffsets[idx];
var endOffset = idx < this._itemVertexOffsets.length - 1 ? this._itemVertexOffsets[idx + 1] : this._vertexOffset;
for (var i = startOffset; i < endOffset; i++) {
this.attributes.color.set(i, color);
}
this.dirty('color');
},
/**
* @return {number}
*/
currentTriangleOffset: function () {
return this._triangleOffset;
},
/**
* @return {number}
*/
currentVertexOffset: function () {
return this._vertexOffset;
}
});
__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default.a.util.defaults(LinesGeometry.prototype, __WEBPACK_IMPORTED_MODULE_2__dynamicConvertMixin__["a" /* default */]);
/* harmony default export */ __webpack_exports__["a"] = (LinesGeometry);
/***/ }),
/* 23 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0__dep_glmatrix__);
var vec2 = __WEBPACK_IMPORTED_MODULE_0__dep_glmatrix___default.a.vec2;
/**
* @constructor
* @alias clay.Vector2
* @param {number} x
* @param {number} y
*/
var Vector2 = function(x, y) {
x = x || 0;
y = y || 0;
/**
* Storage of Vector2, read and write of x, y will change the values in array
* All methods also operate on the array instead of x, y components
* @name array
* @type {Float32Array}
* @memberOf clay.Vector2#
*/
this.array = vec2.fromValues(x, y);
/**
* Dirty flag is used by the Node to determine
* if the matrix is updated to latest
* @name _dirty
* @type {boolean}
* @memberOf clay.Vector2#
*/
this._dirty = true;
};
Vector2.prototype = {
constructor: Vector2,
/**
* Add b to self
* @param {clay.Vector2} b
* @return {clay.Vector2}
*/
add: function(b) {
vec2.add(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Set x and y components
* @param {number} x
* @param {number} y
* @return {clay.Vector2}
*/
set: function(x, y) {
this.array[0] = x;
this.array[1] = y;
this._dirty = true;
return this;
},
/**
* Set x and y components from array
* @param {Float32Array|number[]} arr
* @return {clay.Vector2}
*/
setArray: function(arr) {
this.array[0] = arr[0];
this.array[1] = arr[1];
this._dirty = true;
return this;
},
/**
* Clone a new Vector2
* @return {clay.Vector2}
*/
clone: function() {
return new Vector2(this.x, this.y);
},
/**
* Copy x, y from b
* @param {clay.Vector2} b
* @return {clay.Vector2}
*/
copy: function(b) {
vec2.copy(this.array, b.array);
this._dirty = true;
return this;
},
/**
* Cross product of self and b, written to a Vector3 out
* @param {clay.Vector3} out
* @param {clay.Vector2} b
* @return {clay.Vector2}
*/
cross: function(out, b) {
vec2.cross(out.array, this.array, b.array);
out._dirty = true;
return this;
},
/**
* Alias for distance
* @param {clay.Vector2} b
* @return {number}
*/
dist: function(b) {
return vec2.dist(this.array, b.array);
},
/**
* Distance between self and b
* @param {clay.Vector2} b
* @return {number}
*/
distance: function(b) {
return vec2.distance(this.array, b.array);
},
/**
* Alias for divide
* @param {clay.Vector2} b
* @return {clay.Vector2}
*/
div: function(b) {
vec2.div(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Divide self by b
* @param {clay.Vector2} b
* @return {clay.Vector2}
*/
divide: function(b) {
vec2.divide(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Dot product of self and b
* @param {clay.Vector2} b
* @return {number}
*/
dot: function(b) {
return vec2.dot(this.array, b.array);
},
/**
* Alias of length
* @return {number}
*/
len: function() {
return vec2.len(this.array);
},
/**
* Calculate the length
* @return {number}
*/
length: function() {
return vec2.length(this.array);
},
/**
* Linear interpolation between a and b
* @param {clay.Vector2} a
* @param {clay.Vector2} b
* @param {number} t
* @return {clay.Vector2}
*/
lerp: function(a, b, t) {
vec2.lerp(this.array, a.array, b.array, t);
this._dirty = true;
return this;
},
/**
* Minimum of self and b
* @param {clay.Vector2} b
* @return {clay.Vector2}
*/
min: function(b) {
vec2.min(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Maximum of self and b
* @param {clay.Vector2} b
* @return {clay.Vector2}
*/
max: function(b) {
vec2.max(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Alias for multiply
* @param {clay.Vector2} b
* @return {clay.Vector2}
*/
mul: function(b) {
vec2.mul(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Mutiply self and b
* @param {clay.Vector2} b
* @return {clay.Vector2}
*/
multiply: function(b) {
vec2.multiply(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Negate self
* @return {clay.Vector2}
*/
negate: function() {
vec2.negate(this.array, this.array);
this._dirty = true;
return this;
},
/**
* Normalize self
* @return {clay.Vector2}
*/
normalize: function() {
vec2.normalize(this.array, this.array);
this._dirty = true;
return this;
},
/**
* Generate random x, y components with a given scale
* @param {number} scale
* @return {clay.Vector2}
*/
random: function(scale) {
vec2.random(this.array, scale);
this._dirty = true;
return this;
},
/**
* Scale self
* @param {number} scale
* @return {clay.Vector2}
*/
scale: function(s) {
vec2.scale(this.array, this.array, s);
this._dirty = true;
return this;
},
/**
* Scale b and add to self
* @param {clay.Vector2} b
* @param {number} scale
* @return {clay.Vector2}
*/
scaleAndAdd: function(b, s) {
vec2.scaleAndAdd(this.array, this.array, b.array, s);
this._dirty = true;
return this;
},
/**
* Alias for squaredDistance
* @param {clay.Vector2} b
* @return {number}
*/
sqrDist: function(b) {
return vec2.sqrDist(this.array, b.array);
},
/**
* Squared distance between self and b
* @param {clay.Vector2} b
* @return {number}
*/
squaredDistance: function(b) {
return vec2.squaredDistance(this.array, b.array);
},
/**
* Alias for squaredLength
* @return {number}
*/
sqrLen: function() {
return vec2.sqrLen(this.array);
},
/**
* Squared length of self
* @return {number}
*/
squaredLength: function() {
return vec2.squaredLength(this.array);
},
/**
* Alias for subtract
* @param {clay.Vector2} b
* @return {clay.Vector2}
*/
sub: function(b) {
vec2.sub(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Subtract b from self
* @param {clay.Vector2} b
* @return {clay.Vector2}
*/
subtract: function(b) {
vec2.subtract(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Transform self with a Matrix2 m
* @param {clay.Matrix2} m
* @return {clay.Vector2}
*/
transformMat2: function(m) {
vec2.transformMat2(this.array, this.array, m.array);
this._dirty = true;
return this;
},
/**
* Transform self with a Matrix2d m
* @param {clay.Matrix2d} m
* @return {clay.Vector2}
*/
transformMat2d: function(m) {
vec2.transformMat2d(this.array, this.array, m.array);
this._dirty = true;
return this;
},
/**
* Transform self with a Matrix3 m
* @param {clay.Matrix3} m
* @return {clay.Vector2}
*/
transformMat3: function(m) {
vec2.transformMat3(this.array, this.array, m.array);
this._dirty = true;
return this;
},
/**
* Transform self with a Matrix4 m
* @param {clay.Matrix4} m
* @return {clay.Vector2}
*/
transformMat4: function(m) {
vec2.transformMat4(this.array, this.array, m.array);
this._dirty = true;
return this;
},
toString: function() {
return '[' + Array.prototype.join.call(this.array, ',') + ']';
},
toArray: function () {
return Array.prototype.slice.call(this.array);
}
};
// Getter and Setter
if (Object.defineProperty) {
var proto = Vector2.prototype;
/**
* @name x
* @type {number}
* @memberOf clay.Vector2
* @instance
*/
Object.defineProperty(proto, 'x', {
get: function () {
return this.array[0];
},
set: function (value) {
this.array[0] = value;
this._dirty = true;
}
});
/**
* @name y
* @type {number}
* @memberOf clay.Vector2
* @instance
*/
Object.defineProperty(proto, 'y', {
get: function () {
return this.array[1];
},
set: function (value) {
this.array[1] = value;
this._dirty = true;
}
});
}
// Supply methods that are not in place
/**
* @param {clay.Vector2} out
* @param {clay.Vector2} a
* @param {clay.Vector2} b
* @return {clay.Vector2}
*/
Vector2.add = function(out, a, b) {
vec2.add(out.array, a.array, b.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector2} out
* @param {number} x
* @param {number} y
* @return {clay.Vector2}
*/
Vector2.set = function(out, x, y) {
vec2.set(out.array, x, y);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector2} out
* @param {clay.Vector2} b
* @return {clay.Vector2}
*/
Vector2.copy = function(out, b) {
vec2.copy(out.array, b.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector3} out
* @param {clay.Vector2} a
* @param {clay.Vector2} b
* @return {clay.Vector2}
*/
Vector2.cross = function(out, a, b) {
vec2.cross(out.array, a.array, b.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector2} a
* @param {clay.Vector2} b
* @return {number}
*/
Vector2.dist = function(a, b) {
return vec2.distance(a.array, b.array);
};
/**
* @function
* @param {clay.Vector2} a
* @param {clay.Vector2} b
* @return {number}
*/
Vector2.distance = Vector2.dist;
/**
* @param {clay.Vector2} out
* @param {clay.Vector2} a
* @param {clay.Vector2} b
* @return {clay.Vector2}
*/
Vector2.div = function(out, a, b) {
vec2.divide(out.array, a.array, b.array);
out._dirty = true;
return out;
};
/**
* @function
* @param {clay.Vector2} out
* @param {clay.Vector2} a
* @param {clay.Vector2} b
* @return {clay.Vector2}
*/
Vector2.divide = Vector2.div;
/**
* @param {clay.Vector2} a
* @param {clay.Vector2} b
* @return {number}
*/
Vector2.dot = function(a, b) {
return vec2.dot(a.array, b.array);
};
/**
* @param {clay.Vector2} a
* @return {number}
*/
Vector2.len = function(b) {
return vec2.length(b.array);
};
// Vector2.length = Vector2.len;
/**
* @param {clay.Vector2} out
* @param {clay.Vector2} a
* @param {clay.Vector2} b
* @param {number} t
* @return {clay.Vector2}
*/
Vector2.lerp = function(out, a, b, t) {
vec2.lerp(out.array, a.array, b.array, t);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector2} out
* @param {clay.Vector2} a
* @param {clay.Vector2} b
* @return {clay.Vector2}
*/
Vector2.min = function(out, a, b) {
vec2.min(out.array, a.array, b.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector2} out
* @param {clay.Vector2} a
* @param {clay.Vector2} b
* @return {clay.Vector2}
*/
Vector2.max = function(out, a, b) {
vec2.max(out.array, a.array, b.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector2} out
* @param {clay.Vector2} a
* @param {clay.Vector2} b
* @return {clay.Vector2}
*/
Vector2.mul = function(out, a, b) {
vec2.multiply(out.array, a.array, b.array);
out._dirty = true;
return out;
};
/**
* @function
* @param {clay.Vector2} out
* @param {clay.Vector2} a
* @param {clay.Vector2} b
* @return {clay.Vector2}
*/
Vector2.multiply = Vector2.mul;
/**
* @param {clay.Vector2} out
* @param {clay.Vector2} a
* @return {clay.Vector2}
*/
Vector2.negate = function(out, a) {
vec2.negate(out.array, a.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector2} out
* @param {clay.Vector2} a
* @return {clay.Vector2}
*/
Vector2.normalize = function(out, a) {
vec2.normalize(out.array, a.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector2} out
* @param {number} scale
* @return {clay.Vector2}
*/
Vector2.random = function(out, scale) {
vec2.random(out.array, scale);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector2} out
* @param {clay.Vector2} a
* @param {number} scale
* @return {clay.Vector2}
*/
Vector2.scale = function(out, a, scale) {
vec2.scale(out.array, a.array, scale);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector2} out
* @param {clay.Vector2} a
* @param {clay.Vector2} b
* @param {number} scale
* @return {clay.Vector2}
*/
Vector2.scaleAndAdd = function(out, a, b, scale) {
vec2.scaleAndAdd(out.array, a.array, b.array, scale);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector2} a
* @param {clay.Vector2} b
* @return {number}
*/
Vector2.sqrDist = function(a, b) {
return vec2.sqrDist(a.array, b.array);
};
/**
* @function
* @param {clay.Vector2} a
* @param {clay.Vector2} b
* @return {number}
*/
Vector2.squaredDistance = Vector2.sqrDist;
/**
* @param {clay.Vector2} a
* @return {number}
*/
Vector2.sqrLen = function(a) {
return vec2.sqrLen(a.array);
};
/**
* @function
* @param {clay.Vector2} a
* @return {number}
*/
Vector2.squaredLength = Vector2.sqrLen;
/**
* @param {clay.Vector2} out
* @param {clay.Vector2} a
* @param {clay.Vector2} b
* @return {clay.Vector2}
*/
Vector2.sub = function(out, a, b) {
vec2.subtract(out.array, a.array, b.array);
out._dirty = true;
return out;
};
/**
* @function
* @param {clay.Vector2} out
* @param {clay.Vector2} a
* @param {clay.Vector2} b
* @return {clay.Vector2}
*/
Vector2.subtract = Vector2.sub;
/**
* @param {clay.Vector2} out
* @param {clay.Vector2} a
* @param {clay.Matrix2} m
* @return {clay.Vector2}
*/
Vector2.transformMat2 = function(out, a, m) {
vec2.transformMat2(out.array, a.array, m.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector2} out
* @param {clay.Vector2} a
* @param {clay.Matrix2d} m
* @return {clay.Vector2}
*/
Vector2.transformMat2d = function(out, a, m) {
vec2.transformMat2d(out.array, a.array, m.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector2} out
* @param {clay.Vector2} a
* @param {Matrix3} m
* @return {clay.Vector2}
*/
Vector2.transformMat3 = function(out, a, m) {
vec2.transformMat3(out.array, a.array, m.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector2} out
* @param {clay.Vector2} a
* @param {clay.Matrix4} m
* @return {clay.Vector2}
*/
Vector2.transformMat4 = function(out, a, m) {
vec2.transformMat4(out.array, a.array, m.array);
out._dirty = true;
return out;
};
/* harmony default export */ __webpack_exports__["a"] = (Vector2);
/***/ }),
/* 24 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Texture__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_glenum__ = __webpack_require__(11);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__core_util__ = __webpack_require__(20);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__math_util__ = __webpack_require__(67);
var isPowerOfTwo = __WEBPACK_IMPORTED_MODULE_3__math_util__["a" /* default */].isPowerOfTwo;
var targetList = ['px', 'nx', 'py', 'ny', 'pz', 'nz'];
/**
* @constructor clay.TextureCube
* @extends clay.Texture
*
* @example
* ...
* var mat = new clay.Material({
* shader: clay.shader.library.get('clay.phong', 'environmentMap')
* });
* var envMap = new clay.TextureCube();
* envMap.load({
* 'px': 'assets/textures/sky/px.jpg',
* 'nx': 'assets/textures/sky/nx.jpg'
* 'py': 'assets/textures/sky/py.jpg'
* 'ny': 'assets/textures/sky/ny.jpg'
* 'pz': 'assets/textures/sky/pz.jpg'
* 'nz': 'assets/textures/sky/nz.jpg'
* });
* mat.set('environmentMap', envMap);
* ...
* envMap.success(function () {
* // Wait for the sky texture loaded
* animation.on('frame', function (frameTime) {
* renderer.render(scene, camera);
* });
* });
*/
var TextureCube = __WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].extend(function () {
return /** @lends clay.TextureCube# */{
/**
* @type {boolean}
* @default false
*/
// PENDING cubemap should not flipY in default.
// flipY: false,
/**
* @type {Object}
* @property {?HTMLImageElement|HTMLCanvasElemnet} px
* @property {?HTMLImageElement|HTMLCanvasElemnet} nx
* @property {?HTMLImageElement|HTMLCanvasElemnet} py
* @property {?HTMLImageElement|HTMLCanvasElemnet} ny
* @property {?HTMLImageElement|HTMLCanvasElemnet} pz
* @property {?HTMLImageElement|HTMLCanvasElemnet} nz
*/
image: {
px: null,
nx: null,
py: null,
ny: null,
pz: null,
nz: null
},
/**
* Pixels data of each side. Will be ignored if images are set.
* @type {Object}
* @property {?Uint8Array} px
* @property {?Uint8Array} nx
* @property {?Uint8Array} py
* @property {?Uint8Array} ny
* @property {?Uint8Array} pz
* @property {?Uint8Array} nz
*/
pixels: {
px: null,
nx: null,
py: null,
ny: null,
pz: null,
nz: null
},
/**
* @type {Array.}
*/
mipmaps: []
};
}, {
textureType: 'textureCube',
update: function (renderer) {
var _gl = renderer.gl;
_gl.bindTexture(_gl.TEXTURE_CUBE_MAP, this._cache.get('webgl_texture'));
this.updateCommon(renderer);
var glFormat = this.format;
var glType = this.type;
_gl.texParameteri(_gl.TEXTURE_CUBE_MAP, _gl.TEXTURE_WRAP_S, this.getAvailableWrapS());
_gl.texParameteri(_gl.TEXTURE_CUBE_MAP, _gl.TEXTURE_WRAP_T, this.getAvailableWrapT());
_gl.texParameteri(_gl.TEXTURE_CUBE_MAP, _gl.TEXTURE_MAG_FILTER, this.getAvailableMagFilter());
_gl.texParameteri(_gl.TEXTURE_CUBE_MAP, _gl.TEXTURE_MIN_FILTER, this.getAvailableMinFilter());
var anisotropicExt = renderer.getGLExtension('EXT_texture_filter_anisotropic');
if (anisotropicExt && this.anisotropic > 1) {
_gl.texParameterf(_gl.TEXTURE_CUBE_MAP, anisotropicExt.TEXTURE_MAX_ANISOTROPY_EXT, this.anisotropic);
}
// Fallback to float type if browser don't have half float extension
if (glType === 36193) {
var halfFloatExt = renderer.getGLExtension('OES_texture_half_float');
if (!halfFloatExt) {
glType = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].FLOAT;
}
}
if (this.mipmaps.length) {
var width = this.width;
var height = this.height;
for (var i = 0; i < this.mipmaps.length; i++) {
var mipmap = this.mipmaps[i];
this._updateTextureData(_gl, mipmap, i, width, height, glFormat, glType);
width /= 2;
height /= 2;
}
}
else {
this._updateTextureData(_gl, this, 0, this.width, this.height, glFormat, glType);
if (!this.NPOT && this.useMipmap) {
_gl.generateMipmap(_gl.TEXTURE_CUBE_MAP);
}
}
_gl.bindTexture(_gl.TEXTURE_CUBE_MAP, null);
},
_updateTextureData: function (_gl, data, level, width, height, glFormat, glType) {
for (var i = 0; i < 6; i++) {
var target = targetList[i];
var img = data.image && data.image[target];
if (img) {
_gl.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, level, glFormat, glFormat, glType, img);
}
else {
_gl.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, level, glFormat, width, height, 0, glFormat, glType, data.pixels && data.pixels[target]);
}
}
},
/**
* @param {clay.Renderer} renderer
* @memberOf clay.TextureCube.prototype
*/
generateMipmap: function (renderer) {
var _gl = renderer.gl;
if (this.useMipmap && !this.NPOT) {
_gl.bindTexture(_gl.TEXTURE_CUBE_MAP, this._cache.get('webgl_texture'));
_gl.generateMipmap(_gl.TEXTURE_CUBE_MAP);
}
},
bind: function (renderer) {
renderer.gl.bindTexture(renderer.gl.TEXTURE_CUBE_MAP, this.getWebGLTexture(renderer));
},
unbind: function (renderer) {
renderer.gl.bindTexture(renderer.gl.TEXTURE_CUBE_MAP, null);
},
// Overwrite the isPowerOfTwo method
isPowerOfTwo: function () {
if (this.image.px) {
return isPowerOfTwo(this.image.px.width)
&& isPowerOfTwo(this.image.px.height);
}
else {
return isPowerOfTwo(this.width)
&& isPowerOfTwo(this.height);
}
},
isRenderable: function () {
if (this.image.px) {
return isImageRenderable(this.image.px)
&& isImageRenderable(this.image.nx)
&& isImageRenderable(this.image.py)
&& isImageRenderable(this.image.ny)
&& isImageRenderable(this.image.pz)
&& isImageRenderable(this.image.nz);
}
else {
return !!(this.width && this.height);
}
},
load: function (imageList, crossOrigin) {
var loading = 0;
var self = this;
__WEBPACK_IMPORTED_MODULE_2__core_util__["a" /* default */].each(imageList, function (src, target){
var image = new Image();
if (crossOrigin) {
image.crossOrigin = crossOrigin;
}
image.onload = function () {
loading --;
if (loading === 0){
self.dirty();
self.trigger('success', self);
}
image.onload = null;
};
image.onerror = function () {
loading --;
image.onerror = null;
};
loading++;
image.src = src;
self.image[target] = image;
});
return this;
}
});
Object.defineProperty(TextureCube.prototype, 'width', {
get: function () {
if (this.image && this.image.px) {
return this.image.px.width;
}
return this._width;
},
set: function (value) {
if (this.image && this.image.px) {
console.warn('Texture from image can\'t set width');
}
else {
if (this._width !== value) {
this.dirty();
}
this._width = value;
}
}
});
Object.defineProperty(TextureCube.prototype, 'height', {
get: function () {
if (this.image && this.image.px) {
return this.image.px.height;
}
return this._height;
},
set: function (value) {
if (this.image && this.image.px) {
console.warn('Texture from image can\'t set height');
}
else {
if (this._height !== value) {
this.dirty();
}
this._height = value;
}
}
});
function isImageRenderable(image) {
return image.nodeName === 'CANVAS' ||
image.nodeName === 'VIDEO' ||
image.complete;
}
/* harmony default export */ __webpack_exports__["a"] = (TextureCube);
/***/ }),
/* 25 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ({
defaultOption: {
// Post effect
postEffect: {
enable: false,
bloom: {
enable: true,
intensity: 0.1
},
depthOfField: {
enable: false,
focalRange: 20,
focalDistance: 50,
blurRadius: 10,
fstop: 2.8,
quality: 'medium'
},
screenSpaceAmbientOcclusion: {
enable: false,
radius: 2,
// low, medium, high, ultra
quality: 'medium',
intensity: 1
},
screenSpaceReflection: {
enable: false,
quality: 'medium',
maxRoughness: 0.8
},
colorCorrection: {
enable: true,
exposure: 0,
brightness: 0,
contrast: 1,
saturation: 1,
lookupTexture: ''
},
edge: {
enable: false
},
FXAA: {
enable: false
}
},
// Temporal super sampling when the picture is still.
temporalSuperSampling: {
// Only enabled when postEffect is enabled
enable: 'auto'
}
}
});
/***/ }),
/* 26 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ({
defaultOption: {
// Light is available when material.shading is not color
light: {
// Main light
main: {
shadow: false,
// low, medium, high, ultra
shadowQuality: 'high',
color: '#fff',
intensity: 1,
alpha: 0,
beta: 0
},
ambient: {
color: '#fff',
intensity: 0.2
},
ambientCubemap: {
// Panorama environment texture,
// Support .hdr and commmon web formats.
texture: null,
// Available when texture is hdr.
exposure: 1,
// Intensity for diffuse term
diffuseIntensity: 0.5,
// Intensity for specular term, only available when shading is realastic
specularIntensity: 0.5
}
}
}
});
/***/ }),
/* 27 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_plugin_Skybox__ = __webpack_require__(57);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_plugin_Skydome__ = __webpack_require__(56);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_echarts_lib_echarts__);
function SceneHelper() {
}
SceneHelper.prototype = {
constructor: SceneHelper,
setScene: function (scene) {
this._scene = scene;
if (this._skybox) {
this._skybox.attachScene(this._scene);
}
},
initLight: function (rootNode) {
this._lightRoot = rootNode;
/**
* @type {clay.light.Directional}
*/
this.mainLight = new __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].DirectionalLight({
shadowBias: 0.005
});
/**
* @type {clay.light.Ambient}
*/
this.ambientLight = new __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].AmbientLight();
rootNode.add(this.mainLight);
rootNode.add(this.ambientLight);
},
dispose: function () {
if (this._lightRoot) {
this._lightRoot.remove(this.mainLight);
this._lightRoot.remove(this.ambientLight);
}
},
updateLight: function (componentModel) {
var mainLight = this.mainLight;
var ambientLight = this.ambientLight;
var lightModel = componentModel.getModel('light');
var mainLightModel = lightModel.getModel('main');
var ambientLightModel = lightModel.getModel('ambient');
mainLight.intensity = mainLightModel.get('intensity');
ambientLight.intensity = ambientLightModel.get('intensity');
mainLight.color = __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].parseColor(mainLightModel.get('color')).slice(0, 3);
ambientLight.color = __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].parseColor(ambientLightModel.get('color')).slice(0, 3);
var alpha = mainLightModel.get('alpha') || 0;
var beta = mainLightModel.get('beta') || 0;
mainLight.position.setArray(__WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].directionFromAlphaBeta(alpha, beta));
mainLight.lookAt(__WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Vector3.ZERO);
mainLight.castShadow = mainLightModel.get('shadow');
mainLight.shadowResolution = __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].getShadowResolution(mainLightModel.get('shadowQuality'));
},
updateAmbientCubemap: function (renderer, componentModel, api) {
var ambientCubemapModel = componentModel.getModel('light.ambientCubemap');
var textureUrl = ambientCubemapModel.get('texture');
if (textureUrl) {
this._cubemapLightsCache = this._cubemapLightsCache || {};
var lights = this._cubemapLightsCache[textureUrl];
if (!lights) {
var self = this;
lights = this._cubemapLightsCache[textureUrl]
= __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].createAmbientCubemap(ambientCubemapModel.option, renderer, api, function () {
// Use prefitered cubemap
if (self._skybox instanceof __WEBPACK_IMPORTED_MODULE_1_claygl_src_plugin_Skybox__["a" /* default */]) {
self._skybox.setEnvironmentMap(lights.specular.cubemap);
}
api.getZr().refresh();
});
}
this._lightRoot.add(lights.diffuse);
this._lightRoot.add(lights.specular);
this._currentCubemapLights = lights;
}
else if (this._currentCubemapLights) {
this._lightRoot.remove(this._currentCubemapLights.diffuse);
this._lightRoot.remove(this._currentCubemapLights.specular);
this._currentCubemapLights = null;
}
},
updateSkybox: function (renderer, componentModel, api) {
var environmentUrl = componentModel.get('environment');
var self = this;
function getSkybox() {
if (!(self._skybox instanceof __WEBPACK_IMPORTED_MODULE_1_claygl_src_plugin_Skybox__["a" /* default */])) {
if (self._skybox) {
self._skybox.dispose(renderer);
}
self._skybox = new __WEBPACK_IMPORTED_MODULE_1_claygl_src_plugin_Skybox__["a" /* default */]();
}
return self._skybox;
}
function getSkydome() {
if (!(self._skybox instanceof __WEBPACK_IMPORTED_MODULE_2_claygl_src_plugin_Skydome__["a" /* default */])) {
if (self._skybox) {
self._skybox.dispose(renderer);
}
self._skybox = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_plugin_Skydome__["a" /* default */]();
}
return self._skybox;
}
if (environmentUrl && environmentUrl !== 'none') {
if (environmentUrl === 'auto') {
// Use environment in ambient cubemap
if (this._currentCubemapLights) {
var skybox = getSkybox();
var cubemap = this._currentCubemapLights.specular.cubemap;
skybox.setEnvironmentMap(cubemap);
if (this._scene) {
skybox.attachScene(this._scene);
}
skybox.material.set('lod', 2);
}
else if (this._skybox) {
this._skybox.detachScene();
}
}
// Is gradient or color string
else if ((typeof environmentUrl === 'object' && environmentUrl.colorStops)
|| (typeof environmentUrl === 'string' && __WEBPACK_IMPORTED_MODULE_3_echarts_lib_echarts___default.a.color.parse(environmentUrl))
) {
var skydome = getSkydome();
var texture = new __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Texture2D({
anisotropic: 8,
flipY: false
});
skydome.setEnvironmentMap(texture);
var canvas = texture.image = document.createElement('canvas');
canvas.width = canvas.height = 16;
var ctx = canvas.getContext('2d');
var rect = new __WEBPACK_IMPORTED_MODULE_3_echarts_lib_echarts___default.a.graphic.Rect({
shape: { x: 0, y: 0, width: 16, height: 16 },
style: { fill: environmentUrl }
});
rect.brush(ctx);
skydome.attachScene(this._scene);
}
else {
// Panorama
var skydome = getSkydome();
var texture = __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].loadTexture(environmentUrl, api, {
anisotropic: 8,
flipY: false
});
skydome.setEnvironmentMap(texture);
skydome.attachScene(this._scene);
}
}
else {
if (this._skybox) {
this._skybox.detachScene(this._scene);
}
this._skybox = null;
}
var coordSys = componentModel.coordinateSystem;
if (this._skybox) {
if (coordSys && coordSys.viewGL
&& environmentUrl !== 'auto'
&& !(environmentUrl.match && environmentUrl.match(/.hdr$/))
) {
var srgbDefineMethod = coordSys.viewGL.isLinearSpace() ? 'define' : 'undefine';
this._skybox.material[srgbDefineMethod]('fragment', 'SRGB_DECODE');
}
else {
this._skybox.material.undefine('fragment', 'SRGB_DECODE');
}
// var ambientCubemapUrl = environmentUrl === 'auto'
// ? componentModel.get('light.ambientCubemap.texture')
// : environmentUrl;
}
}
};
/* harmony default export */ __webpack_exports__["a"] = (SceneHelper);
/***/ }),
/* 28 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ({
defaultOption: {
shading: null,
realisticMaterial: {
textureTiling: 1,
textureOffset: 0,
detailTexture: null
},
lambertMaterial: {
textureTiling: 1,
textureOffset: 0,
detailTexture: null
},
colorMaterial: {
textureTiling: 1,
textureOffset: 0,
detailTexture: null
},
hatchingMaterial: {
textureTiling: 1,
textureOffset: 0,
paperColor: '#fff'
}
}
});
/***/ }),
/* 29 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
var formatUtil = {};
formatUtil.getFormattedLabel = function (seriesModel, dataIndex, status, dataType, dimIndex) {
status = status || 'normal';
var data = seriesModel.getData(dataType);
var itemModel = data.getItemModel(dataIndex);
var params = seriesModel.getDataParams(dataIndex, dataType);
if (dimIndex != null && (params.value instanceof Array)) {
params.value = params.value[dimIndex];
}
var formatter = itemModel.get(status === 'normal' ? ['label', 'formatter'] : ['emphasis', 'label', 'formatter']);
if (formatter == null) {
formatter = itemModel.get(['label', 'formatter']);
}
var text;
if (typeof formatter === 'function') {
params.status = status;
text = formatter(params);
}
else if (typeof formatter === 'string') {
text = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.format.formatTpl(formatter, params);
}
return text;
};
/**
* If value is not array, then convert it to array.
* @param {*} value
* @return {Array} [value] or value
*/
formatUtil.normalizeToArray = function (value) {
return value instanceof Array
? value
: value == null
? []
: [value];
};
/* harmony default export */ __webpack_exports__["a"] = (formatUtil);
/***/ }),
/* 30 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_Base__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__math_Vector3__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__math_Quaternion__ = __webpack_require__(50);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__math_Matrix4__ = __webpack_require__(7);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4__dep_glmatrix__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__math_BoundingBox__ = __webpack_require__(15);
var mat4 = __WEBPACK_IMPORTED_MODULE_4__dep_glmatrix___default.a.mat4;
var nameId = 0;
/**
* @constructor clay.Node
* @extends clay.core.Base
*/
var Node = __WEBPACK_IMPORTED_MODULE_0__core_Base__["a" /* default */].extend(/** @lends clay.Node# */{
/**
* Scene node name
* @type {string}
*/
name: '',
/**
* Position relative to its parent node. aka translation.
* @type {clay.Vector3}
*/
position: null,
/**
* Rotation relative to its parent node. Represented by a quaternion
* @type {clay.Quaternion}
*/
rotation: null,
/**
* Scale relative to its parent node
* @type {clay.Vector3}
*/
scale: null,
/**
* Affine transform matrix relative to its root scene.
* @type {clay.Matrix4}
*/
worldTransform: null,
/**
* Affine transform matrix relative to its parent node.
* Composited with position, rotation and scale.
* @type {clay.Matrix4}
*/
localTransform: null,
/**
* If the local transform is update from SRT(scale, rotation, translation, which is position here) each frame
* @type {boolean}
*/
autoUpdateLocalTransform: true,
/**
* Parent of current scene node
* @type {?clay.Node}
* @private
*/
_parent: null,
/**
* The root scene mounted. Null if it is a isolated node
* @type {?clay.Scene}
* @private
*/
_scene: null,
/**
* @type {boolean}
* @private
*/
_needsUpdateWorldTransform: true,
/**
* @type {boolean}
* @private
*/
_inIterating: false,
// Depth for transparent list sorting
__depth: 0
}, function () {
if (!this.name) {
this.name = (this.type || 'NODE') + '_' + (nameId++);
}
if (!this.position) {
this.position = new __WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */]();
}
if (!this.rotation) {
this.rotation = new __WEBPACK_IMPORTED_MODULE_2__math_Quaternion__["a" /* default */]();
}
if (!this.scale) {
this.scale = new __WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */](1, 1, 1);
}
this.worldTransform = new __WEBPACK_IMPORTED_MODULE_3__math_Matrix4__["a" /* default */]();
this.localTransform = new __WEBPACK_IMPORTED_MODULE_3__math_Matrix4__["a" /* default */]();
this._children = [];
},
/**@lends clay.Node.prototype. */
{
/**
* @type {?clay.Vector3}
* @instance
*/
target: null,
/**
* If node and its chilren invisible
* @type {boolean}
* @instance
*/
invisible: false,
/**
* If Node is a skinned mesh
* @return {boolean}
*/
isSkinnedMesh: function () {
return false;
},
/**
* Return true if it is a renderable scene node, like Mesh and ParticleSystem
* @return {boolean}
*/
isRenderable: function () {
return false;
},
/**
* Set the name of the scene node
* @param {string} name
*/
setName: function (name) {
var scene = this._scene;
if (scene) {
var nodeRepository = scene._nodeRepository;
delete nodeRepository[this.name];
nodeRepository[name] = this;
}
this.name = name;
},
/**
* Add a child node
* @param {clay.Node} node
*/
add: function (node) {
var originalParent = node._parent;
if (originalParent === this) {
return;
}
if (originalParent) {
originalParent.remove(node);
}
node._parent = this;
this._children.push(node);
var scene = this._scene;
if (scene && scene !== node.scene) {
node.traverse(this._addSelfToScene, this);
}
// Mark children needs update transform
// In case child are remove and added again after parent moved
node._needsUpdateWorldTransform = true;
},
/**
* Remove the given child scene node
* @param {clay.Node} node
*/
remove: function (node) {
var children = this._children;
var idx = children.indexOf(node);
if (idx < 0) {
return;
}
children.splice(idx, 1);
node._parent = null;
if (this._scene) {
node.traverse(this._removeSelfFromScene, this);
}
},
/**
* Remove all children
*/
removeAll: function () {
var children = this._children;
for (var idx = 0; idx < children.length; idx++) {
children[idx]._parent = null;
if (this._scene) {
children[idx].traverse(this._removeSelfFromScene, this);
}
}
this._children = [];
},
/**
* Get the scene mounted
* @return {clay.Scene}
*/
getScene: function () {
return this._scene;
},
/**
* Get parent node
* @return {clay.Scene}
*/
getParent: function () {
return this._parent;
},
_removeSelfFromScene: function (descendant) {
descendant._scene.removeFromScene(descendant);
descendant._scene = null;
},
_addSelfToScene: function (descendant) {
this._scene.addToScene(descendant);
descendant._scene = this._scene;
},
/**
* Return true if it is ancestor of the given scene node
* @param {clay.Node} node
*/
isAncestor: function (node) {
var parent = node._parent;
while(parent) {
if (parent === this) {
return true;
}
parent = parent._parent;
}
return false;
},
/**
* Get a new created array of all children nodes
* @return {clay.Node[]}
*/
children: function () {
return this._children.slice();
},
/**
* Get child scene node at given index.
* @param {number} idx
* @return {clay.Node}
*/
childAt: function (idx) {
return this._children[idx];
},
/**
* Get first child with the given name
* @param {string} name
* @return {clay.Node}
*/
getChildByName: function (name) {
var children = this._children;
for (var i = 0; i < children.length; i++) {
if (children[i].name === name) {
return children[i];
}
}
},
/**
* Get first descendant have the given name
* @param {string} name
* @return {clay.Node}
*/
getDescendantByName: function (name) {
var children = this._children;
for (var i = 0; i < children.length; i++) {
var child = children[i];
if (child.name === name) {
return child;
} else {
var res = child.getDescendantByName(name);
if (res) {
return res;
}
}
}
},
/**
* Query descendant node by path
* @param {string} path
* @return {clay.Node}
* @example
* node.queryNode('root/parent/child');
*/
queryNode: function (path) {
if (!path) {
return;
}
// TODO Name have slash ?
var pathArr = path.split('/');
var current = this;
for (var i = 0; i < pathArr.length; i++) {
var name = pathArr[i];
// Skip empty
if (!name) {
continue;
}
var found = false;
var children = current._children;
for (var j = 0; j < children.length; j++) {
var child = children[j];
if (child.name === name) {
current = child;
found = true;
break;
}
}
// Early return if not found
if (!found) {
return;
}
}
return current;
},
/**
* Get query path, relative to rootNode(default is scene)
* @param {clay.Node} [rootNode]
* @return {string}
*/
getPath: function (rootNode) {
if (!this._parent) {
return '/';
}
var current = this._parent;
var path = this.name;
while (current._parent) {
path = current.name + '/' + path;
if (current._parent == rootNode) {
break;
}
current = current._parent;
}
if (!current._parent && rootNode) {
return null;
}
return path;
},
/**
* Depth first traverse all its descendant scene nodes.
*
* **WARN** Don't do `add`, `remove` operation in the callback during traverse.
* @param {Function} callback
* @param {Node} [context]
*/
traverse: function (callback, context) {
callback.call(context, this);
var _children = this._children;
for(var i = 0, len = _children.length; i < len; i++) {
_children[i].traverse(callback, context);
}
},
/**
* Traverse all children nodes.
*
* **WARN** DON'T do `add`, `remove` operation in the callback during iteration.
*
* @param {Function} callback
* @param {Node} [context]
*/
eachChild: function (callback, context) {
var _children = this._children;
for(var i = 0, len = _children.length; i < len; i++) {
var child = _children[i];
callback.call(context, child, i);
}
},
/**
* Set the local transform and decompose to SRT
* @param {clay.Matrix4} matrix
*/
setLocalTransform: function (matrix) {
mat4.copy(this.localTransform.array, matrix.array);
this.decomposeLocalTransform();
},
/**
* Decompose the local transform to SRT
*/
decomposeLocalTransform: function (keepScale) {
var scale = !keepScale ? this.scale: null;
this.localTransform.decomposeMatrix(scale, this.rotation, this.position);
},
/**
* Set the world transform and decompose to SRT
* @param {clay.Matrix4} matrix
*/
setWorldTransform: function (matrix) {
mat4.copy(this.worldTransform.array, matrix.array);
this.decomposeWorldTransform();
},
/**
* Decompose the world transform to SRT
* @function
*/
decomposeWorldTransform: (function () {
var tmp = mat4.create();
return function (keepScale) {
var localTransform = this.localTransform;
var worldTransform = this.worldTransform;
// Assume world transform is updated
if (this._parent) {
mat4.invert(tmp, this._parent.worldTransform.array);
mat4.multiply(localTransform.array, tmp, worldTransform.array);
} else {
mat4.copy(localTransform.array, worldTransform.array);
}
var scale = !keepScale ? this.scale: null;
localTransform.decomposeMatrix(scale, this.rotation, this.position);
};
})(),
transformNeedsUpdate: function () {
return this.position._dirty
|| this.rotation._dirty
|| this.scale._dirty;
},
/**
* Update local transform from SRT
* Notice that local transform will not be updated if _dirty mark of position, rotation, scale is all false
*/
updateLocalTransform: function () {
var position = this.position;
var rotation = this.rotation;
var scale = this.scale;
if (this.transformNeedsUpdate()) {
var m = this.localTransform.array;
// Transform order, scale->rotation->position
mat4.fromRotationTranslation(m, rotation.array, position.array);
mat4.scale(m, m, scale.array);
rotation._dirty = false;
scale._dirty = false;
position._dirty = false;
this._needsUpdateWorldTransform = true;
}
},
/**
* Update world transform, assume its parent world transform have been updated
* @private
*/
_updateWorldTransformTopDown: function () {
var localTransform = this.localTransform.array;
var worldTransform = this.worldTransform.array;
if (this._parent) {
mat4.multiplyAffine(
worldTransform,
this._parent.worldTransform.array,
localTransform
);
}
else {
mat4.copy(worldTransform, localTransform);
}
},
/**
* Update world transform before whole scene is updated.
*/
updateWorldTransform: function () {
// Find the root node which transform needs update;
var rootNodeIsDirty = this;
while (rootNodeIsDirty && rootNodeIsDirty.getParent()
&& rootNodeIsDirty.getParent().transformNeedsUpdate()
) {
rootNodeIsDirty = rootNodeIsDirty.getParent();
}
rootNodeIsDirty.update();
},
/**
* Update local transform and world transform recursively
* @param {boolean} forceUpdateWorld
*/
update: function (forceUpdateWorld) {
if (this.autoUpdateLocalTransform) {
this.updateLocalTransform();
}
else {
// Transform is manually setted
forceUpdateWorld = true;
}
if (forceUpdateWorld || this._needsUpdateWorldTransform) {
this._updateWorldTransformTopDown();
forceUpdateWorld = true;
this._needsUpdateWorldTransform = false;
}
var children = this._children;
for(var i = 0, len = children.length; i < len; i++) {
children[i].update(forceUpdateWorld);
}
},
/**
* Get bounding box of node
* @param {Function} [filter]
* @param {clay.BoundingBox} [out]
* @return {clay.BoundingBox}
*/
// TODO Skinning
getBoundingBox: (function () {
function defaultFilter (el) {
return !el.invisible && el.geometry;
}
var tmpBBox = new __WEBPACK_IMPORTED_MODULE_5__math_BoundingBox__["a" /* default */]();
var tmpMat4 = new __WEBPACK_IMPORTED_MODULE_3__math_Matrix4__["a" /* default */]();
var invWorldTransform = new __WEBPACK_IMPORTED_MODULE_3__math_Matrix4__["a" /* default */]();
return function (filter, out) {
out = out || new __WEBPACK_IMPORTED_MODULE_5__math_BoundingBox__["a" /* default */]();
filter = filter || defaultFilter;
if (this._parent) {
__WEBPACK_IMPORTED_MODULE_3__math_Matrix4__["a" /* default */].invert(invWorldTransform, this._parent.worldTransform);
}
else {
__WEBPACK_IMPORTED_MODULE_3__math_Matrix4__["a" /* default */].identity(invWorldTransform);
}
this.traverse(function (mesh) {
if (mesh.geometry && mesh.geometry.boundingBox) {
tmpBBox.copy(mesh.geometry.boundingBox);
__WEBPACK_IMPORTED_MODULE_3__math_Matrix4__["a" /* default */].multiply(tmpMat4, invWorldTransform, mesh.worldTransform);
tmpBBox.applyTransform(tmpMat4);
out.union(tmpBBox);
}
}, this, defaultFilter);
return out;
};
})(),
/**
* Get world position, extracted from world transform
* @param {clay.Vector3} [out]
* @return {clay.Vector3}
*/
getWorldPosition: function (out) {
// PENDING
if (this.transformNeedsUpdate()) {
this.updateWorldTransform();
}
var m = this.worldTransform.array;
if (out) {
var arr = out.array;
arr[0] = m[12];
arr[1] = m[13];
arr[2] = m[14];
return out;
}
else {
return new __WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */](m[12], m[13], m[14]);
}
},
/**
* Clone a new node
* @return {Node}
*/
clone: function () {
var node = new this.constructor();
var children = this._children;
node.setName(this.name);
node.position.copy(this.position);
node.rotation.copy(this.rotation);
node.scale.copy(this.scale);
for (var i = 0; i < children.length; i++) {
node.add(children[i].clone());
}
return node;
},
/**
* Rotate the node around a axis by angle degrees, axis passes through point
* @param {clay.Vector3} point Center point
* @param {clay.Vector3} axis Center axis
* @param {number} angle Rotation angle
* @see http://docs.unity3d.com/Documentation/ScriptReference/Transform.RotateAround.html
* @function
*/
rotateAround: (function () {
var v = new __WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */]();
var RTMatrix = new __WEBPACK_IMPORTED_MODULE_3__math_Matrix4__["a" /* default */]();
// TODO improve performance
return function (point, axis, angle) {
v.copy(this.position).subtract(point);
var localTransform = this.localTransform;
localTransform.identity();
// parent node
localTransform.translate(point);
localTransform.rotate(angle, axis);
RTMatrix.fromRotationTranslation(this.rotation, v);
localTransform.multiply(RTMatrix);
localTransform.scale(this.scale);
this.decomposeLocalTransform();
this._needsUpdateWorldTransform = true;
};
})(),
/**
* @param {clay.Vector3} target
* @param {clay.Vector3} [up]
* @see http://www.opengl.org/sdk/docs/man2/xhtml/gluLookAt.xml
* @function
*/
lookAt: (function () {
var m = new __WEBPACK_IMPORTED_MODULE_3__math_Matrix4__["a" /* default */]();
return function (target, up) {
m.lookAt(this.position, target, up || this.localTransform.y).invert();
this.setLocalTransform(m);
this.target = target;
};
})()
});
/* harmony default export */ __webpack_exports__["a"] = (Node);
/***/ }),
/* 31 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Renderable__ = __webpack_require__(66);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_glenum__ = __webpack_require__(11);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Texture2D__ = __webpack_require__(5);
/**
* @constructor clay.Mesh
* @extends clay.Renderable
*/
var Mesh = __WEBPACK_IMPORTED_MODULE_0__Renderable__["a" /* default */].extend(/** @lends clay.Mesh# */ {
/**
* Used when it is a skinned mesh
* @type {clay.Skeleton}
*/
skeleton: null,
/**
* Joints indices Meshes can share the one skeleton instance and each mesh can use one part of joints. Joints indices indicate the index of joint in the skeleton instance
* @type {number[]}
*/
joints: null,
/**
* If store the skin matrices in vertex texture
* @type {bool}
*/
useSkinMatricesTexture: false
}, function () {
if (!this.joints) {
this.joints = [];
}
}, {
isSkinnedMesh: function () {
return !!(this.skeleton && this.joints && this.joints.length > 0);
},
getSkinMatricesTexture: function () {
this._skinMatricesTexture = this._skinMatricesTexture || new __WEBPACK_IMPORTED_MODULE_2__Texture2D__["a" /* default */]({
type: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].FLOAT,
minFilter: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].NEAREST,
magFilter: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].NEAREST,
useMipmap: false,
flipY: false
});
return this._skinMatricesTexture;
},
clone: function () {
var mesh = __WEBPACK_IMPORTED_MODULE_0__Renderable__["a" /* default */].prototype.clone.call(this);
mesh.skeleton = this.skeleton;
if (this.joints) {
mesh.joints = this.joints.slice();
}
return mesh;
}
});
// Enums
Mesh.POINTS = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].POINTS;
Mesh.LINES = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINES;
Mesh.LINE_LOOP = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINE_LOOP;
Mesh.LINE_STRIP = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINE_STRIP;
Mesh.TRIANGLES = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].TRIANGLES;
Mesh.TRIANGLE_STRIP = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].TRIANGLE_STRIP;
Mesh.TRIANGLE_FAN = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].TRIANGLE_FAN;
Mesh.BACK = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].BACK;
Mesh.FRONT = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].FRONT;
Mesh.FRONT_AND_BACK = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].FRONT_AND_BACK;
Mesh.CW = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].CW;
Mesh.CCW = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].CCW;
/* harmony default export */ __webpack_exports__["a"] = (Mesh);
/***/ }),
/* 32 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Node__ = __webpack_require__(30);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Light__ = __webpack_require__(21);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Camera__ = __webpack_require__(51);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__math_BoundingBox__ = __webpack_require__(15);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__core_util__ = __webpack_require__(20);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5__dep_glmatrix__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__core_LRU__ = __webpack_require__(64);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__math_Matrix4__ = __webpack_require__(7);
var mat4 = __WEBPACK_IMPORTED_MODULE_5__dep_glmatrix___default.a.mat4;
var IDENTITY = mat4.create();
var WORLDVIEW = mat4.create();
var programKeyCache = {};
function getProgramKey(lightNumbers) {
var defineStr = [];
var lightTypes = Object.keys(lightNumbers);
lightTypes.sort();
for (var i = 0; i < lightTypes.length; i++) {
var lightType = lightTypes[i];
defineStr.push(lightType + ' ' + lightNumbers[lightType]);
}
var key = defineStr.join('\n');
if (programKeyCache[key]) {
return programKeyCache[key];
}
var id = __WEBPACK_IMPORTED_MODULE_4__core_util__["a" /* default */].genGUID();
programKeyCache[key] = id;
return id;
}
function RenderList() {
this.opaque = [];
this.transparent = [];
this._opaqueCount = 0;
this._transparentCount = 0;
}
RenderList.prototype.startCount = function () {
this._opaqueCount = 0;
this._transparentCount = 0;
};
RenderList.prototype.add = function (object, isTransparent) {
if (isTransparent) {
this.transparent[this._transparentCount++] = object;
}
else {
this.opaque[this._opaqueCount++] = object;
}
};
RenderList.prototype.endCount = function () {
this.transparent.length = this._transparentCount;
this.opaque.length = this._opaqueCount;
};
/**
* @typedef {Object} clay.Scene.RenderList
* @property {Array.} opaque
* @property {Array.} transparent
*/
/**
* @constructor clay.Scene
* @extends clay.Node
*/
var Scene = __WEBPACK_IMPORTED_MODULE_0__Node__["a" /* default */].extend(function () {
return /** @lends clay.Scene# */ {
/**
* Global material of scene
* @type {clay.Material}
*/
material: null,
lights: [],
/**
* Scene bounding box in view space.
* Used when camera needs to adujst the near and far plane automatically
* so that the view frustum contains the visible objects as tightly as possible.
* Notice:
* It is updated after rendering (in the step of frustum culling passingly). So may be not so accurate, but saves a lot of calculation
*
* @type {clay.BoundingBox}
*/
viewBoundingBoxLastFrame: new __WEBPACK_IMPORTED_MODULE_3__math_BoundingBox__["a" /* default */](),
// Uniforms for shadow map.
shadowUniforms: {},
_cameraList: [],
// Properties to save the light information in the scene
// Will be set in the render function
_lightUniforms: {},
_previousLightNumber: {},
_lightNumber: {
// groupId: {
// POINT_LIGHT: 0,
// DIRECTIONAL_LIGHT: 0,
// SPOT_LIGHT: 0,
// AMBIENT_LIGHT: 0,
// AMBIENT_SH_LIGHT: 0
// }
},
_lightProgramKeys: {},
_nodeRepository: {},
_renderLists: new __WEBPACK_IMPORTED_MODULE_6__core_LRU__["a" /* default */](20)
};
}, function () {
this._scene = this;
},
/** @lends clay.Scene.prototype. */
{
// Add node to scene
addToScene: function (node) {
if (node instanceof __WEBPACK_IMPORTED_MODULE_2__Camera__["a" /* default */]) {
if (this._cameraList.length > 0) {
console.warn('Found multiple camera in one scene. Use the fist one.');
}
this._cameraList.push(node);
}
else if (node instanceof __WEBPACK_IMPORTED_MODULE_1__Light__["a" /* default */]) {
this.lights.push(node);
}
if (node.name) {
this._nodeRepository[node.name] = node;
}
},
// Remove node from scene
removeFromScene: function (node) {
var idx;
if (node instanceof __WEBPACK_IMPORTED_MODULE_2__Camera__["a" /* default */]) {
idx = this._cameraList.indexOf(node);
if (idx >= 0) {
this._cameraList.splice(idx, 1);
}
}
else if (node instanceof __WEBPACK_IMPORTED_MODULE_1__Light__["a" /* default */]) {
idx = this.lights.indexOf(node);
if (idx >= 0) {
this.lights.splice(idx, 1);
}
}
if (node.name) {
delete this._nodeRepository[node.name];
}
},
/**
* Get node by name
* @param {string} name
* @return {Node}
* @DEPRECATED
*/
getNode: function (name) {
return this._nodeRepository[name];
},
/**
* Set main camera of the scene.
* @param {claygl.Camera} camera
*/
setMainCamera: function (camera) {
var idx = this._cameraList.indexOf(camera);
if (idx >= 0) {
this._cameraList.splice(idx, 1);
}
this._cameraList.unshift(camera);
},
/**
* Get main camera of the scene.
*/
getMainCamera: function () {
return this._cameraList[0];
},
getLights: function () {
return this.lights;
},
updateLights: function () {
var lights = this.lights;
this._previousLightNumber = this._lightNumber;
var lightNumber = {};
for (var i = 0; i < lights.length; i++) {
var light = lights[i];
if (light.invisible) {
continue;
}
var group = light.group;
if (!lightNumber[group]) {
lightNumber[group] = {};
}
// User can use any type of light
lightNumber[group][light.type] = lightNumber[group][light.type] || 0;
lightNumber[group][light.type]++;
}
this._lightNumber = lightNumber;
for (var groupId in lightNumber) {
this._lightProgramKeys[groupId] = getProgramKey(lightNumber[groupId]);
}
this._updateLightUniforms();
},
/**
* Clone a node and it's children, including mesh, camera, light, etc.
* Unlike using `Node#clone`. It will clone skeleton and remap the joints. Material will also be cloned.
*
* @param {clay.Node} node
* @return {clay.Node}
*/
cloneNode: function (node) {
var newNode = node.clone();
var clonedNodesMap = {};
function buildNodesMap(sNode, tNode) {
clonedNodesMap[sNode.__uid__] = tNode;
for (var i = 0; i < sNode._children.length; i++) {
var sChild = sNode._children[i];
var tChild = tNode._children[i];
buildNodesMap(sChild, tChild);
}
}
buildNodesMap(node, newNode);
newNode.traverse(function (newChild) {
if (newChild.skeleton) {
newChild.skeleton = newChild.skeleton.clone(clonedNodesMap);
}
if (newChild.material) {
newChild.material = newChild.material.clone();
}
});
return newNode;
},
/**
* Traverse the scene and add the renderable object to the render list.
* It needs camera for the frustum culling.
*
* @param {clay.Camera} camera
* @return {clay.Scene.RenderList}
*/
updateRenderList: function (camera) {
var id = camera.__uid__;
var renderList = this._renderLists.get(id);
if (!renderList) {
renderList = new RenderList();
this._renderLists.put(id, renderList);
}
renderList.startCount();
this.viewBoundingBoxLastFrame.min.set(Infinity, Infinity, Infinity);
this.viewBoundingBoxLastFrame.max.set(-Infinity, -Infinity, -Infinity);
var sceneMaterialTransparent = this.material && this.material.transparent || false;
this._doUpdateRenderList(this, camera, sceneMaterialTransparent, renderList);
renderList.endCount();
return renderList;
},
/**
* Get render list. Used after {@link clay.Scene#updateRenderList}
* @param {clay.Camera} camera
* @return {clay.Scene.RenderList}
*/
getRenderList: function (camera) {
return this._renderLists.get(camera.__uid__);
},
_doUpdateRenderList: function (parent, camera, sceneMaterialTransparent, renderList) {
if (parent.invisible) {
return;
}
// TODO Optimize
for (var i = 0; i < parent._children.length; i++) {
var child = parent._children[i];
if (child.isRenderable()) {
// Frustum culling
var worldM = child.isSkinnedMesh() ? IDENTITY : child.worldTransform.array;
var geometry = child.geometry;
mat4.multiplyAffine(WORLDVIEW, camera.viewMatrix.array, worldM);
if (!geometry.boundingBox || !this.isFrustumCulled(child, camera, WORLDVIEW)) {
renderList.add(child, child.material.transparent || sceneMaterialTransparent);
}
}
if (child._children.length > 0) {
this._doUpdateRenderList(child, camera, sceneMaterialTransparent, renderList);
}
}
},
/**
* If an scene object is culled by camera frustum
*
* Object can be a renderable or a light
*
* @param {clay.Node} object
* @param {clay.Camera} camera
* @param {Array.} worldViewMat represented with array
* @param {Array.} projectionMat represented with array
*/
isFrustumCulled: (function () {
// Frustum culling
// http://www.cse.chalmers.se/~uffe/vfc_bbox.pdf
var cullingBoundingBox = new __WEBPACK_IMPORTED_MODULE_3__math_BoundingBox__["a" /* default */]();
var cullingMatrix = new __WEBPACK_IMPORTED_MODULE_7__math_Matrix4__["a" /* default */]();
return function(object, camera, worldViewMat) {
// Bounding box can be a property of object(like light) or renderable.geometry
// PENDING
var geoBBox = object.boundingBox || object.geometry.boundingBox;
cullingMatrix.array = worldViewMat;
cullingBoundingBox.transformFrom(geoBBox, cullingMatrix);
// Passingly update the scene bounding box
// FIXME exclude very large mesh like ground plane or terrain ?
// FIXME Only rendererable which cast shadow ?
// FIXME boundingBox becomes much larger after transformd.
if (object.castShadow) {
this.viewBoundingBoxLastFrame.union(cullingBoundingBox);
}
// Ignore frustum culling if object is skinned mesh.
if (object.frustumCulling && !object.isSkinnedMesh()) {
if (!cullingBoundingBox.intersectBoundingBox(camera.frustum.boundingBox)) {
return true;
}
cullingMatrix.array = camera.projectionMatrix.array;
if (
cullingBoundingBox.max.array[2] > 0 &&
cullingBoundingBox.min.array[2] < 0
) {
// Clip in the near plane
cullingBoundingBox.max.array[2] = -1e-20;
}
cullingBoundingBox.applyProjection(cullingMatrix);
var min = cullingBoundingBox.min.array;
var max = cullingBoundingBox.max.array;
if (
max[0] < -1 || min[0] > 1
|| max[1] < -1 || min[1] > 1
|| max[2] < -1 || min[2] > 1
) {
return true;
}
}
return false;
};
})(),
_updateLightUniforms: function () {
var lights = this.lights;
// Put the light cast shadow before the light not cast shadow
lights.sort(lightSortFunc);
var lightUniforms = this._lightUniforms;
for (var group in lightUniforms) {
for (var symbol in lightUniforms[group]) {
lightUniforms[group][symbol].value.length = 0;
}
}
for (var i = 0; i < lights.length; i++) {
var light = lights[i];
if (light.invisible) {
continue;
}
var group = light.group;
for (var symbol in light.uniformTemplates) {
var uniformTpl = light.uniformTemplates[symbol];
var value = uniformTpl.value(light);
if (value == null) {
continue;
}
if (!lightUniforms[group]) {
lightUniforms[group] = {};
}
if (!lightUniforms[group][symbol]) {
lightUniforms[group][symbol] = {
type: '',
value: []
};
}
var lu = lightUniforms[group][symbol];
lu.type = uniformTpl.type + 'v';
switch (uniformTpl.type) {
case '1i':
case '1f':
case 't':
lu.value.push(value);
break;
case '2f':
case '3f':
case '4f':
for (var j = 0; j < value.length; j++) {
lu.value.push(value[j]);
}
break;
default:
console.error('Unkown light uniform type ' + uniformTpl.type);
}
}
}
},
getLightGroups: function () {
var lightGroups = [];
for (var groupId in this._lightNumber) {
lightGroups.push(groupId);
}
return lightGroups;
},
getNumberChangedLightGroups: function () {
var lightGroups = [];
for (var groupId in this._lightNumber) {
if (this.isLightNumberChanged(groupId)) {
lightGroups.push(groupId);
}
}
return lightGroups;
},
// Determine if light group is different with since last frame
// Used to determine whether to update shader and scene's uniforms in Renderer.render
isLightNumberChanged: function (lightGroup) {
var prevLightNumber = this._previousLightNumber;
var currentLightNumber = this._lightNumber;
// PENDING Performance
for (var type in currentLightNumber[lightGroup]) {
if (!prevLightNumber[lightGroup]) {
return true;
}
if (currentLightNumber[lightGroup][type] !== prevLightNumber[lightGroup][type]) {
return true;
}
}
for (var type in prevLightNumber[lightGroup]) {
if (!currentLightNumber[lightGroup]) {
return true;
}
if (currentLightNumber[lightGroup][type] !== prevLightNumber[lightGroup][type]) {
return true;
}
}
return false;
},
getLightsNumbers: function (lightGroup) {
return this._lightNumber[lightGroup];
},
getProgramKey: function (lightGroup) {
return this._lightProgramKeys[lightGroup];
},
setLightUniforms: (function () {
function setUniforms(uniforms, program, renderer) {
for (var symbol in uniforms) {
var lu = uniforms[symbol];
if (lu.type === 'tv') {
if (!program.hasUniform(symbol)) {
continue;
}
var texSlots = [];
for (var i = 0; i < lu.value.length; i++) {
var texture = lu.value[i];
var slot = program.takeCurrentTextureSlot(renderer, texture);
texSlots.push(slot);
}
program.setUniform(renderer.gl, '1iv', symbol, texSlots);
}
else {
program.setUniform(renderer.gl, lu.type, symbol, lu.value);
}
}
}
return function (program, lightGroup, renderer) {
setUniforms(this._lightUniforms[lightGroup], program, renderer);
// Set shadows
setUniforms(this.shadowUniforms, program, renderer);
};
})(),
/**
* Dispose self, clear all the scene objects
* But resources of gl like texuture, shader will not be disposed.
* Mostly you should use disposeScene method in Renderer to do dispose.
*/
dispose: function () {
this.material = null;
this._opaqueList = [];
this._transparentList = [];
this.lights = [];
this._lightUniforms = {};
this._lightNumber = {};
this._nodeRepository = {};
}
});
function lightSortFunc(a, b) {
if (b.castShadow && !a.castShadow) {
return true;
}
}
/* harmony default export */ __webpack_exports__["a"] = (Scene);
/***/ }),
/* 33 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Camera__ = __webpack_require__(51);
/**
* @constructor clay.camera.Orthographic
* @extends clay.Camera
*/
var Orthographic = __WEBPACK_IMPORTED_MODULE_0__Camera__["a" /* default */].extend(
/** @lends clay.camera.Orthographic# */
{
/**
* @type {number}
*/
left: -1,
/**
* @type {number}
*/
right: 1,
/**
* @type {number}
*/
near: -1,
/**
* @type {number}
*/
far: 1,
/**
* @type {number}
*/
top: 1,
/**
* @type {number}
*/
bottom: -1
},
/** @lends clay.camera.Orthographic.prototype */
{
updateProjectionMatrix: function() {
this.projectionMatrix.ortho(this.left, this.right, this.bottom, this.top, this.near, this.far);
},
decomposeProjectionMatrix: function () {
var m = this.projectionMatrix.array;
this.left = (-1 - m[12]) / m[0];
this.right = (1 - m[12]) / m[0];
this.top = (1 - m[13]) / m[5];
this.bottom = (-1 - m[13]) / m[5];
this.near = -(-1 - m[14]) / m[10];
this.far = -(1 - m[14]) / m[10];
},
/**
* @return {clay.camera.Orthographic}
*/
clone: function() {
var camera = __WEBPACK_IMPORTED_MODULE_0__Camera__["a" /* default */].prototype.clone.call(this);
camera.left = this.left;
camera.right = this.right;
camera.near = this.near;
camera.far = this.far;
camera.top = this.top;
camera.bottom = this.bottom;
return camera;
}
});
/* harmony default export */ __webpack_exports__["a"] = (Orthographic);
/***/ }),
/* 34 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ({
convertToDynamicArray: function (clear) {
if (clear) {
this.resetOffset();
}
var attributes = this.attributes;
for (var name in attributes) {
if (clear || !attributes[name].value) {
attributes[name].value = [];
}
else {
attributes[name].value = Array.prototype.slice.call(attributes[name].value);
}
}
if (clear || !this.indices) {
this.indices = [];
}
else {
this.indices = Array.prototype.slice.call(this.indices);
}
},
convertToTypedArray: function () {
var attributes = this.attributes;
for (var name in attributes) {
if (attributes[name].value && attributes[name].value.length > 0) {
attributes[name].value = new Float32Array(attributes[name].value);
}
else {
attributes[name].value = null;
}
}
if (this.indices && this.indices.length > 0) {
this.indices = this.vertexCount > 0xffff ? new Uint32Array(this.indices) : new Uint16Array(this.indices);
}
this.dirty();
}
});
/***/ }),
/* 35 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
function otherDimToDataDim (data, otherDim) {
var dataDim = [];
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.each(data.dimensions, function (dimName) {
var dimItem = data.getDimensionInfo(dimName);
var otherDims = dimItem.otherDims;
var dimIndex = otherDims[otherDim];
if (dimIndex != null && dimIndex !== false) {
dataDim[dimIndex] = dimItem.name;
}
});
return dataDim;
}
/* harmony default export */ __webpack_exports__["a"] = (function (seriesModel, dataIndex, multipleSeries) {
function formatArrayValue(value) {
var vertially = true;
var result = [];
var tooltipDims = otherDimToDataDim(data, 'tooltip');
tooltipDims.length
? __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.each(tooltipDims, function (dimIdx) {
setEachItem(data.get(dimIdx, dataIndex), dimIdx);
})
// By default, all dims is used on tooltip.
: __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.each(value, setEachItem);
function setEachItem(val, dimIdx) {
var dimInfo = data.getDimensionInfo(dimIdx);
// If `dimInfo.tooltip` is not set, show tooltip.
if (!dimInfo || dimInfo.otherDims.tooltip === false) {
return;
}
var dimType = dimInfo.type;
var valStr = (vertially ? '- ' + (dimInfo.tooltipName || dimInfo.name) + ': ' : '')
+ (dimType === 'ordinal'
? val + ''
: dimType === 'time'
? (multipleSeries ? '' : __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.format.formatTime('yyyy/MM/dd hh:mm:ss', val))
: __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.format.addCommas(val)
);
valStr && result.push(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.format.encodeHTML(valStr));
}
return (vertially ? ' ' : '') + result.join(vertially ? ' ' : ', ');
}
var data = seriesModel.getData();
var value = seriesModel.getRawValue(dataIndex);
var formattedValue = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.isArray(value)
? formatArrayValue(value) : __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.format.encodeHTML(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.format.addCommas(value));
var name = data.getName(dataIndex);
var color = data.getItemVisual(dataIndex, 'color');
if (__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.isObject(color) && color.colorStops) {
color = (color.colorStops[0] || {}).color;
}
color = color || 'transparent';
var colorEl = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.format.getTooltipMarker(color);
var seriesName = seriesModel.name;
// FIXME
if (seriesName === '\0-') {
// Not show '-'
seriesName = '';
}
seriesName = seriesName
? __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.format.encodeHTML(seriesName) + (!multipleSeries ? ' ' : ': ')
: '';
return !multipleSeries
? seriesName + colorEl
+ (name
? __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.format.encodeHTML(name) + ': ' + formattedValue
: formattedValue
)
: colorEl + seriesName + formattedValue;
});;
/***/ }),
/* 36 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Camera__ = __webpack_require__(51);
/**
* @constructor clay.camera.Perspective
* @extends clay.Camera
*/
var Perspective = __WEBPACK_IMPORTED_MODULE_0__Camera__["a" /* default */].extend(
/** @lends clay.camera.Perspective# */
{
/**
* Vertical field of view in degrees
* @type {number}
*/
fov: 50,
/**
* Aspect ratio, typically viewport width / height
* @type {number}
*/
aspect: 1,
/**
* Near bound of the frustum
* @type {number}
*/
near: 0.1,
/**
* Far bound of the frustum
* @type {number}
*/
far: 2000
},
/** @lends clay.camera.Perspective.prototype */
{
updateProjectionMatrix: function() {
var rad = this.fov / 180 * Math.PI;
this.projectionMatrix.perspective(rad, this.aspect, this.near, this.far);
},
decomposeProjectionMatrix: function () {
var m = this.projectionMatrix.array;
var rad = Math.atan(1 / m[5]) * 2;
this.fov = rad / Math.PI * 180;
this.aspect = m[5] / m[0];
this.near = m[14] / (m[10] - 1);
this.far = m[14] / (m[10] + 1);
},
/**
* @return {clay.camera.Perspective}
*/
clone: function() {
var camera = __WEBPACK_IMPORTED_MODULE_0__Camera__["a" /* default */].prototype.clone.call(this);
camera.fov = this.fov;
camera.aspect = this.aspect;
camera.near = this.near;
camera.far = this.far;
return camera;
}
});
/* harmony default export */ __webpack_exports__["a"] = (Perspective);
/***/ }),
/* 37 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Geometry__ = __webpack_require__(13);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__math_BoundingBox__ = __webpack_require__(15);
/**
* @constructor clay.geometry.Plane
* @extends clay.Geometry
* @param {Object} [opt]
* @param {number} [opt.widthSegments]
* @param {number} [opt.heightSegments]
*/
var Plane = __WEBPACK_IMPORTED_MODULE_0__Geometry__["a" /* default */].extend(
/** @lends clay.geometry.Plane# */
{
dynamic: false,
/**
* @type {number}
*/
widthSegments: 1,
/**
* @type {number}
*/
heightSegments: 1
}, function() {
this.build();
},
/** @lends clay.geometry.Plane.prototype */
{
/**
* Build plane geometry
*/
build: function() {
var heightSegments = this.heightSegments;
var widthSegments = this.widthSegments;
var attributes = this.attributes;
var positions = [];
var texcoords = [];
var normals = [];
var faces = [];
for (var y = 0; y <= heightSegments; y++) {
var t = y / heightSegments;
for (var x = 0; x <= widthSegments; x++) {
var s = x / widthSegments;
positions.push([2 * s - 1, 2 * t - 1, 0]);
if (texcoords) {
texcoords.push([s, t]);
}
if (normals) {
normals.push([0, 0, 1]);
}
if (x < widthSegments && y < heightSegments) {
var i = x + y * (widthSegments + 1);
faces.push([i, i + 1, i + widthSegments + 1]);
faces.push([i + widthSegments + 1, i + 1, i + widthSegments + 2]);
}
}
}
attributes.position.fromArray(positions);
attributes.texcoord0.fromArray(texcoords);
attributes.normal.fromArray(normals);
this.initIndicesFromArray(faces);
this.boundingBox = new __WEBPACK_IMPORTED_MODULE_1__math_BoundingBox__["a" /* default */]();
this.boundingBox.min.set(-1, -1, 0);
this.boundingBox.max.set(1, 1, 0);
}
});
/* harmony default export */ __webpack_exports__["a"] = (Plane);
/***/ }),
/* 38 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ({
defaultOption: {
viewControl: {
// perspective, orthographic.
// TODO Isometric
projection: 'perspective',
// If rotate on on init
autoRotate: false,
// cw or ccw
autoRotateDirection: 'cw',
// Degree per second
autoRotateSpeed: 10,
// Start rotating after still for a given time
// default is 3 seconds
autoRotateAfterStill: 3,
// Rotate, zoom damping.
damping: 0.8,
// Sensitivities for operations.
// Can be array to set x,y respectively
rotateSensitivity: 1,
zoomSensitivity: 1,
// Can be array to set x,y respectively
panSensitivity: 1,
// Which mouse button do rotate or pan
panMouseButton: 'middle',
rotateMouseButton: 'left',
// Distance to the target
// Only available when camera is perspective.
distance: 150,
// Min distance mouse can zoom in
minDistance: 40,
// Max distance mouse can zoom out
maxDistance: 400,
// Size of viewing volume.
// Only available when camera is orthographic
orthographicSize: 150,
maxOrthographicSize: 400,
minOrthographicSize: 20,
// Center view point
center: [0, 0, 0],
// Alpha angle for top-down rotation
// Positive to rotate to top.
alpha: 0,
// beta angle for left-right rotation
// Positive to rotate to right.
beta: 0,
minAlpha: -90,
maxAlpha: 90
// minBeta: -Infinity
// maxBeta: -Infinity
}
},
setView: function (opts) {
opts = opts || {};
this.option.viewControl = this.option.viewControl || {};
if (opts.alpha != null) {
this.option.viewControl.alpha = opts.alpha;
}
if (opts.beta != null) {
this.option.viewControl.beta = opts.beta;
}
if (opts.distance != null) {
this.option.viewControl.distance = opts.distance;
}
if (opts.center != null) {
this.option.viewControl.center = opts.center;
}
}
});
/***/ }),
/* 39 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_core_Base__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector2__ = __webpack_require__(23);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_math_Vector3__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_math_Quaternion__ = __webpack_require__(50);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__retrieve__ = __webpack_require__(3);
/**
* Provide orbit control for 3D objects
*
* @module echarts-gl/util/OrbitControl
* @author Yi Shen(http://github.com/pissang)
*/
// TODO Remove magic numbers on sensitivity
var firstNotNull = __WEBPACK_IMPORTED_MODULE_4__retrieve__["a" /* default */].firstNotNull;
var MOUSE_BUTTON_KEY_MAP = {
left: 0,
middle: 1,
right: 2
};
function convertToArray(val) {
if (!(val instanceof Array)) {
val = [val, val];
}
return val;
}
/**
* @alias module:echarts-x/util/OrbitControl
*/
var OrbitControl = __WEBPACK_IMPORTED_MODULE_0_claygl_src_core_Base__["a" /* default */].extend(function () {
return {
/**
* @type {module:zrender~ZRender}
*/
zr: null,
/**
* @type {module:echarts-gl/core/ViewGL}
*/
viewGL: null,
/**
* @type {clay.math.Vector3}
*/
_center: new __WEBPACK_IMPORTED_MODULE_2_claygl_src_math_Vector3__["a" /* default */](),
/**
* Minimum distance to the center
* Only available when camera is perspective.
* @type {number}
* @default 0.5
*/
minDistance: 0.5,
/**
* Maximum distance to the center
* Only available when camera is perspective.
* @type {number}
* @default 2
*/
maxDistance: 1.5,
/**
* Only available when camera is orthographic
*/
maxOrthographicSize: 300,
/**
* Only available when camera is orthographic
*/
minOrthographicSize: 30,
/**
* Minimum alpha rotation
*/
minAlpha: -90,
/**
* Maximum alpha rotation
*/
maxAlpha: 90,
/**
* Minimum beta rotation
*/
minBeta: -Infinity,
/**
* Maximum beta rotation
*/
maxBeta: Infinity,
/**
* Start auto rotating after still for the given time
*/
autoRotateAfterStill: 0,
/**
* Direction of autoRotate. cw or ccw when looking top down.
*/
autoRotateDirection: 'cw',
/**
* Degree per second
*/
autoRotateSpeed: 60,
/**
* @param {number}
*/
damping: 0.8,
/**
* @param {number}
*/
rotateSensitivity: 1,
/**
* @param {number}
*/
zoomSensitivity: 1,
/**
* @param {number}
*/
panSensitivity: 1,
panMouseButton: 'middle',
rotateMouseButton: 'left',
/**
* Pan or rotate
* @private
* @type {String}
*/
_mode: 'rotate',
/**
* @private
* @type {clay.Camera}
*/
_camera: null,
_needsUpdate: false,
_rotating: false,
// Rotation around yAxis in radian
_phi: 0,
// Rotation around xAxis in radian
_theta: 0,
_mouseX: 0,
_mouseY: 0,
_rotateVelocity: new __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector2__["a" /* default */](),
_panVelocity: new __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector2__["a" /* default */](),
_distance: 500,
_zoomSpeed: 0,
_stillTimeout: 0,
_animators: []
};
}, function () {
// Each OrbitControl has it's own handler
['_mouseDownHandler', '_mouseWheelHandler', '_mouseMoveHandler', '_mouseUpHandler',
'_pinchHandler', '_contextMenuHandler', '_update'].forEach(function (hdlName) {
this[hdlName] = this[hdlName].bind(this);
}, this);
}, {
/**
* Initialize.
* Mouse event binding
*/
init: function () {
var zr = this.zr;
if (zr) {
zr.on('mousedown', this._mouseDownHandler);
zr.on('globalout', this._mouseUpHandler);
zr.on('mousewheel', this._mouseWheelHandler);
zr.on('pinch', this._pinchHandler);
zr.animation.on('frame', this._update);
zr.dom.addEventListener('contextmenu', this._contextMenuHandler);
}
},
/**
* Dispose.
* Mouse event unbinding
*/
dispose: function () {
var zr = this.zr;
if (zr) {
zr.off('mousedown', this._mouseDownHandler);
zr.off('mousemove', this._mouseMoveHandler);
zr.off('mouseup', this._mouseUpHandler);
zr.off('mousewheel', this._mouseWheelHandler);
zr.off('pinch', this._pinchHandler);
zr.off('globalout', this._mouseUpHandler);
zr.dom.removeEventListener('contextmenu', this._contextMenuHandler);
zr.animation.off('frame', this._update);
}
this.stopAllAnimation();
},
/**
* Get distance
* @return {number}
*/
getDistance: function () {
return this._distance;
},
/**
* Set distance
* @param {number} distance
*/
setDistance: function (distance) {
this._distance = distance;
this._needsUpdate = true;
},
/**
* Get size of orthographic viewing volume
* @return {number}
*/
getOrthographicSize: function () {
return this._orthoSize;
},
/**
* Set size of orthographic viewing volume
* @param {number} size
*/
setOrthographicSize: function (size) {
this._orthoSize = size;
this._needsUpdate = true;
},
/**
* Get alpha rotation
* Alpha angle for top-down rotation. Positive to rotate to top.
*
* Which means camera rotation around x axis.
*/
getAlpha: function () {
return this._theta / Math.PI * 180;
},
/**
* Get beta rotation
* Beta angle for left-right rotation. Positive to rotate to right.
*
* Which means camera rotation around y axis.
*/
getBeta: function () {
return -this._phi / Math.PI * 180;
},
/**
* Get control center
* @return {Array.}
*/
getCenter: function () {
return this._center.toArray();
},
/**
* Set alpha rotation angle
* @param {number} alpha
*/
setAlpha: function (alpha) {
alpha = Math.max(Math.min(this.maxAlpha, alpha), this.minAlpha);
this._theta = alpha / 180 * Math.PI;
this._needsUpdate = true;
},
/**
* Set beta rotation angle
* @param {number} beta
*/
setBeta: function (beta) {
beta = Math.max(Math.min(this.maxBeta, beta), this.minBeta);
this._phi = -beta / 180 * Math.PI;
this._needsUpdate = true;
},
/**
* Set control center
* @param {Array.} center
*/
setCenter: function (centerArr) {
this._center.setArray(centerArr);
},
/**
* @param {module:echarts-gl/core/ViewGL} viewGL
*/
setViewGL: function (viewGL) {
this.viewGL = viewGL;
},
/**
* @return {clay.Camera}
*/
getCamera: function () {
return this.viewGL.camera;
},
setFromViewControlModel: function (viewControlModel, extraOpts) {
extraOpts = extraOpts || {};
var baseDistance = extraOpts.baseDistance || 0;
var baseOrthoSize = extraOpts.baseOrthoSize || 1;
var projection = viewControlModel.get('projection');
if (projection !== 'perspective' && projection !== 'orthographic' && projection !== 'isometric') {
if (true) {
console.error('Unkown projection type %s, use perspective projection instead.', projection);
}
projection = 'perspective';
}
this._projection = projection;
this.viewGL.setProjection(projection);
var targetDistance = viewControlModel.get('distance') + baseDistance;
var targetOrthographicSize = viewControlModel.get('orthographicSize') + baseOrthoSize;
[
['damping', 0.8],
['autoRotate', false],
['autoRotateAfterStill', 3],
['autoRotateDirection', 'cw'],
['autoRotateSpeed', 10],
['minDistance', 30],
['maxDistance', 400],
['minOrthographicSize', 30],
['maxOrthographicSize', 300],
['minAlpha', -90],
['maxAlpha', 90],
['minBeta', -Infinity],
['maxBeta', Infinity],
['rotateSensitivity', 1],
['zoomSensitivity', 1],
['panSensitivity', 1],
['panMouseButton', 'left'],
['rotateMouseButton', 'middle'],
].forEach(function (prop) {
this[prop[0]] = firstNotNull(viewControlModel.get(prop[0]), prop[1]);
}, this);
this.minDistance += baseDistance;
this.maxDistance += baseDistance;
this.minOrthographicSize += baseOrthoSize,
this.maxOrthographicSize += baseOrthoSize;
var ecModel = viewControlModel.ecModel;
var animationOpts = {};
['animation', 'animationDurationUpdate', 'animationEasingUpdate'].forEach(function (key) {
animationOpts[key] = firstNotNull(
viewControlModel.get(key), ecModel && ecModel.get(key)
);
});
var alpha = firstNotNull(extraOpts.alpha, viewControlModel.get('alpha')) || 0;
var beta = firstNotNull(extraOpts.beta, viewControlModel.get('beta')) || 0;
var center = firstNotNull(extraOpts.center, viewControlModel.get('center')) || [0, 0, 0];
if (animationOpts.animation && animationOpts.animationDurationUpdate > 0 && this._notFirst) {
this.animateTo({
alpha: alpha,
beta: beta,
center: center,
distance: targetDistance,
targetOrthographicSize: targetOrthographicSize,
easing: animationOpts.animationEasingUpdate,
duration: animationOpts.animationDurationUpdate
});
}
else {
this.setDistance(targetDistance);
this.setAlpha(alpha);
this.setBeta(beta);
this.setCenter(center);
this.setOrthographicSize(targetOrthographicSize);
}
this._notFirst = true;
this._validateProperties();
},
_validateProperties: function () {
if (true) {
if (MOUSE_BUTTON_KEY_MAP[this.panMouseButton] == null) {
console.error('Unkown panMouseButton %s. It should be left|middle|right', this.panMouseButton);
}
if (MOUSE_BUTTON_KEY_MAP[this.rotateMouseButton] == null) {
console.error('Unkown rotateMouseButton %s. It should be left|middle|right', this.rotateMouseButton);
}
if (this.autoRotateDirection !== 'cw' && this.autoRotateDirection !== 'ccw') {
console.error('Unkown autoRotateDirection %s. It should be cw|ccw', this.autoRotateDirection);
}
}
},
/**
* @param {Object} opts
* @param {number} opts.distance
* @param {number} opts.alpha
* @param {number} opts.beta
* @param {number} opts.orthographicSize
* @param {number} [opts.duration=1000]
* @param {number} [opts.easing='linear']
*/
animateTo: function (opts) {
var zr = this.zr;
var self = this;
var obj = {};
var target = {};
if (opts.distance != null) {
obj.distance = this.getDistance();
target.distance = opts.distance;
}
if (opts.orthographicSize != null) {
obj.orthographicSize = this.getOrthographicSize();
target.orthographicSize = opts.orthographicSize;
}
if (opts.alpha != null) {
obj.alpha = this.getAlpha();
target.alpha = opts.alpha;
}
if (opts.beta != null) {
obj.beta = this.getBeta();
target.beta = opts.beta;
}
if (opts.center != null) {
obj.center = this.getCenter();
target.center = opts.center;
}
return this._addAnimator(
zr.animation.animate(obj)
.when(opts.duration || 1000, target)
.during(function () {
if (obj.alpha != null) {
self.setAlpha(obj.alpha);
}
if (obj.beta != null) {
self.setBeta(obj.beta);
}
if (obj.distance != null) {
self.setDistance(obj.distance);
}
if (obj.center != null) {
self.setCenter(obj.center);
}
if (obj.orthographicSize != null) {
self.setOrthographicSize(obj.orthographicSize);
}
self._needsUpdate = true;
})
).start(opts.easing || 'linear');
},
/**
* Stop all animation
*/
stopAllAnimation: function () {
for (var i = 0; i < this._animators.length; i++) {
this._animators[i].stop();
}
this._animators.length = 0;
},
update: function () {
this._needsUpdate = true;
this._update(20);
},
_isAnimating: function () {
return this._animators.length > 0;
},
/**
* Call update each frame
* @param {number} deltaTime Frame time
*/
_update: function (deltaTime) {
if (this._rotating) {
var radian = (this.autoRotateDirection === 'cw' ? 1 : -1)
* this.autoRotateSpeed / 180 * Math.PI;
this._phi -= radian * deltaTime / 1000;
this._needsUpdate = true;
}
else if (this._rotateVelocity.len() > 0) {
this._needsUpdate = true;
}
if (Math.abs(this._zoomSpeed) > 0.1 || this._panVelocity.len() > 0) {
this._needsUpdate = true;
}
if (!this._needsUpdate) {
return;
}
deltaTime = Math.min(deltaTime, 50);
this._updateDistanceOrSize(deltaTime);
this._updatePan(deltaTime);
this._updateRotate(deltaTime);
this._updateTransform();
this.getCamera().update();
this.zr && this.zr.refresh();
this.trigger('update');
this._needsUpdate = false;
},
_updateRotate: function (deltaTime) {
var velocity = this._rotateVelocity;
this._phi = velocity.y * deltaTime / 20 + this._phi;
this._theta = velocity.x * deltaTime / 20 + this._theta;
this.setAlpha(this.getAlpha());
this.setBeta(this.getBeta());
this._vectorDamping(velocity, Math.pow(this.damping, deltaTime / 16));
},
_updateDistanceOrSize: function (deltaTime) {
if (this._projection === 'perspective') {
this._setDistance(this._distance + this._zoomSpeed * deltaTime / 20);
}
else {
this._setOrthoSize(this._orthoSize + this._zoomSpeed * deltaTime / 20);
}
this._zoomSpeed *= Math.pow(this.damping, deltaTime / 16);
},
_setDistance: function (distance) {
this._distance = Math.max(Math.min(distance, this.maxDistance), this.minDistance);
},
_setOrthoSize: function (size) {
this._orthoSize = Math.max(Math.min(size, this.maxOrthographicSize), this.minOrthographicSize);
var camera = this.getCamera();
var cameraHeight = this._orthoSize;
var cameraWidth = cameraHeight / this.viewGL.viewport.height * this.viewGL.viewport.width;
camera.left = -cameraWidth / 2;
camera.right = cameraWidth / 2;
camera.top = cameraHeight / 2;
camera.bottom = -cameraHeight / 2;
},
_updatePan: function (deltaTime) {
var velocity = this._panVelocity;
var len = this._distance;
var target = this.getCamera();
var yAxis = target.worldTransform.y;
var xAxis = target.worldTransform.x;
// PENDING
this._center
.scaleAndAdd(xAxis, -velocity.x * len / 200)
.scaleAndAdd(yAxis, -velocity.y * len / 200);
this._vectorDamping(velocity, 0);
},
_updateTransform: function () {
var camera = this.getCamera();
var dir = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_math_Vector3__["a" /* default */]();
var theta = this._theta + Math.PI / 2;
var phi = this._phi + Math.PI / 2;
var r = Math.sin(theta);
dir.x = r * Math.cos(phi);
dir.y = -Math.cos(theta);
dir.z = r * Math.sin(phi);
camera.position.copy(this._center).scaleAndAdd(dir, this._distance);
camera.rotation.identity()
// First around y, then around x
.rotateY(-this._phi)
.rotateX(-this._theta);
},
_startCountingStill: function () {
clearTimeout(this._stillTimeout);
var time = this.autoRotateAfterStill;
var self = this;
if (!isNaN(time) && time > 0) {
this._stillTimeout = setTimeout(function () {
self._rotating = true;
}, time * 1000);
}
},
_vectorDamping: function (v, damping) {
var speed = v.len();
speed = speed * damping;
if (speed < 1e-4) {
speed = 0;
}
v.normalize().scale(speed);
},
_decomposeTransform: function () {
if (!this.getCamera()) {
return;
}
this.getCamera().updateWorldTransform();
var forward = this.getCamera().worldTransform.z;
var alpha = Math.asin(forward.y);
var beta = Math.atan2(forward.x, forward.z);
this._theta = alpha;
this._phi = -beta;
this.setBeta(this.getBeta());
this.setAlpha(this.getAlpha());
// Is perspective
if (this.getCamera().aspect) {
this._setDistance(this.getCamera().position.dist(this._center));
}
else {
this._setOrthoSize(this.getCamera().top - this.getCamera().bottom);
}
},
_mouseDownHandler: function (e) {
if (e.target) {
// If mouseon some zrender element.
return;
}
if (this._isAnimating()) {
return;
}
var x = e.offsetX;
var y = e.offsetY;
if (this.viewGL && !this.viewGL.containPoint(x, y)) {
return;
}
this.zr.on('mousemove', this._mouseMoveHandler);
this.zr.on('mouseup', this._mouseUpHandler);
if (e.event.targetTouches) {
if (e.event.targetTouches.length === 1) {
this._mode = 'rotate';
}
}
else {
if (e.event.button === MOUSE_BUTTON_KEY_MAP[this.rotateMouseButton]) {
this._mode = 'rotate';
}
else if (e.event.button === MOUSE_BUTTON_KEY_MAP[this.panMouseButton]) {
this._mode = 'pan';
}
else {
this._mode = '';
}
}
// Reset rotate velocity
this._rotateVelocity.set(0, 0);
this._rotating = false;
if (this.autoRotate) {
this._startCountingStill();
}
this._mouseX = e.offsetX;
this._mouseY = e.offsetY;
},
_mouseMoveHandler: function (e) {
if (e.target && e.target.__isGLToZRProxy) {
return;
}
if (this._isAnimating()) {
return;
}
var panSensitivity = convertToArray(this.panSensitivity);
var rotateSensitivity = convertToArray(this.rotateSensitivity);
if (this._mode === 'rotate') {
this._rotateVelocity.y = (e.offsetX - this._mouseX) / this.zr.getHeight() * 2 * rotateSensitivity[0];
this._rotateVelocity.x = (e.offsetY - this._mouseY) / this.zr.getWidth() * 2 * rotateSensitivity[1];
}
else if (this._mode === 'pan') {
this._panVelocity.x = (e.offsetX - this._mouseX) / this.zr.getWidth() * panSensitivity[0] * 400;
this._panVelocity.y = (-e.offsetY + this._mouseY) / this.zr.getHeight() * panSensitivity[1] * 400;
}
this._mouseX = e.offsetX;
this._mouseY = e.offsetY;
e.event.preventDefault();
},
_mouseWheelHandler: function (e) {
if (this._isAnimating()) {
return;
}
var delta = e.event.wheelDelta // Webkit
|| -e.event.detail; // Firefox
this._zoomHandler(e, delta);
},
_pinchHandler: function (e) {
if (this._isAnimating()) {
return;
}
this._zoomHandler(e, e.pinchScale > 1 ? 1 : -1);
// Not rotate when pinch
this._mode = '';
},
_zoomHandler: function (e, delta) {
if (delta === 0) {
return;
}
var x = e.offsetX;
var y = e.offsetY;
if (this.viewGL && !this.viewGL.containPoint(x, y)) {
return;
}
var speed;
if (this._projection === 'perspective') {
speed = Math.max(Math.max(Math.min(
this._distance - this.minDistance,
this.maxDistance - this._distance
)) / 20, 0.5);
}
else {
speed = Math.max(Math.max(Math.min(
this._orthoSize - this.minOrthographicSize,
this.maxOrthographicSize - this._orthoSize
)) / 20, 0.5);
}
this._zoomSpeed = (delta > 0 ? -1 : 1) * speed * this.zoomSensitivity;
this._rotating = false;
if (this.autoRotate && this._mode === 'rotate') {
this._startCountingStill();
}
e.event.preventDefault();
},
_mouseUpHandler: function () {
this.zr.off('mousemove', this._mouseMoveHandler);
this.zr.off('mouseup', this._mouseUpHandler);
},
_isRightMouseButtonUsed: function () {
return this.rotateMouseButton === 'right'
|| this.panMouseButton === 'right';
},
_contextMenuHandler: function (e) {
if (this._isRightMouseButtonUsed()) {
e.preventDefault();
}
},
_addAnimator: function (animator) {
var animators = this._animators;
animators.push(animator);
animator.done(function () {
var idx = animators.indexOf(animator);
if (idx >= 0) {
animators.splice(idx, 1);
}
});
return animator;
}
});
/**
* If auto rotate the target
* @type {boolean}
* @default false
*/
Object.defineProperty(OrbitControl.prototype, 'autoRotate', {
get: function (val) {
return this._autoRotate;
},
set: function (val) {
this._autoRotate = val;
this._rotating = val;
}
});
/* harmony default export */ __webpack_exports__["a"] = (OrbitControl);
/***/ }),
/* 40 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.lines3D.vertex\n\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\n\nattribute vec3 position: POSITION;\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n\nvoid main()\n{\n gl_Position = worldViewProjection * vec4(position, 1.0);\n v_Color = a_Color;\n}\n\n@end\n\n@export ecgl.lines3D.fragment\n\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\n\nvarying vec4 v_Color;\n\n@import clay.util.srgb\n\nvoid main()\n{\n#ifdef SRGB_DECODE\n gl_FragColor = sRGBToLinear(color * v_Color);\n#else\n gl_FragColor = color * v_Color;\n#endif\n}\n@end\n\n\n\n@export ecgl.lines3D.clipNear\n\nvec4 clipNear(vec4 p1, vec4 p2) {\n float n = (p1.w - near) / (p1.w - p2.w);\n return vec4(mix(p1.xy, p2.xy, n), -near, near);\n}\n\n@end\n\n@export ecgl.lines3D.expandLine\n#ifdef VERTEX_ANIMATION\n vec4 prevProj = worldViewProjection * vec4(mix(prevPositionPrev, positionPrev, percent), 1.0);\n vec4 currProj = worldViewProjection * vec4(mix(prevPosition, position, percent), 1.0);\n vec4 nextProj = worldViewProjection * vec4(mix(prevPositionNext, positionNext, percent), 1.0);\n#else\n vec4 prevProj = worldViewProjection * vec4(positionPrev, 1.0);\n vec4 currProj = worldViewProjection * vec4(position, 1.0);\n vec4 nextProj = worldViewProjection * vec4(positionNext, 1.0);\n#endif\n\n if (currProj.w < 0.0) {\n if (nextProj.w > 0.0) {\n currProj = clipNear(currProj, nextProj);\n }\n else if (prevProj.w > 0.0) {\n currProj = clipNear(currProj, prevProj);\n }\n }\n\n vec2 prevScreen = (prevProj.xy / abs(prevProj.w) + 1.0) * 0.5 * viewport.zw;\n vec2 currScreen = (currProj.xy / abs(currProj.w) + 1.0) * 0.5 * viewport.zw;\n vec2 nextScreen = (nextProj.xy / abs(nextProj.w) + 1.0) * 0.5 * viewport.zw;\n\n vec2 dir;\n float len = offset;\n if (position == positionPrev) {\n dir = normalize(nextScreen - currScreen);\n }\n else if (position == positionNext) {\n dir = normalize(currScreen - prevScreen);\n }\n else {\n vec2 dirA = normalize(currScreen - prevScreen);\n vec2 dirB = normalize(nextScreen - currScreen);\n\n vec2 tanget = normalize(dirA + dirB);\n\n float miter = 1.0 / max(dot(tanget, dirA), 0.5);\n len *= miter;\n dir = tanget;\n }\n\n dir = vec2(-dir.y, dir.x) * len;\n currScreen += dir;\n\n currProj.xy = (currScreen / viewport.zw - 0.5) * 2.0 * abs(currProj.w);\n@end\n\n\n@export ecgl.meshLines3D.vertex\n\nattribute vec3 position: POSITION;\nattribute vec3 positionPrev;\nattribute vec3 positionNext;\nattribute float offset;\nattribute vec4 a_Color : COLOR;\n\n#ifdef VERTEX_ANIMATION\nattribute vec3 prevPosition;\nattribute vec3 prevPositionPrev;\nattribute vec3 prevPositionNext;\nuniform float percent : 1.0;\n#endif\n\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform vec4 viewport : VIEWPORT;\nuniform float near : NEAR;\n\nvarying vec4 v_Color;\n\n@import ecgl.common.wireframe.vertexHeader\n\n@import ecgl.lines3D.clipNear\n\nvoid main()\n{\n @import ecgl.lines3D.expandLine\n\n gl_Position = currProj;\n\n v_Color = a_Color;\n\n @import ecgl.common.wireframe.vertexMain\n}\n@end\n\n\n@export ecgl.meshLines3D.fragment\n\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\n\nvarying vec4 v_Color;\n\n@import ecgl.common.wireframe.fragmentHeader\n\n@import clay.util.srgb\n\nvoid main()\n{\n#ifdef SRGB_DECODE\n gl_FragColor = sRGBToLinear(color * v_Color);\n#else\n gl_FragColor = color * v_Color;\n#endif\n\n @import ecgl.common.wireframe.fragmentMain\n}\n\n@end");
/***/ }),
/* 41 */
/***/ (function(module, exports, __webpack_require__) {
var zrUtil = __webpack_require__(12);
var BoundingRect = __webpack_require__(75);
var _number = __webpack_require__(78);
var parsePercent = _number.parsePercent;
var formatUtil = __webpack_require__(162);
// Layout helpers for each component positioning
var each = zrUtil.each;
/**
* @public
*/
var LOCATION_PARAMS = ['left', 'right', 'top', 'bottom', 'width', 'height'];
/**
* @public
*/
var HV_NAMES = [['width', 'left', 'right'], ['height', 'top', 'bottom']];
function boxLayout(orient, group, gap, maxWidth, maxHeight) {
var x = 0;
var y = 0;
if (maxWidth == null) {
maxWidth = Infinity;
}
if (maxHeight == null) {
maxHeight = Infinity;
}
var currentLineMaxSize = 0;
group.eachChild(function (child, idx) {
var position = child.position;
var rect = child.getBoundingRect();
var nextChild = group.childAt(idx + 1);
var nextChildRect = nextChild && nextChild.getBoundingRect();
var nextX;
var nextY;
if (orient === 'horizontal') {
var moveX = rect.width + (nextChildRect ? -nextChildRect.x + rect.x : 0);
nextX = x + moveX; // Wrap when width exceeds maxWidth or meet a `newline` group
// FIXME compare before adding gap?
if (nextX > maxWidth || child.newline) {
x = 0;
nextX = moveX;
y += currentLineMaxSize + gap;
currentLineMaxSize = rect.height;
} else {
// FIXME: consider rect.y is not `0`?
currentLineMaxSize = Math.max(currentLineMaxSize, rect.height);
}
} else {
var moveY = rect.height + (nextChildRect ? -nextChildRect.y + rect.y : 0);
nextY = y + moveY; // Wrap when width exceeds maxHeight or meet a `newline` group
if (nextY > maxHeight || child.newline) {
x += currentLineMaxSize + gap;
y = 0;
nextY = moveY;
currentLineMaxSize = rect.width;
} else {
currentLineMaxSize = Math.max(currentLineMaxSize, rect.width);
}
}
if (child.newline) {
return;
}
position[0] = x;
position[1] = y;
orient === 'horizontal' ? x = nextX + gap : y = nextY + gap;
});
}
/**
* VBox or HBox layouting
* @param {string} orient
* @param {module:zrender/container/Group} group
* @param {number} gap
* @param {number} [width=Infinity]
* @param {number} [height=Infinity]
*/
var box = boxLayout;
/**
* VBox layouting
* @param {module:zrender/container/Group} group
* @param {number} gap
* @param {number} [width=Infinity]
* @param {number} [height=Infinity]
*/
var vbox = zrUtil.curry(boxLayout, 'vertical');
/**
* HBox layouting
* @param {module:zrender/container/Group} group
* @param {number} gap
* @param {number} [width=Infinity]
* @param {number} [height=Infinity]
*/
var hbox = zrUtil.curry(boxLayout, 'horizontal');
/**
* If x or x2 is not specified or 'center' 'left' 'right',
* the width would be as long as possible.
* If y or y2 is not specified or 'middle' 'top' 'bottom',
* the height would be as long as possible.
*
* @param {Object} positionInfo
* @param {number|string} [positionInfo.x]
* @param {number|string} [positionInfo.y]
* @param {number|string} [positionInfo.x2]
* @param {number|string} [positionInfo.y2]
* @param {Object} containerRect {width, height}
* @param {string|number} margin
* @return {Object} {width, height}
*/
function getAvailableSize(positionInfo, containerRect, margin) {
var containerWidth = containerRect.width;
var containerHeight = containerRect.height;
var x = parsePercent(positionInfo.x, containerWidth);
var y = parsePercent(positionInfo.y, containerHeight);
var x2 = parsePercent(positionInfo.x2, containerWidth);
var y2 = parsePercent(positionInfo.y2, containerHeight);
(isNaN(x) || isNaN(parseFloat(positionInfo.x))) && (x = 0);
(isNaN(x2) || isNaN(parseFloat(positionInfo.x2))) && (x2 = containerWidth);
(isNaN(y) || isNaN(parseFloat(positionInfo.y))) && (y = 0);
(isNaN(y2) || isNaN(parseFloat(positionInfo.y2))) && (y2 = containerHeight);
margin = formatUtil.normalizeCssArray(margin || 0);
return {
width: Math.max(x2 - x - margin[1] - margin[3], 0),
height: Math.max(y2 - y - margin[0] - margin[2], 0)
};
}
/**
* Parse position info.
*
* @param {Object} positionInfo
* @param {number|string} [positionInfo.left]
* @param {number|string} [positionInfo.top]
* @param {number|string} [positionInfo.right]
* @param {number|string} [positionInfo.bottom]
* @param {number|string} [positionInfo.width]
* @param {number|string} [positionInfo.height]
* @param {number|string} [positionInfo.aspect] Aspect is width / height
* @param {Object} containerRect
* @param {string|number} [margin]
*
* @return {module:zrender/core/BoundingRect}
*/
function getLayoutRect(positionInfo, containerRect, margin) {
margin = formatUtil.normalizeCssArray(margin || 0);
var containerWidth = containerRect.width;
var containerHeight = containerRect.height;
var left = parsePercent(positionInfo.left, containerWidth);
var top = parsePercent(positionInfo.top, containerHeight);
var right = parsePercent(positionInfo.right, containerWidth);
var bottom = parsePercent(positionInfo.bottom, containerHeight);
var width = parsePercent(positionInfo.width, containerWidth);
var height = parsePercent(positionInfo.height, containerHeight);
var verticalMargin = margin[2] + margin[0];
var horizontalMargin = margin[1] + margin[3];
var aspect = positionInfo.aspect; // If width is not specified, calculate width from left and right
if (isNaN(width)) {
width = containerWidth - right - horizontalMargin - left;
}
if (isNaN(height)) {
height = containerHeight - bottom - verticalMargin - top;
}
if (aspect != null) {
// If width and height are not given
// 1. Graph should not exceeds the container
// 2. Aspect must be keeped
// 3. Graph should take the space as more as possible
// FIXME
// Margin is not considered, because there is no case that both
// using margin and aspect so far.
if (isNaN(width) && isNaN(height)) {
if (aspect > containerWidth / containerHeight) {
width = containerWidth * 0.8;
} else {
height = containerHeight * 0.8;
}
} // Calculate width or height with given aspect
if (isNaN(width)) {
width = aspect * height;
}
if (isNaN(height)) {
height = width / aspect;
}
} // If left is not specified, calculate left from right and width
if (isNaN(left)) {
left = containerWidth - right - width - horizontalMargin;
}
if (isNaN(top)) {
top = containerHeight - bottom - height - verticalMargin;
} // Align left and top
switch (positionInfo.left || positionInfo.right) {
case 'center':
left = containerWidth / 2 - width / 2 - margin[3];
break;
case 'right':
left = containerWidth - width - horizontalMargin;
break;
}
switch (positionInfo.top || positionInfo.bottom) {
case 'middle':
case 'center':
top = containerHeight / 2 - height / 2 - margin[0];
break;
case 'bottom':
top = containerHeight - height - verticalMargin;
break;
} // If something is wrong and left, top, width, height are calculated as NaN
left = left || 0;
top = top || 0;
if (isNaN(width)) {
// Width may be NaN if only one value is given except width
width = containerWidth - horizontalMargin - left - (right || 0);
}
if (isNaN(height)) {
// Height may be NaN if only one value is given except height
height = containerHeight - verticalMargin - top - (bottom || 0);
}
var rect = new BoundingRect(left + margin[3], top + margin[0], width, height);
rect.margin = margin;
return rect;
}
/**
* Position a zr element in viewport
* Group position is specified by either
* {left, top}, {right, bottom}
* If all properties exists, right and bottom will be igonred.
*
* Logic:
* 1. Scale (against origin point in parent coord)
* 2. Rotate (against origin point in parent coord)
* 3. Traslate (with el.position by this method)
* So this method only fixes the last step 'Traslate', which does not affect
* scaling and rotating.
*
* If be called repeatly with the same input el, the same result will be gotten.
*
* @param {module:zrender/Element} el Should have `getBoundingRect` method.
* @param {Object} positionInfo
* @param {number|string} [positionInfo.left]
* @param {number|string} [positionInfo.top]
* @param {number|string} [positionInfo.right]
* @param {number|string} [positionInfo.bottom]
* @param {number|string} [positionInfo.width] Only for opt.boundingModel: 'raw'
* @param {number|string} [positionInfo.height] Only for opt.boundingModel: 'raw'
* @param {Object} containerRect
* @param {string|number} margin
* @param {Object} [opt]
* @param {Array.} [opt.hv=[1,1]] Only horizontal or only vertical.
* @param {Array.} [opt.boundingMode='all']
* Specify how to calculate boundingRect when locating.
* 'all': Position the boundingRect that is transformed and uioned
* both itself and its descendants.
* This mode simplies confine the elements in the bounding
* of their container (e.g., using 'right: 0').
* 'raw': Position the boundingRect that is not transformed and only itself.
* This mode is useful when you want a element can overflow its
* container. (Consider a rotated circle needs to be located in a corner.)
* In this mode positionInfo.width/height can only be number.
*/
function positionElement(el, positionInfo, containerRect, margin, opt) {
var h = !opt || !opt.hv || opt.hv[0];
var v = !opt || !opt.hv || opt.hv[1];
var boundingMode = opt && opt.boundingMode || 'all';
if (!h && !v) {
return;
}
var rect;
if (boundingMode === 'raw') {
rect = el.type === 'group' ? new BoundingRect(0, 0, +positionInfo.width || 0, +positionInfo.height || 0) : el.getBoundingRect();
} else {
rect = el.getBoundingRect();
if (el.needLocalTransform()) {
var transform = el.getLocalTransform(); // Notice: raw rect may be inner object of el,
// which should not be modified.
rect = rect.clone();
rect.applyTransform(transform);
}
} // The real width and height can not be specified but calculated by the given el.
positionInfo = getLayoutRect(zrUtil.defaults({
width: rect.width,
height: rect.height
}, positionInfo), containerRect, margin); // Because 'tranlate' is the last step in transform
// (see zrender/core/Transformable#getLocalTransform),
// we can just only modify el.position to get final result.
var elPos = el.position;
var dx = h ? positionInfo.x - rect.x : 0;
var dy = v ? positionInfo.y - rect.y : 0;
el.attr('position', boundingMode === 'raw' ? [dx, dy] : [elPos[0] + dx, elPos[1] + dy]);
}
/**
* @param {Object} option Contains some of the properties in HV_NAMES.
* @param {number} hvIdx 0: horizontal; 1: vertical.
*/
function sizeCalculable(option, hvIdx) {
return option[HV_NAMES[hvIdx][0]] != null || option[HV_NAMES[hvIdx][1]] != null && option[HV_NAMES[hvIdx][2]] != null;
}
/**
* Consider Case:
* When defulat option has {left: 0, width: 100}, and we set {right: 0}
* through setOption or media query, using normal zrUtil.merge will cause
* {right: 0} does not take effect.
*
* @example
* ComponentModel.extend({
* init: function () {
* ...
* var inputPositionParams = layout.getLayoutParams(option);
* this.mergeOption(inputPositionParams);
* },
* mergeOption: function (newOption) {
* newOption && zrUtil.merge(thisOption, newOption, true);
* layout.mergeLayoutParam(thisOption, newOption);
* }
* });
*
* @param {Object} targetOption
* @param {Object} newOption
* @param {Object|string} [opt]
* @param {boolean|Array.} [opt.ignoreSize=false] Used for the components
* that width (or height) should not be calculated by left and right (or top and bottom).
*/
function mergeLayoutParam(targetOption, newOption, opt) {
!zrUtil.isObject(opt) && (opt = {});
var ignoreSize = opt.ignoreSize;
!zrUtil.isArray(ignoreSize) && (ignoreSize = [ignoreSize, ignoreSize]);
var hResult = merge(HV_NAMES[0], 0);
var vResult = merge(HV_NAMES[1], 1);
copy(HV_NAMES[0], targetOption, hResult);
copy(HV_NAMES[1], targetOption, vResult);
function merge(names, hvIdx) {
var newParams = {};
var newValueCount = 0;
var merged = {};
var mergedValueCount = 0;
var enoughParamNumber = 2;
each(names, function (name) {
merged[name] = targetOption[name];
});
each(names, function (name) {
// Consider case: newOption.width is null, which is
// set by user for removing width setting.
hasProp(newOption, name) && (newParams[name] = merged[name] = newOption[name]);
hasValue(newParams, name) && newValueCount++;
hasValue(merged, name) && mergedValueCount++;
});
if (ignoreSize[hvIdx]) {
// Only one of left/right is premitted to exist.
if (hasValue(newOption, names[1])) {
merged[names[2]] = null;
} else if (hasValue(newOption, names[2])) {
merged[names[1]] = null;
}
return merged;
} // Case: newOption: {width: ..., right: ...},
// or targetOption: {right: ...} and newOption: {width: ...},
// There is no conflict when merged only has params count
// little than enoughParamNumber.
if (mergedValueCount === enoughParamNumber || !newValueCount) {
return merged;
} // Case: newOption: {width: ..., right: ...},
// Than we can make sure user only want those two, and ignore
// all origin params in targetOption.
else if (newValueCount >= enoughParamNumber) {
return newParams;
} else {
// Chose another param from targetOption by priority.
for (var i = 0; i < names.length; i++) {
var name = names[i];
if (!hasProp(newParams, name) && hasProp(targetOption, name)) {
newParams[name] = targetOption[name];
break;
}
}
return newParams;
}
}
function hasProp(obj, name) {
return obj.hasOwnProperty(name);
}
function hasValue(obj, name) {
return obj[name] != null && obj[name] !== 'auto';
}
function copy(names, target, source) {
each(names, function (name) {
target[name] = source[name];
});
}
}
/**
* Retrieve 'left', 'right', 'top', 'bottom', 'width', 'height' from object.
* @param {Object} source
* @return {Object} Result contains those props.
*/
function getLayoutParams(source) {
return copyLayoutParams({}, source);
}
/**
* Retrieve 'left', 'right', 'top', 'bottom', 'width', 'height' from object.
* @param {Object} source
* @return {Object} Result contains those props.
*/
function copyLayoutParams(target, source) {
source && target && each(LOCATION_PARAMS, function (name) {
source.hasOwnProperty(name) && (target[name] = source[name]);
});
return target;
}
exports.LOCATION_PARAMS = LOCATION_PARAMS;
exports.HV_NAMES = HV_NAMES;
exports.box = box;
exports.vbox = vbox;
exports.hbox = hbox;
exports.getAvailableSize = getAvailableSize;
exports.getLayoutRect = getLayoutRect;
exports.positionElement = positionElement;
exports.sizeCalculable = sizeCalculable;
exports.mergeLayoutParam = mergeLayoutParam;
exports.getLayoutParams = getLayoutParams;
exports.copyLayoutParams = copyLayoutParams;
/***/ }),
/* 42 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_Base__ = __webpack_require__(9);
// PENDING
// Use topological sort ?
/**
* Node of graph based post processing.
*
* @constructor clay.compositor.CompositorNode
* @extends clay.core.Base
*
*/
var CompositorNode = __WEBPACK_IMPORTED_MODULE_0__core_Base__["a" /* default */].extend(function () {
return /** @lends clay.compositor.CompositorNode# */ {
/**
* @type {string}
*/
name: '',
/**
* Input links, will be updated by the graph
* @example:
* inputName: {
* node: someNode,
* pin: 'xxxx'
* }
* @type {Object}
*/
inputLinks: {},
/**
* Output links, will be updated by the graph
* @example:
* outputName: {
* node: someNode,
* pin: 'xxxx'
* }
* @type {Object}
*/
outputLinks: {},
// Save the output texture of previous frame
// Will be used when there exist a circular reference
_prevOutputTextures: {},
_outputTextures: {},
// Example: { name: 2 }
_outputReferences: {},
_rendering: false,
// If rendered in this frame
_rendered: false,
_compositor: null
};
},
/** @lends clay.compositor.CompositorNode.prototype */
{
// TODO Remove parameter function callback
updateParameter: function (outputName, renderer) {
var outputInfo = this.outputs[outputName];
var parameters = outputInfo.parameters;
var parametersCopy = outputInfo._parametersCopy;
if (!parametersCopy) {
parametersCopy = outputInfo._parametersCopy = {};
}
if (parameters) {
for (var key in parameters) {
if (key !== 'width' && key !== 'height') {
parametersCopy[key] = parameters[key];
}
}
}
var width, height;
if (parameters.width instanceof Function) {
width = parameters.width.call(this, renderer);
}
else {
width = parameters.width;
}
if (parameters.height instanceof Function) {
height = parameters.height.call(this, renderer);
}
else {
height = parameters.height;
}
if (
parametersCopy.width !== width
|| parametersCopy.height !== height
) {
if (this._outputTextures[outputName]) {
this._outputTextures[outputName].dispose(renderer.gl);
}
}
parametersCopy.width = width;
parametersCopy.height = height;
return parametersCopy;
},
/**
* Set parameter
* @param {string} name
* @param {} value
*/
setParameter: function (name, value) {},
/**
* Get parameter value
* @param {string} name
* @return {}
*/
getParameter: function (name) {},
/**
* Set parameters
* @param {Object} obj
*/
setParameters: function (obj) {
for (var name in obj) {
this.setParameter(name, obj[name]);
}
},
render: function () {},
getOutput: function (renderer /*optional*/, name) {
if (name == null) {
// Return the output texture without rendering
name = renderer;
return this._outputTextures[name];
}
var outputInfo = this.outputs[name];
if (!outputInfo) {
return ;
}
// Already been rendered in this frame
if (this._rendered) {
// Force return texture in last frame
if (outputInfo.outputLastFrame) {
return this._prevOutputTextures[name];
}
else {
return this._outputTextures[name];
}
}
else if (
// TODO
this._rendering // Solve Circular Reference
) {
if (!this._prevOutputTextures[name]) {
// Create a blank texture at first pass
this._prevOutputTextures[name] = this._compositor.allocateTexture(outputInfo.parameters || {});
}
return this._prevOutputTextures[name];
}
this.render(renderer);
return this._outputTextures[name];
},
removeReference: function (outputName) {
this._outputReferences[outputName]--;
if (this._outputReferences[outputName] === 0) {
var outputInfo = this.outputs[outputName];
if (outputInfo.keepLastFrame) {
if (this._prevOutputTextures[outputName]) {
this._compositor.releaseTexture(this._prevOutputTextures[outputName]);
}
this._prevOutputTextures[outputName] = this._outputTextures[outputName];
}
else {
// Output of this node have alreay been used by all other nodes
// Put the texture back to the pool.
this._compositor.releaseTexture(this._outputTextures[outputName]);
}
}
},
link: function (inputPinName, fromNode, fromPinName) {
// The relationship from output pin to input pin is one-on-multiple
this.inputLinks[inputPinName] = {
node: fromNode,
pin: fromPinName
};
if (!fromNode.outputLinks[fromPinName]) {
fromNode.outputLinks[fromPinName] = [];
}
fromNode.outputLinks[fromPinName].push({
node: this,
pin: inputPinName
});
// Enabled the pin texture in shader
this.pass.material.enableTexture(inputPinName);
},
clear: function () {
this.inputLinks = {};
this.outputLinks = {};
},
updateReference: function (outputName) {
if (!this._rendering) {
this._rendering = true;
for (var inputName in this.inputLinks) {
var link = this.inputLinks[inputName];
link.node.updateReference(link.pin);
}
this._rendering = false;
}
if (outputName) {
this._outputReferences[outputName] ++;
}
},
beforeFrame: function () {
this._rendered = false;
for (var name in this.outputLinks) {
this._outputReferences[name] = 0;
}
},
afterFrame: function () {
// Put back all the textures to pool
for (var name in this.outputLinks) {
if (this._outputReferences[name] > 0) {
var outputInfo = this.outputs[name];
if (outputInfo.keepLastFrame) {
if (this._prevOutputTextures[name]) {
this._compositor.releaseTexture(this._prevOutputTextures[name]);
}
this._prevOutputTextures[name] = this._outputTextures[name];
}
else {
this._compositor.releaseTexture(this._outputTextures[name]);
}
}
}
}
});
/* harmony default export */ __webpack_exports__["a"] = (CompositorNode);
/***/ }),
/* 43 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
// Generate halton sequence
// https://en.wikipedia.org/wiki/Halton_sequence
function halton(index, base) {
var result = 0;
var f = 1 / base;
var i = index;
while (i > 0) {
result = result + f * (i % base);
i = Math.floor(i / base);
f = f / base;
}
return result;
}
/* harmony default export */ __webpack_exports__["a"] = (halton);
/***/ }),
/* 44 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony default export */ __webpack_exports__["a"] = (function (seriesModel, dims, source) {
source = source || seriesModel.getSource();
var coordSysDimensions = dims || __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.getCoordinateSystemDimensions(seriesModel.get('coordinateSystem')) || ['x', 'y', 'z'];
var dimensions = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.helper.createDimensions(source, {
dimensionsDefine: source.dimensionsDefine || seriesModel.get('dimensions'),
encodeDefine: source.encodeDefine || seriesModel.get('encode'),
coordDimensions: coordSysDimensions.map(function (dim) {
var axis3DModel = seriesModel.getReferringComponents(dim + 'Axis3D')[0];
return {
type: (axis3DModel && axis3DModel.get('type') === 'category') ? 'ordinal' : 'float',
name: dim
// Find stackable dimension. Which will represent value.
// stackable: dim === 'z'
};
})
});
if (seriesModel.get('coordinateSystem') === 'cartesian3D') {
dimensions.forEach(function (dimInfo) {
if (coordSysDimensions.indexOf(dimInfo.coordDim) >= 0) {
var axis3DModel = seriesModel.getReferringComponents(dimInfo.coordDim + 'Axis3D')[0];
if (axis3DModel && axis3DModel.get('type') === 'category') {
dimInfo.ordinalMeta = axis3DModel.getOrdinalMeta();
}
}
});
}
var stackCalculationInfo = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.helper.dataStack.enableDataStack(
// Only support 'z' and `byIndex` now.
seriesModel, dimensions, {byIndex: true, stackedCoordDimension: 'z'}
);
var data = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.List(dimensions, seriesModel);
data.setCalculationInfo(stackCalculationInfo);
data.initData(source);
return data;
});
/***/ }),
/* 45 */
/***/ (function(module, exports) {
function _default(seriesType, defaultSymbolType, legendSymbol) {
// Encoding visual for all series include which is filtered for legend drawing
return {
seriesType: seriesType,
performRawSeries: true,
reset: function (seriesModel, ecModel, api) {
var data = seriesModel.getData();
var symbolType = seriesModel.get('symbol') || defaultSymbolType;
var symbolSize = seriesModel.get('symbolSize');
data.setVisual({
legendSymbol: legendSymbol || symbolType,
symbol: symbolType,
symbolSize: symbolSize
}); // Only visible series has each data be visual encoded
if (ecModel.isSeriesFiltered(seriesModel)) {
return;
}
var hasCallback = typeof symbolSize === 'function';
function dataEach(data, idx) {
if (typeof symbolSize === 'function') {
var rawValue = seriesModel.getRawValue(idx); // FIXME
var params = seriesModel.getDataParams(idx);
data.setItemVisual(idx, 'symbolSize', symbolSize(rawValue, params));
}
if (data.hasItemOption) {
var itemModel = data.getItemModel(idx);
var itemSymbolType = itemModel.getShallow('symbol', true);
var itemSymbolSize = itemModel.getShallow('symbolSize', true); // If has item symbol
if (itemSymbolType != null) {
data.setItemVisual(idx, 'symbol', itemSymbolType);
}
if (itemSymbolSize != null) {
// PENDING Transform symbolSize ?
data.setItemVisual(idx, 'symbolSize', itemSymbolSize);
}
}
}
return {
dataEach: data.hasItemOption || hasCallback ? dataEach : null
};
}
};
}
module.exports = _default;
/***/ }),
/* 46 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_Base__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_GLInfo__ = __webpack_require__(104);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__core_glenum__ = __webpack_require__(11);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__core_vendor__ = __webpack_require__(18);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__math_BoundingBox__ = __webpack_require__(15);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__math_Matrix4__ = __webpack_require__(7);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__Material__ = __webpack_require__(17);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__math_Vector2__ = __webpack_require__(23);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__gpu_ProgramManager__ = __webpack_require__(107);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__shader_source_header_light__ = __webpack_require__(109);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__shader_source_prez_glsl_js__ = __webpack_require__(65);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_12__dep_glmatrix__);
// TODO Resources like shader, texture, geometry reference management
// Trace and find out which shader, texture, geometry can be destroyed
// Light header
__WEBPACK_IMPORTED_MODULE_9__Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_10__shader_source_header_light__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_9__Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_11__shader_source_prez_glsl_js__["a" /* default */]);
var mat4 = __WEBPACK_IMPORTED_MODULE_12__dep_glmatrix___default.a.mat4;
var vec3 = __WEBPACK_IMPORTED_MODULE_12__dep_glmatrix___default.a.vec3;
var mat4Create = mat4.create;
var errorShader = {};
function defaultGetMaterial(renderable) {
return renderable.material;
}
function noop() {}
var attributeBufferTypeMap = {
float: __WEBPACK_IMPORTED_MODULE_2__core_glenum__["a" /* default */].FLOAT,
byte: __WEBPACK_IMPORTED_MODULE_2__core_glenum__["a" /* default */].BYTE,
ubyte: __WEBPACK_IMPORTED_MODULE_2__core_glenum__["a" /* default */].UNSIGNED_BYTE,
short: __WEBPACK_IMPORTED_MODULE_2__core_glenum__["a" /* default */].SHORT,
ushort: __WEBPACK_IMPORTED_MODULE_2__core_glenum__["a" /* default */].UNSIGNED_SHORT
};
function VertexArrayObject(availableAttributes, availableAttributeSymbols, indicesBuffer) {
this.availableAttributes = availableAttributes;
this.availableAttributeSymbols = availableAttributeSymbols;
this.indicesBuffer = indicesBuffer;
this.vao = null;
}
/**
* @constructor clay.Renderer
*/
var Renderer = __WEBPACK_IMPORTED_MODULE_0__core_Base__["a" /* default */].extend(function () {
return /** @lends clay.Renderer# */ {
/**
* @type {HTMLCanvasElement}
* @readonly
*/
canvas: null,
/**
* Canvas width, set by resize method
* @type {number}
* @private
*/
_width: 100,
/**
* Canvas width, set by resize method
* @type {number}
* @private
*/
_height: 100,
/**
* Device pixel ratio, set by setDevicePixelRatio method
* Specially for high defination display
* @see http://www.khronos.org/webgl/wiki/HandlingHighDPI
* @type {number}
* @private
*/
devicePixelRatio: (window && window.devicePixelRatio) || 1.0,
/**
* Clear color
* @type {number[]}
*/
clearColor: [0.0, 0.0, 0.0, 0.0],
/**
* Default:
* _gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT | _gl.STENCIL_BUFFER_BIT
* @type {number}
*/
clearBit: 17664,
// Settings when getting context
// http://www.khronos.org/registry/webgl/specs/latest/#2.4
/**
* If enable alpha, default true
* @type {boolean}
*/
alpha: true,
/**
* If enable depth buffer, default true
* @type {boolean}
*/
depth: true,
/**
* If enable stencil buffer, default false
* @type {boolean}
*/
stencil: false,
/**
* If enable antialias, default true
* @type {boolean}
*/
antialias: true,
/**
* If enable premultiplied alpha, default true
* @type {boolean}
*/
premultipliedAlpha: true,
/**
* If preserve drawing buffer, default false
* @type {boolean}
*/
preserveDrawingBuffer: false,
/**
* If throw context error, usually turned on in debug mode
* @type {boolean}
*/
throwError: true,
/**
* WebGL Context created from given canvas
* @type {WebGLRenderingContext}
*/
gl: null,
/**
* Renderer viewport, read-only, can be set by setViewport method
* @type {Object}
*/
viewport: {},
// Set by FrameBuffer#bind
__currentFrameBuffer: null,
_viewportStack: [],
_clearStack: [],
_sceneRendering: null
};
}, function () {
if (!this.canvas) {
this.canvas = document.createElement('canvas');
}
var canvas = this.canvas;
try {
var opts = {
alpha: this.alpha,
depth: this.depth,
stencil: this.stencil,
antialias: this.antialias,
premultipliedAlpha: this.premultipliedAlpha,
preserveDrawingBuffer: this.preserveDrawingBuffer
};
this.gl = canvas.getContext('webgl', opts)
|| canvas.getContext('experimental-webgl', opts);
if (!this.gl) {
throw new Error();
}
this._glinfo = new __WEBPACK_IMPORTED_MODULE_1__core_GLInfo__["a" /* default */](this.gl);
if (this.gl.targetRenderer) {
console.error('Already created a renderer');
}
this.gl.targetRenderer = this;
this.resize();
}
catch (e) {
throw 'Error creating WebGL Context ' + e;
}
// Init managers
this._programMgr = new __WEBPACK_IMPORTED_MODULE_8__gpu_ProgramManager__["a" /* default */](this);
},
/** @lends clay.Renderer.prototype. **/
{
/**
* Resize the canvas
* @param {number} width
* @param {number} height
*/
resize: function(width, height) {
var canvas = this.canvas;
// http://www.khronos.org/webgl/wiki/HandlingHighDPI
// set the display size of the canvas.
var dpr = this.devicePixelRatio;
if (width != null) {
canvas.style.width = width + 'px';
canvas.style.height = height + 'px';
// set the size of the drawingBuffer
canvas.width = width * dpr;
canvas.height = height * dpr;
this._width = width;
this._height = height;
}
else {
this._width = canvas.width / dpr;
this._height = canvas.height / dpr;
}
this.setViewport(0, 0, this._width, this._height);
},
/**
* Get renderer width
* @return {number}
*/
getWidth: function () {
return this._width;
},
/**
* Get renderer height
* @return {number}
*/
getHeight: function () {
return this._height;
},
/**
* Get viewport aspect,
* @return {number}
*/
getViewportAspect: function () {
var viewport = this.viewport;
return viewport.width / viewport.height;
},
/**
* Set devicePixelRatio
* @param {number} devicePixelRatio
*/
setDevicePixelRatio: function(devicePixelRatio) {
this.devicePixelRatio = devicePixelRatio;
this.resize(this._width, this._height);
},
/**
* Get devicePixelRatio
* @param {number} devicePixelRatio
*/
getDevicePixelRatio: function () {
return this.devicePixelRatio;
},
/**
* Get WebGL extension
* @param {string} name
* @return {object}
*/
getGLExtension: function (name) {
return this._glinfo.getExtension(name);
},
/**
* Get WebGL parameter
* @param {string} name
* @return {*}
*/
getGLParameter: function (name) {
return this._glinfo.getParameter(name);
},
/**
* Set rendering viewport
* @param {number|Object} x
* @param {number} [y]
* @param {number} [width]
* @param {number} [height]
* @param {number} [devicePixelRatio]
* Defaultly use the renderere devicePixelRatio
* It needs to be 1 when setViewport is called by frameBuffer
*
* @example
* setViewport(0,0,width,height,1)
* setViewport({
* x: 0,
* y: 0,
* width: width,
* height: height,
* devicePixelRatio: 1
* })
*/
setViewport: function (x, y, width, height, dpr) {
if (typeof x === 'object') {
var obj = x;
x = obj.x;
y = obj.y;
width = obj.width;
height = obj.height;
dpr = obj.devicePixelRatio;
}
dpr = dpr || this.devicePixelRatio;
this.gl.viewport(
x * dpr, y * dpr, width * dpr, height * dpr
);
// Use a fresh new object, not write property.
this.viewport = {
x: x,
y: y,
width: width,
height: height,
devicePixelRatio: dpr
};
},
/**
* Push current viewport into a stack
*/
saveViewport: function () {
this._viewportStack.push(this.viewport);
},
/**
* Pop viewport from stack, restore in the renderer
*/
restoreViewport: function () {
if (this._viewportStack.length > 0) {
this.setViewport(this._viewportStack.pop());
}
},
/**
* Push current clear into a stack
*/
saveClear: function () {
this._clearStack.push({
clearBit: this.clearBit,
clearColor: this.clearColor
});
},
/**
* Pop clear from stack, restore in the renderer
*/
restoreClear: function () {
if (this._clearStack.length > 0) {
var opt = this._clearStack.pop();
this.clearColor = opt.clearColor;
this.clearBit = opt.clearBit;
}
},
bindSceneRendering: function (scene) {
this._sceneRendering = scene;
},
/**
* Render the scene in camera to the screen or binded offline framebuffer
* @param {clay.Scene} scene
* @param {clay.Camera} camera
* @param {boolean} [notUpdateScene] If not call the scene.update methods in the rendering, default true
* @param {boolean} [preZ] If use preZ optimization, default false
* @return {IRenderInfo}
*/
render: function(scene, camera, notUpdateScene, preZ) {
var _gl = this.gl;
var clearColor = this.clearColor;
if (this.clearBit) {
// Must set depth and color mask true before clear
_gl.colorMask(true, true, true, true);
_gl.depthMask(true);
var viewport = this.viewport;
var needsScissor = false;
var viewportDpr = viewport.devicePixelRatio;
if (viewport.width !== this._width || viewport.height !== this._height
|| (viewportDpr && viewportDpr !== this.devicePixelRatio)
|| viewport.x || viewport.y
) {
needsScissor = true;
// http://stackoverflow.com/questions/11544608/how-to-clear-a-rectangle-area-in-webgl
// Only clear the viewport
_gl.enable(_gl.SCISSOR_TEST);
_gl.scissor(viewport.x * viewportDpr, viewport.y * viewportDpr, viewport.width * viewportDpr, viewport.height * viewportDpr);
}
_gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
_gl.clear(this.clearBit);
if (needsScissor) {
_gl.disable(_gl.SCISSOR_TEST);
}
}
// If the scene have been updated in the prepass like shadow map
// There is no need to update it again
if (!notUpdateScene) {
scene.update(false);
}
scene.updateLights();
camera = camera || scene.getMainCamera();
if (!camera) {
console.error('Can\'t find camera in the scene.');
return;
}
camera.update();
var renderList = scene.updateRenderList(camera);
this._sceneRendering = scene;
var opaqueList = renderList.opaque;
var transparentList = renderList.transparent;
var sceneMaterial = scene.material;
scene.trigger('beforerender', this, scene, camera, renderList);
// Render pre z
if (preZ) {
this.renderPreZ(opaqueList, scene, camera);
_gl.depthFunc(_gl.LEQUAL);
}
else {
_gl.depthFunc(_gl.LESS);
}
// Update the depth of transparent list.
var worldViewMat = mat4Create();
var posViewSpace = vec3.create();
for (var i = 0; i < transparentList.length; i++) {
var renderable = transparentList[i];
mat4.multiplyAffine(worldViewMat, camera.viewMatrix.array, renderable.worldTransform.array);
vec3.transformMat4(posViewSpace, renderable.position.array, worldViewMat);
renderable.__depth = posViewSpace[2];
}
// Render opaque list
this.renderPass(opaqueList, camera, {
getMaterial: function (renderable) {
return sceneMaterial || renderable.material;
},
sortCompare: this.opaqueSortCompare
});
this.renderPass(transparentList, camera, {
getMaterial: function (renderable) {
return sceneMaterial || renderable.material;
},
sortCompare: this.transparentSortCompare
});
scene.trigger('afterrender', this, scene, camera, renderList);
// Cleanup
this._sceneRendering = null;
},
getProgram: function (renderable, renderMaterial, scene) {
renderMaterial = renderMaterial || renderable.material;
return this._programMgr.getProgram(renderable, renderMaterial, scene);
},
validateProgram: function (program) {
if (program.__error) {
var errorMsg = program.__error;
if (errorShader[program.__uid__]) {
return;
}
errorShader[program.__uid__] = true;
if (this.throwError) {
throw new Error(errorMsg);
}
else {
this.trigger('error', errorMsg);
}
}
},
updatePrograms: function (list, scene, passConfig) {
var getMaterial = (passConfig && passConfig.getMaterial) || defaultGetMaterial;
scene = scene || null;
for (var i = 0; i < list.length; i++) {
var renderable = list[i];
var renderMaterial = getMaterial.call(this, renderable);
if (i > 0) {
var prevRenderable = list[i - 1];
var prevJointsLen = prevRenderable.joints ? prevRenderable.joints.length : 0;
var jointsLen = renderable.joints ? renderable.joints.length : 0;
// Keep program not change if joints, material, lightGroup are same of two renderables.
if (jointsLen === prevJointsLen
&& renderable.material === prevRenderable.material
&& renderable.lightGroup === prevRenderable.lightGroup
) {
renderable.__program = prevRenderable.__program;
continue;
}
}
var program = this._programMgr.getProgram(renderable, renderMaterial, scene);
this.validateProgram(program);
renderable.__program = program;
}
},
/**
* Render a single renderable list in camera in sequence
* @param {clay.Renderable[]} list List of all renderables.
* @param {clay.Camera} camera
* @param {Object} [passConfig]
* @param {Function} [passConfig.getMaterial] Get renderable material.
* @param {Function} [passConfig.beforeRender] Before render each renderable.
* @param {Function} [passConfig.afterRender] After render each renderable
* @param {Function} [passConfig.ifRender] If render the renderable.
* @param {Function} [passConfig.sortCompare] Sort compare function.
* @return {IRenderInfo}
*/
renderPass: function(list, camera, passConfig) {
this.trigger('beforerenderpass', this, list, camera, passConfig);
passConfig = passConfig || {};
passConfig.getMaterial = passConfig.getMaterial || defaultGetMaterial;
passConfig.beforeRender = passConfig.beforeRender || noop;
passConfig.afterRender = passConfig.afterRender || noop;
this.updatePrograms(list, this._sceneRendering, passConfig);
if (passConfig.sortCompare) {
list.sort(passConfig.sortCompare);
}
// Some common builtin uniforms
var viewport = this.viewport;
var vDpr = viewport.devicePixelRatio;
var viewportUniform = [
viewport.x * vDpr, viewport.y * vDpr,
viewport.width * vDpr, viewport.height * vDpr
];
var windowDpr = this.devicePixelRatio;
var windowSizeUniform = this.__currentFrameBuffer
? [this.__currentFrameBuffer.getTextureWidth(), this.__currentFrameBuffer.getTextureHeight()]
: [this._width * windowDpr, this._height * windowDpr];
// DEPRECATED
var viewportSizeUniform = [
viewportUniform[2], viewportUniform[3]
];
var time = Date.now();
// Calculate view and projection matrix
mat4.copy(matrices.VIEW, camera.viewMatrix.array);
mat4.copy(matrices.PROJECTION, camera.projectionMatrix.array);
mat4.multiply(matrices.VIEWPROJECTION, camera.projectionMatrix.array, matrices.VIEW);
mat4.copy(matrices.VIEWINVERSE, camera.worldTransform.array);
mat4.invert(matrices.PROJECTIONINVERSE, matrices.PROJECTION);
mat4.invert(matrices.VIEWPROJECTIONINVERSE, matrices.VIEWPROJECTION);
var _gl = this.gl;
var scene = this._sceneRendering;
var prevMaterial;
var prevProgram;
// Status
var depthTest, depthMask;
var culling, cullFace, frontFace;
var transparent;
var drawID;
var currentVAO;
var vaoExt = this.getGLExtension('OES_vertex_array_object');
for (var i = 0; i < list.length; i++) {
var renderable = list[i];
if (passConfig.ifRender && !passConfig.ifRender(renderable)) {
continue;
}
// Skinned mesh will transformed to joint space. Ignore the mesh transform
var worldM = renderable.isSkinnedMesh() ? matrices.IDENTITY : renderable.worldTransform.array;
var geometry = renderable.geometry;
var material = passConfig.getMaterial.call(this, renderable);
var program = renderable.__program;
var shader = material.shader;
var currentDrawID = geometry.__uid__ + '-' + program.__uid__;
var drawIDChanged = currentDrawID !== drawID;
drawID = currentDrawID;
if (drawIDChanged && vaoExt) {
// TODO Seems need to be bound to null immediately (or before bind another program?) if vao is changed
vaoExt.bindVertexArrayOES(null);
}
mat4.copy(matrices.WORLD, worldM);
mat4.multiply(matrices.WORLDVIEWPROJECTION, matrices.VIEWPROJECTION, worldM);
mat4.multiplyAffine(matrices.WORLDVIEW, camera.viewMatrix.array, worldM);
if (shader.matrixSemantics.WORLDINVERSE ||
shader.matrixSemantics.WORLDINVERSETRANSPOSE) {
mat4.invert(matrices.WORLDINVERSE, worldM);
}
if (shader.matrixSemantics.WORLDVIEWINVERSE ||
shader.matrixSemantics.WORLDVIEWINVERSETRANSPOSE) {
mat4.invert(matrices.WORLDVIEWINVERSE, matrices.WORLDVIEW);
}
if (shader.matrixSemantics.WORLDVIEWPROJECTIONINVERSE ||
shader.matrixSemantics.WORLDVIEWPROJECTIONINVERSETRANSPOSE) {
mat4.invert(matrices.WORLDVIEWPROJECTIONINVERSE, matrices.WORLDVIEWPROJECTION);
}
// Before render hook
renderable.beforeRender(this);
passConfig.beforeRender.call(this, renderable, material, prevMaterial);
var programChanged = program !== prevProgram;
if (programChanged) {
// Set lights number
program.bind(this);
// Set some common uniforms
program.setUniformOfSemantic(_gl, 'VIEWPORT', viewportUniform);
program.setUniformOfSemantic(_gl, 'WINDOW_SIZE', windowSizeUniform);
program.setUniformOfSemantic(_gl, 'NEAR', camera.near);
program.setUniformOfSemantic(_gl, 'FAR', camera.far);
program.setUniformOfSemantic(_gl, 'DEVICEPIXELRATIO', vDpr);
program.setUniformOfSemantic(_gl, 'TIME', time);
// DEPRECATED
program.setUniformOfSemantic(_gl, 'VIEWPORT_SIZE', viewportSizeUniform);
// Set lights uniforms
// TODO needs optimized
if (scene) {
scene.setLightUniforms(program, renderable.lightGroup, this);
}
}
else {
program = prevProgram;
}
// Program changes also needs reset the materials.
if (prevMaterial !== material || programChanged) {
if (material.depthTest !== depthTest) {
material.depthTest ? _gl.enable(_gl.DEPTH_TEST) : _gl.disable(_gl.DEPTH_TEST);
depthTest = material.depthTest;
}
if (material.depthMask !== depthMask) {
_gl.depthMask(material.depthMask);
depthMask = material.depthMask;
}
if (material.transparent !== transparent) {
material.transparent ? _gl.enable(_gl.BLEND) : _gl.disable(_gl.BLEND);
transparent = material.transparent;
}
// TODO cache blending
if (material.transparent) {
if (material.blend) {
material.blend(_gl);
}
else {
// Default blend function
_gl.blendEquationSeparate(_gl.FUNC_ADD, _gl.FUNC_ADD);
_gl.blendFuncSeparate(_gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA, _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA);
}
}
this._bindMaterial(material, program, prevMaterial || null, prevProgram || null);
prevMaterial = material;
}
var matrixSemanticKeys = shader.matrixSemanticKeys;
for (var k = 0; k < matrixSemanticKeys.length; k++) {
var semantic = matrixSemanticKeys[k];
var semanticInfo = shader.matrixSemantics[semantic];
var matrix = matrices[semantic];
if (semanticInfo.isTranspose) {
var matrixNoTranspose = matrices[semanticInfo.semanticNoTranspose];
mat4.transpose(matrix, matrixNoTranspose);
}
program.setUniform(_gl, semanticInfo.type, semanticInfo.symbol, matrix);
}
if (renderable.cullFace !== cullFace) {
cullFace = renderable.cullFace;
_gl.cullFace(cullFace);
}
if (renderable.frontFace !== frontFace) {
frontFace = renderable.frontFace;
_gl.frontFace(frontFace);
}
if (renderable.culling !== culling) {
culling = renderable.culling;
culling ? _gl.enable(_gl.CULL_FACE) : _gl.disable(_gl.CULL_FACE);
}
this._updateSkeleton(renderable, program);
if (drawIDChanged) {
currentVAO = this._bindVAO(vaoExt, shader, geometry, program);
}
this._renderObject(renderable, currentVAO);
// After render hook
passConfig.afterRender.call(this, renderable);
renderable.afterRender(this);
prevProgram = program;
}
// TODO Seems need to be bound to null immediately if vao is changed?
if (vaoExt) {
vaoExt.bindVertexArrayOES(null);
}
this.trigger('afterrenderpass', this, list, camera, passConfig);
},
_updateSkeleton: function (object, program) {
var _gl = this.gl;
// Set pose matrices of skinned mesh
if (object.skeleton) {
object.skeleton.update();
var skinMatricesArray = object.skeleton.getSubSkinMatrices(object.__uid__, object.joints);
program.setUniformOfSemantic(_gl, 'SKIN_MATRIX', skinMatricesArray);
}
},
_renderObject: function (renderable, vao) {
var _gl = this.gl;
var geometry = renderable.geometry;
var glDrawMode = renderable.mode;
// if (glDrawMode === glenum.LINES || glDrawMode === glenum.LINE_STRIP || glDrawMode === glenum.LINE_LOOP) {
// _gl.lineWidth(this.lineWidth);
// }
if (vao.indicesBuffer) {
var uintExt = this.getGLExtension('OES_element_index_uint');
var useUintExt = uintExt && (geometry.indices instanceof Uint32Array);
var indicesType = useUintExt ? _gl.UNSIGNED_INT : _gl.UNSIGNED_SHORT;
_gl.drawElements(glDrawMode, vao.indicesBuffer.count, indicesType, 0);
}
else {
// FIXME Use vertex number in buffer
// vertexCount may get the wrong value when geometry forget to mark dirty after update
_gl.drawArrays(glDrawMode, 0, geometry.vertexCount);
}
},
_bindMaterial: function (material, program, prevMaterial, prevProgram) {
var _gl = this.gl;
// PENDING Same texture in different material take different slot?
// May use shader of other material if shader code are same
var sameProgram = prevProgram === program;
var currentTextureSlot = program.currentTextureSlot();
var enabledUniforms = material.getEnabledUniforms();
var textureUniforms = material.getTextureUniforms();
for (var u = 0; u < textureUniforms.length; u++) {
var symbol = textureUniforms[u];
var uniformValue = material.uniforms[symbol].value;
var uniformType = material.uniforms[symbol].type;
// Not use `instanceof` to determine if a value is texture in Material#bind.
// Use type instead, in some case texture may be in different namespaces.
// TODO Duck type validate.
if (uniformType === 't' && uniformValue) {
// Reset slot
uniformValue.__slot = -1;
}
else if (uniformType === 'tv') {
for (var i = 0; i < uniformValue.length; i++) {
if (uniformValue[i] instanceof Texture) {
uniformValue[i].__slot = -1;
}
}
}
}
// Set uniforms
for (var u = 0; u < enabledUniforms.length; u++) {
var symbol = enabledUniforms[u];
var uniform = material.uniforms[symbol];
var uniformValue = uniform.value;
// PENDING
// When binding two materials with the same shader
// Many uniforms will be be set twice even if they have the same value
// So add a evaluation to see if the uniform is really needed to be set
if (prevMaterial && sameProgram) {
if (prevMaterial.uniforms[symbol].value === uniformValue) {
continue;
}
}
var uniformType = uniform.type;
if (uniformValue == null) {
// FIXME Assume material with same shader have same order uniforms
// Or if different material use same textures,
// the slot will be different and still skipped because optimization
if (uniform.type === 't') {
var slot = program.currentTextureSlot();
var res = program.setUniform(_gl, '1i', symbol, slot);
if (res) { // Texture is enabled
// Still occupy the slot to make sure same texture in different materials have same slot.
program.takeCurrentTextureSlot(this, null);
}
}
continue;
}
else if (uniformType === 't') {
if (uniformValue.__slot < 0) {
var slot = program.currentTextureSlot();
var res = program.setUniform(_gl, '1i', symbol, slot);
if (!res) { // Texture uniform is not enabled
continue;
}
program.takeCurrentTextureSlot(this, uniformValue);
uniformValue.__slot = slot;
}
// Multiple uniform use same texture..
else {
program.setUniform(_gl, '1i', symbol, uniformValue.__slot);
}
}
else if (Array.isArray(uniformValue)) {
if (uniformValue.length === 0) {
continue;
}
// Texture Array
if (uniformType === 'tv') {
if (!program.hasUniform(symbol)) {
continue;
}
var arr = [];
for (var i = 0; i < uniformValue.length; i++) {
var texture = uniformValue[i];
if (texture.__slot < 0) {
var slot = program.currentTextureSlot();
arr.push(slot);
program.takeCurrentTextureSlot(this, texture);
texture.__slot = slot;
}
else {
arr.push(texture.__slot);
}
}
program.setUniform(_gl, '1iv', symbol, arr);
}
else {
program.setUniform(_gl, uniform.type, symbol, uniformValue);
}
}
else{
program.setUniform(_gl, uniform.type, symbol, uniformValue);
}
}
// Texture slot maybe used out of material.
program.resetTextureSlot(currentTextureSlot);
},
_bindVAO: function (vaoExt, shader, geometry, program) {
var isStatic = !geometry.dynamic;
var _gl = this.gl;
var vaoId = this.__uid__ + '-' + program.__uid__;
var vao = geometry.__vaoCache[vaoId];
if (!vao) {
var chunks = geometry.getBufferChunks(this);
if (!chunks || !chunks.length) { // Empty mesh
return;
}
var chunk = chunks[0];
var attributeBuffers = chunk.attributeBuffers;
var indicesBuffer = chunk.indicesBuffer;
var availableAttributes = [];
var availableAttributeSymbols = [];
for (var a = 0; a < attributeBuffers.length; a++) {
var attributeBufferInfo = attributeBuffers[a];
var name = attributeBufferInfo.name;
var semantic = attributeBufferInfo.semantic;
var symbol;
if (semantic) {
var semanticInfo = shader.attributeSemantics[semantic];
symbol = semanticInfo && semanticInfo.symbol;
}
else {
symbol = name;
}
if (symbol && program.attributes[symbol]) {
availableAttributes.push(attributeBufferInfo);
availableAttributeSymbols.push(symbol);
}
}
vao = new VertexArrayObject(
availableAttributes,
availableAttributeSymbols,
indicesBuffer
);
if (isStatic) {
geometry.__vaoCache[vaoId] = vao;
}
}
var needsBindAttributes = true;
// Create vertex object array cost a lot
// So we don't use it on the dynamic object
if (vaoExt && isStatic) {
// Use vertex array object
// http://blog.tojicode.com/2012/10/oesvertexarrayobject-extension.html
if (vao.vao == null) {
vao.vao = vaoExt.createVertexArrayOES();
}
else {
needsBindAttributes = false;
}
vaoExt.bindVertexArrayOES(vao.vao);
}
var availableAttributes = vao.availableAttributes;
var indicesBuffer = vao.indicesBuffer;
if (needsBindAttributes) {
var locationList = program.enableAttributes(this, vao.availableAttributeSymbols, (vaoExt && isStatic && vao));
// Setting attributes;
for (var a = 0; a < availableAttributes.length; a++) {
var location = locationList[a];
if (location === -1) {
continue;
}
var attributeBufferInfo = availableAttributes[a];
var buffer = attributeBufferInfo.buffer;
var size = attributeBufferInfo.size;
var glType = attributeBufferTypeMap[attributeBufferInfo.type] || _gl.FLOAT;
_gl.bindBuffer(_gl.ARRAY_BUFFER, buffer);
_gl.vertexAttribPointer(location, size, glType, false, 0, 0);
}
if (geometry.isUseIndices()) {
_gl.bindBuffer(_gl.ELEMENT_ARRAY_BUFFER, indicesBuffer.buffer);
}
}
return vao;
},
renderPreZ: function (list, scene, camera) {
var _gl = this.gl;
var preZPassMaterial = this._prezMaterial || new __WEBPACK_IMPORTED_MODULE_6__Material__["a" /* default */]({
shader: new __WEBPACK_IMPORTED_MODULE_9__Shader__["a" /* default */](__WEBPACK_IMPORTED_MODULE_9__Shader__["a" /* default */].source('clay.prez.vertex'), __WEBPACK_IMPORTED_MODULE_9__Shader__["a" /* default */].source('clay.prez.fragment'))
});
this._prezMaterial = preZPassMaterial;
_gl.colorMask(false, false, false, false);
_gl.depthMask(true);
// Status
this.renderPass(list, camera, {
ifRender: function (renderable) {
return !renderable.ignorePreZ;
},
getMaterial: function () {
return preZPassMaterial;
},
sort: this.opaqueSortCompare
});
_gl.colorMask(true, true, true, true);
_gl.depthMask(true);
},
/**
* Dispose given scene, including all geometris, textures and shaders in the scene
* @param {clay.Scene} scene
*/
disposeScene: function(scene) {
this.disposeNode(scene, true, true);
scene.dispose();
},
/**
* Dispose given node, including all geometries, textures and shaders attached on it or its descendant
* @param {clay.Node} node
* @param {boolean} [disposeGeometry=false] If dispose the geometries used in the descendant mesh
* @param {boolean} [disposeTexture=false] If dispose the textures used in the descendant mesh
*/
disposeNode: function(root, disposeGeometry, disposeTexture) {
// Dettached from parent
if (root.getParent()) {
root.getParent().remove(root);
}
var disposedMap = {};
root.traverse(function(node) {
var material = node.material;
if (node.geometry && disposeGeometry) {
node.geometry.dispose(this);
}
if (disposeTexture && material && !disposedMap[material.__uid__]) {
var textureUniforms = material.getTextureUniforms();
for (var u = 0; u < textureUniforms.length; u++) {
var uniformName = textureUniforms[u];
var val = material.uniforms[uniformName].value;
var uniformType = material.uniforms[uniformName].type;
if (!val) {
continue;
}
if (uniformType === 't') {
val.dispose && val.dispose(this);
}
else if (uniformType === 'tv') {
for (var k = 0; k < val.length; k++) {
if (val[k]) {
val[k].dispose && val[k].dispose(this);
}
}
}
}
disposedMap[material.__uid__] = true;
}
// Particle system and AmbientCubemap light need to dispose
if (node.dispose) {
node.dispose(this);
}
}, this);
},
/**
* Dispose given geometry
* @param {clay.Geometry} geometry
*/
disposeGeometry: function(geometry) {
geometry.dispose(this);
},
/**
* Dispose given texture
* @param {clay.Texture} texture
*/
disposeTexture: function(texture) {
texture.dispose(this);
},
/**
* Dispose given frame buffer
* @param {clay.FrameBuffer} frameBuffer
*/
disposeFrameBuffer: function(frameBuffer) {
frameBuffer.dispose(this);
},
/**
* Dispose renderer
*/
dispose: function () {},
/**
* Convert screen coords to normalized device coordinates(NDC)
* Screen coords can get from mouse event, it is positioned relative to canvas element
* NDC can be used in ray casting with Camera.prototype.castRay methods
*
* @param {number} x
* @param {number} y
* @param {clay.Vector2} [out]
* @return {clay.Vector2}
*/
screenToNDC: function(x, y, out) {
if (!out) {
out = new __WEBPACK_IMPORTED_MODULE_7__math_Vector2__["a" /* default */]();
}
// Invert y;
y = this._height - y;
var viewport = this.viewport;
var arr = out.array;
arr[0] = (x - viewport.x) / viewport.width;
arr[0] = arr[0] * 2 - 1;
arr[1] = (y - viewport.y) / viewport.height;
arr[1] = arr[1] * 2 - 1;
return out;
}
});
/**
* Opaque renderables compare function
* @param {clay.Renderable} x
* @param {clay.Renderable} y
* @return {boolean}
* @static
*/
Renderer.opaqueSortCompare = Renderer.prototype.opaqueSortCompare = function(x, y) {
// Priority renderOrder -> program -> material -> geometry
if (x.renderOrder === y.renderOrder) {
if (x.__program === y.__program) {
if (x.material === y.material) {
return x.geometry.__uid__ - y.geometry.__uid__;
}
return x.material.__uid__ - y.material.__uid__;
}
if (x.__program && y.__program) {
return x.__program.__uid__ - y.__program.__uid__;
}
return 0;
}
return x.renderOrder - y.renderOrder;
};
/**
* Transparent renderables compare function
* @param {clay.Renderable} a
* @param {clay.Renderable} b
* @return {boolean}
* @static
*/
Renderer.transparentSortCompare = Renderer.prototype.transparentSortCompare = function(x, y) {
// Priority renderOrder -> depth -> program -> material -> geometry
if (x.renderOrder === y.renderOrder) {
if (x.__depth === y.__depth) {
if (x.__program === y.__program) {
if (x.material === y.material) {
return x.geometry.__uid__ - y.geometry.__uid__;
}
return x.material.__uid__ - y.material.__uid__;
}
if (x.__program && y.__program) {
return x.__program.__uid__ - y.__program.__uid__;
}
return 0;
}
// Depth is negative
// So farther object has smaller depth value
return x.__depth - y.__depth;
}
return x.renderOrder - y.renderOrder;
};
// Temporary variables
var matrices = {
IDENTITY: mat4Create(),
WORLD: mat4Create(),
VIEW: mat4Create(),
PROJECTION: mat4Create(),
WORLDVIEW: mat4Create(),
VIEWPROJECTION: mat4Create(),
WORLDVIEWPROJECTION: mat4Create(),
WORLDINVERSE: mat4Create(),
VIEWINVERSE: mat4Create(),
PROJECTIONINVERSE: mat4Create(),
WORLDVIEWINVERSE: mat4Create(),
VIEWPROJECTIONINVERSE: mat4Create(),
WORLDVIEWPROJECTIONINVERSE: mat4Create(),
WORLDTRANSPOSE: mat4Create(),
VIEWTRANSPOSE: mat4Create(),
PROJECTIONTRANSPOSE: mat4Create(),
WORLDVIEWTRANSPOSE: mat4Create(),
VIEWPROJECTIONTRANSPOSE: mat4Create(),
WORLDVIEWPROJECTIONTRANSPOSE: mat4Create(),
WORLDINVERSETRANSPOSE: mat4Create(),
VIEWINVERSETRANSPOSE: mat4Create(),
PROJECTIONINVERSETRANSPOSE: mat4Create(),
WORLDVIEWINVERSETRANSPOSE: mat4Create(),
VIEWPROJECTIONINVERSETRANSPOSE: mat4Create(),
WORLDVIEWPROJECTIONINVERSETRANSPOSE: mat4Create()
};
/**
* @name clay.Renderer.COLOR_BUFFER_BIT
* @type {number}
*/
Renderer.COLOR_BUFFER_BIT = __WEBPACK_IMPORTED_MODULE_2__core_glenum__["a" /* default */].COLOR_BUFFER_BIT;
/**
* @name clay.Renderer.DEPTH_BUFFER_BIT
* @type {number}
*/
Renderer.DEPTH_BUFFER_BIT = __WEBPACK_IMPORTED_MODULE_2__core_glenum__["a" /* default */].DEPTH_BUFFER_BIT;
/**
* @name clay.Renderer.STENCIL_BUFFER_BIT
* @type {number}
*/
Renderer.STENCIL_BUFFER_BIT = __WEBPACK_IMPORTED_MODULE_2__core_glenum__["a" /* default */].STENCIL_BUFFER_BIT;
/* harmony default export */ __webpack_exports__["a"] = (Renderer);
/***/ }),
/* 47 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
function Handler(action, context) {
this.action = action;
this.context = context;
}
/**
* @mixin
* @alias clay.core.mixin.notifier
*/
var notifier = {
/**
* Trigger event
* @param {string} name
*/
trigger: function(name) {
if (!this.hasOwnProperty('__handlers__')) {
return;
}
if (!this.__handlers__.hasOwnProperty(name)) {
return;
}
var hdls = this.__handlers__[name];
var l = hdls.length, i = -1, args = arguments;
// Optimize advise from backbone
switch (args.length) {
case 1:
while (++i < l) {
hdls[i].action.call(hdls[i].context);
}
return;
case 2:
while (++i < l) {
hdls[i].action.call(hdls[i].context, args[1]);
}
return;
case 3:
while (++i < l) {
hdls[i].action.call(hdls[i].context, args[1], args[2]);
}
return;
case 4:
while (++i < l) {
hdls[i].action.call(hdls[i].context, args[1], args[2], args[3]);
}
return;
case 5:
while (++i < l) {
hdls[i].action.call(hdls[i].context, args[1], args[2], args[3], args[4]);
}
return;
default:
while (++i < l) {
hdls[i].action.apply(hdls[i].context, Array.prototype.slice.call(args, 1));
}
return;
}
},
/**
* Register event handler
* @param {string} name
* @param {Function} action
* @param {Object} [context]
* @chainable
*/
on: function(name, action, context) {
if (!name || !action) {
return;
}
var handlers = this.__handlers__ || (this.__handlers__={});
if (!handlers[name]) {
handlers[name] = [];
}
else {
if (this.has(name, action)) {
return;
}
}
var handler = new Handler(action, context || this);
handlers[name].push(handler);
return this;
},
/**
* Register event, event will only be triggered once and then removed
* @param {string} name
* @param {Function} action
* @param {Object} [context]
* @chainable
*/
once: function(name, action, context) {
if (!name || !action) {
return;
}
var self = this;
function wrapper() {
self.off(name, wrapper);
action.apply(this, arguments);
}
return this.on(name, wrapper, context);
},
/**
* Alias of once('before' + name)
* @param {string} name
* @param {Function} action
* @param {Object} [context]
* @chainable
*/
before: function(name, action, context) {
if (!name || !action) {
return;
}
name = 'before' + name;
return this.on(name, action, context);
},
/**
* Alias of once('after' + name)
* @param {string} name
* @param {Function} action
* @param {Object} [context]
* @chainable
*/
after: function(name, action, context) {
if (!name || !action) {
return;
}
name = 'after' + name;
return this.on(name, action, context);
},
/**
* Alias of on('success')
* @param {Function} action
* @param {Object} [context]
* @chainable
*/
success: function(action, context) {
return this.once('success', action, context);
},
/**
* Alias of on('error')
* @param {Function} action
* @param {Object} [context]
* @chainable
*/
error: function(action, context) {
return this.once('error', action, context);
},
/**
* Remove event listener
* @param {Function} action
* @param {Object} [context]
* @chainable
*/
off: function(name, action) {
var handlers = this.__handlers__ || (this.__handlers__={});
if (!action) {
handlers[name] = [];
return;
}
if (handlers[name]) {
var hdls = handlers[name];
var retains = [];
for (var i = 0; i < hdls.length; i++) {
if (action && hdls[i].action !== action) {
retains.push(hdls[i]);
}
}
handlers[name] = retains;
}
return this;
},
/**
* If registered the event handler
* @param {string} name
* @param {Function} action
* @return {boolean}
*/
has: function(name, action) {
var handlers = this.__handlers__;
if (! handlers ||
! handlers[name]) {
return false;
}
var hdls = handlers[name];
for (var i = 0; i < hdls.length; i++) {
if (hdls[i].action === action) {
return true;
}
}
}
};
/* harmony default export */ __webpack_exports__["a"] = (notifier);
/***/ }),
/* 48 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
var DIRTY_PREFIX = '__dt__';
var Cache = function () {
this._contextId = 0;
this._caches = [];
this._context = {};
};
Cache.prototype = {
use: function (contextId, documentSchema) {
var caches = this._caches;
if (!caches[contextId]) {
caches[contextId] = {};
if (documentSchema) {
caches[contextId] = documentSchema();
}
}
this._contextId = contextId;
this._context = caches[contextId];
},
put: function (key, value) {
this._context[key] = value;
},
get: function (key) {
return this._context[key];
},
dirty: function (field) {
field = field || '';
var key = DIRTY_PREFIX + field;
this.put(key, true);
},
dirtyAll: function (field) {
field = field || '';
var key = DIRTY_PREFIX + field;
var caches = this._caches;
for (var i = 0; i < caches.length; i++) {
if (caches[i]) {
caches[i][key] = true;
}
}
},
fresh: function (field) {
field = field || '';
var key = DIRTY_PREFIX + field;
this.put(key, false);
},
freshAll: function (field) {
field = field || '';
var key = DIRTY_PREFIX + field;
var caches = this._caches;
for (var i = 0; i < caches.length; i++) {
if (caches[i]) {
caches[i][key] = false;
}
}
},
isDirty: function (field) {
field = field || '';
var key = DIRTY_PREFIX + field;
var context = this._context;
return !context.hasOwnProperty(key)
|| context[key] === true;
},
deleteContext: function (contextId) {
delete this._caches[contextId];
this._context = {};
},
delete: function (key) {
delete this._context[key];
},
clearAll: function () {
this._caches = {};
},
getContext: function () {
return this._context;
},
eachContext : function (cb, context) {
var keys = Object.keys(this._caches);
keys.forEach(function (key) {
cb && cb.call(context, key);
});
},
miss: function (key) {
return ! this._context.hasOwnProperty(key);
}
};
Cache.prototype.constructor = Cache;
/* harmony default export */ __webpack_exports__["a"] = (Cache);
/***/ }),
/* 49 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Vector3__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1__dep_glmatrix__);
var vec3 = __WEBPACK_IMPORTED_MODULE_1__dep_glmatrix___default.a.vec3;
var EPSILON = 1e-5;
/**
* @constructor
* @alias clay.Ray
* @param {clay.Vector3} [origin]
* @param {clay.Vector3} [direction]
*/
var Ray = function (origin, direction) {
/**
* @type {clay.Vector3}
*/
this.origin = origin || new __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */]();
/**
* @type {clay.Vector3}
*/
this.direction = direction || new __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */]();
};
Ray.prototype = {
constructor: Ray,
// http://www.siggraph.org/education/materials/HyperGraph/raytrace/rayplane_intersection.htm
/**
* Calculate intersection point between ray and a give plane
* @param {clay.Plane} plane
* @param {clay.Vector3} [out]
* @return {clay.Vector3}
*/
intersectPlane: function (plane, out) {
var pn = plane.normal.array;
var d = plane.distance;
var ro = this.origin.array;
var rd = this.direction.array;
var divider = vec3.dot(pn, rd);
// ray is parallel to the plane
if (divider === 0) {
return null;
}
if (!out) {
out = new __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */]();
}
var t = (vec3.dot(pn, ro) - d) / divider;
vec3.scaleAndAdd(out.array, ro, rd, -t);
out._dirty = true;
return out;
},
/**
* Mirror the ray against plane
* @param {clay.Plane} plane
*/
mirrorAgainstPlane: function (plane) {
// Distance to plane
var d = vec3.dot(plane.normal.array, this.direction.array);
vec3.scaleAndAdd(this.direction.array, this.direction.array, plane.normal.array, -d * 2);
this.direction._dirty = true;
},
distanceToPoint: (function () {
var v = vec3.create();
return function (point) {
vec3.sub(v, point, this.origin.array);
// Distance from projection point to origin
var b = vec3.dot(v, this.direction.array);
if (b < 0) {
return vec3.distance(this.origin.array, point);
}
// Squared distance from center to origin
var c2 = vec3.lenSquared(v);
// Squared distance from center to projection point
return Math.sqrt(c2 - b * b);
};
})(),
/**
* Calculate intersection point between ray and sphere
* @param {clay.Vector3} center
* @param {number} radius
* @param {clay.Vector3} out
* @return {clay.Vector3}
*/
intersectSphere: (function () {
var v = vec3.create();
return function (center, radius, out) {
var origin = this.origin.array;
var direction = this.direction.array;
center = center.array;
vec3.sub(v, center, origin);
// Distance from projection point to origin
var b = vec3.dot(v, direction);
// Squared distance from center to origin
var c2 = vec3.squaredLength(v);
// Squared distance from center to projection point
var d2 = c2 - b * b;
var r2 = radius * radius;
// No intersection
if (d2 > r2) {
return;
}
var a = Math.sqrt(r2 - d2);
// First intersect point
var t0 = b - a;
// Second intersect point
var t1 = b + a;
if (!out) {
out = new __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */]();
}
if (t0 < 0) {
if (t1 < 0) {
return null;
}
else {
vec3.scaleAndAdd(out.array, origin, direction, t1);
return out;
}
}
else {
vec3.scaleAndAdd(out.array, origin, direction, t0);
return out;
}
};
})(),
// http://www.scratchapixel.com/lessons/3d-basic-lessons/lesson-7-intersecting-simple-shapes/ray-box-intersection/
/**
* Calculate intersection point between ray and bounding box
* @param {clay.BoundingBox} bbox
* @param {clay.Vector3}
* @return {clay.Vector3}
*/
intersectBoundingBox: function (bbox, out) {
var dir = this.direction.array;
var origin = this.origin.array;
var min = bbox.min.array;
var max = bbox.max.array;
var invdirx = 1 / dir[0];
var invdiry = 1 / dir[1];
var invdirz = 1 / dir[2];
var tmin, tmax, tymin, tymax, tzmin, tzmax;
if (invdirx >= 0) {
tmin = (min[0] - origin[0]) * invdirx;
tmax = (max[0] - origin[0]) * invdirx;
}
else {
tmax = (min[0] - origin[0]) * invdirx;
tmin = (max[0] - origin[0]) * invdirx;
}
if (invdiry >= 0) {
tymin = (min[1] - origin[1]) * invdiry;
tymax = (max[1] - origin[1]) * invdiry;
}
else {
tymax = (min[1] - origin[1]) * invdiry;
tymin = (max[1] - origin[1]) * invdiry;
}
if ((tmin > tymax) || (tymin > tmax)) {
return null;
}
if (tymin > tmin || tmin !== tmin) {
tmin = tymin;
}
if (tymax < tmax || tmax !== tmax) {
tmax = tymax;
}
if (invdirz >= 0) {
tzmin = (min[2] - origin[2]) * invdirz;
tzmax = (max[2] - origin[2]) * invdirz;
}
else {
tzmax = (min[2] - origin[2]) * invdirz;
tzmin = (max[2] - origin[2]) * invdirz;
}
if ((tmin > tzmax) || (tzmin > tmax)) {
return null;
}
if (tzmin > tmin || tmin !== tmin) {
tmin = tzmin;
}
if (tzmax < tmax || tmax !== tmax) {
tmax = tzmax;
}
if (tmax < 0) {
return null;
}
var t = tmin >= 0 ? tmin : tmax;
if (!out) {
out = new __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */]();
}
vec3.scaleAndAdd(out.array, origin, dir, t);
return out;
},
// http://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm
/**
* Calculate intersection point between ray and three triangle vertices
* @param {clay.Vector3} a
* @param {clay.Vector3} b
* @param {clay.Vector3} c
* @param {boolean} singleSided, CW triangle will be ignored
* @param {clay.Vector3} [out]
* @param {clay.Vector3} [barycenteric] barycentric coords
* @return {clay.Vector3}
*/
intersectTriangle: (function () {
var eBA = vec3.create();
var eCA = vec3.create();
var AO = vec3.create();
var vCross = vec3.create();
return function (a, b, c, singleSided, out, barycenteric) {
var dir = this.direction.array;
var origin = this.origin.array;
a = a.array;
b = b.array;
c = c.array;
vec3.sub(eBA, b, a);
vec3.sub(eCA, c, a);
vec3.cross(vCross, eCA, dir);
var det = vec3.dot(eBA, vCross);
if (singleSided) {
if (det > -EPSILON) {
return null;
}
}
else {
if (det > -EPSILON && det < EPSILON) {
return null;
}
}
vec3.sub(AO, origin, a);
var u = vec3.dot(vCross, AO) / det;
if (u < 0 || u > 1) {
return null;
}
vec3.cross(vCross, eBA, AO);
var v = vec3.dot(dir, vCross) / det;
if (v < 0 || v > 1 || (u + v > 1)) {
return null;
}
vec3.cross(vCross, eBA, eCA);
var t = -vec3.dot(AO, vCross) / det;
if (t < 0) {
return null;
}
if (!out) {
out = new __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */]();
}
if (barycenteric) {
__WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */].set(barycenteric, (1 - u - v), u, v);
}
vec3.scaleAndAdd(out.array, origin, dir, t);
return out;
};
})(),
/**
* Apply an affine transform matrix to the ray
* @return {clay.Matrix4} matrix
*/
applyTransform: function (matrix) {
__WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */].add(this.direction, this.direction, this.origin);
__WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */].transformMat4(this.origin, this.origin, matrix);
__WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */].transformMat4(this.direction, this.direction, matrix);
__WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */].sub(this.direction, this.direction, this.origin);
__WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */].normalize(this.direction, this.direction);
},
/**
* Copy values from another ray
* @param {clay.Ray} ray
*/
copy: function (ray) {
__WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */].copy(this.origin, ray.origin);
__WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */].copy(this.direction, ray.direction);
},
/**
* Clone a new ray
* @return {clay.Ray}
*/
clone: function () {
var ray = new Ray();
ray.copy(this);
return ray;
}
};
/* harmony default export */ __webpack_exports__["a"] = (Ray);
/***/ }),
/* 50 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0__dep_glmatrix__);
var quat = __WEBPACK_IMPORTED_MODULE_0__dep_glmatrix___default.a.quat;
/**
* @constructor
* @alias clay.Quaternion
* @param {number} x
* @param {number} y
* @param {number} z
* @param {number} w
*/
var Quaternion = function (x, y, z, w) {
x = x || 0;
y = y || 0;
z = z || 0;
w = w === undefined ? 1 : w;
/**
* Storage of Quaternion, read and write of x, y, z, w will change the values in array
* All methods also operate on the array instead of x, y, z, w components
* @name array
* @type {Float32Array}
* @memberOf clay.Quaternion#
*/
this.array = quat.fromValues(x, y, z, w);
/**
* Dirty flag is used by the Node to determine
* if the matrix is updated to latest
* @name _dirty
* @type {boolean}
* @memberOf clay.Quaternion#
*/
this._dirty = true;
};
Quaternion.prototype = {
constructor: Quaternion,
/**
* Add b to self
* @param {clay.Quaternion} b
* @return {clay.Quaternion}
*/
add: function (b) {
quat.add(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Calculate the w component from x, y, z component
* @return {clay.Quaternion}
*/
calculateW: function () {
quat.calculateW(this.array, this.array);
this._dirty = true;
return this;
},
/**
* Set x, y and z components
* @param {number} x
* @param {number} y
* @param {number} z
* @param {number} w
* @return {clay.Quaternion}
*/
set: function (x, y, z, w) {
this.array[0] = x;
this.array[1] = y;
this.array[2] = z;
this.array[3] = w;
this._dirty = true;
return this;
},
/**
* Set x, y, z and w components from array
* @param {Float32Array|number[]} arr
* @return {clay.Quaternion}
*/
setArray: function (arr) {
this.array[0] = arr[0];
this.array[1] = arr[1];
this.array[2] = arr[2];
this.array[3] = arr[3];
this._dirty = true;
return this;
},
/**
* Clone a new Quaternion
* @return {clay.Quaternion}
*/
clone: function () {
return new Quaternion(this.x, this.y, this.z, this.w);
},
/**
* Calculates the conjugate of self If the quaternion is normalized,
* this function is faster than invert and produces the same result.
*
* @return {clay.Quaternion}
*/
conjugate: function () {
quat.conjugate(this.array, this.array);
this._dirty = true;
return this;
},
/**
* Copy from b
* @param {clay.Quaternion} b
* @return {clay.Quaternion}
*/
copy: function (b) {
quat.copy(this.array, b.array);
this._dirty = true;
return this;
},
/**
* Dot product of self and b
* @param {clay.Quaternion} b
* @return {number}
*/
dot: function (b) {
return quat.dot(this.array, b.array);
},
/**
* Set from the given 3x3 rotation matrix
* @param {clay.Matrix3} m
* @return {clay.Quaternion}
*/
fromMat3: function (m) {
quat.fromMat3(this.array, m.array);
this._dirty = true;
return this;
},
/**
* Set from the given 4x4 rotation matrix
* The 4th column and 4th row will be droped
* @param {clay.Matrix4} m
* @return {clay.Quaternion}
*/
fromMat4: (function () {
var mat3 = __WEBPACK_IMPORTED_MODULE_0__dep_glmatrix___default.a.mat3;
var m3 = mat3.create();
return function (m) {
mat3.fromMat4(m3, m.array);
// TODO Not like mat4, mat3 in glmatrix seems to be row-based
mat3.transpose(m3, m3);
quat.fromMat3(this.array, m3);
this._dirty = true;
return this;
};
})(),
/**
* Set to identity quaternion
* @return {clay.Quaternion}
*/
identity: function () {
quat.identity(this.array);
this._dirty = true;
return this;
},
/**
* Invert self
* @return {clay.Quaternion}
*/
invert: function () {
quat.invert(this.array, this.array);
this._dirty = true;
return this;
},
/**
* Alias of length
* @return {number}
*/
len: function () {
return quat.len(this.array);
},
/**
* Calculate the length
* @return {number}
*/
length: function () {
return quat.length(this.array);
},
/**
* Linear interpolation between a and b
* @param {clay.Quaternion} a
* @param {clay.Quaternion} b
* @param {number} t
* @return {clay.Quaternion}
*/
lerp: function (a, b, t) {
quat.lerp(this.array, a.array, b.array, t);
this._dirty = true;
return this;
},
/**
* Alias for multiply
* @param {clay.Quaternion} b
* @return {clay.Quaternion}
*/
mul: function (b) {
quat.mul(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Alias for multiplyLeft
* @param {clay.Quaternion} a
* @return {clay.Quaternion}
*/
mulLeft: function (a) {
quat.multiply(this.array, a.array, this.array);
this._dirty = true;
return this;
},
/**
* Mutiply self and b
* @param {clay.Quaternion} b
* @return {clay.Quaternion}
*/
multiply: function (b) {
quat.multiply(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Mutiply a and self
* Quaternion mutiply is not commutative, so the result of mutiplyLeft is different with multiply.
* @param {clay.Quaternion} a
* @return {clay.Quaternion}
*/
multiplyLeft: function (a) {
quat.multiply(this.array, a.array, this.array);
this._dirty = true;
return this;
},
/**
* Normalize self
* @return {clay.Quaternion}
*/
normalize: function () {
quat.normalize(this.array, this.array);
this._dirty = true;
return this;
},
/**
* Rotate self by a given radian about X axis
* @param {number} rad
* @return {clay.Quaternion}
*/
rotateX: function (rad) {
quat.rotateX(this.array, this.array, rad);
this._dirty = true;
return this;
},
/**
* Rotate self by a given radian about Y axis
* @param {number} rad
* @return {clay.Quaternion}
*/
rotateY: function (rad) {
quat.rotateY(this.array, this.array, rad);
this._dirty = true;
return this;
},
/**
* Rotate self by a given radian about Z axis
* @param {number} rad
* @return {clay.Quaternion}
*/
rotateZ: function (rad) {
quat.rotateZ(this.array, this.array, rad);
this._dirty = true;
return this;
},
/**
* Sets self to represent the shortest rotation from Vector3 a to Vector3 b.
* a and b needs to be normalized
* @param {clay.Vector3} a
* @param {clay.Vector3} b
* @return {clay.Quaternion}
*/
rotationTo: function (a, b) {
quat.rotationTo(this.array, a.array, b.array);
this._dirty = true;
return this;
},
/**
* Sets self with values corresponding to the given axes
* @param {clay.Vector3} view
* @param {clay.Vector3} right
* @param {clay.Vector3} up
* @return {clay.Quaternion}
*/
setAxes: function (view, right, up) {
quat.setAxes(this.array, view.array, right.array, up.array);
this._dirty = true;
return this;
},
/**
* Sets self with a rotation axis and rotation angle
* @param {clay.Vector3} axis
* @param {number} rad
* @return {clay.Quaternion}
*/
setAxisAngle: function (axis, rad) {
quat.setAxisAngle(this.array, axis.array, rad);
this._dirty = true;
return this;
},
/**
* Perform spherical linear interpolation between a and b
* @param {clay.Quaternion} a
* @param {clay.Quaternion} b
* @param {number} t
* @return {clay.Quaternion}
*/
slerp: function (a, b, t) {
quat.slerp(this.array, a.array, b.array, t);
this._dirty = true;
return this;
},
/**
* Alias for squaredLength
* @return {number}
*/
sqrLen: function () {
return quat.sqrLen(this.array);
},
/**
* Squared length of self
* @return {number}
*/
squaredLength: function () {
return quat.squaredLength(this.array);
},
/**
* Set from euler
* @param {clay.Vector3} v
* @param {String} order
*/
fromEuler: function (v, order) {
return Quaternion.fromEuler(this, v, order);
},
toString: function () {
return '[' + Array.prototype.join.call(this.array, ',') + ']';
},
toArray: function () {
return Array.prototype.slice.call(this.array);
}
};
var defineProperty = Object.defineProperty;
// Getter and Setter
if (defineProperty) {
var proto = Quaternion.prototype;
/**
* @name x
* @type {number}
* @memberOf clay.Quaternion
* @instance
*/
defineProperty(proto, 'x', {
get: function () {
return this.array[0];
},
set: function (value) {
this.array[0] = value;
this._dirty = true;
}
});
/**
* @name y
* @type {number}
* @memberOf clay.Quaternion
* @instance
*/
defineProperty(proto, 'y', {
get: function () {
return this.array[1];
},
set: function (value) {
this.array[1] = value;
this._dirty = true;
}
});
/**
* @name z
* @type {number}
* @memberOf clay.Quaternion
* @instance
*/
defineProperty(proto, 'z', {
get: function () {
return this.array[2];
},
set: function (value) {
this.array[2] = value;
this._dirty = true;
}
});
/**
* @name w
* @type {number}
* @memberOf clay.Quaternion
* @instance
*/
defineProperty(proto, 'w', {
get: function () {
return this.array[3];
},
set: function (value) {
this.array[3] = value;
this._dirty = true;
}
});
}
// Supply methods that are not in place
/**
* @param {clay.Quaternion} out
* @param {clay.Quaternion} a
* @param {clay.Quaternion} b
* @return {clay.Quaternion}
*/
Quaternion.add = function (out, a, b) {
quat.add(out.array, a.array, b.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Quaternion} out
* @param {number} x
* @param {number} y
* @param {number} z
* @param {number} w
* @return {clay.Quaternion}
*/
Quaternion.set = function (out, x, y, z, w) {
quat.set(out.array, x, y, z, w);
out._dirty = true;
};
/**
* @param {clay.Quaternion} out
* @param {clay.Quaternion} b
* @return {clay.Quaternion}
*/
Quaternion.copy = function (out, b) {
quat.copy(out.array, b.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Quaternion} out
* @param {clay.Quaternion} a
* @return {clay.Quaternion}
*/
Quaternion.calculateW = function (out, a) {
quat.calculateW(out.array, a.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Quaternion} out
* @param {clay.Quaternion} a
* @return {clay.Quaternion}
*/
Quaternion.conjugate = function (out, a) {
quat.conjugate(out.array, a.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Quaternion} out
* @return {clay.Quaternion}
*/
Quaternion.identity = function (out) {
quat.identity(out.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Quaternion} out
* @param {clay.Quaternion} a
* @return {clay.Quaternion}
*/
Quaternion.invert = function (out, a) {
quat.invert(out.array, a.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Quaternion} a
* @param {clay.Quaternion} b
* @return {number}
*/
Quaternion.dot = function (a, b) {
return quat.dot(a.array, b.array);
};
/**
* @param {clay.Quaternion} a
* @return {number}
*/
Quaternion.len = function (a) {
return quat.length(a.array);
};
// Quaternion.length = Quaternion.len;
/**
* @param {clay.Quaternion} out
* @param {clay.Quaternion} a
* @param {clay.Quaternion} b
* @param {number} t
* @return {clay.Quaternion}
*/
Quaternion.lerp = function (out, a, b, t) {
quat.lerp(out.array, a.array, b.array, t);
out._dirty = true;
return out;
};
/**
* @param {clay.Quaternion} out
* @param {clay.Quaternion} a
* @param {clay.Quaternion} b
* @param {number} t
* @return {clay.Quaternion}
*/
Quaternion.slerp = function (out, a, b, t) {
quat.slerp(out.array, a.array, b.array, t);
out._dirty = true;
return out;
};
/**
* @param {clay.Quaternion} out
* @param {clay.Quaternion} a
* @param {clay.Quaternion} b
* @return {clay.Quaternion}
*/
Quaternion.mul = function (out, a, b) {
quat.multiply(out.array, a.array, b.array);
out._dirty = true;
return out;
};
/**
* @function
* @param {clay.Quaternion} out
* @param {clay.Quaternion} a
* @param {clay.Quaternion} b
* @return {clay.Quaternion}
*/
Quaternion.multiply = Quaternion.mul;
/**
* @param {clay.Quaternion} out
* @param {clay.Quaternion} a
* @param {number} rad
* @return {clay.Quaternion}
*/
Quaternion.rotateX = function (out, a, rad) {
quat.rotateX(out.array, a.array, rad);
out._dirty = true;
return out;
};
/**
* @param {clay.Quaternion} out
* @param {clay.Quaternion} a
* @param {number} rad
* @return {clay.Quaternion}
*/
Quaternion.rotateY = function (out, a, rad) {
quat.rotateY(out.array, a.array, rad);
out._dirty = true;
return out;
};
/**
* @param {clay.Quaternion} out
* @param {clay.Quaternion} a
* @param {number} rad
* @return {clay.Quaternion}
*/
Quaternion.rotateZ = function (out, a, rad) {
quat.rotateZ(out.array, a.array, rad);
out._dirty = true;
return out;
};
/**
* @param {clay.Quaternion} out
* @param {clay.Vector3} axis
* @param {number} rad
* @return {clay.Quaternion}
*/
Quaternion.setAxisAngle = function (out, axis, rad) {
quat.setAxisAngle(out.array, axis.array, rad);
out._dirty = true;
return out;
};
/**
* @param {clay.Quaternion} out
* @param {clay.Quaternion} a
* @return {clay.Quaternion}
*/
Quaternion.normalize = function (out, a) {
quat.normalize(out.array, a.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Quaternion} a
* @return {number}
*/
Quaternion.sqrLen = function (a) {
return quat.sqrLen(a.array);
};
/**
* @function
* @param {clay.Quaternion} a
* @return {number}
*/
Quaternion.squaredLength = Quaternion.sqrLen;
/**
* @param {clay.Quaternion} out
* @param {clay.Matrix3} m
* @return {clay.Quaternion}
*/
Quaternion.fromMat3 = function (out, m) {
quat.fromMat3(out.array, m.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Quaternion} out
* @param {clay.Vector3} view
* @param {clay.Vector3} right
* @param {clay.Vector3} up
* @return {clay.Quaternion}
*/
Quaternion.setAxes = function (out, view, right, up) {
quat.setAxes(out.array, view.array, right.array, up.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Quaternion} out
* @param {clay.Vector3} a
* @param {clay.Vector3} b
* @return {clay.Quaternion}
*/
Quaternion.rotationTo = function (out, a, b) {
quat.rotationTo(out.array, a.array, b.array);
out._dirty = true;
return out;
};
/**
* Set quaternion from euler
* @param {clay.Quaternion} out
* @param {clay.Vector3} v
* @param {String} order
*/
Quaternion.fromEuler = function (out, v, order) {
out._dirty = true;
v = v.array;
var target = out.array;
var c1 = Math.cos(v[0] / 2);
var c2 = Math.cos(v[1] / 2);
var c3 = Math.cos(v[2] / 2);
var s1 = Math.sin(v[0] / 2);
var s2 = Math.sin(v[1] / 2);
var s3 = Math.sin(v[2] / 2);
var order = (order || 'XYZ').toUpperCase();
// http://www.mathworks.com/matlabcentral/fileexchange/
// 20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/
// content/SpinCalc.m
switch (order) {
case 'XYZ':
target[0] = s1 * c2 * c3 + c1 * s2 * s3;
target[1] = c1 * s2 * c3 - s1 * c2 * s3;
target[2] = c1 * c2 * s3 + s1 * s2 * c3;
target[3] = c1 * c2 * c3 - s1 * s2 * s3;
break;
case 'YXZ':
target[0] = s1 * c2 * c3 + c1 * s2 * s3;
target[1] = c1 * s2 * c3 - s1 * c2 * s3;
target[2] = c1 * c2 * s3 - s1 * s2 * c3;
target[3] = c1 * c2 * c3 + s1 * s2 * s3;
break;
case 'ZXY':
target[0] = s1 * c2 * c3 - c1 * s2 * s3;
target[1] = c1 * s2 * c3 + s1 * c2 * s3;
target[2] = c1 * c2 * s3 + s1 * s2 * c3;
target[3] = c1 * c2 * c3 - s1 * s2 * s3;
break;
case 'ZYX':
target[0] = s1 * c2 * c3 - c1 * s2 * s3;
target[1] = c1 * s2 * c3 + s1 * c2 * s3;
target[2] = c1 * c2 * s3 - s1 * s2 * c3;
target[3] = c1 * c2 * c3 + s1 * s2 * s3;
break;
case 'YZX':
target[0] = s1 * c2 * c3 + c1 * s2 * s3;
target[1] = c1 * s2 * c3 + s1 * c2 * s3;
target[2] = c1 * c2 * s3 - s1 * s2 * c3;
target[3] = c1 * c2 * c3 - s1 * s2 * s3;
break;
case 'XZY':
target[0] = s1 * c2 * c3 - c1 * s2 * s3;
target[1] = c1 * s2 * c3 - s1 * c2 * s3;
target[2] = c1 * c2 * s3 + s1 * s2 * c3;
target[3] = c1 * c2 * c3 + s1 * s2 * s3;
break;
}
};
/* harmony default export */ __webpack_exports__["a"] = (Quaternion);
/***/ }),
/* 51 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Node__ = __webpack_require__(30);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__math_Matrix4__ = __webpack_require__(7);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__math_Frustum__ = __webpack_require__(52);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__math_Ray__ = __webpack_require__(49);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4__dep_glmatrix__);
var vec3 = __WEBPACK_IMPORTED_MODULE_4__dep_glmatrix___default.a.vec3;
var vec4 = __WEBPACK_IMPORTED_MODULE_4__dep_glmatrix___default.a.vec4;
/**
* @constructor clay.Camera
* @extends clay.Node
*/
var Camera = __WEBPACK_IMPORTED_MODULE_0__Node__["a" /* default */].extend(function () {
return /** @lends clay.Camera# */ {
/**
* Camera projection matrix
* @type {clay.Matrix4}
*/
projectionMatrix: new __WEBPACK_IMPORTED_MODULE_1__math_Matrix4__["a" /* default */](),
/**
* Inverse of camera projection matrix
* @type {clay.Matrix4}
*/
invProjectionMatrix: new __WEBPACK_IMPORTED_MODULE_1__math_Matrix4__["a" /* default */](),
/**
* View matrix, equal to inverse of camera's world matrix
* @type {clay.Matrix4}
*/
viewMatrix: new __WEBPACK_IMPORTED_MODULE_1__math_Matrix4__["a" /* default */](),
/**
* Camera frustum in view space
* @type {clay.Frustum}
*/
frustum: new __WEBPACK_IMPORTED_MODULE_2__math_Frustum__["a" /* default */]()
};
}, function () {
this.update(true);
},
/** @lends clay.Camera.prototype */
{
update: function (force) {
__WEBPACK_IMPORTED_MODULE_0__Node__["a" /* default */].prototype.update.call(this, force);
__WEBPACK_IMPORTED_MODULE_1__math_Matrix4__["a" /* default */].invert(this.viewMatrix, this.worldTransform);
this.updateProjectionMatrix();
__WEBPACK_IMPORTED_MODULE_1__math_Matrix4__["a" /* default */].invert(this.invProjectionMatrix, this.projectionMatrix);
this.frustum.setFromProjection(this.projectionMatrix);
},
/**
* Set camera view matrix
*/
setViewMatrix: function (viewMatrix) {
__WEBPACK_IMPORTED_MODULE_1__math_Matrix4__["a" /* default */].copy(this.viewMatrix, viewMatrix);
__WEBPACK_IMPORTED_MODULE_1__math_Matrix4__["a" /* default */].invert(this.worldTransform, viewMatrix);
this.decomposeWorldTransform();
},
/**
* Decompose camera projection matrix
*/
decomposeProjectionMatrix: function () {},
/**
* Set camera projection matrix
* @param {clay.Matrix4} projectionMatrix
*/
setProjectionMatrix: function (projectionMatrix) {
__WEBPACK_IMPORTED_MODULE_1__math_Matrix4__["a" /* default */].copy(this.projectionMatrix, projectionMatrix);
__WEBPACK_IMPORTED_MODULE_1__math_Matrix4__["a" /* default */].invert(this.invProjectionMatrix, projectionMatrix);
this.decomposeProjectionMatrix();
},
/**
* Update projection matrix, called after update
*/
updateProjectionMatrix: function () {},
/**
* Cast a picking ray from camera near plane to far plane
* @function
* @param {clay.Vector2} ndc
* @param {clay.Ray} [out]
* @return {clay.Ray}
*/
castRay: (function () {
var v4 = vec4.create();
return function (ndc, out) {
var ray = out !== undefined ? out : new __WEBPACK_IMPORTED_MODULE_3__math_Ray__["a" /* default */]();
var x = ndc.array[0];
var y = ndc.array[1];
vec4.set(v4, x, y, -1, 1);
vec4.transformMat4(v4, v4, this.invProjectionMatrix.array);
vec4.transformMat4(v4, v4, this.worldTransform.array);
vec3.scale(ray.origin.array, v4, 1 / v4[3]);
vec4.set(v4, x, y, 1, 1);
vec4.transformMat4(v4, v4, this.invProjectionMatrix.array);
vec4.transformMat4(v4, v4, this.worldTransform.array);
vec3.scale(v4, v4, 1 / v4[3]);
vec3.sub(ray.direction.array, v4, ray.origin.array);
vec3.normalize(ray.direction.array, ray.direction.array);
ray.direction._dirty = true;
ray.origin._dirty = true;
return ray;
};
})(),
/**
* @function
* @name clone
* @return {clay.Camera}
* @memberOf clay.Camera.prototype
*/
});
/* harmony default export */ __webpack_exports__["a"] = (Camera);
/***/ }),
/* 52 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Vector3__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__BoundingBox__ = __webpack_require__(15);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Plane__ = __webpack_require__(68);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3__dep_glmatrix__);
var vec3 = __WEBPACK_IMPORTED_MODULE_3__dep_glmatrix___default.a.vec3;
var vec3Set = vec3.set;
var vec3Copy = vec3.copy;
var vec3TranformMat4 = vec3.transformMat4;
var mathMin = Math.min;
var mathMax = Math.max;
/**
* @constructor
* @alias clay.Frustum
*/
var Frustum = function() {
/**
* Eight planes to enclose the frustum
* @type {clay.Plane[]}
*/
this.planes = [];
for (var i = 0; i < 6; i++) {
this.planes.push(new __WEBPACK_IMPORTED_MODULE_2__Plane__["a" /* default */]());
}
/**
* Bounding box of frustum
* @type {clay.BoundingBox}
*/
this.boundingBox = new __WEBPACK_IMPORTED_MODULE_1__BoundingBox__["a" /* default */]();
/**
* Eight vertices of frustum
* @type {Float32Array[]}
*/
this.vertices = [];
for (var i = 0; i < 8; i++) {
this.vertices[i] = vec3.fromValues(0, 0, 0);
}
};
Frustum.prototype = {
// http://web.archive.org/web/20120531231005/http://crazyjoke.free.fr/doc/3D/plane%20extraction.pdf
/**
* Set frustum from a projection matrix
* @param {clay.Matrix4} projectionMatrix
*/
setFromProjection: function(projectionMatrix) {
var planes = this.planes;
var m = projectionMatrix.array;
var m0 = m[0], m1 = m[1], m2 = m[2], m3 = m[3];
var m4 = m[4], m5 = m[5], m6 = m[6], m7 = m[7];
var m8 = m[8], m9 = m[9], m10 = m[10], m11 = m[11];
var m12 = m[12], m13 = m[13], m14 = m[14], m15 = m[15];
// Update planes
vec3Set(planes[0].normal.array, m3 - m0, m7 - m4, m11 - m8);
planes[0].distance = -(m15 - m12);
planes[0].normalize();
vec3Set(planes[1].normal.array, m3 + m0, m7 + m4, m11 + m8);
planes[1].distance = -(m15 + m12);
planes[1].normalize();
vec3Set(planes[2].normal.array, m3 + m1, m7 + m5, m11 + m9);
planes[2].distance = -(m15 + m13);
planes[2].normalize();
vec3Set(planes[3].normal.array, m3 - m1, m7 - m5, m11 - m9);
planes[3].distance = -(m15 - m13);
planes[3].normalize();
vec3Set(planes[4].normal.array, m3 - m2, m7 - m6, m11 - m10);
planes[4].distance = -(m15 - m14);
planes[4].normalize();
vec3Set(planes[5].normal.array, m3 + m2, m7 + m6, m11 + m10);
planes[5].distance = -(m15 + m14);
planes[5].normalize();
// Perspective projection
var boundingBox = this.boundingBox;
var vertices = this.vertices;
if (m15 === 0) {
var aspect = m5 / m0;
var zNear = -m14 / (m10 - 1);
var zFar = -m14 / (m10 + 1);
var farY = -zFar / m5;
var nearY = -zNear / m5;
// Update bounding box
boundingBox.min.set(-farY * aspect, -farY, zFar);
boundingBox.max.set(farY * aspect, farY, zNear);
// update vertices
//--- min z
// min x
vec3Set(vertices[0], -farY * aspect, -farY, zFar);
vec3Set(vertices[1], -farY * aspect, farY, zFar);
// max x
vec3Set(vertices[2], farY * aspect, -farY, zFar);
vec3Set(vertices[3], farY * aspect, farY, zFar);
//-- max z
vec3Set(vertices[4], -nearY * aspect, -nearY, zNear);
vec3Set(vertices[5], -nearY * aspect, nearY, zNear);
vec3Set(vertices[6], nearY * aspect, -nearY, zNear);
vec3Set(vertices[7], nearY * aspect, nearY, zNear);
}
else { // Orthographic projection
var left = (-1 - m12) / m0;
var right = (1 - m12) / m0;
var top = (1 - m13) / m5;
var bottom = (-1 - m13) / m5;
var near = (-1 - m14) / m10;
var far = (1 - m14) / m10;
boundingBox.min.set(Math.min(left, right), Math.min(bottom, top), Math.min(far, near));
boundingBox.max.set(Math.max(right, left), Math.max(top, bottom), Math.max(near, far));
var min = boundingBox.min.array;
var max = boundingBox.max.array;
//--- min z
// min x
vec3Set(vertices[0], min[0], min[1], min[2]);
vec3Set(vertices[1], min[0], max[1], min[2]);
// max x
vec3Set(vertices[2], max[0], min[1], min[2]);
vec3Set(vertices[3], max[0], max[1], min[2]);
//-- max z
vec3Set(vertices[4], min[0], min[1], max[2]);
vec3Set(vertices[5], min[0], max[1], max[2]);
vec3Set(vertices[6], max[0], min[1], max[2]);
vec3Set(vertices[7], max[0], max[1], max[2]);
}
},
/**
* Apply a affine transform matrix and set to the given bounding box
* @function
* @param {clay.BoundingBox}
* @param {clay.Matrix4}
* @return {clay.BoundingBox}
*/
getTransformedBoundingBox: (function() {
var tmpVec3 = vec3.create();
return function(bbox, matrix) {
var vertices = this.vertices;
var m4 = matrix.array;
var min = bbox.min;
var max = bbox.max;
var minArr = min.array;
var maxArr = max.array;
var v = vertices[0];
vec3TranformMat4(tmpVec3, v, m4);
vec3Copy(minArr, tmpVec3);
vec3Copy(maxArr, tmpVec3);
for (var i = 1; i < 8; i++) {
v = vertices[i];
vec3TranformMat4(tmpVec3, v, m4);
minArr[0] = mathMin(tmpVec3[0], minArr[0]);
minArr[1] = mathMin(tmpVec3[1], minArr[1]);
minArr[2] = mathMin(tmpVec3[2], minArr[2]);
maxArr[0] = mathMax(tmpVec3[0], maxArr[0]);
maxArr[1] = mathMax(tmpVec3[1], maxArr[1]);
maxArr[2] = mathMax(tmpVec3[2], maxArr[2]);
}
min._dirty = true;
max._dirty = true;
return bbox;
};
}) ()
};
/* harmony default export */ __webpack_exports__["a"] = (Frustum);
/***/ }),
/* 53 */
/***/ (function(module, exports) {
// Simple LRU cache use doubly linked list
// @module zrender/core/LRU
/**
* Simple double linked list. Compared with array, it has O(1) remove operation.
* @constructor
*/
var LinkedList = function () {
/**
* @type {module:zrender/core/LRU~Entry}
*/
this.head = null;
/**
* @type {module:zrender/core/LRU~Entry}
*/
this.tail = null;
this._len = 0;
};
var linkedListProto = LinkedList.prototype;
/**
* Insert a new value at the tail
* @param {} val
* @return {module:zrender/core/LRU~Entry}
*/
linkedListProto.insert = function (val) {
var entry = new Entry(val);
this.insertEntry(entry);
return entry;
};
/**
* Insert an entry at the tail
* @param {module:zrender/core/LRU~Entry} entry
*/
linkedListProto.insertEntry = function (entry) {
if (!this.head) {
this.head = this.tail = entry;
} else {
this.tail.next = entry;
entry.prev = this.tail;
entry.next = null;
this.tail = entry;
}
this._len++;
};
/**
* Remove entry.
* @param {module:zrender/core/LRU~Entry} entry
*/
linkedListProto.remove = function (entry) {
var prev = entry.prev;
var next = entry.next;
if (prev) {
prev.next = next;
} else {
// Is head
this.head = next;
}
if (next) {
next.prev = prev;
} else {
// Is tail
this.tail = prev;
}
entry.next = entry.prev = null;
this._len--;
};
/**
* @return {number}
*/
linkedListProto.len = function () {
return this._len;
};
/**
* Clear list
*/
linkedListProto.clear = function () {
this.head = this.tail = null;
this._len = 0;
};
/**
* @constructor
* @param {} val
*/
var Entry = function (val) {
/**
* @type {}
*/
this.value = val;
/**
* @type {module:zrender/core/LRU~Entry}
*/
this.next;
/**
* @type {module:zrender/core/LRU~Entry}
*/
this.prev;
};
/**
* LRU Cache
* @constructor
* @alias module:zrender/core/LRU
*/
var LRU = function (maxSize) {
this._list = new LinkedList();
this._map = {};
this._maxSize = maxSize || 10;
this._lastRemovedEntry = null;
};
var LRUProto = LRU.prototype;
/**
* @param {string} key
* @param {} value
* @return {} Removed value
*/
LRUProto.put = function (key, value) {
var list = this._list;
var map = this._map;
var removed = null;
if (map[key] == null) {
var len = list.len(); // Reuse last removed entry
var entry = this._lastRemovedEntry;
if (len >= this._maxSize && len > 0) {
// Remove the least recently used
var leastUsedEntry = list.head;
list.remove(leastUsedEntry);
delete map[leastUsedEntry.key];
removed = leastUsedEntry.value;
this._lastRemovedEntry = leastUsedEntry;
}
if (entry) {
entry.value = value;
} else {
entry = new Entry(value);
}
entry.key = key;
list.insertEntry(entry);
map[key] = entry;
}
return removed;
};
/**
* @param {string} key
* @return {}
*/
LRUProto.get = function (key) {
var entry = this._map[key];
var list = this._list;
if (entry != null) {
// Put the latest used entry in the tail
if (entry !== list.tail) {
list.remove(entry);
list.insertEntry(entry);
}
return entry.value;
}
};
/**
* Clear the cache
*/
LRUProto.clear = function () {
this._list.clear();
this._map = {};
};
var _default = LRU;
module.exports = _default;
/***/ }),
/* 54 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__TextureCube__ = __webpack_require__(24);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__core_request__ = __webpack_require__(112);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__prePass_EnvironmentMap__ = __webpack_require__(55);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__plugin_Skydome__ = __webpack_require__(56);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__Scene__ = __webpack_require__(32);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__dds__ = __webpack_require__(114);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__hdr__ = __webpack_require__(115);
/**
* @alias clay.util.texture
*/
var textureUtil = {
/**
* @param {string|object} path
* @param {object} [option]
* @param {Function} [onsuccess]
* @param {Function} [onerror]
* @return {clay.Texture}
*/
loadTexture: function (path, option, onsuccess, onerror) {
var texture;
if (typeof(option) === 'function') {
onsuccess = option;
onerror = onsuccess;
option = {};
}
else {
option = option || {};
}
if (typeof(path) === 'string') {
if (path.match(/.hdr$/) || option.fileType === 'hdr') {
texture = new __WEBPACK_IMPORTED_MODULE_0__Texture2D__["a" /* default */]({
width: 0,
height: 0,
sRGB: false
});
textureUtil._fetchTexture(
path,
function (data) {
__WEBPACK_IMPORTED_MODULE_7__hdr__["a" /* default */].parseRGBE(data, texture, option.exposure);
texture.dirty();
onsuccess && onsuccess(texture);
},
onerror
);
return texture;
}
else if (path.match(/.dds$/) || option.fileType === 'dds') {
texture = new __WEBPACK_IMPORTED_MODULE_0__Texture2D__["a" /* default */]({
width: 0,
height: 0
});
textureUtil._fetchTexture(
path,
function (data) {
__WEBPACK_IMPORTED_MODULE_6__dds__["a" /* default */].parse(data, texture);
texture.dirty();
onsuccess && onsuccess(texture);
},
onerror
);
}
else {
texture = new __WEBPACK_IMPORTED_MODULE_0__Texture2D__["a" /* default */]();
texture.load(path);
texture.success(onsuccess);
texture.error(onerror);
}
}
else if (typeof path === 'object' && typeof(path.px) !== 'undefined') {
texture = new __WEBPACK_IMPORTED_MODULE_1__TextureCube__["a" /* default */]();
texture.load(path);
texture.success(onsuccess);
texture.error(onerror);
}
return texture;
},
/**
* Load a panorama texture and render it to a cube map
* @param {clay.Renderer} renderer
* @param {string} path
* @param {clay.TextureCube} cubeMap
* @param {object} [option]
* @param {boolean} [option.encodeRGBM]
* @param {number} [option.exposure]
* @param {Function} [onsuccess]
* @param {Function} [onerror]
*/
loadPanorama: function (renderer, path, cubeMap, option, onsuccess, onerror) {
var self = this;
if (typeof(option) === 'function') {
onsuccess = option;
onerror = onsuccess;
option = {};
}
else {
option = option || {};
}
textureUtil.loadTexture(path, option, function (texture) {
// PENDING
texture.flipY = option.flipY || false;
self.panoramaToCubeMap(renderer, texture, cubeMap, option);
texture.dispose(renderer);
onsuccess && onsuccess(cubeMap);
}, onerror);
},
/**
* Render a panorama texture to a cube map
* @param {clay.Renderer} renderer
* @param {clay.Texture2D} panoramaMap
* @param {clay.TextureCube} cubeMap
* @param {Object} option
* @param {boolean} [option.encodeRGBM]
*/
panoramaToCubeMap: function (renderer, panoramaMap, cubeMap, option) {
var environmentMapPass = new __WEBPACK_IMPORTED_MODULE_3__prePass_EnvironmentMap__["a" /* default */]();
var skydome = new __WEBPACK_IMPORTED_MODULE_4__plugin_Skydome__["a" /* default */]({
scene: new __WEBPACK_IMPORTED_MODULE_5__Scene__["a" /* default */]()
});
skydome.setEnvironmentMap(panoramaMap);
option = option || {};
if (option.encodeRGBM) {
skydome.material.define('fragment', 'RGBM_ENCODE');
}
// Share sRGB
cubeMap.sRGB = panoramaMap.sRGB;
environmentMapPass.texture = cubeMap;
environmentMapPass.render(renderer, skydome.scene);
environmentMapPass.texture = null;
environmentMapPass.dispose(renderer);
return cubeMap;
},
/**
* Convert height map to normal map
* @param {HTMLImageElement|HTMLCanvasElement} image
* @param {boolean} [checkBump=false]
* @return {HTMLCanvasElement}
*/
heightToNormal: function (image, checkBump) {
var canvas = document.createElement('canvas');
var width = canvas.width = image.width;
var height = canvas.height = image.height;
var ctx = canvas.getContext('2d');
ctx.drawImage(image, 0, 0, width, height);
checkBump = checkBump || false;
var srcData = ctx.getImageData(0, 0, width, height);
var dstData = ctx.createImageData(width, height);
for (var i = 0; i < srcData.data.length; i += 4) {
if (checkBump) {
var r = srcData.data[i];
var g = srcData.data[i + 1];
var b = srcData.data[i + 2];
var diff = Math.abs(r - g) + Math.abs(g - b);
if (diff > 20) {
console.warn('Given image is not a height map');
return image;
}
}
// Modified from http://mrdoob.com/lab/javascript/height2normal/
var x1, y1, x2, y2;
if (i % (width * 4) === 0) {
// left edge
x1 = srcData.data[i];
x2 = srcData.data[i + 4];
}
else if (i % (width * 4) === (width - 1) * 4) {
// right edge
x1 = srcData.data[i - 4];
x2 = srcData.data[i];
}
else {
x1 = srcData.data[i - 4];
x2 = srcData.data[i + 4];
}
if (i < width * 4) {
// top edge
y1 = srcData.data[i];
y2 = srcData.data[i + width * 4];
}
else if (i > width * (height - 1) * 4) {
// bottom edge
y1 = srcData.data[i - width * 4];
y2 = srcData.data[i];
}
else {
y1 = srcData.data[i - width * 4];
y2 = srcData.data[i + width * 4];
}
dstData.data[i] = (x1 - x2) + 127;
dstData.data[i + 1] = (y1 - y2) + 127;
dstData.data[i + 2] = 255;
dstData.data[i + 3] = 255;
}
ctx.putImageData(dstData, 0, 0);
return canvas;
},
/**
* Convert height map to normal map
* @param {HTMLImageElement|HTMLCanvasElement} image
* @param {boolean} [checkBump=false]
* @param {number} [threshold=20]
* @return {HTMLCanvasElement}
*/
isHeightImage: function (img, downScaleSize, threshold) {
if (!img || !img.width || !img.height) {
return false;
}
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
var size = downScaleSize || 32;
threshold = threshold || 20;
canvas.width = canvas.height = size;
ctx.drawImage(img, 0, 0, size, size);
var srcData = ctx.getImageData(0, 0, size, size);
for (var i = 0; i < srcData.data.length; i += 4) {
var r = srcData.data[i];
var g = srcData.data[i + 1];
var b = srcData.data[i + 2];
var diff = Math.abs(r - g) + Math.abs(g - b);
if (diff > threshold) {
return false;
}
}
return true;
},
_fetchTexture: function (path, onsuccess, onerror) {
__WEBPACK_IMPORTED_MODULE_2__core_request__["a" /* default */].get({
url: path,
responseType: 'arraybuffer',
onload: onsuccess,
onerror: onerror
});
},
/**
* Create a chessboard texture
* @param {number} [size]
* @param {number} [unitSize]
* @param {string} [color1]
* @param {string} [color2]
* @return {clay.Texture2D}
*/
createChessboard: function (size, unitSize, color1, color2) {
size = size || 512;
unitSize = unitSize || 64;
color1 = color1 || 'black';
color2 = color2 || 'white';
var repeat = Math.ceil(size / unitSize);
var canvas = document.createElement('canvas');
canvas.width = size;
canvas.height = size;
var ctx = canvas.getContext('2d');
ctx.fillStyle = color2;
ctx.fillRect(0, 0, size, size);
ctx.fillStyle = color1;
for (var i = 0; i < repeat; i++) {
for (var j = 0; j < repeat; j++) {
var isFill = j % 2 ? (i % 2) : (i % 2 - 1);
if (isFill) {
ctx.fillRect(i * unitSize, j * unitSize, unitSize, unitSize);
}
}
}
var texture = new __WEBPACK_IMPORTED_MODULE_0__Texture2D__["a" /* default */]({
image: canvas,
anisotropic: 8
});
return texture;
},
/**
* Create a blank pure color 1x1 texture
* @param {string} color
* @return {clay.Texture2D}
*/
createBlank: function (color) {
var canvas = document.createElement('canvas');
canvas.width = 1;
canvas.height = 1;
var ctx = canvas.getContext('2d');
ctx.fillStyle = color;
ctx.fillRect(0, 0, 1, 1);
var texture = new __WEBPACK_IMPORTED_MODULE_0__Texture2D__["a" /* default */]({
image: canvas
});
return texture;
}
};
/* harmony default export */ __webpack_exports__["a"] = (textureUtil);
/***/ }),
/* 55 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_Base__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__math_Vector3__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__camera_Perspective__ = __webpack_require__(36);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__FrameBuffer__ = __webpack_require__(10);
var targets = ['px', 'nx', 'py', 'ny', 'pz', 'nz'];
/**
* Pass rendering scene to a environment cube map
*
* @constructor clay.prePass.EnvironmentMap
* @extends clay.core.Base
* @example
* // Example of car reflection
* var envMap = new clay.TextureCube({
* width: 256,
* height: 256
* });
* var envPass = new clay.prePass.EnvironmentMap({
* position: car.position,
* texture: envMap
* });
* var carBody = car.getChildByName('body');
* carBody.material.enableTexture('environmentMap');
* carBody.material.set('environmentMap', envMap);
* ...
* animation.on('frame', function(frameTime) {
* envPass.render(renderer, scene);
* renderer.render(scene, camera);
* });
*/
var EnvironmentMapPass = __WEBPACK_IMPORTED_MODULE_0__core_Base__["a" /* default */].extend(function() {
var ret = /** @lends clay.prePass.EnvironmentMap# */ {
/**
* Camera position
* @type {clay.Vector3}
* @memberOf clay.prePass.EnvironmentMap#
*/
position: new __WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */](),
/**
* Camera far plane
* @type {number}
* @memberOf clay.prePass.EnvironmentMap#
*/
far: 1000,
/**
* Camera near plane
* @type {number}
* @memberOf clay.prePass.EnvironmentMap#
*/
near: 0.1,
/**
* Environment cube map
* @type {clay.TextureCube}
* @memberOf clay.prePass.EnvironmentMap#
*/
texture: null,
/**
* Used if you wan't have shadow in environment map
* @type {clay.prePass.ShadowMap}
*/
shadowMapPass: null,
};
var cameras = ret._cameras = {
px: new __WEBPACK_IMPORTED_MODULE_2__camera_Perspective__["a" /* default */]({ fov: 90 }),
nx: new __WEBPACK_IMPORTED_MODULE_2__camera_Perspective__["a" /* default */]({ fov: 90 }),
py: new __WEBPACK_IMPORTED_MODULE_2__camera_Perspective__["a" /* default */]({ fov: 90 }),
ny: new __WEBPACK_IMPORTED_MODULE_2__camera_Perspective__["a" /* default */]({ fov: 90 }),
pz: new __WEBPACK_IMPORTED_MODULE_2__camera_Perspective__["a" /* default */]({ fov: 90 }),
nz: new __WEBPACK_IMPORTED_MODULE_2__camera_Perspective__["a" /* default */]({ fov: 90 })
};
cameras.px.lookAt(__WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */].POSITIVE_X, __WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */].NEGATIVE_Y);
cameras.nx.lookAt(__WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */].NEGATIVE_X, __WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */].NEGATIVE_Y);
cameras.py.lookAt(__WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */].POSITIVE_Y, __WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */].POSITIVE_Z);
cameras.ny.lookAt(__WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */].NEGATIVE_Y, __WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */].NEGATIVE_Z);
cameras.pz.lookAt(__WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */].POSITIVE_Z, __WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */].NEGATIVE_Y);
cameras.nz.lookAt(__WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */].NEGATIVE_Z, __WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */].NEGATIVE_Y);
// FIXME In windows, use one framebuffer only renders one side of cubemap
ret._frameBuffer = new __WEBPACK_IMPORTED_MODULE_3__FrameBuffer__["a" /* default */]();
return ret;
}, /** @lends clay.prePass.EnvironmentMap# */ {
/**
* @param {string} target
* @return {clay.Camera}
*/
getCamera: function (target) {
return this._cameras[target];
},
/**
* @param {clay.Renderer} renderer
* @param {clay.Scene} scene
* @param {boolean} [notUpdateScene=false]
*/
render: function(renderer, scene, notUpdateScene) {
var _gl = renderer.gl;
if (!notUpdateScene) {
scene.update();
}
// Tweak fov
// http://the-witness.net/news/2012/02/seamless-cube-map-filtering/
var n = this.texture.width;
var fov = 2 * Math.atan(n / (n - 0.5)) / Math.PI * 180;
for (var i = 0; i < 6; i++) {
var target = targets[i];
var camera = this._cameras[target];
__WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */].copy(camera.position, this.position);
camera.far = this.far;
camera.near = this.near;
camera.fov = fov;
if (this.shadowMapPass) {
camera.update();
// update boundingBoxLastFrame
var bbox = scene.getBoundingBox();
bbox.applyTransform(camera.viewMatrix);
scene.viewBoundingBoxLastFrame.copy(bbox);
this.shadowMapPass.render(renderer, scene, camera, true);
}
this._frameBuffer.attach(
this.texture, _gl.COLOR_ATTACHMENT0,
_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i
);
this._frameBuffer.bind(renderer);
renderer.render(scene, camera, true);
this._frameBuffer.unbind(renderer);
}
},
/**
* @param {clay.Renderer} renderer
*/
dispose: function (renderer) {
this._frameBuffer.dispose(renderer);
}
});
/* harmony default export */ __webpack_exports__["a"] = (EnvironmentMapPass);
/***/ }),
/* 56 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Mesh__ = __webpack_require__(31);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__geometry_Sphere__ = __webpack_require__(69);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__Material__ = __webpack_require__(17);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__shader_source_skydome_glsl_js__ = __webpack_require__(113);
__WEBPACK_IMPORTED_MODULE_2__Shader__["a" /* default */].import(__WEBPACK_IMPORTED_MODULE_4__shader_source_skydome_glsl_js__["a" /* default */]);
/**
* @constructor clay.plugin.Skydome
*
* @example
* var skyTex = new clay.Texture2D();
* skyTex.load('assets/textures/sky.jpg');
* var skydome = new clay.plugin.Skydome({
* scene: scene
* });
* skydome.material.set('diffuseMap', skyTex);
*/
var Skydome = __WEBPACK_IMPORTED_MODULE_0__Mesh__["a" /* default */].extend(function () {
var skydomeShader = new __WEBPACK_IMPORTED_MODULE_2__Shader__["a" /* default */](__WEBPACK_IMPORTED_MODULE_2__Shader__["a" /* default */].source('clay.skydome.vertex'), __WEBPACK_IMPORTED_MODULE_2__Shader__["a" /* default */].source('clay.skydome.fragment'));
var material = new __WEBPACK_IMPORTED_MODULE_3__Material__["a" /* default */]({
shader: skydomeShader,
depthMask: false
});
return {
/**
* @type {clay.Scene}
* @memberOf clay.plugin.Skydome#
*/
scene: null,
geometry: new __WEBPACK_IMPORTED_MODULE_1__geometry_Sphere__["a" /* default */]({
widthSegments: 30,
heightSegments: 30,
// thetaLength: Math.PI / 2
}),
material: material,
environmentMap: null,
culling: false
};
}, function () {
var scene = this.scene;
if (scene) {
this.attachScene(scene);
}
if (this.environmentMap) {
this.setEnvironmentMap(this.environmentMap);
}
}, {
/**
* Attach the skybox to the scene
* @param {clay.Scene} scene
* @memberOf clay.plugin.Skydome.prototype
*/
attachScene: function (scene) {
if (this.scene) {
this.detachScene();
}
scene.skydome = this;
this.scene = scene;
scene.on('beforerender', this._beforeRenderScene, this);
},
/**
* Detach from scene
* @memberOf clay.plugin.Skydome.prototype
*/
detachScene: function () {
if (this.scene) {
this.scene.off('beforerender', this._beforeRenderScene);
this.scene.skydome = null;
}
this.scene = null;
},
_beforeRenderScene: function (renderer, scene, camera) {
this.position.copy(camera.getWorldPosition());
this.update();
renderer.renderPass([this], camera);
},
setEnvironmentMap: function (envMap) {
this.material.set('environmentMap', envMap);
},
getEnvironmentMap: function () {
return this.material.get('environmentMap');
},
dispose: function (renderer) {
this.detachScene();
this.geometry.dispose(renderer);
}
});
/* harmony default export */ __webpack_exports__["a"] = (Skydome);
/***/ }),
/* 57 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Mesh__ = __webpack_require__(31);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__geometry_Cube__ = __webpack_require__(71);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__Material__ = __webpack_require__(17);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__shader_source_skybox_glsl_js__ = __webpack_require__(119);
// TODO Should not derived from mesh?
__WEBPACK_IMPORTED_MODULE_2__Shader__["a" /* default */].import(__WEBPACK_IMPORTED_MODULE_4__shader_source_skybox_glsl_js__["a" /* default */]);
/**
* @constructor clay.plugin.Skybox
*
* @example
* var skyTex = new clay.TextureCube();
* skyTex.load({
* 'px': 'assets/textures/sky/px.jpg',
* 'nx': 'assets/textures/sky/nx.jpg'
* 'py': 'assets/textures/sky/py.jpg'
* 'ny': 'assets/textures/sky/ny.jpg'
* 'pz': 'assets/textures/sky/pz.jpg'
* 'nz': 'assets/textures/sky/nz.jpg'
* });
* var skybox = new clay.plugin.Skybox({
* scene: scene
* });
* skybox.material.set('environmentMap', skyTex);
*/
var Skybox = __WEBPACK_IMPORTED_MODULE_0__Mesh__["a" /* default */].extend(function () {
var skyboxShader = new __WEBPACK_IMPORTED_MODULE_2__Shader__["a" /* default */]({
vertex: __WEBPACK_IMPORTED_MODULE_2__Shader__["a" /* default */].source('clay.skybox.vertex'),
fragment: __WEBPACK_IMPORTED_MODULE_2__Shader__["a" /* default */].source('clay.skybox.fragment')
});
var material = new __WEBPACK_IMPORTED_MODULE_3__Material__["a" /* default */]({
shader: skyboxShader,
depthMask: false
});
return {
/**
* @type {clay.Scene}
* @memberOf clay.plugin.Skybox.prototype
*/
scene: null,
geometry: new __WEBPACK_IMPORTED_MODULE_1__geometry_Cube__["a" /* default */](),
material: material,
environmentMap: null,
culling: false
};
}, function () {
var scene = this.scene;
if (scene) {
this.attachScene(scene);
}
if (this.environmentMap) {
this.setEnvironmentMap(this.environmentMap);
}
}, /** @lends clay.plugin.Skybox# */ {
/**
* Attach the skybox to the scene
* @param {clay.Scene} scene
*/
attachScene: function (scene) {
if (this.scene) {
this.detachScene();
}
scene.skybox = this;
this.scene = scene;
scene.on('beforerender', this._beforeRenderScene, this);
},
/**
* Detach from scene
*/
detachScene: function () {
if (this.scene) {
this.scene.off('beforerender', this._beforeRenderScene);
this.scene.skybox = null;
}
this.scene = null;
},
/**
* Dispose skybox
* @param {clay.Renderer} renderer
*/
dispose: function (renderer) {
this.detachScene();
this.geometry.dispose(renderer);
},
/**
* Set environment map
* @param {clay.TextureCube} envMap
*/
setEnvironmentMap: function (envMap) {
this.material.set('environmentMap', envMap);
},
/**
* Get environment map
* @return {clay.TextureCube}
*/
getEnvironmentMap: function () {
return this.material.get('environmentMap');
},
_beforeRenderScene: function(renderer, scene, camera) {
this.renderSkybox(renderer, camera);
},
renderSkybox: function (renderer, camera) {
this.position.copy(camera.getWorldPosition());
this.update();
// Don't remember to disable blend
renderer.gl.disable(renderer.gl.BLEND);
if (this.material.get('lod') > 0) {
this.material.define('fragment', 'LOD');
}
else {
this.material.undefine('fragment', 'LOD');
}
renderer.renderPass([this], camera);
}
});
/* harmony default export */ __webpack_exports__["a"] = (Skybox);
/***/ }),
/* 58 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__graphicGL__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__geometry_Sprites__ = __webpack_require__(156);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__shader_labels_glsl_js__ = __webpack_require__(157);
__WEBPACK_IMPORTED_MODULE_0__graphicGL__["a" /* default */].Shader.import(__WEBPACK_IMPORTED_MODULE_2__shader_labels_glsl_js__["a" /* default */]);
/* harmony default export */ __webpack_exports__["a"] = (__WEBPACK_IMPORTED_MODULE_0__graphicGL__["a" /* default */].Mesh.extend(function () {
var geometry = new __WEBPACK_IMPORTED_MODULE_1__geometry_Sprites__["a" /* default */]({
dynamic: true
});
var material = new __WEBPACK_IMPORTED_MODULE_0__graphicGL__["a" /* default */].Material({
shader: __WEBPACK_IMPORTED_MODULE_0__graphicGL__["a" /* default */].createShader('ecgl.labels'),
transparent: true,
depthMask: false
});
return {
geometry: geometry,
material: material,
culling: false,
castShadow: false,
ignorePicking: true
};
}));
/***/ }),
/* 59 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_earcut__ = __webpack_require__(196);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_geometry_Lines3D__ = __webpack_require__(22);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_retrieve__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_claygl_src_dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_claygl_src_dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_claygl_src_dep_glmatrix__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__util_geometry_trianglesSortMixin__ = __webpack_require__(60);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__LabelsBuilder__ = __webpack_require__(61);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__util_shader_lines3D_glsl_js__ = __webpack_require__(40);
var vec3 = __WEBPACK_IMPORTED_MODULE_5_claygl_src_dep_glmatrix___default.a.vec3;
__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.import(__WEBPACK_IMPORTED_MODULE_8__util_shader_lines3D_glsl_js__["a" /* default */]);
function Geo3DBuilder(api) {
this.rootNode = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();
// Cache triangulation result
this._triangulationResults = {};
this._shadersMap = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].COMMON_SHADERS.reduce(function (obj, shaderName) {
obj[shaderName] = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createShader('ecgl.' + shaderName);
return obj;
}, {});
this._linesShader = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createShader('ecgl.meshLines3D');
var groundMaterials = {};
__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].COMMON_SHADERS.forEach(function (shading) {
groundMaterials[shading] = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
shader: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createShader('ecgl.' + shading)
});
});
this._groundMaterials = groundMaterials;
this._groundMesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
geometry: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].PlaneGeometry({ dynamic: true }),
castShadow: false,
renderNormal: true,
$ignorePicking: true
});
this._groundMesh.rotation.rotateX(-Math.PI / 2);
this._labelsBuilder = new __WEBPACK_IMPORTED_MODULE_7__LabelsBuilder__["a" /* default */](512, 512, api);
// Give a large render order.
this._labelsBuilder.getMesh().renderOrder = 100;
this._labelsBuilder.getMesh().material.depthTest = false;
this.rootNode.add(this._labelsBuilder.getMesh());
this._initMeshes();
this._api = api;
}
Geo3DBuilder.prototype = {
constructor: Geo3DBuilder,
// Which dimension to extrude. Y or Z
extrudeY: true,
update: function (componentModel, ecModel, api, start, end) {
var data = componentModel.getData();
if (start == null) {
start = 0;
}
if (end == null) {
end = data.count();
}
this._startIndex = start;
this._endIndex = end - 1;
this._triangulation(componentModel, start, end);
var shader = this._getShader(componentModel.get('shading'));
this._prepareMesh(componentModel, shader, api, start, end);
this.rootNode.updateWorldTransform();
this._updateRegionMesh(componentModel, api, start, end);
var coordSys = componentModel.coordinateSystem;
// PENDING
if (coordSys.type === 'geo3D') {
this._updateGroundPlane(componentModel, coordSys, api);
}
var self = this;
this._labelsBuilder.updateData(data, start, end);
this._labelsBuilder.getLabelPosition = function (dataIndex, positionDesc, distance) {
var name = data.getName(dataIndex);
var center;
var height = distance;
if (coordSys.type === 'geo3D') {
var region = coordSys.getRegion(name);
if (!region) {
return [NaN, NaN, NaN];
}
center = region.center;
var pos = coordSys.dataToPoint([center[0], center[1], height]);
return pos;
}
else {
var tmp = self._triangulationResults[dataIndex - self._startIndex];
var center = self.extrudeY ? [
(tmp.max[0] + tmp.min[0]) / 2,
tmp.max[1] + height,
(tmp.max[2] + tmp.min[2]) / 2
] : [
(tmp.max[0] + tmp.min[0]) / 2,
(tmp.max[1] + tmp.min[1]) / 2,
tmp.max[2] + height
];
}
};
this._data = data;
this._labelsBuilder.updateLabels();
this._updateDebugWireframe(componentModel);
// Reset some state.
this._lastHoverDataIndex = 0;
},
_initMeshes: function () {
var self = this;
function createPolygonMesh() {
var mesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
name: 'Polygon',
material: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
shader: self._shadersMap.lambert
}),
geometry: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Geometry({
sortTriangles: true,
dynamic: true
}),
// TODO Disable culling
culling: false,
ignorePicking: true,
// Render normal in normal pass
renderNormal: true
});
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.extend(mesh.geometry, __WEBPACK_IMPORTED_MODULE_6__util_geometry_trianglesSortMixin__["a" /* default */]);
return mesh;
}
var polygonMesh = createPolygonMesh();
var linesMesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
material: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
shader: this._linesShader
}),
castShadow: false,
ignorePicking: true,
$ignorePicking: true,
geometry: new __WEBPACK_IMPORTED_MODULE_3__util_geometry_Lines3D__["a" /* default */]({
useNativeLine: false
})
});
this.rootNode.add(polygonMesh);
this.rootNode.add(linesMesh);
polygonMesh.material.define('both', 'VERTEX_COLOR');
polygonMesh.material.define('fragment', 'DOUBLE_SIDED');
this._polygonMesh = polygonMesh;
this._linesMesh = linesMesh;
this.rootNode.add(this._groundMesh);
},
_getShader: function (shading) {
var shader = this._shadersMap[shading];
if (!shader) {
if (true) {
console.warn('Unkown shading ' + shading);
}
// Default use lambert shader.
shader = this._shadersMap.lambert;
}
shader.__shading = shading;
return shader;
},
_prepareMesh: function (componentModel, shader, api, start, end) {
var polygonVertexCount = 0;
var polygonTriangleCount = 0;
var linesVertexCount = 0;
var linesTriangleCount = 0;
// TODO Lines
for (var idx = start; idx < end; idx++) {
var polyInfo = this._getRegionPolygonInfo(idx);
var lineInfo = this._getRegionLinesInfo(idx, componentModel, this._linesMesh.geometry);
polygonVertexCount += polyInfo.vertexCount;
polygonTriangleCount += polyInfo.triangleCount;
linesVertexCount += lineInfo.vertexCount;
linesTriangleCount += lineInfo.triangleCount;
}
var polygonMesh = this._polygonMesh;
var polygonGeo = polygonMesh.geometry;
['position', 'normal', 'texcoord0', 'color'].forEach(function (attrName) {
polygonGeo.attributes[attrName].init(polygonVertexCount);
});
polygonGeo.indices = polygonVertexCount > 0xffff ? new Uint32Array(polygonTriangleCount * 3) : new Uint16Array(polygonTriangleCount * 3);
if (polygonMesh.material.shader !== shader) {
polygonMesh.material.attachShader(shader, true);
}
__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].setMaterialFromModel(shader.__shading, polygonMesh.material, componentModel, api);
if (linesVertexCount > 0) {
this._linesMesh.geometry.resetOffset();
this._linesMesh.geometry.setVertexCount(linesVertexCount);
this._linesMesh.geometry.setTriangleCount(linesTriangleCount);
}
// Indexing data index from vertex index.
this._dataIndexOfVertex = new Uint32Array(polygonVertexCount);
// Indexing vertex index range from data index
this._vertexRangeOfDataIndex = new Uint32Array((end - start) * 2);
},
_updateRegionMesh: function (componentModel, api, start, end) {
var data = componentModel.getData();
var vertexOffset = 0;
var triangleOffset = 0;
// Materials configurations.
var hasTranparentRegion = false;
var polygonMesh = this._polygonMesh;
var linesMesh = this._linesMesh;
for (var dataIndex = start; dataIndex < end; dataIndex++) {
// Get bunch of visual properties.
var regionModel = componentModel.getRegionModel(dataIndex);
var itemStyleModel = regionModel.getModel('itemStyle');
var color = itemStyleModel.get('color');
var opacity = __WEBPACK_IMPORTED_MODULE_4__util_retrieve__["a" /* default */].firstNotNull(itemStyleModel.get('opacity'), 1.0);
// Use visual color if it is encoded by visualMap component
var visualColor = data.getItemVisual(dataIndex, 'color', true);
if (visualColor != null && data.hasValue(dataIndex)) {
color = visualColor;
}
// Set color, opacity to visual for label usage.
data.setItemVisual(dataIndex, 'color', color);
data.setItemVisual(dataIndex, 'opacity', opacity);
color = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(color);
var borderColor = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(itemStyleModel.get('borderColor'));
color[3] *= opacity;
borderColor[3] *= opacity;
var isTransparent = color[3] < 0.99;
polygonMesh.material.set('color', [1,1,1,1]);
hasTranparentRegion = hasTranparentRegion || isTransparent;
var regionHeight = __WEBPACK_IMPORTED_MODULE_4__util_retrieve__["a" /* default */].firstNotNull(regionModel.get('height', true), componentModel.get('regionHeight'));
var newOffsets = this._updatePolygonGeometry(
componentModel, polygonMesh.geometry, dataIndex, regionHeight,
vertexOffset, triangleOffset, color
);
for (var i = vertexOffset; i < newOffsets.vertexOffset; i++) {
this._dataIndexOfVertex[i] = dataIndex;
}
this._vertexRangeOfDataIndex[(dataIndex - start) * 2] = vertexOffset;
this._vertexRangeOfDataIndex[(dataIndex - start) * 2 + 1] = newOffsets.vertexOffset;
vertexOffset = newOffsets.vertexOffset;
triangleOffset = newOffsets.triangleOffset;
// Update lines.
var lineWidth = itemStyleModel.get('borderWidth');
var hasLine = lineWidth > 0;
if (hasLine) {
lineWidth *= api.getDevicePixelRatio();
this._updateLinesGeometry(
linesMesh.geometry, componentModel, dataIndex, regionHeight, lineWidth,
componentModel.coordinateSystem.transform
);
}
linesMesh.invisible = !hasLine;
linesMesh.material.set({
color: borderColor
});
}
var polygonMesh = this._polygonMesh;
polygonMesh.material.transparent = hasTranparentRegion;
polygonMesh.material.depthMask = !hasTranparentRegion;
polygonMesh.geometry.updateBoundingBox();
polygonMesh.frontFace = this.extrudeY ? __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh.CCW : __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh.CW;
// Update tangents
if (polygonMesh.material.get('normalMap')) {
polygonMesh.geometry.generateTangents();
}
polygonMesh.seriesIndex = componentModel.seriesIndex;
polygonMesh.on('mousemove', this._onmousemove, this);
polygonMesh.on('mouseout', this._onmouseout, this);
},
_updateDebugWireframe: function (componentModel) {
var debugWireframeModel = componentModel.getModel('debug.wireframe');
// TODO Unshow
if (debugWireframeModel.get('show')) {
var color = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(
debugWireframeModel.get('lineStyle.color') || 'rgba(0,0,0,0.5)'
);
var width = __WEBPACK_IMPORTED_MODULE_4__util_retrieve__["a" /* default */].firstNotNull(
debugWireframeModel.get('lineStyle.width'), 1
);
// TODO Will cause highlight wrong
var mesh = this._polygonMesh;
mesh.geometry.generateBarycentric();
mesh.material.define('both', 'WIREFRAME_TRIANGLE');
mesh.material.set('wireframeLineColor', color);
mesh.material.set('wireframeLineWidth', width);
}
},
_onmousemove: function (e) {
var dataIndex = this._dataIndexOfVertex[e.triangle[0]];
if (dataIndex == null) {
dataIndex = -1;
}
if (dataIndex !== this._lastHoverDataIndex) {
this.downplay(this._lastHoverDataIndex);
this.highlight(dataIndex);
this._labelsBuilder.updateLabels([dataIndex]);
}
this._lastHoverDataIndex = dataIndex;
this._polygonMesh.dataIndex = dataIndex;
},
_onmouseout: function (e) {
if (e.target) {
this.downplay(this._lastHoverDataIndex);
this._lastHoverDataIndex = -1;
this._polygonMesh.dataIndex = -1;
}
this._labelsBuilder.updateLabels([]);
},
_updateGroundPlane: function (componentModel, geo3D, api) {
var groundModel = componentModel.getModel('groundPlane', componentModel);
this._groundMesh.invisible = !groundModel.get('show', true);
if (this._groundMesh.invisible) {
return;
}
var shading = componentModel.get('shading');
var material = this._groundMaterials[shading];
if (!material) {
if (true) {
console.warn('Unkown shading ' + shading);
}
material = this._groundMaterials.lambert;
}
__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].setMaterialFromModel(shading, material, groundModel, api);
if (material.get('normalMap')) {
this._groundMesh.geometry.generateTangents();
}
this._groundMesh.material = material;
this._groundMesh.material.set('color', __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(groundModel.get('color')));
this._groundMesh.scale.set(geo3D.size[0], geo3D.size[2], 1);
},
_triangulation: function (componentModel, start, end) {
this._triangulationResults = [];
var minAll = [Infinity, Infinity, Infinity];
var maxAll = [-Infinity, -Infinity, -Infinity];
var coordSys = componentModel.coordinateSystem;
for (var idx = start; idx < end; idx++) {
var polygons = [];
var polygonCoords = componentModel.getRegionPolygonCoords(idx);
for (var i = 0; i < polygonCoords.length; i++) {
var exterior = polygonCoords[i].exterior;
var interiors = polygonCoords[i].interiors;
var points = [];
var holes = [];
if (exterior.length < 3) {
continue;
}
var offset = 0;
for (var j = 0; j < exterior.length; j++) {
var p = exterior[j];
points[offset++] = p[0];
points[offset++] = p[1];
}
for (var j = 0; j < interiors.length; j++) {
if (interiors[j].length < 3) {
continue;
}
var startIdx = points.length / 2;
for (var k = 0; k < interiors[j].length; k++) {
var p = interiors[j][k];
points.push(p[0]);
points.push(p[1]);
}
holes.push(startIdx);
}
var triangles = Object(__WEBPACK_IMPORTED_MODULE_2__util_earcut__["a" /* default */])(points, holes);
var points3 = new Float64Array(points.length / 2 * 3);
var pos = [];
var min = [Infinity, Infinity, Infinity];
var max = [-Infinity, -Infinity, -Infinity];
var off3 = 0;
for (var j = 0; j < points.length;) {
vec3.set(pos, points[j++], 0, points[j++]);
if (coordSys && coordSys.transform) {
vec3.transformMat4(pos, pos, coordSys.transform);
}
vec3.min(min, min, pos);
vec3.max(max, max, pos);
points3[off3++] = pos[0];
points3[off3++] = pos[1];
points3[off3++] = pos[2];
}
vec3.min(minAll, minAll, min);
vec3.max(maxAll, maxAll, max);
polygons.push({
points: points3,
indices: triangles,
min: min,
max: max
});
}
this._triangulationResults.push(polygons);
}
this._geoBoundingBox = [minAll, maxAll];
},
/**
* Get region vertex and triangle count
*/
_getRegionPolygonInfo: function (idx) {
var polygons = this._triangulationResults[idx - this._startIndex];
var sideVertexCount = 0;
var sideTriangleCount = 0;
for (var i = 0; i < polygons.length; i++) {
sideVertexCount += polygons[i].points.length / 3;
sideTriangleCount += polygons[i].indices.length / 3;
}
var vertexCount = sideVertexCount * 2 + sideVertexCount * 4;
var triangleCount = sideTriangleCount * 2 + sideVertexCount * 2;
return {
vertexCount: vertexCount,
triangleCount: triangleCount
};
},
_updatePolygonGeometry: function (
componentModel, geometry, dataIndex, regionHeight,
vertexOffset, triangleOffset, color
) {
// FIXME
var projectUVOnGround = componentModel.get('projectUVOnGround');
var positionAttr = geometry.attributes.position;
var normalAttr = geometry.attributes.normal;
var texcoordAttr = geometry.attributes.texcoord0;
var colorAttr = geometry.attributes.color;
var polygons = this._triangulationResults[dataIndex - this._startIndex];
var hasColor = colorAttr.value && color;
var indices = geometry.indices;
var extrudeCoordIndex = this.extrudeY ? 1 : 2;
var sideCoordIndex = this.extrudeY ? 2 : 1;
var scale = [
this.rootNode.worldTransform.x.len(),
this.rootNode.worldTransform.y.len(),
this.rootNode.worldTransform.z.len()
];
var min = vec3.mul([], this._geoBoundingBox[0], scale);
var max = vec3.mul([], this._geoBoundingBox[1], scale);
var maxDimSize = Math.max(max[0] - min[0], max[2] - min[2]);
function addVertices(polygon, y, insideOffset) {
var points = polygon.points;
var pointsLen = points.length;
var currentPosition = [];
var uv = [];
for (var k = 0; k < pointsLen; k += 3) {
currentPosition[0] = points[k];
currentPosition[extrudeCoordIndex] = y;
currentPosition[sideCoordIndex] = points[k + 2];
uv[0] = (points[k] * scale[0] - min[0]) / maxDimSize;
uv[1] = (points[k + 2] * scale[sideCoordIndex] - min[2]) / maxDimSize;
positionAttr.set(vertexOffset, currentPosition);
if (hasColor) {
colorAttr.set(vertexOffset, color);
}
texcoordAttr.set(vertexOffset++, uv);
}
}
function buildTopBottom(polygon, y, insideOffset) {
var startVertexOffset = vertexOffset;
addVertices(polygon, y, insideOffset);
var len = polygon.indices.length;
for (var k = 0; k < len; k++) {
indices[triangleOffset * 3 + k] = polygon.indices[k] + startVertexOffset;
}
triangleOffset += polygon.indices.length / 3;
}
var normalTop = this.extrudeY ? [0, 1, 0] : [0, 0, 1];
var normalBottom = vec3.negate([], normalTop);
for (var p = 0; p < polygons.length; p++) {
var startVertexOffset = vertexOffset;
var polygon = polygons[p];
// BOTTOM
buildTopBottom(polygon, 0, 0);
// TOP
buildTopBottom(polygon, regionHeight, 0);
var ringVertexCount = polygon.points.length / 3;
for (var v = 0; v < ringVertexCount; v++) {
normalAttr.set(startVertexOffset + v, normalBottom);
normalAttr.set(startVertexOffset + v + ringVertexCount, normalTop);
}
var quadToTriangle = [0, 3, 1, 1, 3, 2];
var quadPos = [[], [], [], []];
var a = [];
var b = [];
var normal = [];
var uv = [];
var len = 0;
for (var v = 0; v < ringVertexCount; v++) {
var next = (v + 1) % ringVertexCount;
var dx = (polygon.points[next * 3] - polygon.points[v * 3]) * scale[0];
var dy = (polygon.points[next * 3 + 2] - polygon.points[v * 3 + 2]) * scale[sideCoordIndex];
var sideLen = Math.sqrt(dx * dx + dy * dy);
// 0----1
// 3----2
for (var k = 0; k < 4; k++) {
var isCurrent = (k === 0 || k === 3);
var idx3 = (isCurrent ? v : next) * 3;
quadPos[k][0] = polygon.points[idx3];
quadPos[k][extrudeCoordIndex] = k > 1 ? regionHeight : 0;
quadPos[k][sideCoordIndex] = polygon.points[idx3 + 2];
positionAttr.set(vertexOffset + k, quadPos[k]);
if (projectUVOnGround) {
uv[0] = (polygon.points[idx3] * scale[0] - min[0]) / maxDimSize;
uv[1] = (polygon.points[idx3 + 2] * scale[sideCoordIndex] - min[sideCoordIndex]) / maxDimSize;
}
else {
uv[0] = (isCurrent ? len : (len + sideLen)) / maxDimSize;
uv[1] = (quadPos[k][extrudeCoordIndex] * scale[extrudeCoordIndex] - min[extrudeCoordIndex]) / maxDimSize;
}
texcoordAttr.set(vertexOffset + k, uv);
}
vec3.sub(a, quadPos[1], quadPos[0]);
vec3.sub(b, quadPos[3], quadPos[0]);
vec3.cross(normal, a, b);
vec3.normalize(normal, normal);
for (var k = 0; k < 4; k++) {
normalAttr.set(vertexOffset + k, normal);
if (hasColor) {
colorAttr.set(vertexOffset + k, color);
}
}
for (var k = 0; k < 6; k++) {
indices[triangleOffset * 3 + k] = quadToTriangle[k] + vertexOffset;
}
vertexOffset += 4;
triangleOffset += 2;
len += sideLen;
}
}
geometry.dirty();
return {
vertexOffset: vertexOffset,
triangleOffset: triangleOffset
};
},
_getRegionLinesInfo: function (idx, componentModel, geometry) {
var vertexCount = 0;
var triangleCount = 0;
var regionModel = componentModel.getRegionModel(idx);
var itemStyleModel = regionModel.getModel('itemStyle');
var lineWidth = itemStyleModel.get('borderWidth');
if (lineWidth > 0) {
var polygonCoords = componentModel.getRegionPolygonCoords(idx);
polygonCoords.forEach(function (coords) {
var exterior = coords.exterior;
var interiors = coords.interiors;
vertexCount += geometry.getPolylineVertexCount(exterior);
triangleCount += geometry.getPolylineTriangleCount(exterior);
for (var i = 0; i < interiors.length; i++) {
vertexCount += geometry.getPolylineVertexCount(interiors[i]);
triangleCount += geometry.getPolylineTriangleCount(interiors[i]);
}
}, this);
}
return {
vertexCount: vertexCount,
triangleCount: triangleCount
};
},
_updateLinesGeometry: function (geometry, componentModel, dataIndex, regionHeight, lineWidth, transform) {
function convertToPoints3(polygon) {
var points = new Float64Array(polygon.length * 3);
var offset = 0;
var pos = [];
for (var i = 0; i < polygon.length; i++) {
pos[0] = polygon[i][0];
// Add a offset to avoid z-fighting
pos[1] = regionHeight + 0.1;
pos[2] = polygon[i][1];
if (transform) {
vec3.transformMat4(pos, pos, transform);
}
points[offset++] = pos[0];
points[offset++] = pos[1];
points[offset++] = pos[2];
}
return points;
}
var whiteColor = [1, 1, 1, 1];
var coords = componentModel.getRegionPolygonCoords(dataIndex);
coords.forEach(function (geo) {
var exterior = geo.exterior;
var interiors = geo.interiors;
geometry.addPolyline(convertToPoints3(exterior), whiteColor, lineWidth);
for (var i = 0; i < interiors.length; i++) {
geometry.addPolyline(convertToPoints3(interiors[i]), whiteColor, lineWidth);
}
});
},
highlight: function (dataIndex) {
var data = this._data;
if (!data) {
return;
}
var itemModel = data.getItemModel(dataIndex);
var emphasisItemStyleModel = itemModel.getModel('emphasis.itemStyle');
var emphasisColor = emphasisItemStyleModel.get('color');
var emphasisOpacity = __WEBPACK_IMPORTED_MODULE_4__util_retrieve__["a" /* default */].firstNotNull(
emphasisItemStyleModel.get('opacity'),
data.getItemVisual(dataIndex, 'opacity'),
1
);
if (emphasisColor == null) {
var color = data.getItemVisual(dataIndex, 'color');
emphasisColor = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.color.lift(color, -0.4);
}
if (emphasisOpacity == null) {
emphasisOpacity = data.getItemVisual(dataIndex, 'opacity');
}
var colorArr = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(emphasisColor);
colorArr[3] *= emphasisOpacity;
this._setColorOfDataIndex(data, dataIndex, colorArr);
},
downplay: function (dataIndex) {
var data = this._data;
if (!data) {
return;
}
var color = data.getItemVisual(dataIndex, 'color');
var opacity = __WEBPACK_IMPORTED_MODULE_4__util_retrieve__["a" /* default */].firstNotNull(data.getItemVisual(dataIndex, 'opacity'), 1);
var colorArr = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(color);
colorArr[3] *= opacity;
this._setColorOfDataIndex(data, dataIndex, colorArr);
},
_setColorOfDataIndex: function (data, dataIndex, colorArr) {
if (dataIndex < this._startIndex && dataIndex > this._endIndex) {
return;
}
dataIndex -= this._startIndex;
for (var i = this._vertexRangeOfDataIndex[dataIndex * 2]; i < this._vertexRangeOfDataIndex[dataIndex * 2 + 1]; i++) {
this._polygonMesh.geometry.attributes.color.set(i, colorArr);
}
this._polygonMesh.geometry.dirty();
this._api.getZr().refresh();
}
};
/* harmony default export */ __webpack_exports__["a"] = (Geo3DBuilder);
/***/ }),
/* 60 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__ProgressiveQuickSort__ = __webpack_require__(90);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix__);
var vec3 = __WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix___default.a.vec3;
var p0 = vec3.create();
var p1 = vec3.create();
var p2 = vec3.create();
// var cp = vec3.create();
/* harmony default export */ __webpack_exports__["a"] = ({
needsSortTriangles: function () {
return this.indices && this.sortTriangles;
},
needsSortTrianglesProgressively: function () {
return this.needsSortTriangles() && this.triangleCount >= 2e4;
},
doSortTriangles: function (cameraPos, frame) {
var indices = this.indices;
// Do progressive quick sort.
if (frame === 0) {
var posAttr = this.attributes.position;
var cameraPos = cameraPos.array;
if (!this._triangleZList || this._triangleZList.length !== this.triangleCount) {
this._triangleZList = new Float32Array(this.triangleCount);
this._sortedTriangleIndices = new Uint32Array(this.triangleCount);
this._indicesTmp = new indices.constructor(indices.length);
this._triangleZListTmp = new Float32Array(this.triangleCount);
}
var cursor = 0;
var firstZ;
for (var i = 0; i < indices.length;) {
posAttr.get(indices[i++], p0);
posAttr.get(indices[i++], p1);
posAttr.get(indices[i++], p2);
// FIXME If use center ?
// cp[0] = (p0[0] + p1[0] + p2[0]) / 3;
// cp[1] = (p0[1] + p1[1] + p2[1]) / 3;
// cp[2] = (p0[2] + p1[2] + p2[2]) / 3;
// Camera position is in object space
// Use max of three points, PENDING
var z0 = vec3.sqrDist(p0, cameraPos);
var z1 = vec3.sqrDist(p1, cameraPos);
var z2 = vec3.sqrDist(p2, cameraPos);
var zMax = Math.min(z0, z1);
zMax = Math.min(zMax, z2);
if (i === 3) {
firstZ = zMax;
zMax = 0;
}
else {
// Only store the difference to avoid the precision issue.
zMax = zMax - firstZ;
}
this._triangleZList[cursor++] = zMax;
}
}
var sortedTriangleIndices = this._sortedTriangleIndices;
for (var i = 0; i < sortedTriangleIndices.length; i++) {
sortedTriangleIndices[i] = i;
}
if (this.triangleCount < 2e4) {
// Use simple timsort for simple geometries.
if (frame === 0) {
// Use native sort temporary.
this._simpleSort(true);
}
}
else {
for (var i = 0; i < 3; i++) {
this._progressiveQuickSort(frame * 3 + i);
}
}
var targetIndices = this._indicesTmp;
var targetTriangleZList = this._triangleZListTmp;
var faceZList = this._triangleZList;
for (var i = 0; i < this.triangleCount; i++) {
var fromIdx3 = sortedTriangleIndices[i] * 3;
var toIdx3 = i * 3;
targetIndices[toIdx3++] = indices[fromIdx3++];
targetIndices[toIdx3++] = indices[fromIdx3++];
targetIndices[toIdx3] = indices[fromIdx3];
targetTriangleZList[i] = faceZList[sortedTriangleIndices[i]];
}
// Swap indices.
var tmp = this._indicesTmp;
this._indicesTmp = this.indices;
this.indices = tmp;
var tmp = this._triangleZListTmp;
this._triangleZListTmp = this._triangleZList;
this._triangleZList = tmp;
this.dirtyIndices();
},
_simpleSort: function (useNativeQuickSort) {
var faceZList = this._triangleZList;
var sortedTriangleIndices = this._sortedTriangleIndices;
function compare(a, b) {
// Sort from far to near. which is descending order
return faceZList[b] - faceZList[a];
}
if (useNativeQuickSort) {
Array.prototype.sort.call(sortedTriangleIndices, compare);
}
else {
__WEBPACK_IMPORTED_MODULE_0__ProgressiveQuickSort__["a" /* default */].sort(sortedTriangleIndices, compare, 0, sortedTriangleIndices.length - 1);
}
},
_progressiveQuickSort: function (frame) {
var faceZList = this._triangleZList;
var sortedTriangleIndices = this._sortedTriangleIndices;
this._quickSort = this._quickSort || new __WEBPACK_IMPORTED_MODULE_0__ProgressiveQuickSort__["a" /* default */]();
this._quickSort.step(sortedTriangleIndices, function (a, b) {
return faceZList[b] - faceZList[a];
}, frame);
}
});
/***/ }),
/* 61 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_ZRTextureAtlasSurface__ = __webpack_require__(73);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_mesh_LabelsMesh__ = __webpack_require__(58);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_retrieve__ = __webpack_require__(3);
var LABEL_NORMAL_SHOW_BIT = 1;
var LABEL_EMPHASIS_SHOW_BIT = 2;
function LabelsBuilder(width, height, api) {
this._labelsMesh = new __WEBPACK_IMPORTED_MODULE_2__util_mesh_LabelsMesh__["a" /* default */]();
this._labelTextureSurface = new __WEBPACK_IMPORTED_MODULE_1__util_ZRTextureAtlasSurface__["a" /* default */]({
width: 512,
height: 512,
devicePixelRatio: api.getDevicePixelRatio(),
onupdate: function () {
api.getZr().refresh();
}
});
this._api = api;
this._labelsMesh.material.set('textureAtlas', this._labelTextureSurface.getTexture());
}
LabelsBuilder.prototype.getLabelPosition = function (dataIndex, positionDesc, distance) {
return [0, 0, 0];
};
LabelsBuilder.prototype.getLabelDistance = function (dataIndex, positionDesc, distance) {
return 0;
};
LabelsBuilder.prototype.getMesh = function () {
return this._labelsMesh;
};
LabelsBuilder.prototype.updateData = function (data, start, end) {
if (start == null) {
start = 0;
}
if (end == null) {
end = data.count();
}
if (!this._labelsVisibilitiesBits || this._labelsVisibilitiesBits.length !== (end - start)) {
this._labelsVisibilitiesBits = new Uint8Array(end - start);
}
var normalLabelVisibilityQuery = ['label', 'show'];
var emphasisLabelVisibilityQuery = ['emphasis', 'label', 'show'];
for (var idx = start; idx < end; idx++) {
var itemModel = data.getItemModel(idx);
var normalVisibility = itemModel.get(normalLabelVisibilityQuery);
var emphasisVisibility = itemModel.get(emphasisLabelVisibilityQuery);
if (emphasisVisibility == null) {
emphasisVisibility = normalVisibility;
}
var bit = (normalVisibility ? LABEL_NORMAL_SHOW_BIT : 0)
| (emphasisVisibility ? LABEL_EMPHASIS_SHOW_BIT : 0);
this._labelsVisibilitiesBits[idx - start] = bit;
}
this._start = start;
this._end = end;
this._data = data;
};
LabelsBuilder.prototype.updateLabels = function (highlightDataIndices) {
if (!this._data) {
return;
}
highlightDataIndices = highlightDataIndices || [];
var hasHighlightData = highlightDataIndices.length > 0;
var highlightDataIndicesMap = {};
for (var i = 0; i < highlightDataIndices.length; i++) {
highlightDataIndicesMap[highlightDataIndices[i]] = true;
}
this._labelsMesh.geometry.convertToDynamicArray(true);
this._labelTextureSurface.clear();
var normalLabelQuery = ['label'];
var emphasisLabelQuery = ['emphasis', 'label'];
var seriesModel = this._data.hostModel;
var data = this._data;
var seriesLabelModel = seriesModel.getModel(normalLabelQuery);
var seriesLabelEmphasisModel = seriesModel.getModel(emphasisLabelQuery, seriesLabelModel);
var textAlignMap = {
left: 'right',
right: 'left',
top: 'center',
bottom: 'center'
};
var textVerticalAlignMap = {
left: 'middle',
right: 'middle',
top: 'bottom',
bottom: 'top'
};
for (var dataIndex = this._start; dataIndex < this._end; dataIndex++) {
var isEmphasis = false;
if (hasHighlightData && highlightDataIndicesMap[dataIndex]) {
isEmphasis = true;
}
var ifShow = this._labelsVisibilitiesBits[dataIndex - this._start]
& (isEmphasis ? LABEL_EMPHASIS_SHOW_BIT : LABEL_NORMAL_SHOW_BIT);
if (!ifShow) {
continue;
}
var itemModel = data.getItemModel(dataIndex);
var labelModel = itemModel.getModel(
isEmphasis ? emphasisLabelQuery : normalLabelQuery,
isEmphasis ? seriesLabelEmphasisModel : seriesLabelModel
);
var distance = labelModel.get('distance') || 0;
var position = labelModel.get('position');
var textStyleModel = labelModel.getModel('textStyle');
var dpr = this._api.getDevicePixelRatio();
var text = seriesModel.getFormattedLabel(dataIndex, isEmphasis ? 'emphasis' : 'normal');
if (text == null || text === '') {
return;
}
// TODO Background.
var textEl = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.graphic.Text();
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.graphic.setTextStyle(textEl.style, textStyleModel, {
text: text,
textFill: textStyleModel.get('color') || data.getItemVisual(dataIndex, 'color') || '#000',
textAlign: 'left',
textVerticalAlign: 'top',
opacity: __WEBPACK_IMPORTED_MODULE_3__util_retrieve__["a" /* default */].firstNotNull(textStyleModel.get('opacity'), data.getItemVisual(dataIndex, 'opacity'), 1)
});
var rect = textEl.getBoundingRect();
var lineHeight = 1.2;
rect.height *= lineHeight;
var coords = this._labelTextureSurface.add(textEl);
var textAlign = textAlignMap[position] || 'center';
var textVerticalAlign = textVerticalAlignMap[position] || 'bottom';
this._labelsMesh.geometry.addSprite(
this.getLabelPosition(dataIndex, position, distance),
[rect.width * dpr, rect.height * dpr], coords,
textAlign, textVerticalAlign,
this.getLabelDistance(dataIndex, position, distance) * dpr
);
}
this._labelsMesh.material.set('uvScale', this._labelTextureSurface.getCoordsScale());
// var canvas = this._labelTextureSurface.getTexture().image;
// document.body.appendChild(canvas);
// canvas.style.cssText = 'position:absolute;z-index: 1000';
// Update image.
this._labelTextureSurface.getZr().refreshImmediately();
this._labelsMesh.geometry.convertToTypedArray();
this._labelsMesh.geometry.dirty();
};
/* harmony default export */ __webpack_exports__["a"] = (LabelsBuilder);
/***/ }),
/* 62 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_sprite__ = __webpack_require__(231);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__PointsMesh__ = __webpack_require__(232);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__component_common_LabelsBuilder__ = __webpack_require__(61);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_claygl_src_math_Matrix4__ = __webpack_require__(7);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__util_retrieve__ = __webpack_require__(3);
var SDF_RANGE = 20;
var Z_2D = -10;
function isSymbolSizeSame(a, b) {
return a && b && a[0] === b[0] && a[1] === b[1];
}
// TODO gl_PointSize has max value.
function PointsBuilder(is2D, api) {
this.rootNode = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();
/**
* @type {boolean}
*/
this.is2D = is2D;
this._labelsBuilder = new __WEBPACK_IMPORTED_MODULE_4__component_common_LabelsBuilder__["a" /* default */](256, 256, api);
// Give a large render order.
this._labelsBuilder.getMesh().renderOrder = 100;
this.rootNode.add(this._labelsBuilder.getMesh());
this._api = api;
this._spriteImageCanvas = document.createElement('canvas');
this._startDataIndex = 0;
this._endDataIndex = 0;
this._sizeScale = 1;
}
PointsBuilder.prototype = {
constructor: PointsBuilder,
/**
* If highlight on over
*/
highlightOnMouseover: true,
update: function (seriesModel, ecModel, api, start, end) {
// Swap barMesh
var tmp = this._prevMesh;
this._prevMesh = this._mesh;
this._mesh = tmp;
var data = seriesModel.getData();
if (start == null) {
start = 0;
}
if (end == null) {
end = data.count();
}
this._startDataIndex = start;
this._endDataIndex = end - 1;
if (!this._mesh) {
var material = this._prevMesh && this._prevMesh.material;
this._mesh = new __WEBPACK_IMPORTED_MODULE_3__PointsMesh__["a" /* default */]({
// Render after axes
renderOrder: 10,
// FIXME
frustumCulling: false
});
if (material) {
this._mesh.material = material;
}
}
var material = this._mesh.material;
var geometry = this._mesh.geometry;
var attributes = geometry.attributes;
this.rootNode.remove(this._prevMesh);
this.rootNode.add(this._mesh);
this._setPositionTextureToMesh(this._mesh, this._positionTexture);
var symbolInfo = this._getSymbolInfo(seriesModel, start, end);
var dpr = api.getDevicePixelRatio();
// TODO image symbol
var itemStyle = seriesModel.getModel('itemStyle').getItemStyle();
var largeMode = seriesModel.get('large');
var pointSizeScale = 1;
if (symbolInfo.maxSize > 2) {
pointSizeScale = this._updateSymbolSprite(seriesModel, itemStyle, symbolInfo, dpr);
material.enableTexture('sprite');
}
else {
material.disableTexture('sprite');
}
attributes.position.init(end - start);
var rgbaArr = [];
if (largeMode) {
material.undefine('VERTEX_SIZE');
material.undefine('VERTEX_COLOR');
var color = data.getVisual('color');
var opacity = data.getVisual('opacity');
__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(color, rgbaArr);
rgbaArr[3] *= opacity;
material.set({
color: rgbaArr,
'u_Size': symbolInfo.maxSize * this._sizeScale
});
}
else {
material.set({
color: [1, 1, 1, 1]
});
material.define('VERTEX_SIZE');
material.define('VERTEX_COLOR');
attributes.size.init(end - start);
attributes.color.init(end - start);
this._originalOpacity = new Float32Array(end - start);
}
var points = data.getLayout('points');
var positionArr = attributes.position.value;
var hasTransparentPoint = false;
for (var i = 0; i < end - start; i++) {
var i3 = i * 3;
var i2 = i * 2;
if (this.is2D) {
positionArr[i3] = points[i2];
positionArr[i3 + 1] = points[i2 + 1];
positionArr[i3 + 2] = Z_2D;
}
else {
positionArr[i3] = points[i3];
positionArr[i3 + 1] = points[i3 + 1];
positionArr[i3 + 2] = points[i3 + 2];
}
if (!largeMode) {
var color = data.getItemVisual(i, 'color');
var opacity = data.getItemVisual(i, 'opacity');
__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(color, rgbaArr);
rgbaArr[3] *= opacity;
attributes.color.set(i, rgbaArr);
if (rgbaArr[3] < 0.99) {
hasTransparentPoint = true;
}
var symbolSize = data.getItemVisual(i, 'symbolSize');
symbolSize = (symbolSize instanceof Array
? Math.max(symbolSize[0], symbolSize[1]) : symbolSize);
// NaN pointSize may have strange result.
if (isNaN(symbolSize)) {
symbolSize = 0;
}
// Scale point size because canvas has margin.
attributes.size.value[i] = symbolSize * pointSizeScale * this._sizeScale;
// Save the original opacity for recover from fadeIn.
this._originalOpacity[i] = rgbaArr[3];
}
}
this._mesh.sizeScale = pointSizeScale;
geometry.updateBoundingBox();
geometry.dirty();
// Update material.
this._updateMaterial(seriesModel, itemStyle);
var coordSys = seriesModel.coordinateSystem;
if (coordSys && coordSys.viewGL) {
var methodName = coordSys.viewGL.isLinearSpace() ? 'define' : 'undefine';
material[methodName]('fragment', 'SRGB_DECODE');
}
if (!largeMode) {
this._updateLabelBuilder(seriesModel, start, end);
}
this._updateHandler(seriesModel, ecModel, api);
this._updateAnimation(seriesModel);
this._api = api;
},
getPointsMesh: function () {
return this._mesh;
},
updateLabels: function (highlightDataIndices) {
this._labelsBuilder.updateLabels(highlightDataIndices);
},
hideLabels: function () {
this.rootNode.remove(this._labelsBuilder.getMesh());
},
showLabels: function () {
this.rootNode.add(this._labelsBuilder.getMesh());
},
_updateSymbolSprite: function (seriesModel, itemStyle, symbolInfo, dpr) {
symbolInfo.maxSize = Math.min(symbolInfo.maxSize * 2, 200);
var symbolSize = [];
if (symbolInfo.aspect > 1) {
symbolSize[0] = symbolInfo.maxSize;
symbolSize[1] = symbolInfo.maxSize / symbolInfo.aspect;
}
else {
symbolSize[1] = symbolInfo.maxSize;
symbolSize[0] = symbolInfo.maxSize * symbolInfo.aspect;
}
// In case invalid data.
symbolSize[0] = symbolSize[0] || 1;
symbolSize[1] = symbolSize[1] || 1;
if (this._symbolType !== symbolInfo.type
|| !isSymbolSizeSame(this._symbolSize, symbolSize)
|| this._lineWidth !== itemStyle.lineWidth
) {
__WEBPACK_IMPORTED_MODULE_2__util_sprite__["a" /* default */].createSymbolSprite(symbolInfo.type, symbolSize, {
fill: '#fff',
lineWidth: itemStyle.lineWidth,
stroke: 'transparent',
shadowColor: 'transparent',
minMargin: Math.min(symbolSize[0] / 2, 10)
}, this._spriteImageCanvas);
__WEBPACK_IMPORTED_MODULE_2__util_sprite__["a" /* default */].createSDFFromCanvas(
this._spriteImageCanvas, Math.min(this._spriteImageCanvas.width, 32), SDF_RANGE,
this._mesh.material.get('sprite').image
);
this._symbolType = symbolInfo.type;
this._symbolSize = symbolSize;
this._lineWidth = itemStyle.lineWidth;
}
return this._spriteImageCanvas.width / symbolInfo.maxSize * dpr;
},
_updateMaterial: function (seriesModel, itemStyle) {
var blendFunc = seriesModel.get('blendMode') === 'lighter'
? __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].additiveBlend : null;
var material = this._mesh.material;
material.blend = blendFunc;
material.set('lineWidth', itemStyle.lineWidth / SDF_RANGE);
var strokeColor = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(itemStyle.stroke);
material.set('strokeColor', strokeColor);
// Because of symbol texture, we always needs it be transparent.
material.transparent = true;
material.depthMask = false;
material.depthTest = !this.is2D;
material.sortVertices = !this.is2D;
},
_updateLabelBuilder: function (seriesModel, start, end) {
var data =seriesModel.getData();
var geometry = this._mesh.geometry;
var positionArr = geometry.attributes.position.value;
var start = this._startDataIndex;
var pointSizeScale = this._mesh.sizeScale;
this._labelsBuilder.updateData(data, start, end);
this._labelsBuilder.getLabelPosition = function (dataIndex, positionDesc, distance) {
var idx3 = (dataIndex - start) * 3;
return [positionArr[idx3], positionArr[idx3 + 1], positionArr[idx3 + 2]];
};
this._labelsBuilder.getLabelDistance = function (dataIndex, positionDesc, distance) {
var size = geometry.attributes.size.get(dataIndex - start) / pointSizeScale;
return size / 2 + distance;
};
this._labelsBuilder.updateLabels();
},
_updateAnimation: function (seriesModel) {
__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].updateVertexAnimation(
[['prevPosition', 'position'],
['prevSize', 'size']],
this._prevMesh,
this._mesh,
seriesModel
);
},
_updateHandler: function (seriesModel, ecModel, api) {
var data = seriesModel.getData();
var pointsMesh = this._mesh;
var self = this;
var lastDataIndex = -1;
var isCartesian3D = seriesModel.coordinateSystem
&& seriesModel.coordinateSystem.type === 'cartesian3D';
var grid3DModel;
if (isCartesian3D) {
grid3DModel = seriesModel.coordinateSystem.model;
}
pointsMesh.seriesIndex = seriesModel.seriesIndex;
pointsMesh.off('mousemove');
pointsMesh.off('mouseout');
pointsMesh.on('mousemove', function (e) {
var dataIndex = e.vertexIndex + self._startDataIndex;
if (dataIndex !== lastDataIndex) {
if (this.highlightOnMouseover) {
this.downplay(data, lastDataIndex);
this.highlight(data, dataIndex);
this._labelsBuilder.updateLabels([dataIndex]);
}
if (isCartesian3D) {
api.dispatchAction({
type: 'grid3DShowAxisPointer',
value: [
data.get(seriesModel.coordDimToDataDim('x')[0], dataIndex),
data.get(seriesModel.coordDimToDataDim('y')[0], dataIndex),
data.get(seriesModel.coordDimToDataDim('z')[0], dataIndex)
],
grid3DIndex: grid3DModel.componentIndex
});
}
}
pointsMesh.dataIndex = dataIndex;
lastDataIndex = dataIndex;
}, this);
pointsMesh.on('mouseout', function (e) {
var dataIndex = e.vertexIndex + self._startDataIndex;
if (this.highlightOnMouseover) {
this.downplay(data, dataIndex);
this._labelsBuilder.updateLabels();
}
lastDataIndex = -1;
pointsMesh.dataIndex = -1;
if (isCartesian3D) {
api.dispatchAction({
type: 'grid3DHideAxisPointer',
grid3DIndex: grid3DModel.componentIndex
});
}
}, this);
},
updateLayout: function (seriesModel, ecModel, api) {
var data = seriesModel.getData();
if (!this._mesh) {
return;
}
var positionArr = this._mesh.geometry.attributes.position.value;
var points = data.getLayout('points');
if (this.is2D) {
for (var i = 0; i < points.length / 2; i++) {
var i3 = i * 3;
var i2 = i * 2;
positionArr[i3] = points[i2];
positionArr[i3 + 1] = points[i2 + 1];
positionArr[i3 + 2] = Z_2D;
}
}
else {
for (var i = 0; i < points.length; i++) {
positionArr[i] = points[i];
}
}
this._mesh.geometry.dirty();
api.getZr().refresh();
},
updateView: function (camera) {
if (!this._mesh) {
return;
}
var worldViewProjection = new __WEBPACK_IMPORTED_MODULE_5_claygl_src_math_Matrix4__["a" /* default */]();
__WEBPACK_IMPORTED_MODULE_5_claygl_src_math_Matrix4__["a" /* default */].mul(worldViewProjection, camera.viewMatrix, this._mesh.worldTransform);
__WEBPACK_IMPORTED_MODULE_5_claygl_src_math_Matrix4__["a" /* default */].mul(worldViewProjection, camera.projectionMatrix, worldViewProjection);
this._mesh.updateNDCPosition(worldViewProjection, this.is2D, this._api);
},
highlight: function (data, dataIndex) {
if (dataIndex > this._endDataIndex || dataIndex < this._startDataIndex) {
return;
}
var itemModel = data.getItemModel(dataIndex);
var emphasisItemStyleModel = itemModel.getModel('emphasis.itemStyle');
var emphasisColor = emphasisItemStyleModel.get('color');
var emphasisOpacity = emphasisItemStyleModel.get('opacity');
if (emphasisColor == null) {
var color = data.getItemVisual(dataIndex, 'color');
emphasisColor = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.color.lift(color, -0.4);
}
if (emphasisOpacity == null) {
emphasisOpacity = data.getItemVisual(dataIndex, 'opacity');
}
var colorArr = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(emphasisColor);
colorArr[3] *= emphasisOpacity;
this._mesh.geometry.attributes.color.set(dataIndex - this._startDataIndex, colorArr);
this._mesh.geometry.dirtyAttribute('color');
this._api.getZr().refresh();
},
downplay: function (data, dataIndex) {
if (dataIndex > this._endDataIndex || dataIndex < this._startDataIndex) {
return;
}
var color = data.getItemVisual(dataIndex, 'color');
var opacity = data.getItemVisual(dataIndex, 'opacity');
var colorArr = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(color);
colorArr[3] *= opacity;
this._mesh.geometry.attributes.color.set(dataIndex - this._startDataIndex, colorArr);
this._mesh.geometry.dirtyAttribute('color');
this._api.getZr().refresh();
},
fadeOutAll: function (fadeOutPercent) {
if (this._originalOpacity) {
var geo = this._mesh.geometry;
for (var i = 0; i < geo.vertexCount; i++) {
var fadeOutOpacity = this._originalOpacity[i] * fadeOutPercent;
geo.attributes.color.value[i * 4 + 3] = fadeOutOpacity;
}
geo.dirtyAttribute('color');
this._api.getZr().refresh();
}
},
fadeInAll: function () {
this.fadeOutAll(1);
},
setPositionTexture: function (texture) {
if (this._mesh) {
this._setPositionTextureToMesh(this._mesh, texture);
}
this._positionTexture = texture;
},
removePositionTexture: function () {
this._positionTexture = null;
if (this._mesh) {
this._setPositionTextureToMesh(this._mesh, null);
}
},
setSizeScale: function (sizeScale) {
if (sizeScale !== this._sizeScale) {
if (this._mesh) {
var originalSize = this._mesh.material.get('u_Size');
this._mesh.material.set('u_Size', originalSize / this._sizeScale * sizeScale);
var attributes = this._mesh.geometry.attributes;
if (attributes.size.value) {
for (var i = 0; i < attributes.size.value.length; i++) {
attributes.size.value[i] = attributes.size.value[i] / this._sizeScale * sizeScale;
}
}
}
this._sizeScale = sizeScale;
}
},
_setPositionTextureToMesh: function (mesh, texture) {
if (texture) {
mesh.material.set('positionTexture', texture);
}
mesh.material[
texture ? 'enableTexture' : 'disableTexture'
]('positionTexture');
},
_getSymbolInfo: function (seriesModel, start, end) {
if (seriesModel.get('large')) {
var symbolSize = __WEBPACK_IMPORTED_MODULE_6__util_retrieve__["a" /* default */].firstNotNull(seriesModel.get('symbolSize'), 1);
var maxSymbolSize;
var symbolAspect;
if (symbolSize instanceof Array) {
maxSymbolSize = Math.max(symbolSize[0], symbolSize[1]);
symbolAspect = symbolSize[0] / symbolSize[1];
}
else {
maxSymbolSize = symbolSize;
symbolAspect = 1;
}
return {
maxSize: symbolSize,
type: seriesModel.get('symbol'),
aspect: symbolAspect
}
}
var data = seriesModel.getData();
var symbolAspect;
var differentSymbolAspect = false;
var symbolType = data.getItemVisual(0, 'symbol') || 'circle';
var differentSymbolType = false;
var maxSymbolSize = 0;
for (var idx = start; idx < end; idx++) {
var symbolSize = data.getItemVisual(idx, 'symbolSize');
var currentSymbolType = data.getItemVisual(idx, 'symbol');
var currentSymbolAspect;
if (!(symbolSize instanceof Array)) {
// Ignore NaN value.
if (isNaN(symbolSize)) {
return;
}
currentSymbolAspect = 1;
maxSymbolSize = Math.max(symbolSize, maxSymbolSize);
}
else {
currentSymbolAspect = symbolSize[0] / symbolSize[1];
maxSymbolSize = Math.max(Math.max(symbolSize[0], symbolSize[1]), maxSymbolSize);
}
if (true) {
if (symbolAspect != null && Math.abs(currentSymbolAspect - symbolAspect) > 0.05) {
differentSymbolAspect = true;
}
if (currentSymbolType !== symbolType) {
differentSymbolType = true;
}
}
symbolType = currentSymbolType;
symbolAspect = currentSymbolAspect;
}
if (true) {
if (differentSymbolAspect) {
console.warn('Different symbol width / height ratio will be ignored.');
}
if (differentSymbolType) {
console.warn('Different symbol type will be ignored.');
}
}
return {
maxSize: maxSymbolSize,
type: symbolType,
aspect: symbolAspect
};
}
};
/* harmony default export */ __webpack_exports__["a"] = (PointsBuilder);
/***/ }),
/* 63 */
/***/ (function(module, exports) {
var g;
// This works in non-strict mode
g = (function() {
return this;
})();
try {
// This works if eval is allowed (see CSP)
g = g || Function("return this")() || (1,eval)("this");
} catch(e) {
// This works if the window reference is available
if(typeof window === "object")
g = window;
}
// g can still be undefined, but nothing to do about it...
// We return undefined, instead of nothing here, so it's
// easier to handle this case. if(!global) { ...}
module.exports = g;
/***/ }),
/* 64 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__LinkedList__ = __webpack_require__(106);
/**
* LRU Cache
* @constructor
* @alias clay.core.LRU
*/
var LRU = function(maxSize) {
this._list = new __WEBPACK_IMPORTED_MODULE_0__LinkedList__["a" /* default */]();
this._map = {};
this._maxSize = maxSize || 10;
};
/**
* Set cache max size
* @param {number} size
*/
LRU.prototype.setMaxSize = function(size) {
this._maxSize = size;
};
/**
* @param {string} key
* @param {} value
*/
LRU.prototype.put = function(key, value) {
if (typeof(this._map[key]) == 'undefined') {
var len = this._list.length();
if (len >= this._maxSize && len > 0) {
// Remove the least recently used
var leastUsedEntry = this._list.head;
this._list.remove(leastUsedEntry);
delete this._map[leastUsedEntry.key];
}
var entry = this._list.insert(value);
entry.key = key;
this._map[key] = entry;
}
};
/**
* @param {string} key
* @return {}
*/
LRU.prototype.get = function(key) {
var entry = this._map[key];
if (typeof(entry) != 'undefined') {
// Put the latest used entry in the tail
if (entry !== this._list.tail) {
this._list.remove(entry);
this._list.insertEntry(entry);
}
return entry.value;
}
};
/**
* @param {string} key
*/
LRU.prototype.remove = function(key) {
var entry = this._map[key];
if (typeof(entry) != 'undefined') {
delete this._map[key];
this._list.remove(entry);
}
};
/**
* Clear the cache
*/
LRU.prototype.clear = function() {
this._list.clear();
this._map = {};
};
/* harmony default export */ __webpack_exports__["a"] = (LRU);
/***/ }),
/* 65 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.prez.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nattribute vec3 position : POSITION;\n@import clay.chunk.skinning_header\nvoid main()\n{\n vec3 skinnedPosition = position;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n#endif\n gl_Position = worldViewProjection * vec4(skinnedPosition, 1.0);\n}\n@end\n@export clay.prez.fragment\nvoid main()\n{\n gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);\n}\n@end");
/***/ }),
/* 66 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Node__ = __webpack_require__(30);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_glenum__ = __webpack_require__(11);
/**
* @constructor
* @alias clay.Renderable
* @extends clay.Node
*/
var Renderable = __WEBPACK_IMPORTED_MODULE_0__Node__["a" /* default */].extend(/** @lends clay.Renderable# */ {
/**
* @type {clay.Material}
*/
material: null,
/**
* @type {clay.Geometry}
*/
geometry: null,
/**
* @type {number}
*/
mode: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].TRIANGLES,
_renderInfo: null
},
/** @lends clay.Renderable.prototype */
{
__program: null,
/**
* Group of received light.
*/
lightGroup: 0,
/**
* Render order, Nodes with smaller value renders before nodes with larger values.
* @type {Number}
*/
renderOrder: 0,
/**
* Used when mode is LINES, LINE_STRIP or LINE_LOOP
* @type {number}
*/
// lineWidth: 1,
/**
* If enable culling
* @type {boolean}
*/
culling: true,
/**
* Specify which side of polygon will be culled.
* Possible values:
* + {@link clay.Renderable.BACK}
* + {@link clay.Renderable.FRONT}
* + {@link clay.Renderable.FRONT_AND_BACK}
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/cullFace
* @type {number}
*/
cullFace: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].BACK,
/**
* Specify which side is front face.
* Possible values:
* + {@link clay.Renderable.CW}
* + {@link clay.Renderable.CCW}
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/frontFace
* @type {number}
*/
frontFace: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].CCW,
/**
* If enable software frustum culling
* @type {boolean}
*/
frustumCulling: true,
/**
* @type {boolean}
*/
receiveShadow: true,
/**
* @type {boolean}
*/
castShadow: true,
/**
* @type {boolean}
*/
ignorePicking: false,
/**
* @type {boolean}
*/
ignorePreZ: false,
/**
* @type {boolean}
*/
ignoreGBuffer: false,
/**
* @return {boolean}
*/
isRenderable: function() {
// TODO Shader ?
return this.geometry && this.material && this.material.shader && !this.invisible
&& this.geometry.vertexCount > 0;
},
/**
* Before render hook
* @type {Function}
*/
beforeRender: function (_gl) {},
/**
* Before render hook
* @type {Function}
*/
afterRender: function (_gl, renderStat) {},
getBoundingBox: function (filter, out) {
out = __WEBPACK_IMPORTED_MODULE_0__Node__["a" /* default */].prototype.getBoundingBox.call(this, filter, out);
if (this.geometry && this.geometry.boundingBox) {
out.union(this.geometry.boundingBox);
}
return out;
},
/**
* Clone a new renderable
* @function
* @return {clay.Renderable}
*/
clone: (function() {
var properties = [
'castShadow', 'receiveShadow',
'mode', 'culling', 'cullFace', 'frontFace',
'frustumCulling',
'renderOrder', 'lineWidth',
'ignorePicking', 'ignorePreZ', 'ignoreGBuffer'
];
return function() {
var renderable = __WEBPACK_IMPORTED_MODULE_0__Node__["a" /* default */].prototype.clone.call(this);
renderable.geometry = this.geometry;
renderable.material = this.material;
for (var i = 0; i < properties.length; i++) {
var name = properties[i];
// Try not to overwrite the prototype property
if (renderable[name] !== this[name]) {
renderable[name] = this[name];
}
}
return renderable;
};
})()
});
/**
* @type {number}
*/
Renderable.POINTS = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].POINTS;
/**
* @type {number}
*/
Renderable.LINES = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINES;
/**
* @type {number}
*/
Renderable.LINE_LOOP = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINE_LOOP;
/**
* @type {number}
*/
Renderable.LINE_STRIP = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINE_STRIP;
/**
* @type {number}
*/
Renderable.TRIANGLES = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].TRIANGLES;
/**
* @type {number}
*/
Renderable.TRIANGLE_STRIP = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].TRIANGLE_STRIP;
/**
* @type {number}
*/
Renderable.TRIANGLE_FAN = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].TRIANGLE_FAN;
/**
* @type {number}
*/
Renderable.BACK = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].BACK;
/**
* @type {number}
*/
Renderable.FRONT = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].FRONT;
/**
* @type {number}
*/
Renderable.FRONT_AND_BACK = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].FRONT_AND_BACK;
/**
* @type {number}
*/
Renderable.CW = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].CW;
/**
* @type {number}
*/
Renderable.CCW = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].CCW;
/* harmony default export */ __webpack_exports__["a"] = (Renderable);
/***/ }),
/* 67 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
var mathUtil = {};
mathUtil.isPowerOfTwo = function (value) {
return (value & (value - 1)) === 0;
};
mathUtil.nextPowerOfTwo = function (value) {
value --;
value |= value >> 1;
value |= value >> 2;
value |= value >> 4;
value |= value >> 8;
value |= value >> 16;
value ++;
return value;
};
mathUtil.nearestPowerOfTwo = function (value) {
return Math.pow( 2, Math.round( Math.log( value ) / Math.LN2 ) );
};
/* harmony default export */ __webpack_exports__["a"] = (mathUtil);
/***/ }),
/* 68 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Vector3__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1__dep_glmatrix__);
var vec3 = __WEBPACK_IMPORTED_MODULE_1__dep_glmatrix___default.a.vec3;
var mat4 = __WEBPACK_IMPORTED_MODULE_1__dep_glmatrix___default.a.mat4;
var vec4 = __WEBPACK_IMPORTED_MODULE_1__dep_glmatrix___default.a.vec4;
/**
* @constructor
* @alias clay.Plane
* @param {clay.Vector3} [normal]
* @param {number} [distance]
*/
var Plane = function(normal, distance) {
/**
* Normal of the plane
* @type {clay.Vector3}
*/
this.normal = normal || new __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */](0, 1, 0);
/**
* Constant of the plane equation, used as distance to the origin
* @type {number}
*/
this.distance = distance || 0;
};
Plane.prototype = {
constructor: Plane,
/**
* Distance from a given point to the plane
* @param {clay.Vector3} point
* @return {number}
*/
distanceToPoint: function(point) {
return vec3.dot(point.array, this.normal.array) - this.distance;
},
/**
* Calculate the projection point on the plane
* @param {clay.Vector3} point
* @param {clay.Vector3} out
* @return {clay.Vector3}
*/
projectPoint: function(point, out) {
if (!out) {
out = new __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */]();
}
var d = this.distanceToPoint(point);
vec3.scaleAndAdd(out.array, point.array, this.normal.array, -d);
out._dirty = true;
return out;
},
/**
* Normalize the plane's normal and calculate the distance
*/
normalize: function() {
var invLen = 1 / vec3.len(this.normal.array);
vec3.scale(this.normal.array, invLen);
this.distance *= invLen;
},
/**
* If the plane intersect a frustum
* @param {clay.Frustum} Frustum
* @return {boolean}
*/
intersectFrustum: function(frustum) {
// Check if all coords of frustum is on plane all under plane
var coords = frustum.vertices;
var normal = this.normal.array;
var onPlane = vec3.dot(coords[0].array, normal) > this.distance;
for (var i = 1; i < 8; i++) {
if ((vec3.dot(coords[i].array, normal) > this.distance) != onPlane) {
return true;
}
}
},
/**
* Calculate the intersection point between plane and a given line
* @function
* @param {clay.Vector3} start start point of line
* @param {clay.Vector3} end end point of line
* @param {clay.Vector3} [out]
* @return {clay.Vector3}
*/
intersectLine: (function() {
var rd = vec3.create();
return function(start, end, out) {
var d0 = this.distanceToPoint(start);
var d1 = this.distanceToPoint(end);
if ((d0 > 0 && d1 > 0) || (d0 < 0 && d1 < 0)) {
return null;
}
// Ray intersection
var pn = this.normal.array;
var d = this.distance;
var ro = start.array;
// direction
vec3.sub(rd, end.array, start.array);
vec3.normalize(rd, rd);
var divider = vec3.dot(pn, rd);
// ray is parallel to the plane
if (divider === 0) {
return null;
}
if (!out) {
out = new __WEBPACK_IMPORTED_MODULE_0__Vector3__["a" /* default */]();
}
var t = (vec3.dot(pn, ro) - d) / divider;
vec3.scaleAndAdd(out.array, ro, rd, -t);
out._dirty = true;
return out;
};
})(),
/**
* Apply an affine transform matrix to plane
* @function
* @return {clay.Matrix4}
*/
applyTransform: (function() {
var inverseTranspose = mat4.create();
var normalv4 = vec4.create();
var pointv4 = vec4.create();
pointv4[3] = 1;
return function(m4) {
m4 = m4.array;
// Transform point on plane
vec3.scale(pointv4, this.normal.array, this.distance);
vec4.transformMat4(pointv4, pointv4, m4);
this.distance = vec3.dot(pointv4, this.normal.array);
// Transform plane normal
mat4.invert(inverseTranspose, m4);
mat4.transpose(inverseTranspose, inverseTranspose);
normalv4[3] = 0;
vec3.copy(normalv4, this.normal.array);
vec4.transformMat4(normalv4, normalv4, inverseTranspose);
vec3.copy(this.normal.array, normalv4);
};
})(),
/**
* Copy from another plane
* @param {clay.Vector3} plane
*/
copy: function(plane) {
vec3.copy(this.normal.array, plane.normal.array);
this.normal._dirty = true;
this.distance = plane.distance;
},
/**
* Clone a new plane
* @return {clay.Plane}
*/
clone: function() {
var plane = new Plane();
plane.copy(this);
return plane;
}
};
/* harmony default export */ __webpack_exports__["a"] = (Plane);
/***/ }),
/* 69 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Geometry__ = __webpack_require__(13);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__math_BoundingBox__ = __webpack_require__(15);
/**
* @constructor clay.geometry.Sphere
* @extends clay.Geometry
* @param {Object} [opt]
* @param {number} [widthSegments]
* @param {number} [heightSegments]
* @param {number} [phiStart]
* @param {number} [phiLength]
* @param {number} [thetaStart]
* @param {number} [thetaLength]
* @param {number} [radius]
*/
var Sphere = __WEBPACK_IMPORTED_MODULE_0__Geometry__["a" /* default */].extend(/** @lends clay.geometry.Sphere# */ {
dynamic: false,
/**
* @type {number}
*/
widthSegments: 40,
/**
* @type {number}
*/
heightSegments: 20,
/**
* @type {number}
*/
phiStart: 0,
/**
* @type {number}
*/
phiLength: Math.PI * 2,
/**
* @type {number}
*/
thetaStart: 0,
/**
* @type {number}
*/
thetaLength: Math.PI,
/**
* @type {number}
*/
radius: 1
}, function() {
this.build();
},
/** @lends clay.geometry.Sphere.prototype */
{
/**
* Build sphere geometry
*/
build: function() {
var heightSegments = this.heightSegments;
var widthSegments = this.widthSegments;
var positionAttr = this.attributes.position;
var texcoordAttr = this.attributes.texcoord0;
var normalAttr = this.attributes.normal;
var vertexCount = (widthSegments + 1) * (heightSegments + 1);
positionAttr.init(vertexCount);
texcoordAttr.init(vertexCount);
normalAttr.init(vertexCount);
var IndicesCtor = vertexCount > 0xffff ? Uint32Array : Uint16Array;
var indices = this.indices = new IndicesCtor(widthSegments * heightSegments * 6);
var x, y, z,
u, v,
i, j;
var radius = this.radius;
var phiStart = this.phiStart;
var phiLength = this.phiLength;
var thetaStart = this.thetaStart;
var thetaLength = this.thetaLength;
var radius = this.radius;
var pos = [];
var uv = [];
var offset = 0;
var divider = 1 / radius;
for (j = 0; j <= heightSegments; j ++) {
for (i = 0; i <= widthSegments; i ++) {
u = i / widthSegments;
v = j / heightSegments;
// X axis is inverted so texture can be mapped from left to right
x = -radius * Math.cos(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength);
y = radius * Math.cos(thetaStart + v * thetaLength);
z = radius * Math.sin(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength);
pos[0] = x; pos[1] = y; pos[2] = z;
uv[0] = u; uv[1] = v;
positionAttr.set(offset, pos);
texcoordAttr.set(offset, uv);
pos[0] *= divider;
pos[1] *= divider;
pos[2] *= divider;
normalAttr.set(offset, pos);
offset++;
}
}
var i1, i2, i3, i4;
var len = widthSegments + 1;
var n = 0;
for (j = 0; j < heightSegments; j ++) {
for (i = 0; i < widthSegments; i ++) {
i2 = j * len + i;
i1 = (j * len + i + 1);
i4 = (j + 1) * len + i + 1;
i3 = (j + 1) * len + i;
indices[n++] = i1;
indices[n++] = i2;
indices[n++] = i4;
indices[n++] = i2;
indices[n++] = i3;
indices[n++] = i4;
}
}
this.boundingBox = new __WEBPACK_IMPORTED_MODULE_1__math_BoundingBox__["a" /* default */]();
this.boundingBox.max.set(radius, radius, radius);
this.boundingBox.min.set(-radius, -radius, -radius);
}
});
/* harmony default export */ __webpack_exports__["a"] = (Sphere);
/***/ }),
/* 70 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__TextureCube__ = __webpack_require__(24);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Texture__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__FrameBuffer__ = __webpack_require__(10);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__compositor_Pass__ = __webpack_require__(14);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__Material__ = __webpack_require__(17);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__plugin_Skybox__ = __webpack_require__(57);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__Scene__ = __webpack_require__(32);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__prePass_EnvironmentMap__ = __webpack_require__(55);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__core_vendor__ = __webpack_require__(18);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__texture__ = __webpack_require__(54);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__shader_integrateBRDF_glsl_js__ = __webpack_require__(120);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_13__shader_prefilter_glsl_js__ = __webpack_require__(121);
// Cubemap prefilter utility
// http://www.unrealengine.com/files/downloads/2013SiggraphPresentationsNotes.pdf
// http://http.developer.nvidia.com/GPUGems3/gpugems3_ch20.html
var cubemapUtil = {};
var targets = ['px', 'nx', 'py', 'ny', 'pz', 'nz'];
/**
* @name clay.util.cubemap.prefilterEnvironmentMap
* @param {clay.Renderer} renderer
* @param {clay.Texture} envMap
* @param {Object} [textureOpts]
* @param {number} [textureOpts.width=64]
* @param {number} [textureOpts.height=64]
* @param {number} [textureOpts.type]
* @param {boolean} [textureOpts.encodeRGBM=false]
* @param {boolean} [textureOpts.decodeRGBM=false]
* @param {clay.Texture2D} [normalDistribution]
* @param {clay.Texture2D} [brdfLookup]
*/
cubemapUtil.prefilterEnvironmentMap = function (
renderer, envMap, textureOpts, normalDistribution, brdfLookup
) {
// Not create other renderer, it is easy having issue of cross reference of resources like framebuffer
// PENDING preserveDrawingBuffer?
if (!brdfLookup || !normalDistribution) {
normalDistribution = cubemapUtil.generateNormalDistribution();
brdfLookup = cubemapUtil.integrateBRDF(renderer, normalDistribution);
}
textureOpts = textureOpts || {};
var width = textureOpts.width || 64;
var height = textureOpts.height || 64;
var textureType = textureOpts.type || envMap.type;
// Use same type with given envMap
var prefilteredCubeMap = new __WEBPACK_IMPORTED_MODULE_1__TextureCube__["a" /* default */]({
width: width,
height: height,
type: textureType,
flipY: false,
mipmaps: []
});
if (!prefilteredCubeMap.isPowerOfTwo()) {
console.warn('Width and height must be power of two to enable mipmap.');
}
var size = Math.min(width, height);
var mipmapNum = Math.log(size) / Math.log(2) + 1;
var prefilterMaterial = new __WEBPACK_IMPORTED_MODULE_5__Material__["a" /* default */]({
shader: new __WEBPACK_IMPORTED_MODULE_6__Shader__["a" /* default */]({
vertex: __WEBPACK_IMPORTED_MODULE_6__Shader__["a" /* default */].source('clay.skybox.vertex'),
fragment: __WEBPACK_IMPORTED_MODULE_13__shader_prefilter_glsl_js__["a" /* default */]
})
});
prefilterMaterial.set('normalDistribution', normalDistribution);
textureOpts.encodeRGBM && prefilterMaterial.define('fragment', 'RGBM_ENCODE');
textureOpts.decodeRGBM && prefilterMaterial.define('fragment', 'RGBM_DECODE');
var dummyScene = new __WEBPACK_IMPORTED_MODULE_8__Scene__["a" /* default */]();
var skyEnv;
if (envMap.textureType === 'texture2D') {
// Convert panorama to cubemap
var envCubemap = new __WEBPACK_IMPORTED_MODULE_1__TextureCube__["a" /* default */]({
width: width,
height: height,
// FIXME FLOAT type will cause GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT error on iOS
type: textureType === __WEBPACK_IMPORTED_MODULE_2__Texture__["a" /* default */].FLOAT ?
__WEBPACK_IMPORTED_MODULE_2__Texture__["a" /* default */].HALF_FLOAT : textureType
});
__WEBPACK_IMPORTED_MODULE_11__texture__["a" /* default */].panoramaToCubeMap(renderer, envMap, envCubemap, {
// PENDING encodeRGBM so it can be decoded as RGBM
encodeRGBM: textureOpts.decodeRGBM
});
envMap = envCubemap;
}
skyEnv = new __WEBPACK_IMPORTED_MODULE_7__plugin_Skybox__["a" /* default */]({
scene: dummyScene,
material: prefilterMaterial
});
skyEnv.material.set('environmentMap', envMap);
var envMapPass = new __WEBPACK_IMPORTED_MODULE_9__prePass_EnvironmentMap__["a" /* default */]({
texture: prefilteredCubeMap
});
// Force to be UNSIGNED_BYTE
if (textureOpts.encodeRGBM) {
textureType = prefilteredCubeMap.type = __WEBPACK_IMPORTED_MODULE_2__Texture__["a" /* default */].UNSIGNED_BYTE;
}
var renderTargetTmp = new __WEBPACK_IMPORTED_MODULE_0__Texture2D__["a" /* default */]({
width: width,
height: height,
type: textureType
});
var frameBuffer = new __WEBPACK_IMPORTED_MODULE_3__FrameBuffer__["a" /* default */]({
depthBuffer: false
});
var ArrayCtor = __WEBPACK_IMPORTED_MODULE_10__core_vendor__["a" /* default */][textureType === __WEBPACK_IMPORTED_MODULE_2__Texture__["a" /* default */].UNSIGNED_BYTE ? 'Uint8Array' : 'Float32Array'];
for (var i = 0; i < mipmapNum; i++) {
// console.time('prefilter');
prefilteredCubeMap.mipmaps[i] = {
pixels: {}
};
skyEnv.material.set('roughness', i / (targets.length - 1));
var maxSampleNumber = renderTargetTmp.width * renderTargetTmp.height;
if (renderTargetTmp.width >= 32) {
maxSampleNumber /= 4;
}
skyEnv.material.set('maxSampleNumber', Math.min(maxSampleNumber, 1024));
// Tweak fov
// http://the-witness.net/news/2012/02/seamless-cube-map-filtering/
var n = renderTargetTmp.width;
var fov = 2 * Math.atan(n / (n - 0.5)) / Math.PI * 180;
for (var j = 0; j < targets.length; j++) {
var pixels = new ArrayCtor(renderTargetTmp.width * renderTargetTmp.height * 4);
frameBuffer.attach(renderTargetTmp);
frameBuffer.bind(renderer);
var camera = envMapPass.getCamera(targets[j]);
camera.fov = fov;
renderer.render(dummyScene, camera);
renderer.gl.readPixels(
0, 0, renderTargetTmp.width, renderTargetTmp.height,
__WEBPACK_IMPORTED_MODULE_2__Texture__["a" /* default */].RGBA, textureType, pixels
);
// var canvas = document.createElement('canvas');
// var ctx = canvas.getContext('2d');
// canvas.width = renderTargetTmp.width;
// canvas.height = renderTargetTmp.height;
// var imageData = ctx.createImageData(renderTargetTmp.width, renderTargetTmp.height);
// for (var k = 0; k < pixels.length; k++) {
// imageData.data[k] = pixels[k];
// }
// ctx.putImageData(imageData, 0, 0);
// document.body.appendChild(canvas);
frameBuffer.unbind(renderer);
prefilteredCubeMap.mipmaps[i].pixels[targets[j]] = pixels;
}
renderTargetTmp.width /= 2;
renderTargetTmp.height /= 2;
renderTargetTmp.dirty();
// console.timeEnd('prefilter');
}
frameBuffer.dispose(renderer);
renderTargetTmp.dispose(renderer);
skyEnv.dispose(renderer);
// Remove gpu resource allucated in renderer
normalDistribution.dispose(renderer);
// renderer.dispose();
return {
environmentMap: prefilteredCubeMap,
brdfLookup: brdfLookup,
normalDistribution: normalDistribution,
maxMipmapLevel: mipmapNum
};
};
cubemapUtil.integrateBRDF = function (renderer, normalDistribution) {
normalDistribution = normalDistribution || cubemapUtil.generateNormalDistribution();
var framebuffer = new __WEBPACK_IMPORTED_MODULE_3__FrameBuffer__["a" /* default */]({
depthBuffer: false
});
var pass = new __WEBPACK_IMPORTED_MODULE_4__compositor_Pass__["a" /* default */]({
fragment: __WEBPACK_IMPORTED_MODULE_12__shader_integrateBRDF_glsl_js__["a" /* default */]
});
var texture = new __WEBPACK_IMPORTED_MODULE_0__Texture2D__["a" /* default */]({
width: 512,
height: 256,
type: __WEBPACK_IMPORTED_MODULE_2__Texture__["a" /* default */].HALF_FLOAT,
minFilter: __WEBPACK_IMPORTED_MODULE_2__Texture__["a" /* default */].NEAREST,
magFilter: __WEBPACK_IMPORTED_MODULE_2__Texture__["a" /* default */].NEAREST,
useMipmap: false
});
pass.setUniform('normalDistribution', normalDistribution);
pass.setUniform('viewportSize', [512, 256]);
pass.attachOutput(texture);
pass.render(renderer, framebuffer);
// FIXME Only chrome and firefox can readPixels with float type.
// framebuffer.bind(renderer);
// var pixels = new Float32Array(512 * 256 * 4);
// renderer.gl.readPixels(
// 0, 0, texture.width, texture.height,
// Texture.RGBA, Texture.FLOAT, pixels
// );
// texture.pixels = pixels;
// texture.flipY = false;
// texture.dirty();
// framebuffer.unbind(renderer);
framebuffer.dispose(renderer);
return texture;
};
cubemapUtil.generateNormalDistribution = function (roughnessLevels, sampleSize) {
// http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
// GLSL not support bit operation, use lookup instead
// V -> i / N, U -> roughness
var roughnessLevels = roughnessLevels || 256;
var sampleSize = sampleSize || 1024;
var normalDistribution = new __WEBPACK_IMPORTED_MODULE_0__Texture2D__["a" /* default */]({
width: roughnessLevels,
height: sampleSize,
type: __WEBPACK_IMPORTED_MODULE_2__Texture__["a" /* default */].FLOAT,
minFilter: __WEBPACK_IMPORTED_MODULE_2__Texture__["a" /* default */].NEAREST,
magFilter: __WEBPACK_IMPORTED_MODULE_2__Texture__["a" /* default */].NEAREST,
wrapS: __WEBPACK_IMPORTED_MODULE_2__Texture__["a" /* default */].CLAMP_TO_EDGE,
wrapT: __WEBPACK_IMPORTED_MODULE_2__Texture__["a" /* default */].CLAMP_TO_EDGE,
useMipmap: false
});
var pixels = new Float32Array(sampleSize * roughnessLevels * 4);
var tmp = [];
// function sortFunc(a, b) {
// return Math.abs(b) - Math.abs(a);
// }
for (var j = 0; j < roughnessLevels; j++) {
var roughness = j / roughnessLevels;
var a = roughness * roughness;
for (var i = 0; i < sampleSize; i++) {
// http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
// http://stackoverflow.com/questions/1908492/unsigned-integer-in-javascript
// http://stackoverflow.com/questions/1822350/what-is-the-javascript-operator-and-how-do-you-use-it
var y = (i << 16 | i >>> 16) >>> 0;
y = ((y & 1431655765) << 1 | (y & 2863311530) >>> 1) >>> 0;
y = ((y & 858993459) << 2 | (y & 3435973836) >>> 2) >>> 0;
y = ((y & 252645135) << 4 | (y & 4042322160) >>> 4) >>> 0;
y = (((y & 16711935) << 8 | (y & 4278255360) >>> 8) >>> 0) / 4294967296;
// CDF
var cosTheta = Math.sqrt((1 - y) / (1 + (a * a - 1.0) * y));
tmp[i] = cosTheta;
}
for (var i = 0; i < sampleSize; i++) {
var offset = (i * roughnessLevels + j) * 4;
var cosTheta = tmp[i];
var sinTheta = Math.sqrt(1.0 - cosTheta * cosTheta);
var x = i / sampleSize;
var phi = 2.0 * Math.PI * x;
pixels[offset] = sinTheta * Math.cos(phi);
pixels[offset + 1] = cosTheta;
pixels[offset + 2] = sinTheta * Math.sin(phi);
pixels[offset + 3] = 1.0;
}
}
normalDistribution.pixels = pixels;
return normalDistribution;
};
/* harmony default export */ __webpack_exports__["a"] = (cubemapUtil);
/***/ }),
/* 71 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Geometry__ = __webpack_require__(13);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Plane__ = __webpack_require__(37);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__math_Matrix4__ = __webpack_require__(7);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__math_Vector3__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__math_BoundingBox__ = __webpack_require__(15);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__core_vendor__ = __webpack_require__(18);
var planeMatrix = new __WEBPACK_IMPORTED_MODULE_2__math_Matrix4__["a" /* default */]();
/**
* @constructor clay.geometry.Cube
* @extends clay.Geometry
* @param {Object} [opt]
* @param {number} [opt.widthSegments]
* @param {number} [opt.heightSegments]
* @param {number} [opt.depthSegments]
* @param {boolean} [opt.inside]
*/
var Cube = __WEBPACK_IMPORTED_MODULE_0__Geometry__["a" /* default */].extend(
/**@lends clay.geometry.Cube# */
{
dynamic: false,
/**
* @type {number}
*/
widthSegments: 1,
/**
* @type {number}
*/
heightSegments: 1,
/**
* @type {number}
*/
depthSegments: 1,
/**
* @type {boolean}
*/
inside: false
}, function() {
this.build();
},
/** @lends clay.geometry.Cube.prototype */
{
/**
* Build cube geometry
*/
build: function() {
var planes = {
'px': createPlane('px', this.depthSegments, this.heightSegments),
'nx': createPlane('nx', this.depthSegments, this.heightSegments),
'py': createPlane('py', this.widthSegments, this.depthSegments),
'ny': createPlane('ny', this.widthSegments, this.depthSegments),
'pz': createPlane('pz', this.widthSegments, this.heightSegments),
'nz': createPlane('nz', this.widthSegments, this.heightSegments),
};
var attrList = ['position', 'texcoord0', 'normal'];
var vertexNumber = 0;
var faceNumber = 0;
for (var pos in planes) {
vertexNumber += planes[pos].vertexCount;
faceNumber += planes[pos].indices.length;
}
for (var k = 0; k < attrList.length; k++) {
this.attributes[attrList[k]].init(vertexNumber);
}
this.indices = new __WEBPACK_IMPORTED_MODULE_5__core_vendor__["a" /* default */].Uint16Array(faceNumber);
var faceOffset = 0;
var vertexOffset = 0;
for (var pos in planes) {
var plane = planes[pos];
for (var k = 0; k < attrList.length; k++) {
var attrName = attrList[k];
var attrArray = plane.attributes[attrName].value;
var attrSize = plane.attributes[attrName].size;
var isNormal = attrName === 'normal';
for (var i = 0; i < attrArray.length; i++) {
var value = attrArray[i];
if (this.inside && isNormal) {
value = -value;
}
this.attributes[attrName].value[i + attrSize * vertexOffset] = value;
}
}
var len = plane.indices.length;
for (var i = 0; i < plane.indices.length; i++) {
this.indices[i + faceOffset] = vertexOffset + plane.indices[this.inside ? (len - i - 1) : i];
}
faceOffset += plane.indices.length;
vertexOffset += plane.vertexCount;
}
this.boundingBox = new __WEBPACK_IMPORTED_MODULE_4__math_BoundingBox__["a" /* default */]();
this.boundingBox.max.set(1, 1, 1);
this.boundingBox.min.set(-1, -1, -1);
}
});
function createPlane(pos, widthSegments, heightSegments) {
planeMatrix.identity();
var plane = new __WEBPACK_IMPORTED_MODULE_1__Plane__["a" /* default */]({
widthSegments: widthSegments,
heightSegments: heightSegments
});
switch(pos) {
case 'px':
__WEBPACK_IMPORTED_MODULE_2__math_Matrix4__["a" /* default */].translate(planeMatrix, planeMatrix, __WEBPACK_IMPORTED_MODULE_3__math_Vector3__["a" /* default */].POSITIVE_X);
__WEBPACK_IMPORTED_MODULE_2__math_Matrix4__["a" /* default */].rotateY(planeMatrix, planeMatrix, Math.PI / 2);
break;
case 'nx':
__WEBPACK_IMPORTED_MODULE_2__math_Matrix4__["a" /* default */].translate(planeMatrix, planeMatrix, __WEBPACK_IMPORTED_MODULE_3__math_Vector3__["a" /* default */].NEGATIVE_X);
__WEBPACK_IMPORTED_MODULE_2__math_Matrix4__["a" /* default */].rotateY(planeMatrix, planeMatrix, -Math.PI / 2);
break;
case 'py':
__WEBPACK_IMPORTED_MODULE_2__math_Matrix4__["a" /* default */].translate(planeMatrix, planeMatrix, __WEBPACK_IMPORTED_MODULE_3__math_Vector3__["a" /* default */].POSITIVE_Y);
__WEBPACK_IMPORTED_MODULE_2__math_Matrix4__["a" /* default */].rotateX(planeMatrix, planeMatrix, -Math.PI / 2);
break;
case 'ny':
__WEBPACK_IMPORTED_MODULE_2__math_Matrix4__["a" /* default */].translate(planeMatrix, planeMatrix, __WEBPACK_IMPORTED_MODULE_3__math_Vector3__["a" /* default */].NEGATIVE_Y);
__WEBPACK_IMPORTED_MODULE_2__math_Matrix4__["a" /* default */].rotateX(planeMatrix, planeMatrix, Math.PI / 2);
break;
case 'pz':
__WEBPACK_IMPORTED_MODULE_2__math_Matrix4__["a" /* default */].translate(planeMatrix, planeMatrix, __WEBPACK_IMPORTED_MODULE_3__math_Vector3__["a" /* default */].POSITIVE_Z);
break;
case 'nz':
__WEBPACK_IMPORTED_MODULE_2__math_Matrix4__["a" /* default */].translate(planeMatrix, planeMatrix, __WEBPACK_IMPORTED_MODULE_3__math_Vector3__["a" /* default */].NEGATIVE_Z);
__WEBPACK_IMPORTED_MODULE_2__math_Matrix4__["a" /* default */].rotateY(planeMatrix, planeMatrix, Math.PI);
break;
}
plane.applyTransform(planeMatrix);
return plane;
}
/* harmony default export */ __webpack_exports__["a"] = (Cube);
/***/ }),
/* 72 */
/***/ (function(module, exports) {
var _default = typeof window !== 'undefined' && (window.requestAnimationFrame && window.requestAnimationFrame.bind(window) || // https://github.com/ecomfe/zrender/issues/189#issuecomment-224919809
window.msRequestAnimationFrame && window.msRequestAnimationFrame.bind(window) || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame) || function (func) {
setTimeout(func, 16);
};
module.exports = _default;
/***/ }),
/* 73 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_Texture2D__ = __webpack_require__(5);
/**
* Texture Atlas for the sprites.
* It uses zrender for 2d element management and rendering
* @module echarts-gl/util/ZRTextureAtlasSurface
*/
// TODO Expand.
function ZRTextureAtlasSurfaceNode(zr, offsetX, offsetY, width, height, gap, dpr) {
this._zr = zr;
/**
* Current cursor x
* @type {number}
* @private
*/
this._x = 0;
/**
* Current cursor y
* @type {number}
*/
this._y = 0;
this._rowHeight = 0;
/**
* width without dpr.
* @type {number}
* @private
*/
this.width = width;
/**
* height without dpr.
* @type {number}
* @private
*/
this.height = height;
/**
* offsetX without dpr
* @type {number}
*/
this.offsetX = offsetX;
/**
* offsetY without dpr
* @type {number}
*/
this.offsetY = offsetY;
this.dpr = dpr;
this.gap = gap;
}
ZRTextureAtlasSurfaceNode.prototype = {
constructor: ZRTextureAtlasSurfaceNode,
clear: function () {
this._x = 0;
this._y = 0;
this._rowHeight = 0;
},
/**
* Add shape to atlas
* @param {module:zrender/graphic/Displayable} shape
* @param {number} width
* @param {number} height
* @return {Array}
*/
add: function (el, width, height) {
// FIXME Text element not consider textAlign and textVerticalAlign.
// TODO, inner text, shadow
var rect = el.getBoundingRect();
// FIXME aspect ratio
if (width == null) {
width = rect.width;
}
if (height == null) {
height = rect.height;
}
width *= this.dpr;
height *= this.dpr;
this._fitElement(el, width, height);
// var aspect = el.scale[1] / el.scale[0];
// Adjust aspect ratio to make the text more clearly
// FIXME If height > width, width is useless ?
// width = height * aspect;
// el.position[0] *= aspect;
// el.scale[0] = el.scale[1];
var x = this._x;
var y = this._y;
var canvasWidth = this.width * this.dpr;
var canvasHeight = this.height * this.dpr;
var gap = this.gap;
if (x + width + gap > canvasWidth) {
// Change a new row
x = this._x = 0;
y += this._rowHeight + gap;
this._y = y;
// Reset row height
this._rowHeight = 0;
}
this._x += width + gap;
this._rowHeight = Math.max(this._rowHeight, height);
if (y + height + gap > canvasHeight) {
// There is no space anymore
return null;
}
// Shift the el
el.position[0] += this.offsetX * this.dpr + x;
el.position[1] += this.offsetY * this.dpr + y;
this._zr.add(el);
var coordsOffset = [
this.offsetX / this.width,
this.offsetY / this.height
];
var coords = [
[x / canvasWidth + coordsOffset[0], y / canvasHeight + coordsOffset[1]],
[(x + width) / canvasWidth + coordsOffset[0], (y + height) / canvasHeight + coordsOffset[1]]
];
return coords;
},
/**
* Fit element size by correct its position and scaling
* @param {module:zrender/graphic/Displayable} el
* @param {number} spriteWidth
* @param {number} spriteHeight
*/
_fitElement: function (el, spriteWidth, spriteHeight) {
// TODO, inner text, shadow
var rect = el.getBoundingRect();
var scaleX = spriteWidth / rect.width;
var scaleY = spriteHeight / rect.height;
el.position = [-rect.x * scaleX, -rect.y * scaleY];
el.scale = [scaleX, scaleY];
el.update();
}
}
/**
* constructor
* @alias module:echarts-gl/util/ZRTextureAtlasSurface
* @param {number} opt.width
* @param {number} opt.height
* @param {number} opt.devicePixelRatio
* @param {number} opt.gap Gap for safe.
* @param {Function} opt.onupdate
*/
function ZRTextureAtlasSurface (opt) {
opt = opt || {};
opt.width = opt.width || 512;
opt.height = opt.height || 512;
opt.devicePixelRatio = opt.devicePixelRatio || 1;
opt.gap = opt.gap == null ? 2 : opt.gap;
var canvas = document.createElement('canvas');
canvas.width = opt.width * opt.devicePixelRatio;
canvas.height = opt.height * opt.devicePixelRatio;
this._canvas = canvas;
this._texture = new __WEBPACK_IMPORTED_MODULE_1_claygl_src_Texture2D__["a" /* default */]({
image: canvas,
flipY: false
});
var self = this;
/**
* zrender instance in the Chart
* @type {zrender~ZRender}
*/
this._zr = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.zrender.init(canvas);
var oldRefreshImmediately = this._zr.refreshImmediately;
this._zr.refreshImmediately = function () {
oldRefreshImmediately.call(this);
self._texture.dirty();
self.onupdate && self.onupdate();
};
this._dpr = opt.devicePixelRatio;
/**
* Texture coords map for each sprite image
* @type {Object}
*/
this._coords = {};
this.onupdate = opt.onupdate;
this._gap = opt.gap;
// Left sub atlas.
this._textureAtlasNodes = [new ZRTextureAtlasSurfaceNode(
this._zr, 0, 0, opt.width, opt.height, this._gap, this._dpr
)];
this._nodeWidth = opt.width;
this._nodeHeight = opt.height;
this._currentNodeIdx = 0;
}
ZRTextureAtlasSurface.prototype = {
/**
* Clear the texture atlas
*/
clear: function () {
for (var i = 0; i < this._textureAtlasNodes.length; i++) {
this._textureAtlasNodes[i].clear();
}
this._currentNodeIdx = 0;
this._zr.clear();
this._coords = {};
},
/**
* @return {number}
*/
getWidth: function () {
return this._width;
},
/**
* @return {number}
*/
getHeight: function () {
return this._height;
},
/**
* @return {number}
*/
getTexture: function () {
return this._texture;
},
/**
* @return {number}
*/
getDevicePixelRatio: function () {
return this._dpr;
},
getZr: function () {
return this._zr;
},
_getCurrentNode: function () {
return this._textureAtlasNodes[this._currentNodeIdx];
},
_expand: function () {
this._currentNodeIdx++;
if (this._textureAtlasNodes[this._currentNodeIdx]) {
// Use the node created previously.
return this._textureAtlasNodes[this._currentNodeIdx];
}
var maxSize = 4096 / this._dpr;
var textureAtlasNodes = this._textureAtlasNodes;
var nodeLen = textureAtlasNodes.length;
var offsetX = (nodeLen * this._nodeWidth) % maxSize;
var offsetY = Math.floor(nodeLen * this._nodeWidth / maxSize) * this._nodeHeight;
if (offsetY >= maxSize) {
// Failed if image is too large.
if (true) {
console.error('Too much labels. Some will be ignored.');
}
return;
}
var width = (offsetX + this._nodeWidth) * this._dpr;
var height = (offsetY + this._nodeHeight) * this._dpr;
try {
// Resize will error in node.
this._zr.resize({
width: width,
height: height
});
}
catch (e) {
this._canvas.width = width;
this._canvas.height = height;
}
var newNode = new ZRTextureAtlasSurfaceNode(
this._zr, offsetX, offsetY, this._nodeWidth, this._nodeHeight, this._gap, this._dpr
);
this._textureAtlasNodes.push(newNode);
return newNode;
},
add: function (el, width, height) {
if (this._coords[el.id]) {
if (true) {
console.warn('Element already been add');
}
return this._coords[el.id];
}
var coords = this._getCurrentNode().add(el, width, height);
if (!coords) {
var newNode = this._expand();
if (!newNode) {
// To maximum
return;
}
coords = newNode.add(el, width, height);
}
this._coords[el.id] = coords;
return coords;
},
/**
* Get coord scale after texture atlas is expanded.
* @return {Array.}
*/
getCoordsScale: function () {
var dpr = this._dpr;
return [this._nodeWidth / this._canvas.width * dpr, this._nodeHeight / this._canvas.height * dpr];
},
/**
* Get texture coords of sprite image
* @param {string} id Image id
* @return {Array}
*/
getCoords: function (id) {
return this._coords[id];
}
};
/* harmony default export */ __webpack_exports__["a"] = (ZRTextureAtlasSurface);
/***/ }),
/* 74 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony export (immutable) */ __webpack_exports__["a"] = ifIgnoreOnTick;
function ifIgnoreOnTick(axis, i, interval) {
var rawTick;
var scale = axis.scale;
return scale.type === 'ordinal'
&& (
typeof interval === 'function'
? (
rawTick = scale.getTicks()[i],
!interval(rawTick, scale.getLabel(rawTick))
)
: i % (interval + 1)
);
};
/***/ }),
/* 75 */
/***/ (function(module, exports, __webpack_require__) {
var vec2 = __webpack_require__(76);
var matrix = __webpack_require__(77);
/**
* @module echarts/core/BoundingRect
*/
var v2ApplyTransform = vec2.applyTransform;
var mathMin = Math.min;
var mathMax = Math.max;
/**
* @alias module:echarts/core/BoundingRect
*/
function BoundingRect(x, y, width, height) {
if (width < 0) {
x = x + width;
width = -width;
}
if (height < 0) {
y = y + height;
height = -height;
}
/**
* @type {number}
*/
this.x = x;
/**
* @type {number}
*/
this.y = y;
/**
* @type {number}
*/
this.width = width;
/**
* @type {number}
*/
this.height = height;
}
BoundingRect.prototype = {
constructor: BoundingRect,
/**
* @param {module:echarts/core/BoundingRect} other
*/
union: function (other) {
var x = mathMin(other.x, this.x);
var y = mathMin(other.y, this.y);
this.width = mathMax(other.x + other.width, this.x + this.width) - x;
this.height = mathMax(other.y + other.height, this.y + this.height) - y;
this.x = x;
this.y = y;
},
/**
* @param {Array.} m
* @methods
*/
applyTransform: function () {
var lt = [];
var rb = [];
var lb = [];
var rt = [];
return function (m) {
// In case usage like this
// el.getBoundingRect().applyTransform(el.transform)
// And element has no transform
if (!m) {
return;
}
lt[0] = lb[0] = this.x;
lt[1] = rt[1] = this.y;
rb[0] = rt[0] = this.x + this.width;
rb[1] = lb[1] = this.y + this.height;
v2ApplyTransform(lt, lt, m);
v2ApplyTransform(rb, rb, m);
v2ApplyTransform(lb, lb, m);
v2ApplyTransform(rt, rt, m);
this.x = mathMin(lt[0], rb[0], lb[0], rt[0]);
this.y = mathMin(lt[1], rb[1], lb[1], rt[1]);
var maxX = mathMax(lt[0], rb[0], lb[0], rt[0]);
var maxY = mathMax(lt[1], rb[1], lb[1], rt[1]);
this.width = maxX - this.x;
this.height = maxY - this.y;
};
}(),
/**
* Calculate matrix of transforming from self to target rect
* @param {module:zrender/core/BoundingRect} b
* @return {Array.}
*/
calculateTransform: function (b) {
var a = this;
var sx = b.width / a.width;
var sy = b.height / a.height;
var m = matrix.create(); // 矩阵右乘
matrix.translate(m, m, [-a.x, -a.y]);
matrix.scale(m, m, [sx, sy]);
matrix.translate(m, m, [b.x, b.y]);
return m;
},
/**
* @param {(module:echarts/core/BoundingRect|Object)} b
* @return {boolean}
*/
intersect: function (b) {
if (!b) {
return false;
}
if (!(b instanceof BoundingRect)) {
// Normalize negative width/height.
b = BoundingRect.create(b);
}
var a = this;
var ax0 = a.x;
var ax1 = a.x + a.width;
var ay0 = a.y;
var ay1 = a.y + a.height;
var bx0 = b.x;
var bx1 = b.x + b.width;
var by0 = b.y;
var by1 = b.y + b.height;
return !(ax1 < bx0 || bx1 < ax0 || ay1 < by0 || by1 < ay0);
},
contain: function (x, y) {
var rect = this;
return x >= rect.x && x <= rect.x + rect.width && y >= rect.y && y <= rect.y + rect.height;
},
/**
* @return {module:echarts/core/BoundingRect}
*/
clone: function () {
return new BoundingRect(this.x, this.y, this.width, this.height);
},
/**
* Copy from another rect
*/
copy: function (other) {
this.x = other.x;
this.y = other.y;
this.width = other.width;
this.height = other.height;
},
plain: function () {
return {
x: this.x,
y: this.y,
width: this.width,
height: this.height
};
}
};
/**
* @param {Object|module:zrender/core/BoundingRect} rect
* @param {number} rect.x
* @param {number} rect.y
* @param {number} rect.width
* @param {number} rect.height
* @return {module:zrender/core/BoundingRect}
*/
BoundingRect.create = function (rect) {
return new BoundingRect(rect.x, rect.y, rect.width, rect.height);
};
var _default = BoundingRect;
module.exports = _default;
/***/ }),
/* 76 */
/***/ (function(module, exports) {
var ArrayCtor = typeof Float32Array === 'undefined' ? Array : Float32Array;
/**
* 创建一个向量
* @param {number} [x=0]
* @param {number} [y=0]
* @return {Vector2}
*/
function create(x, y) {
var out = new ArrayCtor(2);
if (x == null) {
x = 0;
}
if (y == null) {
y = 0;
}
out[0] = x;
out[1] = y;
return out;
}
/**
* 复制向量数据
* @param {Vector2} out
* @param {Vector2} v
* @return {Vector2}
*/
function copy(out, v) {
out[0] = v[0];
out[1] = v[1];
return out;
}
/**
* 克隆一个向量
* @param {Vector2} v
* @return {Vector2}
*/
function clone(v) {
var out = new ArrayCtor(2);
out[0] = v[0];
out[1] = v[1];
return out;
}
/**
* 设置向量的两个项
* @param {Vector2} out
* @param {number} a
* @param {number} b
* @return {Vector2} 结果
*/
function set(out, a, b) {
out[0] = a;
out[1] = b;
return out;
}
/**
* 向量相加
* @param {Vector2} out
* @param {Vector2} v1
* @param {Vector2} v2
*/
function add(out, v1, v2) {
out[0] = v1[0] + v2[0];
out[1] = v1[1] + v2[1];
return out;
}
/**
* 向量缩放后相加
* @param {Vector2} out
* @param {Vector2} v1
* @param {Vector2} v2
* @param {number} a
*/
function scaleAndAdd(out, v1, v2, a) {
out[0] = v1[0] + v2[0] * a;
out[1] = v1[1] + v2[1] * a;
return out;
}
/**
* 向量相减
* @param {Vector2} out
* @param {Vector2} v1
* @param {Vector2} v2
*/
function sub(out, v1, v2) {
out[0] = v1[0] - v2[0];
out[1] = v1[1] - v2[1];
return out;
}
/**
* 向量长度
* @param {Vector2} v
* @return {number}
*/
function len(v) {
return Math.sqrt(lenSquare(v));
}
var length = len; // jshint ignore:line
/**
* 向量长度平方
* @param {Vector2} v
* @return {number}
*/
function lenSquare(v) {
return v[0] * v[0] + v[1] * v[1];
}
var lengthSquare = lenSquare;
/**
* 向量乘法
* @param {Vector2} out
* @param {Vector2} v1
* @param {Vector2} v2
*/
function mul(out, v1, v2) {
out[0] = v1[0] * v2[0];
out[1] = v1[1] * v2[1];
return out;
}
/**
* 向量除法
* @param {Vector2} out
* @param {Vector2} v1
* @param {Vector2} v2
*/
function div(out, v1, v2) {
out[0] = v1[0] / v2[0];
out[1] = v1[1] / v2[1];
return out;
}
/**
* 向量点乘
* @param {Vector2} v1
* @param {Vector2} v2
* @return {number}
*/
function dot(v1, v2) {
return v1[0] * v2[0] + v1[1] * v2[1];
}
/**
* 向量缩放
* @param {Vector2} out
* @param {Vector2} v
* @param {number} s
*/
function scale(out, v, s) {
out[0] = v[0] * s;
out[1] = v[1] * s;
return out;
}
/**
* 向量归一化
* @param {Vector2} out
* @param {Vector2} v
*/
function normalize(out, v) {
var d = len(v);
if (d === 0) {
out[0] = 0;
out[1] = 0;
} else {
out[0] = v[0] / d;
out[1] = v[1] / d;
}
return out;
}
/**
* 计算向量间距离
* @param {Vector2} v1
* @param {Vector2} v2
* @return {number}
*/
function distance(v1, v2) {
return Math.sqrt((v1[0] - v2[0]) * (v1[0] - v2[0]) + (v1[1] - v2[1]) * (v1[1] - v2[1]));
}
var dist = distance;
/**
* 向量距离平方
* @param {Vector2} v1
* @param {Vector2} v2
* @return {number}
*/
function distanceSquare(v1, v2) {
return (v1[0] - v2[0]) * (v1[0] - v2[0]) + (v1[1] - v2[1]) * (v1[1] - v2[1]);
}
var distSquare = distanceSquare;
/**
* 求负向量
* @param {Vector2} out
* @param {Vector2} v
*/
function negate(out, v) {
out[0] = -v[0];
out[1] = -v[1];
return out;
}
/**
* 插值两个点
* @param {Vector2} out
* @param {Vector2} v1
* @param {Vector2} v2
* @param {number} t
*/
function lerp(out, v1, v2, t) {
out[0] = v1[0] + t * (v2[0] - v1[0]);
out[1] = v1[1] + t * (v2[1] - v1[1]);
return out;
}
/**
* 矩阵左乘向量
* @param {Vector2} out
* @param {Vector2} v
* @param {Vector2} m
*/
function applyTransform(out, v, m) {
var x = v[0];
var y = v[1];
out[0] = m[0] * x + m[2] * y + m[4];
out[1] = m[1] * x + m[3] * y + m[5];
return out;
}
/**
* 求两个向量最小值
* @param {Vector2} out
* @param {Vector2} v1
* @param {Vector2} v2
*/
function min(out, v1, v2) {
out[0] = Math.min(v1[0], v2[0]);
out[1] = Math.min(v1[1], v2[1]);
return out;
}
/**
* 求两个向量最大值
* @param {Vector2} out
* @param {Vector2} v1
* @param {Vector2} v2
*/
function max(out, v1, v2) {
out[0] = Math.max(v1[0], v2[0]);
out[1] = Math.max(v1[1], v2[1]);
return out;
}
exports.create = create;
exports.copy = copy;
exports.clone = clone;
exports.set = set;
exports.add = add;
exports.scaleAndAdd = scaleAndAdd;
exports.sub = sub;
exports.len = len;
exports.length = length;
exports.lenSquare = lenSquare;
exports.lengthSquare = lengthSquare;
exports.mul = mul;
exports.div = div;
exports.dot = dot;
exports.scale = scale;
exports.normalize = normalize;
exports.distance = distance;
exports.dist = dist;
exports.distanceSquare = distanceSquare;
exports.distSquare = distSquare;
exports.negate = negate;
exports.lerp = lerp;
exports.applyTransform = applyTransform;
exports.min = min;
exports.max = max;
/***/ }),
/* 77 */
/***/ (function(module, exports) {
/**
* 3x2矩阵操作类
* @exports zrender/tool/matrix
*/
var ArrayCtor = typeof Float32Array === 'undefined' ? Array : Float32Array;
/**
* Create a identity matrix.
* @return {Float32Array|Array.}
*/
function create() {
var out = new ArrayCtor(6);
identity(out);
return out;
}
/**
* 设置矩阵为单位矩阵
* @param {Float32Array|Array.} out
*/
function identity(out) {
out[0] = 1;
out[1] = 0;
out[2] = 0;
out[3] = 1;
out[4] = 0;
out[5] = 0;
return out;
}
/**
* 复制矩阵
* @param {Float32Array|Array.} out
* @param {Float32Array|Array.} m
*/
function copy(out, m) {
out[0] = m[0];
out[1] = m[1];
out[2] = m[2];
out[3] = m[3];
out[4] = m[4];
out[5] = m[5];
return out;
}
/**
* 矩阵相乘
* @param {Float32Array|Array.} out
* @param {Float32Array|Array.} m1
* @param {Float32Array|Array.} m2
*/
function mul(out, m1, m2) {
// Consider matrix.mul(m, m2, m);
// where out is the same as m2.
// So use temp variable to escape error.
var out0 = m1[0] * m2[0] + m1[2] * m2[1];
var out1 = m1[1] * m2[0] + m1[3] * m2[1];
var out2 = m1[0] * m2[2] + m1[2] * m2[3];
var out3 = m1[1] * m2[2] + m1[3] * m2[3];
var out4 = m1[0] * m2[4] + m1[2] * m2[5] + m1[4];
var out5 = m1[1] * m2[4] + m1[3] * m2[5] + m1[5];
out[0] = out0;
out[1] = out1;
out[2] = out2;
out[3] = out3;
out[4] = out4;
out[5] = out5;
return out;
}
/**
* 平移变换
* @param {Float32Array|Array.} out
* @param {Float32Array|Array.} a
* @param {Float32Array|Array.} v
*/
function translate(out, a, v) {
out[0] = a[0];
out[1] = a[1];
out[2] = a[2];
out[3] = a[3];
out[4] = a[4] + v[0];
out[5] = a[5] + v[1];
return out;
}
/**
* 旋转变换
* @param {Float32Array|Array.} out
* @param {Float32Array|Array.} a
* @param {number} rad
*/
function rotate(out, a, rad) {
var aa = a[0];
var ac = a[2];
var atx = a[4];
var ab = a[1];
var ad = a[3];
var aty = a[5];
var st = Math.sin(rad);
var ct = Math.cos(rad);
out[0] = aa * ct + ab * st;
out[1] = -aa * st + ab * ct;
out[2] = ac * ct + ad * st;
out[3] = -ac * st + ct * ad;
out[4] = ct * atx + st * aty;
out[5] = ct * aty - st * atx;
return out;
}
/**
* 缩放变换
* @param {Float32Array|Array.} out
* @param {Float32Array|Array.} a
* @param {Float32Array|Array.} v
*/
function scale(out, a, v) {
var vx = v[0];
var vy = v[1];
out[0] = a[0] * vx;
out[1] = a[1] * vy;
out[2] = a[2] * vx;
out[3] = a[3] * vy;
out[4] = a[4] * vx;
out[5] = a[5] * vy;
return out;
}
/**
* 求逆矩阵
* @param {Float32Array|Array.} out
* @param {Float32Array|Array.} a
*/
function invert(out, a) {
var aa = a[0];
var ac = a[2];
var atx = a[4];
var ab = a[1];
var ad = a[3];
var aty = a[5];
var det = aa * ad - ab * ac;
if (!det) {
return null;
}
det = 1.0 / det;
out[0] = ad * det;
out[1] = -ab * det;
out[2] = -ac * det;
out[3] = aa * det;
out[4] = (ac * aty - ad * atx) * det;
out[5] = (ab * atx - aa * aty) * det;
return out;
}
/**
* Clone a new matrix.
* @param {Float32Array|Array.} a
*/
function clone(a) {
var b = create();
copy(b, a);
return b;
}
exports.create = create;
exports.identity = identity;
exports.copy = copy;
exports.mul = mul;
exports.translate = translate;
exports.rotate = rotate;
exports.scale = scale;
exports.invert = invert;
exports.clone = clone;
/***/ }),
/* 78 */
/***/ (function(module, exports, __webpack_require__) {
var zrUtil = __webpack_require__(12);
var RADIAN_EPSILON = 1e-4;
function _trim(str) {
return str.replace(/^\s+/, '').replace(/\s+$/, '');
}
/**
* Linear mapping a value from domain to range
* @memberOf module:echarts/util/number
* @param {(number|Array.)} val
* @param {Array.} domain Domain extent domain[0] can be bigger than domain[1]
* @param {Array.} range Range extent range[0] can be bigger than range[1]
* @param {boolean} clamp
* @return {(number|Array.}
*/
function linearMap(val, domain, range, clamp) {
var subDomain = domain[1] - domain[0];
var subRange = range[1] - range[0];
if (subDomain === 0) {
return subRange === 0 ? range[0] : (range[0] + range[1]) / 2;
} // Avoid accuracy problem in edge, such as
// 146.39 - 62.83 === 83.55999999999999.
// See echarts/test/ut/spec/util/number.js#linearMap#accuracyError
// It is a little verbose for efficiency considering this method
// is a hotspot.
if (clamp) {
if (subDomain > 0) {
if (val <= domain[0]) {
return range[0];
} else if (val >= domain[1]) {
return range[1];
}
} else {
if (val >= domain[0]) {
return range[0];
} else if (val <= domain[1]) {
return range[1];
}
}
} else {
if (val === domain[0]) {
return range[0];
}
if (val === domain[1]) {
return range[1];
}
}
return (val - domain[0]) / subDomain * subRange + range[0];
}
/**
* Convert a percent string to absolute number.
* Returns NaN if percent is not a valid string or number
* @memberOf module:echarts/util/number
* @param {string|number} percent
* @param {number} all
* @return {number}
*/
function parsePercent(percent, all) {
switch (percent) {
case 'center':
case 'middle':
percent = '50%';
break;
case 'left':
case 'top':
percent = '0%';
break;
case 'right':
case 'bottom':
percent = '100%';
break;
}
if (typeof percent === 'string') {
if (_trim(percent).match(/%$/)) {
return parseFloat(percent) / 100 * all;
}
return parseFloat(percent);
}
return percent == null ? NaN : +percent;
}
/**
* (1) Fix rounding error of float numbers.
* (2) Support return string to avoid scientific notation like '3.5e-7'.
*
* @param {number} x
* @param {number} [precision]
* @param {boolean} [returnStr]
* @return {number|string}
*/
function round(x, precision, returnStr) {
if (precision == null) {
precision = 10;
} // Avoid range error
precision = Math.min(Math.max(0, precision), 20);
x = (+x).toFixed(precision);
return returnStr ? x : +x;
}
function asc(arr) {
arr.sort(function (a, b) {
return a - b;
});
return arr;
}
/**
* Get precision
* @param {number} val
*/
function getPrecision(val) {
val = +val;
if (isNaN(val)) {
return 0;
} // It is much faster than methods converting number to string as follows
// var tmp = val.toString();
// return tmp.length - 1 - tmp.indexOf('.');
// especially when precision is low
var e = 1;
var count = 0;
while (Math.round(val * e) / e !== val) {
e *= 10;
count++;
}
return count;
}
/**
* @param {string|number} val
* @return {number}
*/
function getPrecisionSafe(val) {
var str = val.toString(); // Consider scientific notation: '3.4e-12' '3.4e+12'
var eIndex = str.indexOf('e');
if (eIndex > 0) {
var precision = +str.slice(eIndex + 1);
return precision < 0 ? -precision : 0;
} else {
var dotIndex = str.indexOf('.');
return dotIndex < 0 ? 0 : str.length - 1 - dotIndex;
}
}
/**
* Minimal dicernible data precisioin according to a single pixel.
*
* @param {Array.} dataExtent
* @param {Array.} pixelExtent
* @return {number} precision
*/
function getPixelPrecision(dataExtent, pixelExtent) {
var log = Math.log;
var LN10 = Math.LN10;
var dataQuantity = Math.floor(log(dataExtent[1] - dataExtent[0]) / LN10);
var sizeQuantity = Math.round(log(Math.abs(pixelExtent[1] - pixelExtent[0])) / LN10); // toFixed() digits argument must be between 0 and 20.
var precision = Math.min(Math.max(-dataQuantity + sizeQuantity, 0), 20);
return !isFinite(precision) ? 20 : precision;
}
/**
* Get a data of given precision, assuring the sum of percentages
* in valueList is 1.
* The largest remainer method is used.
* https://en.wikipedia.org/wiki/Largest_remainder_method
*
* @param {Array.} valueList a list of all data
* @param {number} idx index of the data to be processed in valueList
* @param {number} precision integer number showing digits of precision
* @return {number} percent ranging from 0 to 100
*/
function getPercentWithPrecision(valueList, idx, precision) {
if (!valueList[idx]) {
return 0;
}
var sum = zrUtil.reduce(valueList, function (acc, val) {
return acc + (isNaN(val) ? 0 : val);
}, 0);
if (sum === 0) {
return 0;
}
var digits = Math.pow(10, precision);
var votesPerQuota = zrUtil.map(valueList, function (val) {
return (isNaN(val) ? 0 : val) / sum * digits * 100;
});
var targetSeats = digits * 100;
var seats = zrUtil.map(votesPerQuota, function (votes) {
// Assign automatic seats.
return Math.floor(votes);
});
var currentSum = zrUtil.reduce(seats, function (acc, val) {
return acc + val;
}, 0);
var remainder = zrUtil.map(votesPerQuota, function (votes, idx) {
return votes - seats[idx];
}); // Has remainding votes.
while (currentSum < targetSeats) {
// Find next largest remainder.
var max = Number.NEGATIVE_INFINITY;
var maxId = null;
for (var i = 0, len = remainder.length; i < len; ++i) {
if (remainder[i] > max) {
max = remainder[i];
maxId = i;
}
} // Add a vote to max remainder.
++seats[maxId];
remainder[maxId] = 0;
++currentSum;
}
return seats[idx] / digits;
} // Number.MAX_SAFE_INTEGER, ie do not support.
var MAX_SAFE_INTEGER = 9007199254740991;
/**
* To 0 - 2 * PI, considering negative radian.
* @param {number} radian
* @return {number}
*/
function remRadian(radian) {
var pi2 = Math.PI * 2;
return (radian % pi2 + pi2) % pi2;
}
/**
* @param {type} radian
* @return {boolean}
*/
function isRadianAroundZero(val) {
return val > -RADIAN_EPSILON && val < RADIAN_EPSILON;
}
var TIME_REG = /^(?:(\d{4})(?:[-\/](\d{1,2})(?:[-\/](\d{1,2})(?:[T ](\d{1,2})(?::(\d\d)(?::(\d\d)(?:[.,](\d+))?)?)?(Z|[\+\-]\d\d:?\d\d)?)?)?)?)?$/; // jshint ignore:line
/**
* @param {string|Date|number} value These values can be accepted:
* + An instance of Date, represent a time in its own time zone.
* + Or string in a subset of ISO 8601, only including:
* + only year, month, date: '2012-03', '2012-03-01', '2012-03-01 05', '2012-03-01 05:06',
* + separated with T or space: '2012-03-01T12:22:33.123', '2012-03-01 12:22:33.123',
* + time zone: '2012-03-01T12:22:33Z', '2012-03-01T12:22:33+8000', '2012-03-01T12:22:33-05:00',
* all of which will be treated as local time if time zone is not specified
* (see ).
* + Or other string format, including (all of which will be treated as loacal time):
* '2012', '2012-3-1', '2012/3/1', '2012/03/01',
* '2009/6/12 2:00', '2009/6/12 2:05:08', '2009/6/12 2:05:08.123'
* + a timestamp, which represent a time in UTC.
* @return {Date} date
*/
function parseDate(value) {
if (value instanceof Date) {
return value;
} else if (typeof value === 'string') {
// Different browsers parse date in different way, so we parse it manually.
// Some other issues:
// new Date('1970-01-01') is UTC,
// new Date('1970/01/01') and new Date('1970-1-01') is local.
// See issue #3623
var match = TIME_REG.exec(value);
if (!match) {
// return Invalid Date.
return new Date(NaN);
} // Use local time when no timezone offset specifed.
if (!match[8]) {
// match[n] can only be string or undefined.
// But take care of '12' + 1 => '121'.
return new Date(+match[1], +(match[2] || 1) - 1, +match[3] || 1, +match[4] || 0, +(match[5] || 0), +match[6] || 0, +match[7] || 0);
} // Timezoneoffset of Javascript Date has considered DST (Daylight Saving Time,
// https://tc39.github.io/ecma262/#sec-daylight-saving-time-adjustment).
// For example, system timezone is set as "Time Zone: America/Toronto",
// then these code will get different result:
// `new Date(1478411999999).getTimezoneOffset(); // get 240`
// `new Date(1478412000000).getTimezoneOffset(); // get 300`
// So we should not use `new Date`, but use `Date.UTC`.
else {
var hour = +match[4] || 0;
if (match[8].toUpperCase() !== 'Z') {
hour -= match[8].slice(0, 3);
}
return new Date(Date.UTC(+match[1], +(match[2] || 1) - 1, +match[3] || 1, hour, +(match[5] || 0), +match[6] || 0, +match[7] || 0));
}
} else if (value == null) {
return new Date(NaN);
}
return new Date(Math.round(value));
}
/**
* Quantity of a number. e.g. 0.1, 1, 10, 100
*
* @param {number} val
* @return {number}
*/
function quantity(val) {
return Math.pow(10, quantityExponent(val));
}
function quantityExponent(val) {
return Math.floor(Math.log(val) / Math.LN10);
}
/**
* find a “nice” number approximately equal to x. Round the number if round = true,
* take ceiling if round = false. The primary observation is that the “nicest”
* numbers in decimal are 1, 2, and 5, and all power-of-ten multiples of these numbers.
*
* See "Nice Numbers for Graph Labels" of Graphic Gems.
*
* @param {number} val Non-negative value.
* @param {boolean} round
* @return {number}
*/
function nice(val, round) {
var exponent = quantityExponent(val);
var exp10 = Math.pow(10, exponent);
var f = val / exp10; // 1 <= f < 10
var nf;
if (round) {
if (f < 1.5) {
nf = 1;
} else if (f < 2.5) {
nf = 2;
} else if (f < 4) {
nf = 3;
} else if (f < 7) {
nf = 5;
} else {
nf = 10;
}
} else {
if (f < 1) {
nf = 1;
} else if (f < 2) {
nf = 2;
} else if (f < 3) {
nf = 3;
} else if (f < 5) {
nf = 5;
} else {
nf = 10;
}
}
val = nf * exp10; // Fix 3 * 0.1 === 0.30000000000000004 issue (see IEEE 754).
// 20 is the uppper bound of toFixed.
return exponent >= -20 ? +val.toFixed(exponent < 0 ? -exponent : 0) : val;
}
/**
* Order intervals asc, and split them when overlap.
* expect(numberUtil.reformIntervals([
* {interval: [18, 62], close: [1, 1]},
* {interval: [-Infinity, -70], close: [0, 0]},
* {interval: [-70, -26], close: [1, 1]},
* {interval: [-26, 18], close: [1, 1]},
* {interval: [62, 150], close: [1, 1]},
* {interval: [106, 150], close: [1, 1]},
* {interval: [150, Infinity], close: [0, 0]}
* ])).toEqual([
* {interval: [-Infinity, -70], close: [0, 0]},
* {interval: [-70, -26], close: [1, 1]},
* {interval: [-26, 18], close: [0, 1]},
* {interval: [18, 62], close: [0, 1]},
* {interval: [62, 150], close: [0, 1]},
* {interval: [150, Infinity], close: [0, 0]}
* ]);
* @param {Array.} list, where `close` mean open or close
* of the interval, and Infinity can be used.
* @return {Array.} The origin list, which has been reformed.
*/
function reformIntervals(list) {
list.sort(function (a, b) {
return littleThan(a, b, 0) ? -1 : 1;
});
var curr = -Infinity;
var currClose = 1;
for (var i = 0; i < list.length;) {
var interval = list[i].interval;
var close = list[i].close;
for (var lg = 0; lg < 2; lg++) {
if (interval[lg] <= curr) {
interval[lg] = curr;
close[lg] = !lg ? 1 - currClose : 1;
}
curr = interval[lg];
currClose = close[lg];
}
if (interval[0] === interval[1] && close[0] * close[1] !== 1) {
list.splice(i, 1);
} else {
i++;
}
}
return list;
function littleThan(a, b, lg) {
return a.interval[lg] < b.interval[lg] || a.interval[lg] === b.interval[lg] && (a.close[lg] - b.close[lg] === (!lg ? 1 : -1) || !lg && littleThan(a, b, 1));
}
}
/**
* parseFloat NaNs numeric-cast false positives (null|true|false|"")
* ...but misinterprets leading-number strings, particularly hex literals ("0x...")
* subtraction forces infinities to NaN
*
* @param {*} v
* @return {boolean}
*/
function isNumeric(v) {
return v - parseFloat(v) >= 0;
}
exports.linearMap = linearMap;
exports.parsePercent = parsePercent;
exports.round = round;
exports.asc = asc;
exports.getPrecision = getPrecision;
exports.getPrecisionSafe = getPrecisionSafe;
exports.getPixelPrecision = getPixelPrecision;
exports.getPercentWithPrecision = getPercentWithPrecision;
exports.MAX_SAFE_INTEGER = MAX_SAFE_INTEGER;
exports.remRadian = remRadian;
exports.isRadianAroundZero = isRadianAroundZero;
exports.parseDate = parseDate;
exports.quantity = quantity;
exports.nice = nice;
exports.reformIntervals = reformIntervals;
exports.isNumeric = isNumeric;
/***/ }),
/* 79 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_glenum__ = __webpack_require__(11);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__core_util__ = __webpack_require__(20);
var TexturePool = function () {
this._pool = {};
this._allocatedTextures = [];
};
TexturePool.prototype = {
constructor: TexturePool,
get: function (parameters) {
var key = generateKey(parameters);
if (!this._pool.hasOwnProperty(key)) {
this._pool[key] = [];
}
var list = this._pool[key];
if (!list.length) {
var texture = new __WEBPACK_IMPORTED_MODULE_0__Texture2D__["a" /* default */](parameters);
this._allocatedTextures.push(texture);
return texture;
}
return list.pop();
},
put: function (texture) {
var key = generateKey(texture);
if (!this._pool.hasOwnProperty(key)) {
this._pool[key] = [];
}
var list = this._pool[key];
list.push(texture);
},
clear: function (renderer) {
for (var i = 0; i < this._allocatedTextures.length; i++) {
this._allocatedTextures[i].dispose(renderer);
}
this._pool = {};
this._allocatedTextures = [];
}
};
var defaultParams = {
width: 512,
height: 512,
type: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].UNSIGNED_BYTE,
format: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].RGBA,
wrapS: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].CLAMP_TO_EDGE,
wrapT: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].CLAMP_TO_EDGE,
minFilter: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINEAR_MIPMAP_LINEAR,
magFilter: __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINEAR,
useMipmap: true,
anisotropic: 1,
flipY: true,
unpackAlignment: 4,
premultiplyAlpha: false
};
var defaultParamPropList = Object.keys(defaultParams);
function generateKey(parameters) {
__WEBPACK_IMPORTED_MODULE_2__core_util__["a" /* default */].defaultsWithPropList(parameters, defaultParams, defaultParamPropList);
fallBack(parameters);
var key = '';
for (var i = 0; i < defaultParamPropList.length; i++) {
var name = defaultParamPropList[i];
var chunk = parameters[name].toString();
key += chunk;
}
return key;
}
function fallBack(target) {
var IPOT = isPowerOfTwo(target.width, target.height);
if (target.format === __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].DEPTH_COMPONENT) {
target.useMipmap = false;
}
if (!IPOT || !target.useMipmap) {
if (target.minFilter == __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].NEAREST_MIPMAP_NEAREST ||
target.minFilter == __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].NEAREST_MIPMAP_LINEAR) {
target.minFilter = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].NEAREST;
} else if (
target.minFilter == __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINEAR_MIPMAP_LINEAR ||
target.minFilter == __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINEAR_MIPMAP_NEAREST
) {
target.minFilter = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].LINEAR;
}
}
if (!IPOT) {
target.wrapS = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].CLAMP_TO_EDGE;
target.wrapT = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].CLAMP_TO_EDGE;
}
}
function isPowerOfTwo(width, height) {
return (width & (width-1)) === 0 &&
(height & (height-1)) === 0;
}
/* harmony default export */ __webpack_exports__["a"] = (TexturePool);
/***/ }),
/* 80 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.compositor.kernel.gaussian_9\nfloat gaussianKernel[9];\ngaussianKernel[0] = 0.07;\ngaussianKernel[1] = 0.09;\ngaussianKernel[2] = 0.12;\ngaussianKernel[3] = 0.14;\ngaussianKernel[4] = 0.16;\ngaussianKernel[5] = 0.14;\ngaussianKernel[6] = 0.12;\ngaussianKernel[7] = 0.09;\ngaussianKernel[8] = 0.07;\n@end\n@export clay.compositor.kernel.gaussian_13\nfloat gaussianKernel[13];\ngaussianKernel[0] = 0.02;\ngaussianKernel[1] = 0.03;\ngaussianKernel[2] = 0.06;\ngaussianKernel[3] = 0.08;\ngaussianKernel[4] = 0.11;\ngaussianKernel[5] = 0.13;\ngaussianKernel[6] = 0.14;\ngaussianKernel[7] = 0.13;\ngaussianKernel[8] = 0.11;\ngaussianKernel[9] = 0.08;\ngaussianKernel[10] = 0.06;\ngaussianKernel[11] = 0.03;\ngaussianKernel[12] = 0.02;\n@end\n@export clay.compositor.gaussian_blur\n#define SHADER_NAME gaussian_blur\nuniform sampler2D texture;varying vec2 v_Texcoord;\nuniform float blurSize : 2.0;\nuniform vec2 textureSize : [512.0, 512.0];\nuniform float blurDir : 0.0;\n@import clay.util.rgbm\n@import clay.util.clamp_sample\nvoid main (void)\n{\n @import clay.compositor.kernel.gaussian_9\n vec2 off = blurSize / textureSize;\n off *= vec2(1.0 - blurDir, blurDir);\n vec4 sum = vec4(0.0);\n float weightAll = 0.0;\n for (int i = 0; i < 9; i++) {\n float w = gaussianKernel[i];\n vec4 texel = decodeHDR(clampSample(texture, v_Texcoord + float(i - 4) * off));\n sum += texel * w;\n weightAll += w;\n }\n gl_FragColor = encodeHDR(sum / max(weightAll, 0.01));\n}\n@end\n");
/***/ }),
/* 81 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("\n@export clay.compositor.lut\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform sampler2D lookup;\nvoid main()\n{\n vec4 tex = texture2D(texture, v_Texcoord);\n float blueColor = tex.b * 63.0;\n vec2 quad1;\n quad1.y = floor(floor(blueColor) / 8.0);\n quad1.x = floor(blueColor) - (quad1.y * 8.0);\n vec2 quad2;\n quad2.y = floor(ceil(blueColor) / 8.0);\n quad2.x = ceil(blueColor) - (quad2.y * 8.0);\n vec2 texPos1;\n texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * tex.r);\n texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * tex.g);\n vec2 texPos2;\n texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * tex.r);\n texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * tex.g);\n vec4 newColor1 = texture2D(lookup, texPos1);\n vec4 newColor2 = texture2D(lookup, texPos2);\n vec4 newColor = mix(newColor1, newColor2, fract(blueColor));\n gl_FragColor = vec4(newColor.rgb, tex.w);\n}\n@end");
/***/ }),
/* 82 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.compositor.output\n#define OUTPUT_ALPHA\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\n@import clay.util.rgbm\nvoid main()\n{\n vec4 tex = decodeHDR(texture2D(texture, v_Texcoord));\n gl_FragColor.rgb = tex.rgb;\n#ifdef OUTPUT_ALPHA\n gl_FragColor.a = tex.a;\n#else\n gl_FragColor.a = 1.0;\n#endif\n gl_FragColor = encodeHDR(gl_FragColor);\n#ifdef PREMULTIPLY_ALPHA\n gl_FragColor.rgb *= gl_FragColor.a;\n#endif\n}\n@end");
/***/ }),
/* 83 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.compositor.bright\nuniform sampler2D texture;\nuniform float threshold : 1;\nuniform float scale : 1.0;\nuniform vec2 textureSize: [512, 512];\nvarying vec2 v_Texcoord;\nconst vec3 lumWeight = vec3(0.2125, 0.7154, 0.0721);\n@import clay.util.rgbm\nvec4 median(vec4 a, vec4 b, vec4 c)\n{\n return a + b + c - min(min(a, b), c) - max(max(a, b), c);\n}\nvoid main()\n{\n vec4 texel = decodeHDR(texture2D(texture, v_Texcoord));\n#ifdef ANTI_FLICKER\n vec3 d = 1.0 / textureSize.xyx * vec3(1.0, 1.0, 0.0);\n vec4 s1 = decodeHDR(texture2D(texture, v_Texcoord - d.xz));\n vec4 s2 = decodeHDR(texture2D(texture, v_Texcoord + d.xz));\n vec4 s3 = decodeHDR(texture2D(texture, v_Texcoord - d.zy));\n vec4 s4 = decodeHDR(texture2D(texture, v_Texcoord + d.zy));\n texel = median(median(texel, s1, s2), s3, s4);\n#endif\n float lum = dot(texel.rgb , lumWeight);\n vec4 color;\n if (lum > threshold && texel.a > 0.0)\n {\n color = vec4(texel.rgb * scale, texel.a * scale);\n }\n else\n {\n color = vec4(0.0);\n }\n gl_FragColor = encodeHDR(color);\n}\n@end\n");
/***/ }),
/* 84 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.compositor.downsample\nuniform sampler2D texture;\nuniform vec2 textureSize : [512, 512];\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\nfloat brightness(vec3 c)\n{\n return max(max(c.r, c.g), c.b);\n}\n@import clay.util.clamp_sample\nvoid main()\n{\n vec4 d = vec4(-1.0, -1.0, 1.0, 1.0) / textureSize.xyxy;\n#ifdef ANTI_FLICKER\n vec3 s1 = decodeHDR(clampSample(texture, v_Texcoord + d.xy)).rgb;\n vec3 s2 = decodeHDR(clampSample(texture, v_Texcoord + d.zy)).rgb;\n vec3 s3 = decodeHDR(clampSample(texture, v_Texcoord + d.xw)).rgb;\n vec3 s4 = decodeHDR(clampSample(texture, v_Texcoord + d.zw)).rgb;\n float s1w = 1.0 / (brightness(s1) + 1.0);\n float s2w = 1.0 / (brightness(s2) + 1.0);\n float s3w = 1.0 / (brightness(s3) + 1.0);\n float s4w = 1.0 / (brightness(s4) + 1.0);\n float oneDivideSum = 1.0 / (s1w + s2w + s3w + s4w);\n vec4 color = vec4(\n (s1 * s1w + s2 * s2w + s3 * s3w + s4 * s4w) * oneDivideSum,\n 1.0\n );\n#else\n vec4 color = decodeHDR(clampSample(texture, v_Texcoord + d.xy));\n color += decodeHDR(clampSample(texture, v_Texcoord + d.zy));\n color += decodeHDR(clampSample(texture, v_Texcoord + d.xw));\n color += decodeHDR(clampSample(texture, v_Texcoord + d.zw));\n color *= 0.25;\n#endif\n gl_FragColor = encodeHDR(color);\n}\n@end");
/***/ }),
/* 85 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("\n@export clay.compositor.upsample\n#define HIGH_QUALITY\nuniform sampler2D texture;\nuniform vec2 textureSize : [512, 512];\nuniform float sampleScale: 0.5;\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\n@import clay.util.clamp_sample\nvoid main()\n{\n#ifdef HIGH_QUALITY\n vec4 d = vec4(1.0, 1.0, -1.0, 0.0) / textureSize.xyxy * sampleScale;\n vec4 s;\n s = decodeHDR(clampSample(texture, v_Texcoord - d.xy));\n s += decodeHDR(clampSample(texture, v_Texcoord - d.wy)) * 2.0;\n s += decodeHDR(clampSample(texture, v_Texcoord - d.zy));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.zw)) * 2.0;\n s += decodeHDR(clampSample(texture, v_Texcoord )) * 4.0;\n s += decodeHDR(clampSample(texture, v_Texcoord + d.xw)) * 2.0;\n s += decodeHDR(clampSample(texture, v_Texcoord + d.zy));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.wy)) * 2.0;\n s += decodeHDR(clampSample(texture, v_Texcoord + d.xy));\n gl_FragColor = encodeHDR(s / 16.0);\n#else\n vec4 d = vec4(-1.0, -1.0, +1.0, +1.0) / textureSize.xyxy;\n vec4 s;\n s = decodeHDR(clampSample(texture, v_Texcoord + d.xy));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.zy));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.xw));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.zw));\n gl_FragColor = encodeHDR(s / 4.0);\n#endif\n}\n@end");
/***/ }),
/* 86 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.compositor.hdr.composite\nuniform sampler2D texture;\n#ifdef BLOOM_ENABLED\nuniform sampler2D bloom;\n#endif\n#ifdef LENSFLARE_ENABLED\nuniform sampler2D lensflare;\nuniform sampler2D lensdirt;\n#endif\n#ifdef LUM_ENABLED\nuniform sampler2D lum;\n#endif\n#ifdef LUT_ENABLED\nuniform sampler2D lut;\n#endif\n#ifdef COLOR_CORRECTION\nuniform float brightness : 0.0;\nuniform float contrast : 1.0;\nuniform float saturation : 1.0;\n#endif\n#ifdef VIGNETTE\nuniform float vignetteDarkness: 1.0;\nuniform float vignetteOffset: 1.0;\n#endif\nuniform float exposure : 1.0;\nuniform float bloomIntensity : 0.25;\nuniform float lensflareIntensity : 1;\nvarying vec2 v_Texcoord;\n@import clay.util.srgb\nvec3 ACESToneMapping(vec3 color)\n{\n const float A = 2.51;\n const float B = 0.03;\n const float C = 2.43;\n const float D = 0.59;\n const float E = 0.14;\n return (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nfloat eyeAdaption(float fLum)\n{\n return mix(0.2, fLum, 0.5);\n}\n#ifdef LUT_ENABLED\nvec3 lutTransform(vec3 color) {\n float blueColor = color.b * 63.0;\n vec2 quad1;\n quad1.y = floor(floor(blueColor) / 8.0);\n quad1.x = floor(blueColor) - (quad1.y * 8.0);\n vec2 quad2;\n quad2.y = floor(ceil(blueColor) / 8.0);\n quad2.x = ceil(blueColor) - (quad2.y * 8.0);\n vec2 texPos1;\n texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.r);\n texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.g);\n vec2 texPos2;\n texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.r);\n texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.g);\n vec4 newColor1 = texture2D(lut, texPos1);\n vec4 newColor2 = texture2D(lut, texPos2);\n vec4 newColor = mix(newColor1, newColor2, fract(blueColor));\n return newColor.rgb;\n}\n#endif\n@import clay.util.rgbm\nvoid main()\n{\n vec4 texel = vec4(0.0);\n vec4 originalTexel = vec4(0.0);\n#ifdef TEXTURE_ENABLED\n texel = decodeHDR(texture2D(texture, v_Texcoord));\n originalTexel = texel;\n#endif\n#ifdef BLOOM_ENABLED\n vec4 bloomTexel = decodeHDR(texture2D(bloom, v_Texcoord));\n texel.rgb += bloomTexel.rgb * bloomIntensity;\n texel.a += bloomTexel.a * bloomIntensity;\n#endif\n#ifdef LENSFLARE_ENABLED\n texel += decodeHDR(texture2D(lensflare, v_Texcoord)) * texture2D(lensdirt, v_Texcoord) * lensflareIntensity;\n#endif\n texel.a = min(texel.a, 1.0);\n#ifdef LUM_ENABLED\n float fLum = texture2D(lum, vec2(0.5, 0.5)).r;\n float adaptedLumDest = 3.0 / (max(0.1, 1.0 + 10.0*eyeAdaption(fLum)));\n float exposureBias = adaptedLumDest * exposure;\n#else\n float exposureBias = exposure;\n#endif\n texel.rgb *= exposureBias;\n texel.rgb = ACESToneMapping(texel.rgb);\n texel = linearTosRGB(texel);\n#ifdef LUT_ENABLED\n texel.rgb = lutTransform(clamp(texel.rgb,vec3(0.0),vec3(1.0)));\n#endif\n#ifdef COLOR_CORRECTION\n texel.rgb = clamp(texel.rgb + vec3(brightness), 0.0, 1.0);\n texel.rgb = clamp((texel.rgb - vec3(0.5))*contrast+vec3(0.5), 0.0, 1.0);\n float lum = dot(texel.rgb, vec3(0.2125, 0.7154, 0.0721));\n texel.rgb = mix(vec3(lum), texel.rgb, saturation);\n#endif\n#ifdef VIGNETTE\n vec2 uv = (v_Texcoord - vec2(0.5)) * vec2(vignetteOffset);\n texel.rgb = mix(texel.rgb, vec3(1.0 - vignetteDarkness), dot(uv, uv));\n#endif\n gl_FragColor = encodeHDR(texel);\n#ifdef DEBUG\n #if DEBUG == 1\n gl_FragColor = encodeHDR(decodeHDR(texture2D(texture, v_Texcoord)));\n #elif DEBUG == 2\n gl_FragColor = encodeHDR(decodeHDR(texture2D(bloom, v_Texcoord)) * bloomIntensity);\n #elif DEBUG == 3\n gl_FragColor = encodeHDR(decodeHDR(texture2D(lensflare, v_Texcoord) * lensflareIntensity));\n #endif\n#endif\n if (originalTexel.a <= 0.01 && gl_FragColor.a > 1e-5) {\n gl_FragColor.a = dot(gl_FragColor.rgb, vec3(0.2125, 0.7154, 0.0721));\n }\n#ifdef PREMULTIPLY_ALPHA\n gl_FragColor.rgb *= gl_FragColor.a;\n#endif\n}\n@end");
/***/ }),
/* 87 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.compositor.blend\n#define SHADER_NAME blend\n#ifdef TEXTURE1_ENABLED\nuniform sampler2D texture1;\nuniform float weight1 : 1.0;\n#endif\n#ifdef TEXTURE2_ENABLED\nuniform sampler2D texture2;\nuniform float weight2 : 1.0;\n#endif\n#ifdef TEXTURE3_ENABLED\nuniform sampler2D texture3;\nuniform float weight3 : 1.0;\n#endif\n#ifdef TEXTURE4_ENABLED\nuniform sampler2D texture4;\nuniform float weight4 : 1.0;\n#endif\n#ifdef TEXTURE5_ENABLED\nuniform sampler2D texture5;\nuniform float weight5 : 1.0;\n#endif\n#ifdef TEXTURE6_ENABLED\nuniform sampler2D texture6;\nuniform float weight6 : 1.0;\n#endif\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\nvoid main()\n{\n vec4 tex = vec4(0.0);\n#ifdef TEXTURE1_ENABLED\n tex += decodeHDR(texture2D(texture1, v_Texcoord)) * weight1;\n#endif\n#ifdef TEXTURE2_ENABLED\n tex += decodeHDR(texture2D(texture2, v_Texcoord)) * weight2;\n#endif\n#ifdef TEXTURE3_ENABLED\n tex += decodeHDR(texture2D(texture3, v_Texcoord)) * weight3;\n#endif\n#ifdef TEXTURE4_ENABLED\n tex += decodeHDR(texture2D(texture4, v_Texcoord)) * weight4;\n#endif\n#ifdef TEXTURE5_ENABLED\n tex += decodeHDR(texture2D(texture5, v_Texcoord)) * weight5;\n#endif\n#ifdef TEXTURE6_ENABLED\n tex += decodeHDR(texture2D(texture6, v_Texcoord)) * weight6;\n#endif\n gl_FragColor = encodeHDR(tex);\n}\n@end");
/***/ }),
/* 88 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.compositor.fxaa\nuniform sampler2D texture;\nuniform vec4 viewport : VIEWPORT;\nvarying vec2 v_Texcoord;\n#define FXAA_REDUCE_MIN (1.0/128.0)\n#define FXAA_REDUCE_MUL (1.0/8.0)\n#define FXAA_SPAN_MAX 8.0\n@import clay.util.rgbm\nvoid main()\n{\n vec2 resolution = 1.0 / viewport.zw;\n vec3 rgbNW = decodeHDR( texture2D( texture, ( gl_FragCoord.xy + vec2( -1.0, -1.0 ) ) * resolution ) ).xyz;\n vec3 rgbNE = decodeHDR( texture2D( texture, ( gl_FragCoord.xy + vec2( 1.0, -1.0 ) ) * resolution ) ).xyz;\n vec3 rgbSW = decodeHDR( texture2D( texture, ( gl_FragCoord.xy + vec2( -1.0, 1.0 ) ) * resolution ) ).xyz;\n vec3 rgbSE = decodeHDR( texture2D( texture, ( gl_FragCoord.xy + vec2( 1.0, 1.0 ) ) * resolution ) ).xyz;\n vec4 rgbaM = decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution ) );\n vec3 rgbM = rgbaM.xyz;\n float opacity = rgbaM.w;\n vec3 luma = vec3( 0.299, 0.587, 0.114 );\n float lumaNW = dot( rgbNW, luma );\n float lumaNE = dot( rgbNE, luma );\n float lumaSW = dot( rgbSW, luma );\n float lumaSE = dot( rgbSE, luma );\n float lumaM = dot( rgbM, luma );\n float lumaMin = min( lumaM, min( min( lumaNW, lumaNE ), min( lumaSW, lumaSE ) ) );\n float lumaMax = max( lumaM, max( max( lumaNW, lumaNE) , max( lumaSW, lumaSE ) ) );\n vec2 dir;\n dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));\n dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));\n float dirReduce = max( ( lumaNW + lumaNE + lumaSW + lumaSE ) * ( 0.25 * FXAA_REDUCE_MUL ), FXAA_REDUCE_MIN );\n float rcpDirMin = 1.0 / ( min( abs( dir.x ), abs( dir.y ) ) + dirReduce );\n dir = min( vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),\n max( vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),\n dir * rcpDirMin)) * resolution;\n vec3 rgbA = decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution + dir * ( 1.0 / 3.0 - 0.5 ) ) ).xyz;\n rgbA += decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution + dir * ( 2.0 / 3.0 - 0.5 ) ) ).xyz;\n rgbA *= 0.5;\n vec3 rgbB = decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution + dir * -0.5 ) ).xyz;\n rgbB += decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution + dir * 0.5 ) ).xyz;\n rgbB *= 0.25;\n rgbB += rgbA * 0.5;\n float lumaB = dot( rgbB, luma );\n if ( ( lumaB < lumaMin ) || ( lumaB > lumaMax ) )\n {\n gl_FragColor = vec4( rgbA, opacity );\n }\n else {\n gl_FragColor = vec4( rgbB, opacity );\n }\n}\n@end");
/***/ }),
/* 89 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony default export */ __webpack_exports__["a"] = ({
getFilledRegions: function (regions, mapData) {
var regionsArr = (regions || []).slice();
var geoJson;
if (typeof mapData === 'string') {
mapData = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.getMap(mapData);
geoJson = mapData && mapData.geoJson;
}
else {
if (mapData && mapData.features) {
geoJson = mapData;
}
}
if (!geoJson) {
if (true) {
console.error('Map ' + mapData + ' not exists. You can download map file on http://echarts.baidu.com/download-map.html');
if (!geoJson.features) {
console.error('Invalid GeoJSON for map3D');
}
}
return [];
}
var dataNameMap = {};
var features = geoJson.features;
for (var i = 0; i < regionsArr.length; i++) {
dataNameMap[regionsArr[i].name] = regionsArr[i];
}
for (var i = 0; i < features.length; i++) {
var name = features[i].properties.name;
if (!dataNameMap[name]) {
regionsArr.push({
name: name
});
}
}
return regionsArr;
},
defaultOption: {
show: true,
zlevel: -10,
// geoJson used by geo3D
map: '',
// Layout used for viewport
left: 0,
top: 0,
width: '100%',
height: '100%',
boxWidth: 100,
boxHeight: 10,
boxDepth: 'auto',
regionHeight: 3,
environment: 'auto',
groundPlane: {
show: false,
color: '#aaa'
},
shading: 'lambert',
light: {
main: {
alpha: 40,
beta: 30
}
},
viewControl: {
alpha: 40,
beta: 0,
distance: 100,
orthographicSize: 60,
minAlpha: 5,
minBeta: -80,
maxBeta: 80
},
label: {
show: false,
// Distance in 3d space.
distance: 2,
textStyle: {
fontSize: 20,
color: '#000',
backgroundColor: 'rgba(255,255,255,0.7)',
padding: 3,
borderRadius: 4
}
},
// TODO
// altitude: {
// min: 'auto',
// max: 'auto',
// height: []
// },
// labelLine
// light
// postEffect
// temporalSuperSampling
itemStyle: {
color: '#fff',
borderWidth: 0,
borderColor: '#333'
},
emphasis: {
itemStyle: {
// color: '#f94b59'
color: '#639fc0'
},
label: {
show: true
}
}
}
});
/***/ }),
/* 90 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
function swap(arr, a, b) {
var tmp = arr[a];
arr[a] = arr[b];
arr[b] = tmp;
}
function partition(arr, pivot, left, right, compare) {
var storeIndex = left;
var pivotValue = arr[pivot];
// put the pivot on the right
swap(arr, pivot, right);
// go through the rest
for(var v = left; v < right; v++) {
if(compare(arr[v], pivotValue) < 0) {
swap(arr, v, storeIndex);
storeIndex++;
}
}
// finally put the pivot in the correct place
swap(arr, right, storeIndex);
return storeIndex;
}
function quickSort(array, compare, left, right) {
if(left < right) {
var pivot = Math.floor((left + right) / 2);
var newPivot = partition(array, pivot, left, right, compare);
quickSort(array, compare, left, newPivot - 1);
quickSort(array, compare, newPivot + 1, right);
}
}
// TODO Test.
function ProgressiveQuickSort() {
// this._pivotList = new LinkedList();
this._parts = [];
}
ProgressiveQuickSort.prototype.step = function (arr, compare, frame) {
var len = arr.length;
if (frame === 0) {
this._parts = [];
this._sorted = false;
// Pick a start pivot;
var pivot = Math.floor(len / 2);
this._parts.push({
pivot: pivot,
left: 0,
right: len - 1
});
this._currentSortPartIdx = 0;
}
if (this._sorted) {
return;
}
var parts = this._parts;
if (parts.length === 0) {
this._sorted = true;
// Already finished.
return true;
}
else if (parts.length < 512) {
// Sort large parts in about 10 frames.
for (var i = 0; i < parts.length; i++) {
// Partition and Modify the pivot index.
parts[i].pivot = partition(
arr, parts[i].pivot, parts[i].left, parts[i].right, compare
);
}
var subdividedParts = [];
for (var i = 0; i < parts.length; i++) {
// Subdivide left
var left = parts[i].left;
var right = parts[i].pivot - 1;
if (right > left) {
subdividedParts.push({
pivot: Math.floor((right + left) / 2),
left: left, right: right
});
}
// Subdivide right
var left = parts[i].pivot + 1;
var right = parts[i].right;
if (right > left) {
subdividedParts.push({
pivot: Math.floor((right + left) / 2),
left: left, right: right
});
}
}
parts = this._parts = subdividedParts;
}
else {
// console.time('sort');
// Finally quick sort each parts in 10 frames.
for (var i = 0; i < Math.floor(parts.length / 10); i++) {
// Sort near parts first.
var idx = parts.length - 1 - this._currentSortPartIdx;
quickSort(arr, compare, parts[idx].left, parts[idx].right);
this._currentSortPartIdx++;
// Finish sort
if (this._currentSortPartIdx === parts.length) {
this._sorted = true;
return true;
}
}
// console.timeEnd('sort');
}
return false;
};
ProgressiveQuickSort.sort = quickSort;
/* harmony default export */ __webpack_exports__["a"] = (ProgressiveQuickSort);
/***/ }),
/* 91 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__geo3D_Geo3D__ = __webpack_require__(92);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_util_layout__ = __webpack_require__(41);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_util_layout___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_echarts_lib_util_layout__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__core_ViewGL__ = __webpack_require__(19);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_retrieve__ = __webpack_require__(3);
function resizeGeo3D(geo3DModel, api) {
// Use left/top/width/height
var boxLayoutOption = geo3DModel.getBoxLayoutParams();
var viewport = __WEBPACK_IMPORTED_MODULE_2_echarts_lib_util_layout___default.a.getLayoutRect(boxLayoutOption, {
width: api.getWidth(),
height: api.getHeight()
});
// Flip Y
viewport.y = api.getHeight() - viewport.y - viewport.height;
this.viewGL.setViewport(viewport.x, viewport.y, viewport.width, viewport.height, api.getDevicePixelRatio());
var geoRect = this.getGeoBoundingRect();
var aspect = geoRect.width / geoRect.height * (geo3DModel.get('aspectScale') || 0.75);
var width = geo3DModel.get('boxWidth');
var depth = geo3DModel.get('boxDepth');
var height = geo3DModel.get('boxHeight');
if (height == null) {
height = 5;
}
if (isNaN(width) && isNaN(depth)) {
// Default to have 100 width
width = 100;
}
if (isNaN(depth)) {
depth = width / aspect;
}
else if (isNaN(width)) {
width = depth / aspect;
}
this.setSize(width, height, depth);
this.regionHeight = geo3DModel.get('regionHeight');
if (this.altitudeAxis) {
this.altitudeAxis.setExtent(0, Math.max(height - this.regionHeight, 0));
}
}
function updateGeo3D(ecModel, api) {
var altitudeDataExtent = [Infinity, -Infinity];
ecModel.eachSeries(function (seriesModel) {
if (seriesModel.coordinateSystem !== this) {
return;
}
if (seriesModel.type === 'series.map3D') {
return;
}
// Get altitude data extent.
var data = seriesModel.getData();
var altDims = seriesModel.coordDimToDataDim('alt');
var altDim = altDims && altDims[0];
if (altDim) {
// TODO altitiude is in coords of lines.
var dataExtent = data.getDataExtent(altDim, true);
altitudeDataExtent[0] = Math.min(
altitudeDataExtent[0], dataExtent[0]
);
altitudeDataExtent[1] = Math.max(
altitudeDataExtent[1], dataExtent[1]
);
}
}, this);
// Create altitude axis
if (altitudeDataExtent && isFinite(altitudeDataExtent[1] - altitudeDataExtent[0])) {
var scale = __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default.a.helper.createScale(
altitudeDataExtent, {
type: 'value',
// PENDING
min: 'dataMin',
max: 'dataMax'
}
);
this.altitudeAxis = new __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default.a.Axis('altitude', scale);
// Resize again
this.resize(this.model, api);
}
}
if (true) {
var mapNotExistsError = function (name) {
console.error('Map ' + name + ' not exists. You can download map file on http://echarts.baidu.com/download-map.html');
};
}
var idStart = 0;
var geo3DCreator = {
dimensions: __WEBPACK_IMPORTED_MODULE_0__geo3D_Geo3D__["a" /* default */].prototype.dimensions,
create: function (ecModel, api) {
var geo3DList = [];
if (!__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default.a.getMap) {
throw new Error('geo3D component depends on geo component');
}
function createGeo3D(componentModel, idx) {
var geo3D = geo3DCreator.createGeo3D(componentModel);
// FIXME
componentModel.__viewGL = componentModel.__viewGL || new __WEBPACK_IMPORTED_MODULE_3__core_ViewGL__["a" /* default */]();
geo3D.viewGL = componentModel.__viewGL;
componentModel.coordinateSystem = geo3D;
geo3D.model = componentModel;
geo3DList.push(geo3D);
// Inject resize
geo3D.resize = resizeGeo3D;
geo3D.resize(componentModel, api);
geo3D.update = updateGeo3D;
}
ecModel.eachComponent('geo3D', function (geo3DModel, idx) {
createGeo3D(geo3DModel, idx);
});
ecModel.eachSeriesByType('map3D', function (map3DModel, idx) {
var coordSys = map3DModel.get('coordinateSystem');
if (coordSys == null) {
coordSys = 'geo3D';
}
if (coordSys === 'geo3D') {
createGeo3D(map3DModel, idx);
}
});
ecModel.eachSeries(function (seriesModel) {
if (seriesModel.get('coordinateSystem') === 'geo3D') {
if (seriesModel.type === 'series.map3D') {
return;
}
var geo3DModel = seriesModel.getReferringComponents('geo3D')[0];
if (!geo3DModel) {
geo3DModel = ecModel.getComponent('geo3D');
}
if (!geo3DModel) {
throw new Error('geo "' + __WEBPACK_IMPORTED_MODULE_4__util_retrieve__["a" /* default */].firstNotNull(
seriesModel.get('geo3DIndex'),
seriesModel.get('geo3DId'),
0
) + '" not found');
}
seriesModel.coordinateSystem = geo3DModel.coordinateSystem;
}
});
return geo3DList;
},
createGeo3D: function (componentModel) {
var mapData = componentModel.get('map');
var name;
if (typeof mapData === 'string') {
name = mapData;
mapData = __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default.a.getMap(mapData);
}
else {
if (mapData && mapData.features) {
mapData = {
geoJson: mapData
};
}
}
if (true) {
if (!mapData) {
mapNotExistsError(mapData);
}
if (!mapData.geoJson.features) {
throw new Error('Invalid GeoJSON for map3D');
}
}
if (name == null) {
name = 'GEO_ANONYMOUS_' + idStart++;
}
return new __WEBPACK_IMPORTED_MODULE_0__geo3D_Geo3D__["a" /* default */](
name + idStart++, name,
mapData && mapData.geoJson, mapData && mapData.specialAreas,
componentModel.get('nameMap')
);
}
};
__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default.a.registerCoordinateSystem('geo3D', geo3DCreator);
/* harmony default export */ __webpack_exports__["a"] = (geo3DCreator);
/***/ }),
/* 92 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_coord_geo_fix_textCoord__ = __webpack_require__(197);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_coord_geo_fix_textCoord___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_echarts_lib_coord_geo_fix_textCoord__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_echarts_lib_coord_geo_fix_geoCoord__ = __webpack_require__(198);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_echarts_lib_coord_geo_fix_geoCoord___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_echarts_lib_coord_geo_fix_geoCoord__);
var vec3 = __WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix___default.a.vec3;
var mat4 = __WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix___default.a.mat4;
// Geo fix functions
var geoFixFuncs = [__WEBPACK_IMPORTED_MODULE_2_echarts_lib_coord_geo_fix_textCoord___default.a, __WEBPACK_IMPORTED_MODULE_3_echarts_lib_coord_geo_fix_geoCoord___default.a];
function Geo3D(name, map, geoJson, specialAreas, nameMap) {
this.name = name;
this.map = map;
this.regionHeight = 0;
this.regions = [];
this._nameCoordMap = {};
this.loadGeoJson(geoJson, specialAreas, nameMap);
this.transform = mat4.identity(new Float64Array(16));
this.invTransform = mat4.identity(new Float64Array(16));
// Which dimension to extrude. Y or Z
this.extrudeY = true;
this.altitudeAxis;
}
Geo3D.prototype = {
constructor: Geo3D,
type: 'geo3D',
dimensions: ['lng', 'lat', 'alt'],
containPoint: function () {},
loadGeoJson: function (geoJson, specialAreas, nameMap) {
var parseGeoJSON = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.parseGeoJSON || __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.parseGeoJson;
try {
this.regions = geoJson ? parseGeoJSON(geoJson) : [];
}
catch (e) {
throw 'Invalid geoJson format\n' + e;
}
specialAreas = specialAreas || {};
nameMap = nameMap || {};
var regions = this.regions;
var regionsMap = {};
for (var i = 0; i < regions.length; i++) {
var regionName = regions[i].name;
// Try use the alias in nameMap
regionName = nameMap[regionName] || regionName;
regions[i].name = regionName;
regionsMap[regionName] = regions[i];
// Add geoJson
this.addGeoCoord(regionName, regions[i].center);
// Some area like Alaska in USA map needs to be tansformed
// to look better
var specialArea = specialAreas[regionName];
if (specialArea) {
regions[i].transformTo(
specialArea.left, specialArea.top, specialArea.width, specialArea.height
);
}
}
this._regionsMap = regionsMap;
this._geoRect = null;
geoFixFuncs.forEach(function (fixFunc) {
fixFunc(this);
}, this);
},
getGeoBoundingRect: function () {
if (this._geoRect) {
return this._geoRect;
}
var rect;
var regions = this.regions;
for (var i = 0; i < regions.length; i++) {
var regionRect = regions[i].getBoundingRect();
rect = rect || regionRect.clone();
rect.union(regionRect);
}
// FIXME Always return new ?
return (this._geoRect = rect || new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.graphic.BoundingRect(0, 0, 0, 0));
},
/**
* Add geoCoord for indexing by name
* @param {string} name
* @param {Array.} geoCoord
*/
addGeoCoord: function (name, geoCoord) {
this._nameCoordMap[name] = geoCoord;
},
/**
* @param {string} name
* @return {module:echarts/coord/geo/Region}
*/
getRegion: function (name) {
return this._regionsMap[name];
},
getRegionByCoord: function (coord) {
var regions = this.regions;
for (var i = 0; i < regions.length; i++) {
if (regions[i].contain(coord)) {
return regions[i];
}
}
},
setSize: function (width, height, depth) {
this.size = [width, height, depth];
var rect = this.getGeoBoundingRect();
var scaleX = width / rect.width;
var scaleZ = -depth / rect.height;
var translateX = -width / 2 - rect.x * scaleX;
var translateZ = depth / 2 - rect.y * scaleZ;
var position = this.extrudeY ? [translateX, 0, translateZ] : [translateX, translateZ, 0];
var scale = this.extrudeY ? [scaleX, 1, scaleZ] : [scaleX, scaleZ, 1];
var m = this.transform;
mat4.identity(m);
mat4.translate(m, m, position);
mat4.scale(m, m, scale);
mat4.invert(this.invTransform, m);
},
dataToPoint: function (data, out) {
out = out || [];
var extrudeCoordIndex = this.extrudeY ? 1 : 2;
var sideCoordIndex = this.extrudeY ? 2 : 1;
var altitudeVal = data[2];
// PENDING.
if (isNaN(altitudeVal)) {
altitudeVal = 0;
}
// lng
out[0] = data[0];
// lat
out[sideCoordIndex] = data[1];
if (this.altitudeAxis) {
out[extrudeCoordIndex] = this.altitudeAxis.dataToCoord(altitudeVal);
}
else {
out[extrudeCoordIndex] = 0;
}
// PENDING different region height.
out[extrudeCoordIndex] += this.regionHeight;
vec3.transformMat4(out, out, this.transform);
return out;
},
pointToData: function (point, out) {
// TODO
}
};
/* harmony default export */ __webpack_exports__["a"] = (Geo3D);
/***/ }),
/* 93 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_claygl_src_dep_glmatrix__);
var mat4 = __WEBPACK_IMPORTED_MODULE_0_claygl_src_dep_glmatrix___default.a.mat4;
var TILE_SIZE = 512;
var FOV = 0.6435011087932844;
var PI = Math.PI;
var WORLD_SCALE = 1 / 10;
function MapServiceCoordSys3D() {
/**
* Width of mapbox viewport
*/
this.width = 0;
/**
* Height of mapbox viewport
*/
this.height = 0;
this.altitudeScale = 1;
// TODO Change boxHeight won't have animation.
this.boxHeight = 'auto';
// Set by mapbox creator
this.altitudeExtent;
this.bearing = 0;
this.pitch = 0;
this.center = [0, 0];
this._origin;
this.zoom = 0;
this._initialZoom;
// Some parameters for different map services.
this.maxPitch = 60;
this.zoomOffset = 0;
}
MapServiceCoordSys3D.prototype = {
constructor: MapServiceCoordSys3D,
dimensions: ['lng', 'lat', 'alt'],
containPoint: function () {},
setCameraOption: function (option) {
this.bearing = option.bearing;
this.pitch = option.pitch;
this.center = option.center;
this.zoom = option.zoom;
if (!this._origin) {
this._origin = this.projectOnTileWithScale(this.center, TILE_SIZE);
}
if (this._initialZoom == null) {
this._initialZoom = this.zoom;
}
this.updateTransform();
},
// https://github.com/mapbox/mapbox-gl-js/blob/master/src/geo/transform.js#L479
updateTransform: function () {
if (!this.height) { return; }
var cameraToCenterDistance = 0.5 / Math.tan(FOV / 2) * this.height * WORLD_SCALE;
// Convert to radian.
var pitch = Math.max(Math.min(this.pitch, this.maxPitch), 0) / 180 * Math.PI;
// Find the distance from the center point [width/2, height/2] to the
// center top point [width/2, 0] in Z units, using the law of sines.
// 1 Z unit is equivalent to 1 horizontal px at the center of the map
// (the distance between[width/2, height/2] and [width/2 + 1, height/2])
var halfFov = FOV / 2;
var groundAngle = Math.PI / 2 + pitch;
var topHalfSurfaceDistance = Math.sin(halfFov) * cameraToCenterDistance / Math.sin(Math.PI - groundAngle - halfFov);
// Calculate z distance of the farthest fragment that should be rendered.
var furthestDistance = Math.cos(Math.PI / 2 - pitch) * topHalfSurfaceDistance + cameraToCenterDistance;
// Add a bit extra to avoid precision problems when a fragment's distance is exactly `furthestDistance`
var farZ = furthestDistance * 1.1;
// Forced to be 1000
if (this.pitch > 50) {
farZ = 1000;
}
// matrix for conversion from location to GL coordinates (-1 .. 1)
var m = [];
mat4.perspective(m, FOV, this.width / this.height, 1, farZ);
this.viewGL.camera.projectionMatrix.setArray(m);
this.viewGL.camera.decomposeProjectionMatrix();
var m = mat4.identity([]);
var pt = this.dataToPoint(this.center);
// Inverse
mat4.scale(m, m, [1, -1, 1]);
// Translate to altitude
mat4.translate(m, m, [0, 0, -cameraToCenterDistance]);
mat4.rotateX(m, m, pitch);
mat4.rotateZ(m, m, -this.bearing / 180 * Math.PI);
// Translate to center.
mat4.translate(m, m, [-pt[0] * this.getScale() * WORLD_SCALE, -pt[1] * this.getScale() * WORLD_SCALE, 0]);
this.viewGL.camera.viewMatrix.array = m;
var invertM = [];
mat4.invert(invertM, m);
this.viewGL.camera.worldTransform.array = invertM;
this.viewGL.camera.decomposeWorldTransform();
// scale vertically to meters per pixel (inverse of ground resolution):
// worldSize / (circumferenceOfEarth * cos(lat * π / 180))
var worldSize = TILE_SIZE * this.getScale();
var verticalScale;
if (this.altitudeExtent && !isNaN(this.boxHeight)) {
var range = this.altitudeExtent[1] - this.altitudeExtent[0];
verticalScale = this.boxHeight / range * this.getScale() / Math.pow(2, this._initialZoom - this.zoomOffset);
}
else {
verticalScale = worldSize / (2 * Math.PI * 6378000 * Math.abs(Math.cos(this.center[1] * (Math.PI / 180))))
* this.altitudeScale * WORLD_SCALE;
}
// Include scale to avoid relayout when zooming
// FIXME Camera scale may have problem in shadow
this.viewGL.rootNode.scale.set(
this.getScale() * WORLD_SCALE, this.getScale() * WORLD_SCALE, verticalScale
);
},
getScale: function () {
return Math.pow(2, this.zoom - this.zoomOffset);
},
projectOnTile: function (data, out) {
return this.projectOnTileWithScale(data, this.getScale() * TILE_SIZE, out);
},
projectOnTileWithScale: function (data, scale, out) {
var lng = data[0];
var lat = data[1];
var lambda2 = lng * PI / 180;
var phi2 = lat * PI / 180;
var x = scale * (lambda2 + PI) / (2 * PI);
var y = scale * (PI - Math.log(Math.tan(PI / 4 + phi2 * 0.5))) / (2 * PI);
out = out || [];
out[0] = x;
out[1] = y;
return out;
},
unprojectFromTile: function (point, out) {
return this.unprojectOnTileWithScale(point, this.getScale() * TILE_SIZE, out);
},
unprojectOnTileWithScale: function (point, scale, out) {
var x = point[0];
var y = point[1];
var lambda2 = (x / scale) * (2 * PI) - PI;
var phi2 = 2 * (Math.atan(Math.exp(PI - (y / scale) * (2 * PI))) - PI / 4);
out = out || [];
out[0] = lambda2 * 180 / PI;
out[1] = phi2 * 180 / PI;
return out;
},
dataToPoint: function (data, out) {
out = this.projectOnTileWithScale(data, TILE_SIZE, out);
// Add a origin to avoid precision issue in WebGL.
out[0] -= this._origin[0];
out[1] -= this._origin[1];
// PENDING
out[2] = !isNaN(data[2]) ? data[2] : 0;
if (!isNaN(data[2])) {
out[2] = data[2];
if (this.altitudeExtent) {
out[2] -= this.altitudeExtent[0];
}
}
return out;
}
};
/* harmony default export */ __webpack_exports__["a"] = (MapServiceCoordSys3D);
/***/ }),
/* 94 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__util_retrieve__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__core_ViewGL__ = __webpack_require__(19);
/* harmony default export */ __webpack_exports__["a"] = (function (serviceComponentType, ServiceCtor, afterCreate) {
function resizeMapService3D(mapService3DModel, api) {
var width = api.getWidth();
var height = api.getHeight();
var dpr = api.getDevicePixelRatio();
this.viewGL.setViewport(0, 0, width, height, dpr);
this.width = width;
this.height = height;
this.altitudeScale = mapService3DModel.get('altitudeScale');
this.boxHeight = mapService3DModel.get('boxHeight');
// this.updateTransform();
}
function updateService3D(ecModel, api) {
if (this.model.get('boxHeight') === 'auto') {
return;
}
var altitudeDataExtent = [Infinity, -Infinity]
ecModel.eachSeries(function (seriesModel) {
if (seriesModel.coordinateSystem !== this) {
return;
}
// Get altitude data extent.
var data = seriesModel.getData();
var altDim = seriesModel.coordDimToDataDim('alt')[0];
if (altDim) {
// TODO altitiude is in coords of lines.
var dataExtent = data.getDataExtent(altDim, true);
altitudeDataExtent[0] = Math.min(
altitudeDataExtent[0], dataExtent[0]
);
altitudeDataExtent[1] = Math.max(
altitudeDataExtent[1], dataExtent[1]
);
}
}, this);
if (altitudeDataExtent && isFinite(altitudeDataExtent[1] - altitudeDataExtent[0])) {
this.altitudeExtent = altitudeDataExtent;
}
}
return {
dimensions: ServiceCtor.prototype.dimensions,
create: function (ecModel, api) {
var mapService3DList = [];
ecModel.eachComponent(serviceComponentType, function (mapService3DModel) {
var viewGL = mapService3DModel.__viewGL;
if (!viewGL) {
viewGL = mapService3DModel.__viewGL = new __WEBPACK_IMPORTED_MODULE_2__core_ViewGL__["a" /* default */]();
viewGL.setRootNode(new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node());
}
var mapService3DCoordSys = new ServiceCtor();
mapService3DCoordSys.viewGL = mapService3DModel.__viewGL;
// Inject resize
mapService3DCoordSys.resize = resizeMapService3D;
mapService3DCoordSys.resize(mapService3DModel, api);
mapService3DList.push(mapService3DCoordSys);
mapService3DModel.coordinateSystem = mapService3DCoordSys;
mapService3DCoordSys.model = mapService3DModel;
mapService3DCoordSys.update = updateService3D;
});
ecModel.eachSeries(function (seriesModel) {
if (seriesModel.get('coordinateSystem') === serviceComponentType) {
var mapService3DModel = seriesModel.getReferringComponents(serviceComponentType)[0];
if (!mapService3DModel) {
mapService3DModel = ecModel.getComponent(serviceComponentType);
}
if (!mapService3DModel) {
throw new Error(serviceComponentType + ' "' + __WEBPACK_IMPORTED_MODULE_0__util_retrieve__["a" /* default */].firstNotNull(
seriesModel.get(serviceComponentType + 'Index'),
seriesModel.get(serviceComponentType + 'Id'),
0
) + '" not found');
}
seriesModel.coordinateSystem = mapService3DModel.coordinateSystem;
}
});
afterCreate && afterCreate(mapService3DList, ecModel, api);
return mapService3DList;
}
};
});
/***/ }),
/* 95 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("\n@export ecgl.displayShadow.vertex\n\n@import ecgl.common.transformUniforms\n\n@import ecgl.common.uv.header\n\n@import ecgl.common.attributes\n\nvarying vec3 v_WorldPosition;\n\nvarying vec3 v_Normal;\n\nvoid main()\n{\n @import ecgl.common.uv.main\n v_Normal = normalize((worldInverseTranspose * vec4(normal, 0.0)).xyz);\n\n v_WorldPosition = (world * vec4(position, 1.0)).xyz;\n gl_Position = worldViewProjection * vec4(position, 1.0);\n}\n\n@end\n\n\n@export ecgl.displayShadow.fragment\n\n@import ecgl.common.uv.fragmentHeader\n\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\n\nuniform float roughness: 0.2;\n\n#ifdef DIRECTIONAL_LIGHT_COUNT\n@import clay.header.directional_light\n#endif\n\n@import ecgl.common.ssaoMap.header\n\n@import clay.plugin.compute_shadow_map\n\nvoid main()\n{\n float shadow = 1.0;\n\n @import ecgl.common.ssaoMap.main\n\n#if defined(DIRECTIONAL_LIGHT_COUNT) && defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsDir[DIRECTIONAL_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfDirectionalLights(v_WorldPosition, shadowContribsDir);\n }\n for (int i = 0; i < DIRECTIONAL_LIGHT_COUNT; i++) {\n shadow = min(shadow, shadowContribsDir[i] * 0.5 + 0.5);\n }\n#endif\n\n shadow *= 0.5 + ao * 0.5;\n shadow = clamp(shadow, 0.0, 1.0);\n\n gl_FragColor = vec4(vec3(0.0), 1.0 - shadow);\n}\n\n@end");
/***/ }),
/* 96 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_zrender_lib_core_matrix__ = __webpack_require__(77);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_zrender_lib_core_matrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_zrender_lib_core_matrix__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_zrender_lib_core_vector__ = __webpack_require__(76);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_zrender_lib_core_vector___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_zrender_lib_core_vector__);
function GLViewHelper(viewGL) {
this.viewGL = viewGL;
}
GLViewHelper.prototype.reset = function (seriesModel, api) {
this._updateCamera(api.getWidth(), api.getHeight(), api.getDevicePixelRatio());
this._viewTransform = __WEBPACK_IMPORTED_MODULE_0_zrender_lib_core_matrix___default.a.create();
this.updateTransform(seriesModel, api);
};
GLViewHelper.prototype.updateTransform = function (seriesModel, api) {
var coordinateSystem = seriesModel.coordinateSystem;
if (coordinateSystem.getRoamTransform) {
__WEBPACK_IMPORTED_MODULE_0_zrender_lib_core_matrix___default.a.invert(this._viewTransform, coordinateSystem.getRoamTransform());
this._setCameraTransform(this._viewTransform);
api.getZr().refresh();
}
};
// Reimplement the dataToPoint of coordinate system.
// Remove the effect of pan/zoom transform
GLViewHelper.prototype.dataToPoint = function (coordSys, data, pt) {
pt = coordSys.dataToPoint(data, null, pt);
var viewTransform = this._viewTransform;
if (viewTransform) {
__WEBPACK_IMPORTED_MODULE_1_zrender_lib_core_vector___default.a.applyTransform(pt, pt, viewTransform);
}
};
/**
* Remove transform info in point.
*/
GLViewHelper.prototype.removeTransformInPoint = function (pt) {
if (this._viewTransform) {
__WEBPACK_IMPORTED_MODULE_1_zrender_lib_core_vector___default.a.applyTransform(pt, pt, this._viewTransform);
}
return pt;
};
/**
* Return number
*/
GLViewHelper.prototype.getZoom = function () {
if (this._viewTransform) {
var m = this._viewTransform;
return 1 / Math.max(
Math.sqrt(m[0] * m[0] + m[1] * m[1]),
Math.sqrt(m[2] * m[2] + m[3] * m[3])
);
}
return 1;
};
GLViewHelper.prototype._setCameraTransform = function (m) {
var camera = this.viewGL.camera;
camera.position.set(m[4], m[5], 0);
camera.scale.set(
Math.sqrt(m[0] * m[0] + m[1] * m[1]),
Math.sqrt(m[2] * m[2] + m[3] * m[3]),
1
);
};
GLViewHelper.prototype._updateCamera = function (width, height, dpr) {
// TODO, left, top, right, bottom
this.viewGL.setViewport(0, 0, width, height, dpr);
var camera = this.viewGL.camera;
camera.left = camera.top = 0;
camera.bottom = height;
camera.right = width;
camera.near = 0;
camera.far = 100;
};
/* harmony default export */ __webpack_exports__["a"] = (GLViewHelper);
/***/ }),
/* 97 */
/***/ (function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global) {// (1) The code `if (__DEV__) ...` can be removed by build tool.
// (2) If intend to use `__DEV__`, this module should be imported. Use a global
// variable `__DEV__` may cause that miss the declaration (see #6535), or the
// declaration is behind of the using position (for example in `Model.extent`,
// And tools like rollup can not analysis the dependency if not import).
var dev; // In browser
if (typeof window !== 'undefined') {
dev = window.__DEV__;
} // In node
else if (typeof global !== 'undefined') {
dev = global.__DEV__;
}
if (typeof dev === 'undefined') {
dev = true;
}
var __DEV__ = dev;
exports.__DEV__ = __DEV__;
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(63)))
/***/ }),
/* 98 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__ = __webpack_require__(13);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__dynamicConvertMixin__ = __webpack_require__(34);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix__);
/**
* Lines geometry
* Use screen space projected lines lineWidth > MAX_LINE_WIDTH
* https://mattdesl.svbtle.com/drawing-lines-is-hard
* @module echarts-gl/util/geometry/LinesGeometry
* @author Yi Shen(http://github.com/pissang)
*/
var vec2 = __WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix___default.a.vec2;
// var CURVE_RECURSION_LIMIT = 8;
// var CURVE_COLLINEAR_EPSILON = 40;
var sampleLinePoints = [[0, 0], [1, 1]];
/**
* @constructor
* @alias module:echarts-gl/util/geometry/LinesGeometry
* @extends clay.Geometry
*/
var LinesGeometry = __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].extend(function () {
return {
segmentScale: 4,
dynamic: true,
/**
* Need to use mesh to expand lines if lineWidth > MAX_LINE_WIDTH
*/
useNativeLine: true,
attributes: {
position: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('position', 'float', 2, 'POSITION'),
normal: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('normal', 'float', 2),
offset: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('offset', 'float', 1),
color: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('color', 'float', 4, 'COLOR')
}
};
},
/** @lends module: echarts-gl/util/geometry/LinesGeometry.prototype */
{
/**
* Reset offset
*/
resetOffset: function () {
this._vertexOffset = 0;
this._faceOffset = 0;
this._itemVertexOffsets = [];
},
/**
* @param {number} nVertex
*/
setVertexCount: function (nVertex) {
var attributes = this.attributes;
if (this.vertexCount !== nVertex) {
attributes.position.init(nVertex);
attributes.color.init(nVertex);
if (!this.useNativeLine) {
attributes.offset.init(nVertex);
attributes.normal.init(nVertex);
}
if (nVertex > 0xffff) {
if (this.indices instanceof Uint16Array) {
this.indices = new Uint32Array(this.indices);
}
}
else {
if (this.indices instanceof Uint32Array) {
this.indices = new Uint16Array(this.indices);
}
}
}
},
/**
* @param {number} nTriangle
*/
setTriangleCount: function (nTriangle) {
if (this.triangleCount !== nTriangle) {
if (nTriangle === 0) {
this.indices = null;
}
else {
this.indices = this.vertexCount > 0xffff ? new Uint32Array(nTriangle * 3) : new Uint16Array(nTriangle * 3);
}
}
},
_getCubicCurveApproxStep: function (p0, p1, p2, p3) {
var len = vec2.dist(p0, p1) + vec2.dist(p2, p1) + vec2.dist(p3, p2);
var step = 1 / (len + 1) * this.segmentScale;
return step;
},
/**
* Get vertex count of cubic curve
* @param {Array.} p0
* @param {Array.} p1
* @param {Array.} p2
* @param {Array.} p3
* @return number
*/
getCubicCurveVertexCount: function (p0, p1, p2, p3) {
var step = this._getCubicCurveApproxStep(p0, p1, p2, p3);
var segCount = Math.ceil(1 / step);
if (!this.useNativeLine) {
return segCount * 2 + 2;
}
else {
return segCount * 2;
}
},
/**
* Get face count of cubic curve
* @param {Array.} p0
* @param {Array.} p1
* @param {Array.} p2
* @param {Array.} p3
* @return number
*/
getCubicCurveTriangleCount: function (p0, p1, p2, p3) {
var step = this._getCubicCurveApproxStep(p0, p1, p2, p3);
var segCount = Math.ceil(1 / step);
if (!this.useNativeLine) {
return segCount * 2;
}
else {
return 0;
}
},
/**
* Get vertex count of line
* @return {number}
*/
getLineVertexCount: function () {
return this.getPolylineVertexCount(sampleLinePoints);
},
/**
* Get face count of line
* @return {number}
*/
getLineTriangleCount: function () {
return this.getPolylineTriangleCount(sampleLinePoints);
},
/**
* Get how many vertices will polyline take.
* @type {number|Array} points Can be a 1d/2d list of points, or a number of points amount.
* @return {number}
*/
getPolylineVertexCount: function (points) {
var pointsLen;
if (typeof points === 'number') {
pointsLen = points;
}
else {
var is2DArray = typeof points[0] !== 'number';
pointsLen = is2DArray ? points.length : (points.length / 2);
}
return !this.useNativeLine ? ((pointsLen - 1) * 2 + 2) : (pointsLen - 1) * 2;
},
/**
* Get how many triangles will polyline take.
* @type {number|Array} points Can be a 1d/2d list of points, or a number of points amount.
* @return {number}
*/
getPolylineTriangleCount: function (points) {
var pointsLen;
if (typeof points === 'number') {
pointsLen = points;
}
else {
var is2DArray = typeof points[0] !== 'number';
pointsLen = is2DArray ? points.length : (points.length / 2);
}
return !this.useNativeLine ? (pointsLen - 1) * 2 : 0;
},
/**
* Add a cubic curve
* @param {Array.} p0
* @param {Array.} p1
* @param {Array.} p2
* @param {Array.} p3
* @param {Array.} color
* @param {number} [lineWidth=1]
*/
addCubicCurve: function (p0, p1, p2, p3, color, lineWidth) {
if (lineWidth == null) {
lineWidth = 1;
}
// incremental interpolation
// http://antigrain.com/research/bezier_interpolation/index.html#PAGE_BEZIER_INTERPOLATION
var x0 = p0[0], y0 = p0[1];
var x1 = p1[0], y1 = p1[1];
var x2 = p2[0], y2 = p2[1];
var x3 = p3[0], y3 = p3[1];
var step = this._getCubicCurveApproxStep(p0, p1, p2, p3);
var step2 = step * step;
var step3 = step2 * step;
var pre1 = 3.0 * step;
var pre2 = 3.0 * step2;
var pre4 = 6.0 * step2;
var pre5 = 6.0 * step3;
var tmp1x = x0 - x1 * 2.0 + x2;
var tmp1y = y0 - y1 * 2.0 + y2;
var tmp2x = (x1 - x2) * 3.0 - x0 + x3;
var tmp2y = (y1 - y2) * 3.0 - y0 + y3;
var fx = x0;
var fy = y0;
var dfx = (x1 - x0) * pre1 + tmp1x * pre2 + tmp2x * step3;
var dfy = (y1 - y0) * pre1 + tmp1y * pre2 + tmp2y * step3;
var ddfx = tmp1x * pre4 + tmp2x * pre5;
var ddfy = tmp1y * pre4 + tmp2y * pre5;
var dddfx = tmp2x * pre5;
var dddfy = tmp2y * pre5;
var t = 0;
var k = 0;
var segCount = Math.ceil(1 / step);
var points = new Float32Array((segCount + 1) * 3);
var points = [];
var offset = 0;
for (var k = 0; k < segCount + 1; k++) {
points[offset++] = fx;
points[offset++] = fy;
fx += dfx; fy += dfy;
dfx += ddfx; dfy += ddfy;
ddfx += dddfx; ddfy += dddfy;
t += step;
if (t > 1) {
fx = dfx > 0 ? Math.min(fx, x3) : Math.max(fx, x3);
fy = dfy > 0 ? Math.min(fy, y3) : Math.max(fy, y3);
}
}
this.addPolyline(points, color, lineWidth);
},
/**
* Add a straight line
* @param {Array.} p0
* @param {Array.} p1
* @param {Array.} color
* @param {number} [lineWidth=1]
*/
addLine: function (p0, p1, color, lineWidth) {
this.addPolyline([p0, p1], color, lineWidth);
},
/**
* Add a straight line
* @param {Array. | Array.} points
* @param {Array. | Array.} color
* @param {number} [lineWidth=1]
* @param {number} [arrayOffset=0]
* @param {number} [pointsCount] Default to be amount of points in the first argument
*/
addPolyline: (function () {
var dirA = vec2.create();
var dirB = vec2.create();
var normal = vec2.create();
var tangent = vec2.create();
var point = [], nextPoint = [], prevPoint = [];
return function (points, color, lineWidth, arrayOffset, pointsCount) {
if (!points.length) {
return;
}
var is2DArray = typeof points[0] !== 'number';
if (pointsCount == null) {
pointsCount = is2DArray ? points.length : points.length / 2;
}
if (pointsCount < 2) {
return;
}
if (arrayOffset == null) {
arrayOffset = 0;
}
if (lineWidth == null) {
lineWidth = 1;
}
this._itemVertexOffsets.push(this._vertexOffset);
var notSharingColor = is2DArray
? typeof color[0] !== 'number'
: color.length / 4 === pointsCount;
var positionAttr = this.attributes.position;
var colorAttr = this.attributes.color;
var offsetAttr = this.attributes.offset;
var normalAttr = this.attributes.normal;
var indices = this.indices;
var vertexOffset = this._vertexOffset;
var pointColor;
for (var k = 0; k < pointsCount; k++) {
if (is2DArray) {
point = points[k + arrayOffset];
if (notSharingColor) {
pointColor = color[k + arrayOffset];
}
else {
pointColor = color;
}
}
else {
var k2 = k * 2 + arrayOffset;
point = point || [];
point[0] = points[k2];
point[1] = points[k2 + 1];
if (notSharingColor) {
var k4 = k * 4 + arrayOffset;
pointColor = pointColor || [];
pointColor[0] = color[k4];
pointColor[1] = color[k4 + 1];
pointColor[2] = color[k4 + 2];
pointColor[3] = color[k4 + 3];
}
else {
pointColor = color;
}
}
if (!this.useNativeLine) {
var offset;
if (k < pointsCount - 1) {
if (is2DArray) {
vec2.copy(nextPoint, points[k + 1]);
}
else {
var k2 = (k + 1) * 2 + arrayOffset;
nextPoint = nextPoint || [];
nextPoint[0] = points[k2];
nextPoint[1] = points[k2 + 1];
}
// TODO In case dir is (0, 0)
// TODO miterLimit
if (k > 0) {
vec2.sub(dirA, point, prevPoint);
vec2.sub(dirB, nextPoint, point);
vec2.normalize(dirA, dirA);
vec2.normalize(dirB, dirB);
vec2.add(tangent, dirA, dirB);
vec2.normalize(tangent, tangent);
var miter = lineWidth / 2 * Math.min(1 / vec2.dot(dirA, tangent), 2);
normal[0] = -tangent[1];
normal[1] = tangent[0];
offset = miter;
}
else {
vec2.sub(dirA, nextPoint, point);
vec2.normalize(dirA, dirA);
normal[0] = -dirA[1];
normal[1] = dirA[0];
offset = lineWidth / 2;
}
}
else {
vec2.sub(dirA, point, prevPoint);
vec2.normalize(dirA, dirA);
normal[0] = -dirA[1];
normal[1] = dirA[0];
offset = lineWidth / 2;
}
normalAttr.set(vertexOffset, normal);
normalAttr.set(vertexOffset + 1, normal);
offsetAttr.set(vertexOffset, offset);
offsetAttr.set(vertexOffset + 1, -offset);
vec2.copy(prevPoint, point);
positionAttr.set(vertexOffset, point);
positionAttr.set(vertexOffset + 1, point);
colorAttr.set(vertexOffset, pointColor);
colorAttr.set(vertexOffset + 1, pointColor);
vertexOffset += 2;
}
else {
if (k > 1) {
positionAttr.copy(vertexOffset, vertexOffset - 1);
colorAttr.copy(vertexOffset, vertexOffset - 1);
vertexOffset++;
}
}
if (!this.useNativeLine) {
if (k > 0) {
var idx3 = this._faceOffset * 3;
var indices = this.indices;
// 0-----2
// 1-----3
// 0->1->2, 1->3->2
indices[idx3] = vertexOffset - 4;
indices[idx3 + 1] = vertexOffset - 3;
indices[idx3 + 2] = vertexOffset - 2;
indices[idx3 + 3] = vertexOffset - 3;
indices[idx3 + 4] = vertexOffset - 1;
indices[idx3 + 5] = vertexOffset - 2;
this._faceOffset += 2;
}
}
else {
colorAttr.set(vertexOffset, pointColor);
positionAttr.set(vertexOffset, point);
vertexOffset++;
}
}
this._vertexOffset = vertexOffset;
};
})(),
/**
* Set color of single line.
*/
setItemColor: function (idx, color) {
var startOffset = this._itemVertexOffsets[idx];
var endOffset = idx < this._itemVertexOffsets.length - 1 ? this._itemVertexOffsets[idx + 1] : this._vertexOffset;
for (var i = startOffset; i < endOffset; i++) {
this.attributes.color.set(i, color);
}
this.dirty('color');
}
});
__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default.a.util.defaults(LinesGeometry.prototype, __WEBPACK_IMPORTED_MODULE_2__dynamicConvertMixin__["a" /* default */]);
/* harmony default export */ __webpack_exports__["a"] = (LinesGeometry);
/***/ }),
/* 99 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__src_echarts_gl__ = __webpack_require__(100);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__src_component_grid3D__ = __webpack_require__(146);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__src_component_geo3D__ = __webpack_require__(193);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__src_component_globe__ = __webpack_require__(199);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__src_component_mapbox3D__ = __webpack_require__(205);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__src_component_maptalks3D__ = __webpack_require__(211);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__src_chart_bar3D__ = __webpack_require__(217);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__src_chart_line3D__ = __webpack_require__(224);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__src_chart_scatter3D__ = __webpack_require__(228);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__src_chart_lines3D__ = __webpack_require__(235);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__src_chart_polygons3D__ = __webpack_require__(241);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__src_chart_surface__ = __webpack_require__(244);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__src_chart_map3D__ = __webpack_require__(248);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_13__src_chart_scatterGL__ = __webpack_require__(251);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_14__src_chart_graphGL__ = __webpack_require__(254);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_15__src_chart_flowGL__ = __webpack_require__(267);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_16__src_chart_linesGL__ = __webpack_require__(273);
/***/ }),
/* 100 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_version__ = __webpack_require__(101);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__core_LayerGL__ = __webpack_require__(102);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__preprocessor_backwardCompat__ = __webpack_require__(145);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_graphicGL__ = __webpack_require__(2);
/**
* echarts-gl
* Extension pack of ECharts providing 3d plots and globe visualization
*
* Copyright (c) 2014, echarts-gl
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @module echarts-gl
* @author Yi Shen(http://github.com/pissang)
*/
// PENDING Use a single canvas as layer or use image element?
var echartsGl = {
version: '1.1.0',
dependencies: {
echarts: '4.0.3',
claygl: '1.1.0'
}
};
// Version checking
var deps = echartsGl.dependencies;
function versionTooOldMsg(name) {
throw new Error(
name + ' version is too old, needs ' + deps[name] + ' or higher'
);
}
function checkVersion(version, name) {
if ((version.replace('.', '') - 0) < (deps[name].replace('.', '') - 0)) {
versionTooOldMsg(name);
}
console.log('Loaded ' + name + ', version ' + version);
}
checkVersion(__WEBPACK_IMPORTED_MODULE_1_claygl_src_version__["a" /* default */], 'claygl');
checkVersion(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.version, 'echarts');
function EChartsGL (zr) {
this._layers = {};
this._zr = zr;
}
EChartsGL.prototype.update = function (ecModel, api) {
var self = this;
var zr = api.getZr();
if (!zr.getWidth() || !zr.getHeight()) {
console.warn('Dom has no width or height');
return;
}
function getLayerGL(model) {
var zlevel;
// Host on coordinate system.
if (model.coordinateSystem && model.coordinateSystem.model) {
zlevel = model.get('zlevel');
}
else {
zlevel = model.get('zlevel');
}
var layers = self._layers;
var layerGL = layers[zlevel];
if (!layerGL) {
layerGL = layers[zlevel] = new __WEBPACK_IMPORTED_MODULE_2__core_LayerGL__["a" /* default */]('gl-' + zlevel, zr);
if (zr.painter.isSingleCanvas()) {
layerGL.virtual = true;
// If container is canvas, use image to represent LayerGL
// FIXME Performance
var img = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.graphic.Image({
z: 1e4,
style: {
image: layerGL.renderer.canvas
},
silent: true
});
layerGL.__hostImage = img;
zr.add(img);
}
zr.painter.insertLayer(zlevel, layerGL);
}
if (layerGL.__hostImage) {
layerGL.__hostImage.setStyle({
width: layerGL.renderer.getWidth(),
height: layerGL.renderer.getHeight()
});
}
return layerGL;
}
function setSilent(groupGL, silent) {
if (groupGL) {
groupGL.traverse(function (mesh) {
if (mesh.isRenderable && mesh.isRenderable()) {
mesh.ignorePicking = mesh.$ignorePicking != null
? mesh.$ignorePicking : silent;
}
});
}
}
for (var zlevel in this._layers) {
this._layers[zlevel].removeViewsAll();
}
ecModel.eachComponent(function (componentType, componentModel) {
if (componentType !== 'series') {
var view = api.getViewOfComponentModel(componentModel);
var coordSys = componentModel.coordinateSystem;
// View with __ecgl__ flag is a echarts-gl component.
if (view.__ecgl__) {
var viewGL;
if (coordSys) {
if (!coordSys.viewGL) {
console.error('Can\'t find viewGL in coordinateSystem of component ' + componentModel.id);
return;
}
viewGL = coordSys.viewGL;
}
else {
if (!componentModel.viewGL) {
console.error('Can\'t find viewGL of component ' + componentModel.id);
return;
}
viewGL = coordSys.viewGL;
}
var viewGL = coordSys.viewGL;
var layerGL = getLayerGL(componentModel);
layerGL.addView(viewGL);
view.afterRender && view.afterRender(
componentModel, ecModel, api, layerGL
);
setSilent(view.groupGL, componentModel.get('silent'));
}
}
});
ecModel.eachSeries(function (seriesModel) {
var chartView = api.getViewOfSeriesModel(seriesModel);
var coordSys = seriesModel.coordinateSystem;
if (chartView.__ecgl__) {
if ((coordSys && !coordSys.viewGL) && !chartView.viewGL) {
console.error('Can\'t find viewGL of series ' + chartView.id);
return;
}
var viewGL = (coordSys && coordSys.viewGL) || chartView.viewGL;
// TODO Check zlevel not same with component of coordinate system ?
var layerGL = getLayerGL(seriesModel);
layerGL.addView(viewGL);
chartView.afterRender && chartView.afterRender(
seriesModel, ecModel, api, layerGL
);
setSilent(chartView.groupGL, seriesModel.get('silent'));
}
});
};
// Hack original getRenderedCanvas. Will removed after new echarts released
// TODO
var oldInit = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.init;
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.init = function () {
var chart = oldInit.apply(this, arguments);
chart.getZr().painter.getRenderedCanvas = function (opts) {
opts = opts || {};
if (this._singleCanvas) {
return this._layers[0].dom;
}
var canvas = document.createElement('canvas');
var dpr = opts.pixelRatio || this.dpr;
canvas.width = this.getWidth() * dpr;
canvas.height = this.getHeight() * dpr;
var ctx = canvas.getContext('2d');
ctx.dpr = dpr;
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (opts.backgroundColor) {
ctx.fillStyle = opts.backgroundColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
var displayList = this.storage.getDisplayList(true);
var scope = {};
var zlevel;
var self = this;
function findAndDrawOtherLayer(smaller, larger) {
var zlevelList = self._zlevelList;
if (smaller == null) {
smaller = -Infinity;
}
var intermediateLayer;
for (var i = 0; i < zlevelList.length; i++) {
var z = zlevelList[i];
var layer = self._layers[z];
if (!layer.__builtin__ && z > smaller && z < larger) {
intermediateLayer = layer;
break;
}
}
if (intermediateLayer && intermediateLayer.renderToCanvas) {
ctx.save();
intermediateLayer.renderToCanvas(ctx);
ctx.restore();
}
}
var layer = {
ctx: ctx
};
for (var i = 0; i < displayList.length; i++) {
var el = displayList[i];
if (el.zlevel !== zlevel) {
findAndDrawOtherLayer(zlevel, el.zlevel);
zlevel = el.zlevel;
}
this._doPaintEl(el, layer, true, scope);
}
findAndDrawOtherLayer(zlevel, Infinity);
return canvas;
};
return chart;
};
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerPostUpdate(function (ecModel, api) {
var zr = api.getZr();
var egl = zr.__egl = zr.__egl || new EChartsGL(zr);
egl.update(ecModel, api);
});
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerPreprocessor(__WEBPACK_IMPORTED_MODULE_3__preprocessor_backwardCompat__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.graphicGL = __WEBPACK_IMPORTED_MODULE_4__util_graphicGL__["a" /* default */];
/* unused harmony default export */ var _unused_webpack_default_export = (EChartsGL);
/***/ }),
/* 101 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/**
* @name clay.version
*/
/* harmony default export */ __webpack_exports__["a"] = ('1.1.0');
/***/ }),
/* 102 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_Renderer__ = __webpack_require__(46);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_picking_RayPicking__ = __webpack_require__(111);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_graphicGL__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_claygl_src_core_mixin_notifier__ = __webpack_require__(47);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_zrender_lib_animation_requestAnimationFrame__ = __webpack_require__(72);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_zrender_lib_animation_requestAnimationFrame___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_zrender_lib_animation_requestAnimationFrame__);
/**
* Provide WebGL layer to zrender. Which is rendered on top of clay.
*
*
* Relationship between zrender, LayerGL(renderer) and ViewGL(Scene, Camera, Viewport)
* zrender
* / \
* LayerGL LayerGL
* (renderer) (renderer)
* / \
* ViewGL ViewGL
*
* @module echarts-gl/core/LayerGL
* @author Yi Shen(http://github.com/pissang)
*/
// PENDING, clay. notifier is same with zrender Eventful
/**
* @constructor
* @alias module:echarts-gl/core/LayerGL
* @param {string} id Layer ID
* @param {module:zrender/ZRender} zr
*/
var LayerGL = function (id, zr) {
/**
* Layer ID
* @type {string}
*/
this.id = id;
/**
* @type {module:zrender/ZRender}
*/
this.zr = zr;
/**
* @type {clay.Renderer}
*/
try {
this.renderer = new __WEBPACK_IMPORTED_MODULE_1_claygl_src_Renderer__["a" /* default */]({
clearBit: 0,
devicePixelRatio: zr.painter.dpr,
preserveDrawingBuffer: true,
// PENDING
premultipliedAlpha: true
});
this.renderer.resize(zr.painter.getWidth(), zr.painter.getHeight());
}
catch (e) {
this.renderer = null;
this.dom = document.createElement('div');
this.dom.style.cssText = 'position:absolute; left: 0; top: 0; right: 0; bottom: 0;';
this.dom.className = 'ecgl-nowebgl';
this.dom.innerHTML = 'Sorry, your browser does support WebGL';
console.error(e);
return;
}
this.onglobalout = this.onglobalout.bind(this);
zr.on('globalout', this.onglobalout);
/**
* Canvas dom for webgl rendering
* @type {HTMLCanvasElement}
*/
this.dom = this.renderer.canvas;
var style = this.dom.style;
style.position = 'absolute';
style.left = '0';
style.top = '0';
/**
* @type {Array.}
*/
this.views = [];
this._picking = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_picking_RayPicking__["a" /* default */]({
renderer: this.renderer
});
this._viewsToDispose = [];
/**
* Current accumulating id.
*/
this._accumulatingId = 0;
this._zrEventProxy = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.graphic.Rect({
shape: {x: -1, y: -1, width: 2, height: 2},
// FIXME Better solution.
__isGLToZRProxy: true
});
this._backgroundColor = null;
};
/**
* @param {module:echarts-gl/core/ViewGL} view
*/
LayerGL.prototype.addView = function (view) {
if (view.layer === this) {
return;
}
// If needs to dispose in this layer. unmark it.
var idx = this._viewsToDispose.indexOf(view);
if (idx >= 0) {
this._viewsToDispose.splice(idx, 1);
}
this.views.push(view);
view.layer = this;
var zr = this.zr;
view.scene.traverse(function (node) {
node.__zr = zr;
if (node.addAnimatorsToZr) {
node.addAnimatorsToZr(zr);
}
});
};
function removeFromZr(node) {
var zr = node.__zr;
node.__zr = null;
if (zr && node.removeAnimatorsFromZr) {
node.removeAnimatorsFromZr(zr);
}
}
/**
* @param {module:echarts-gl/core/ViewGL} view
*/
LayerGL.prototype.removeView = function (view) {
if (view.layer !== this) {
return;
}
var idx = this.views.indexOf(view);
if (idx >= 0) {
this.views.splice(idx, 1);
view.scene.traverse(removeFromZr, this);
view.layer = null;
// Mark to dispose in this layer.
this._viewsToDispose.push(view);
}
};
/**
* Remove all views
*/
LayerGL.prototype.removeViewsAll = function () {
this.views.forEach(function (view) {
view.scene.traverse(removeFromZr, this);
view.layer = null;
// Mark to dispose in this layer.
this._viewsToDispose.push(view);
}, this);
this.views.length = 0;
};
/**
* Resize the canvas and viewport, will be invoked by zrender
* @param {number} width
* @param {number} height
*/
LayerGL.prototype.resize = function (width, height) {
var renderer = this.renderer;
renderer.resize(width, height);
};
/**
* Clear color and depth
* @return {[type]} [description]
*/
LayerGL.prototype.clear = function () {
var gl = this.renderer.gl;
var clearColor = this._backgroundColor || [0, 0, 0, 0];
gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
gl.depthMask(true);
gl.colorMask(true, true, true, true);
gl.clear(gl.DEPTH_BUFFER_BIT | gl.COLOR_BUFFER_BIT);
};
/**
* Clear depth
*/
LayerGL.prototype.clearDepth = function () {
var gl = this.renderer.gl;
gl.clear(gl.DEPTH_BUFFER_BIT);
};
/**
* Clear color
*/
LayerGL.prototype.clearColor = function () {
var gl = this.renderer.gl;
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
};
/**
* Mark layer to refresh next tick
*/
LayerGL.prototype.needsRefresh = function () {
this.zr.refresh();
};
/**
* Refresh the layer, will be invoked by zrender
*/
LayerGL.prototype.refresh = function (bgColor) {
this._backgroundColor = bgColor ? __WEBPACK_IMPORTED_MODULE_4__util_graphicGL__["a" /* default */].parseColor(bgColor) : [0, 0, 0, 0];
this.renderer.clearColor = this._backgroundColor;
for (var i = 0; i < this.views.length; i++) {
this.views[i].prepareRender(this.renderer);
}
this._doRender(false);
// Auto dispose unused resources on GPU, like program(shader), texture, geometry(buffers)
this._trackAndClean();
// Dispose trashed views
for (var i = 0; i < this._viewsToDispose.length; i++) {
this._viewsToDispose[i].dispose(this.renderer);
}
this._viewsToDispose.length = 0;
this._startAccumulating();
};
LayerGL.prototype.renderToCanvas = function (ctx) {
// PENDING will block the page
this._startAccumulating(true);
ctx.drawImage(this.dom, 0, 0, ctx.canvas.width, ctx.canvas.height);
};
LayerGL.prototype._doRender = function (accumulating) {
this.clear();
this.renderer.saveViewport();
for (var i = 0; i < this.views.length; i++) {
this.views[i].render(this.renderer, accumulating);
}
this.renderer.restoreViewport();
};
/**
* Stop accumulating
*/
LayerGL.prototype._stopAccumulating = function () {
this._accumulatingId = 0;
clearTimeout(this._accumulatingTimeout);
};
var accumulatingId = 1;
/**
* Start accumulating all the views.
* Accumulating is for antialising and have more sampling in SSAO
* @private
*/
LayerGL.prototype._startAccumulating = function (immediate) {
var self = this;
this._stopAccumulating();
var needsAccumulate = false;
for (var i = 0; i < this.views.length; i++) {
needsAccumulate = this.views[i].needsAccumulate() || needsAccumulate;
}
if (!needsAccumulate) {
return;
}
function accumulate(id) {
if (!self._accumulatingId || id !== self._accumulatingId) {
return;
}
var isFinished = true;
for (var i = 0; i < self.views.length; i++) {
isFinished = self.views[i].isAccumulateFinished() && needsAccumulate;
}
if (!isFinished) {
self._doRender(true);
if (immediate) {
accumulate(id);
}
else {
__WEBPACK_IMPORTED_MODULE_6_zrender_lib_animation_requestAnimationFrame___default()(function () {
accumulate(id);
});
}
}
}
this._accumulatingId = accumulatingId++;
if (immediate) {
accumulate(self._accumulatingId);
}
else {
this._accumulatingTimeout = setTimeout(function () {
accumulate(self._accumulatingId);
}, 50);
}
};
LayerGL.prototype._trackAndClean = function () {
var textureList = [];
var geometriesList = [];
// Mark all resources unused;
if (this._textureList) {
markUnused(this._textureList);
markUnused(this._geometriesList);
}
for (var i = 0; i < this.views.length; i++) {
collectResources(this.views[i].scene, textureList, geometriesList);
}
// Dispose those unsed resources.
if (this._textureList) {
checkAndDispose(this.renderer, this._textureList);
checkAndDispose(this.renderer, this._geometriesList);
}
this._textureList = textureList;
this._geometriesList = geometriesList;
};
function markUnused(resourceList) {
for (var i = 0; i < resourceList.length; i++) {
resourceList[i].__used__ = 0;
}
}
function checkAndDispose(renderer, resourceList) {
for (var i = 0; i < resourceList.length; i++) {
if (!resourceList[i].__used__) {
resourceList[i].dispose(renderer);
}
}
}
function updateUsed(resource, list) {
resource.__used__ = resource.__used__ || 0;
resource.__used__++;
if (resource.__used__ === 1) {
// Don't push to the list twice.
list.push(resource);
}
}
function collectResources(scene, textureResourceList, geometryResourceList) {
var prevMaterial;
var prevGeometry;
scene.traverse(function (renderable) {
if (renderable.isRenderable()) {
var geometry = renderable.geometry;
var material = renderable.material;
// TODO optimize!!
if (material !== prevMaterial) {
var textureUniforms = material.getTextureUniforms();
for (var u = 0; u < textureUniforms.length; u++) {
var uniformName = textureUniforms[u];
var val = material.uniforms[uniformName].value;
if (!val) {
continue;
}
if (val instanceof __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__["a" /* default */]) {
updateUsed(val, textureResourceList);
}
else if (val instanceof Array) {
for (var k = 0; k < val.length; k++) {
if (val[k] instanceof __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__["a" /* default */]) {
updateUsed(val[k], textureResourceList);
}
}
}
}
}
if (geometry !== prevGeometry) {
updateUsed(geometry, geometryResourceList);
}
prevMaterial = material;
prevGeometry = geometry;
}
});
for (var k = 0; k < scene.lights.length; k++) {
// Track AmbientCubemap
if (scene.lights[k].cubemap) {
updateUsed(scene.lights[k].cubemap, textureResourceList);
}
}
}
/**
* Dispose the layer
*/
LayerGL.prototype.dispose = function () {
this._stopAccumulating();
this.renderer.disposeScene(this.scene);
this.zr.off('globalout', this.onglobalout);
};
// Event handlers
LayerGL.prototype.onmousedown = function (e) {
if (e.target && e.target.__isGLToZRProxy) {
return;
}
e = e.event;
var obj = this.pickObject(e.offsetX, e.offsetY);
if (obj) {
this._dispatchEvent('mousedown', e, obj);
this._dispatchDataEvent('mousedown', e, obj);
}
this._downX = e.offsetX;
this._downY = e.offsetY;
};
LayerGL.prototype.onmousemove = function (e) {
if (e.target && e.target.__isGLToZRProxy) {
return;
}
e = e.event;
var obj = this.pickObject(e.offsetX, e.offsetY);
var target = obj && obj.target;
var lastHovered = this._hovered;
this._hovered = obj;
if (lastHovered && target !== lastHovered.target) {
lastHovered.relatedTarget = target;
this._dispatchEvent('mouseout', e, lastHovered);
// this._dispatchDataEvent('mouseout', e, lastHovered);
this.zr.setCursorStyle('default');
}
this._dispatchEvent('mousemove', e, obj);
if (obj) {
this.zr.setCursorStyle('pointer');
if (!lastHovered || (target !== lastHovered.target)) {
this._dispatchEvent('mouseover', e, obj);
// this._dispatchDataEvent('mouseover', e, obj);
}
}
this._dispatchDataEvent('mousemove', e, obj);
};
LayerGL.prototype.onmouseup = function (e) {
if (e.target && e.target.__isGLToZRProxy) {
return;
}
e = e.event;
var obj = this.pickObject(e.offsetX, e.offsetY);
if (obj) {
this._dispatchEvent('mouseup', e, obj);
this._dispatchDataEvent('mouseup', e, obj);
}
this._upX = e.offsetX;
this._upY = e.offsetY;
};
LayerGL.prototype.onclick = LayerGL.prototype.dblclick = function (e) {
if (e.target && e.target.__isGLToZRProxy) {
return;
}
// Ignore click event if mouse moved
var dx = this._upX - this._downX;
var dy = this._upY - this._downY;
if (Math.sqrt(dx * dx + dy * dy) > 20) {
return;
}
e = e.event;
var obj = this.pickObject(e.offsetX, e.offsetY);
if (obj) {
this._dispatchEvent(e.type, e, obj);
this._dispatchDataEvent(e.type, e, obj);
}
// Try set depth of field onclick
var result = this._clickToSetFocusPoint(e);
if (result) {
var success = result.view.setDOFFocusOnPoint(result.distance);
if (success) {
this.zr.refresh();
}
}
};
LayerGL.prototype._clickToSetFocusPoint = function (e) {
var renderer = this.renderer;
var oldViewport = renderer.viewport;
for (var i = this.views.length - 1; i >= 0; i--) {
var viewGL = this.views[i];
if (viewGL.hasDOF() && viewGL.containPoint(e.offsetX, e.offsetY)) {
this._picking.scene = viewGL.scene;
this._picking.camera = viewGL.camera;
// Only used for picking, renderer.setViewport will also invoke gl.viewport.
// Set directly, PENDING.
renderer.viewport = viewGL.viewport;
var result = this._picking.pick(e.offsetX, e.offsetY, true);
if (result) {
result.view = viewGL;
return result;
}
}
}
renderer.viewport = oldViewport;
};
LayerGL.prototype.onglobalout = function (e) {
var lastHovered = this._hovered;
if (lastHovered) {
this._dispatchEvent('mouseout', e, {
target: lastHovered.target
});
}
};
LayerGL.prototype.pickObject = function (x, y) {
var output = [];
var renderer = this.renderer;
var oldViewport = renderer.viewport;
for (var i = 0; i < this.views.length; i++) {
var viewGL = this.views[i];
if (viewGL.containPoint(x, y)) {
this._picking.scene = viewGL.scene;
this._picking.camera = viewGL.camera;
// Only used for picking, renderer.setViewport will also invoke gl.viewport.
// Set directly, PENDING.
renderer.viewport = viewGL.viewport;
this._picking.pickAll(x, y, output);
}
}
renderer.viewport = oldViewport;
output.sort(function (a, b) {
return a.distance - b.distance;
});
return output[0];
};
LayerGL.prototype._dispatchEvent = function (eveName, originalEvent, newEvent) {
if (!newEvent) {
newEvent = {};
}
var current = newEvent.target;
newEvent.cancelBubble = false;
newEvent.event = originalEvent;
newEvent.type = eveName;
newEvent.offsetX = originalEvent.offsetX;
newEvent.offsetY = originalEvent.offsetY;
while (current) {
current.trigger(eveName, newEvent);
current = current.getParent();
if (newEvent.cancelBubble) {
break;
}
}
this._dispatchToView(eveName, newEvent);
};
LayerGL.prototype._dispatchDataEvent = function (eveName, originalEvent, newEvent) {
var mesh = newEvent && newEvent.target;
var dataIndex = mesh && mesh.dataIndex;
var seriesIndex = mesh && mesh.seriesIndex;
// Custom event data
var eventData = mesh && mesh.eventData;
var elChangedInMouseMove = false;
var eventProxy = this._zrEventProxy;
eventProxy.position = [originalEvent.offsetX, originalEvent.offsetY];
eventProxy.update();
var targetInfo = {
target: eventProxy
};
if (eveName === 'mousemove') {
if (dataIndex != null) {
if (dataIndex !== this._lastDataIndex) {
if (parseInt(this._lastDataIndex, 10) >= 0) {
eventProxy.dataIndex = this._lastDataIndex;
eventProxy.seriesIndex = this._lastSeriesIndex;
// FIXME May cause double events.
this.zr.handler.dispatchToElement(targetInfo, 'mouseout', originalEvent);
}
elChangedInMouseMove = true;
}
}
else if (eventData != null) {
if (eventData !== this._lastEventData) {
if (this._lastEventData != null) {
eventProxy.eventData = this._lastEventData;
// FIXME May cause double events.
this.zr.handler.dispatchToElement(targetInfo, 'mouseout', originalEvent);
}
elChangedInMouseMove = true;
}
}
this._lastEventData = eventData;
this._lastDataIndex = dataIndex;
this._lastSeriesIndex = seriesIndex;
}
eventProxy.eventData = eventData;
eventProxy.dataIndex = dataIndex;
eventProxy.seriesIndex = seriesIndex;
if (eventData != null || (parseInt(dataIndex, 10) >= 0 && parseInt(seriesIndex, 10) >= 0)) {
this.zr.handler.dispatchToElement(targetInfo, eveName, originalEvent);
if (elChangedInMouseMove) {
this.zr.handler.dispatchToElement(targetInfo, 'mouseover', originalEvent);
}
}
};
LayerGL.prototype._dispatchToView = function (eventName, e) {
for (var i = 0; i < this.views.length; i++) {
if (this.views[i].containPoint(e.offsetX, e.offsetY)) {
this.views[i].trigger(eventName, e);
}
}
};
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.extend(LayerGL.prototype, __WEBPACK_IMPORTED_MODULE_5_claygl_src_core_mixin_notifier__["a" /* default */]);
/* harmony default export */ __webpack_exports__["a"] = (LayerGL);
/***/ }),
/* 103 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/**
* Extend a sub class from base class
* @param {object|Function} makeDefaultOpt default option of this sub class, method of the sub can use this.xxx to access this option
* @param {Function} [initialize] Initialize after the sub class is instantiated
* @param {Object} [proto] Prototype methods/properties of the sub class
* @memberOf clay.core.mixin.extend
* @return {Function}
*/
function derive(makeDefaultOpt, initialize/*optional*/, proto/*optional*/) {
if (typeof initialize == 'object') {
proto = initialize;
initialize = null;
}
var _super = this;
var propList;
if (!(makeDefaultOpt instanceof Function)) {
// Optimize the property iterate if it have been fixed
propList = [];
for (var propName in makeDefaultOpt) {
if (makeDefaultOpt.hasOwnProperty(propName)) {
propList.push(propName);
}
}
}
var sub = function(options) {
// call super constructor
_super.apply(this, arguments);
if (makeDefaultOpt instanceof Function) {
// Invoke makeDefaultOpt each time if it is a function, So we can make sure each
// property in the object will not be shared by mutiple instances
extend(this, makeDefaultOpt.call(this, options));
}
else {
extendWithPropList(this, makeDefaultOpt, propList);
}
if (this.constructor === sub) {
// Initialize function will be called in the order of inherit
var initializers = sub.__initializers__;
for (var i = 0; i < initializers.length; i++) {
initializers[i].apply(this, arguments);
}
}
};
// save super constructor
sub.__super__ = _super;
// Initialize function will be called after all the super constructor is called
if (!_super.__initializers__) {
sub.__initializers__ = [];
} else {
sub.__initializers__ = _super.__initializers__.slice();
}
if (initialize) {
sub.__initializers__.push(initialize);
}
var Ctor = function() {};
Ctor.prototype = _super.prototype;
sub.prototype = new Ctor();
sub.prototype.constructor = sub;
extend(sub.prototype, proto);
// extend the derive method as a static method;
sub.extend = _super.extend;
// DEPCRATED
sub.derive = _super.extend;
return sub;
}
function extend(target, source) {
if (!source) {
return;
}
for (var name in source) {
if (source.hasOwnProperty(name)) {
target[name] = source[name];
}
}
}
function extendWithPropList(target, source, propList) {
for (var i = 0; i < propList.length; i++) {
var propName = propList[i];
target[propName] = source[propName];
}
}
/**
* @alias clay.core.mixin.extend
* @mixin
*/
/* harmony default export */ __webpack_exports__["a"] = ({
extend: derive,
// DEPCRATED
derive: derive
});
/***/ }),
/* 104 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
var EXTENSION_LIST = [
'OES_texture_float',
'OES_texture_half_float',
'OES_texture_float_linear',
'OES_texture_half_float_linear',
'OES_standard_derivatives',
'OES_vertex_array_object',
'OES_element_index_uint',
'WEBGL_compressed_texture_s3tc',
'WEBGL_depth_texture',
'EXT_texture_filter_anisotropic',
'EXT_shader_texture_lod',
'WEBGL_draw_buffers',
'EXT_frag_depth',
'EXT_sRGB'
];
var PARAMETER_NAMES = [
'MAX_TEXTURE_SIZE',
'MAX_CUBE_MAP_TEXTURE_SIZE'
];
function GLInfo(_gl) {
var extensions = {};
var parameters = {};
// Get webgl extension
for (var i = 0; i < EXTENSION_LIST.length; i++) {
var extName = EXTENSION_LIST[i];
createExtension(extName);
}
// Get parameters
for (var i = 0; i < PARAMETER_NAMES.length; i++) {
var name = PARAMETER_NAMES[i];
parameters[name] = _gl.getParameter(_gl[name]);
}
this.getExtension = function (name) {
if (!(name in extensions)) {
createExtension(name);
}
return extensions[name];
};
this.getParameter = function (name) {
return parameters[name];
};
function createExtension(name) {
var ext = _gl.getExtension(name);
if (!ext) {
ext = _gl.getExtension('MOZ_' + name);
}
if (!ext) {
ext = _gl.getExtension('WEBKIT_' + name);
}
extensions[name] = ext;
}
}
/* harmony default export */ __webpack_exports__["a"] = (GLInfo);
/***/ }),
/* 105 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_LRU__ = __webpack_require__(64);
/**
* @namespace clay.core.color
*/
var colorUtil = {};
var kCSSColorTable = {
'transparent': [0,0,0,0], 'aliceblue': [240,248,255,1],
'antiquewhite': [250,235,215,1], 'aqua': [0,255,255,1],
'aquamarine': [127,255,212,1], 'azure': [240,255,255,1],
'beige': [245,245,220,1], 'bisque': [255,228,196,1],
'black': [0,0,0,1], 'blanchedalmond': [255,235,205,1],
'blue': [0,0,255,1], 'blueviolet': [138,43,226,1],
'brown': [165,42,42,1], 'burlywood': [222,184,135,1],
'cadetblue': [95,158,160,1], 'chartreuse': [127,255,0,1],
'chocolate': [210,105,30,1], 'coral': [255,127,80,1],
'cornflowerblue': [100,149,237,1], 'cornsilk': [255,248,220,1],
'crimson': [220,20,60,1], 'cyan': [0,255,255,1],
'darkblue': [0,0,139,1], 'darkcyan': [0,139,139,1],
'darkgoldenrod': [184,134,11,1], 'darkgray': [169,169,169,1],
'darkgreen': [0,100,0,1], 'darkgrey': [169,169,169,1],
'darkkhaki': [189,183,107,1], 'darkmagenta': [139,0,139,1],
'darkolivegreen': [85,107,47,1], 'darkorange': [255,140,0,1],
'darkorchid': [153,50,204,1], 'darkred': [139,0,0,1],
'darksalmon': [233,150,122,1], 'darkseagreen': [143,188,143,1],
'darkslateblue': [72,61,139,1], 'darkslategray': [47,79,79,1],
'darkslategrey': [47,79,79,1], 'darkturquoise': [0,206,209,1],
'darkviolet': [148,0,211,1], 'deeppink': [255,20,147,1],
'deepskyblue': [0,191,255,1], 'dimgray': [105,105,105,1],
'dimgrey': [105,105,105,1], 'dodgerblue': [30,144,255,1],
'firebrick': [178,34,34,1], 'floralwhite': [255,250,240,1],
'forestgreen': [34,139,34,1], 'fuchsia': [255,0,255,1],
'gainsboro': [220,220,220,1], 'ghostwhite': [248,248,255,1],
'gold': [255,215,0,1], 'goldenrod': [218,165,32,1],
'gray': [128,128,128,1], 'green': [0,128,0,1],
'greenyellow': [173,255,47,1], 'grey': [128,128,128,1],
'honeydew': [240,255,240,1], 'hotpink': [255,105,180,1],
'indianred': [205,92,92,1], 'indigo': [75,0,130,1],
'ivory': [255,255,240,1], 'khaki': [240,230,140,1],
'lavender': [230,230,250,1], 'lavenderblush': [255,240,245,1],
'lawngreen': [124,252,0,1], 'lemonchiffon': [255,250,205,1],
'lightblue': [173,216,230,1], 'lightcoral': [240,128,128,1],
'lightcyan': [224,255,255,1], 'lightgoldenrodyellow': [250,250,210,1],
'lightgray': [211,211,211,1], 'lightgreen': [144,238,144,1],
'lightgrey': [211,211,211,1], 'lightpink': [255,182,193,1],
'lightsalmon': [255,160,122,1], 'lightseagreen': [32,178,170,1],
'lightskyblue': [135,206,250,1], 'lightslategray': [119,136,153,1],
'lightslategrey': [119,136,153,1], 'lightsteelblue': [176,196,222,1],
'lightyellow': [255,255,224,1], 'lime': [0,255,0,1],
'limegreen': [50,205,50,1], 'linen': [250,240,230,1],
'magenta': [255,0,255,1], 'maroon': [128,0,0,1],
'mediumaquamarine': [102,205,170,1], 'mediumblue': [0,0,205,1],
'mediumorchid': [186,85,211,1], 'mediumpurple': [147,112,219,1],
'mediumseagreen': [60,179,113,1], 'mediumslateblue': [123,104,238,1],
'mediumspringgreen': [0,250,154,1], 'mediumturquoise': [72,209,204,1],
'mediumvioletred': [199,21,133,1], 'midnightblue': [25,25,112,1],
'mintcream': [245,255,250,1], 'mistyrose': [255,228,225,1],
'moccasin': [255,228,181,1], 'navajowhite': [255,222,173,1],
'navy': [0,0,128,1], 'oldlace': [253,245,230,1],
'olive': [128,128,0,1], 'olivedrab': [107,142,35,1],
'orange': [255,165,0,1], 'orangered': [255,69,0,1],
'orchid': [218,112,214,1], 'palegoldenrod': [238,232,170,1],
'palegreen': [152,251,152,1], 'paleturquoise': [175,238,238,1],
'palevioletred': [219,112,147,1], 'papayawhip': [255,239,213,1],
'peachpuff': [255,218,185,1], 'peru': [205,133,63,1],
'pink': [255,192,203,1], 'plum': [221,160,221,1],
'powderblue': [176,224,230,1], 'purple': [128,0,128,1],
'red': [255,0,0,1], 'rosybrown': [188,143,143,1],
'royalblue': [65,105,225,1], 'saddlebrown': [139,69,19,1],
'salmon': [250,128,114,1], 'sandybrown': [244,164,96,1],
'seagreen': [46,139,87,1], 'seashell': [255,245,238,1],
'sienna': [160,82,45,1], 'silver': [192,192,192,1],
'skyblue': [135,206,235,1], 'slateblue': [106,90,205,1],
'slategray': [112,128,144,1], 'slategrey': [112,128,144,1],
'snow': [255,250,250,1], 'springgreen': [0,255,127,1],
'steelblue': [70,130,180,1], 'tan': [210,180,140,1],
'teal': [0,128,128,1], 'thistle': [216,191,216,1],
'tomato': [255,99,71,1], 'turquoise': [64,224,208,1],
'violet': [238,130,238,1], 'wheat': [245,222,179,1],
'white': [255,255,255,1], 'whitesmoke': [245,245,245,1],
'yellow': [255,255,0,1], 'yellowgreen': [154,205,50,1]
};
function clampCssByte(i) { // Clamp to integer 0 .. 255.
i = Math.round(i); // Seems to be what Chrome does (vs truncation).
return i < 0 ? 0 : i > 255 ? 255 : i;
}
function clampCssAngle(i) { // Clamp to integer 0 .. 360.
i = Math.round(i); // Seems to be what Chrome does (vs truncation).
return i < 0 ? 0 : i > 360 ? 360 : i;
}
function clampCssFloat(f) { // Clamp to float 0.0 .. 1.0.
return f < 0 ? 0 : f > 1 ? 1 : f;
}
function parseCssInt(str) { // int or percentage.
if (str.length && str.charAt(str.length - 1) === '%') {
return clampCssByte(parseFloat(str) / 100 * 255);
}
return clampCssByte(parseInt(str, 10));
}
function parseCssFloat(str) { // float or percentage.
if (str.length && str.charAt(str.length - 1) === '%') {
return clampCssFloat(parseFloat(str) / 100);
}
return clampCssFloat(parseFloat(str));
}
function cssHueToRgb(m1, m2, h) {
if (h < 0) {
h += 1;
}
else if (h > 1) {
h -= 1;
}
if (h * 6 < 1) {
return m1 + (m2 - m1) * h * 6;
}
if (h * 2 < 1) {
return m2;
}
if (h * 3 < 2) {
return m1 + (m2 - m1) * (2/3 - h) * 6;
}
return m1;
}
function lerpNumber(a, b, p) {
return a + (b - a) * p;
}
function setRgba(out, r, g, b, a) {
out[0] = r; out[1] = g; out[2] = b; out[3] = a;
return out;
}
function copyRgba(out, a) {
out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3];
return out;
}
var colorCache = new __WEBPACK_IMPORTED_MODULE_0__core_LRU__["a" /* default */](20);
var lastRemovedArr = null;
function putToCache(colorStr, rgbaArr) {
// Reuse removed array
if (lastRemovedArr) {
copyRgba(lastRemovedArr, rgbaArr);
}
lastRemovedArr = colorCache.put(colorStr, lastRemovedArr || (rgbaArr.slice()));
}
/**
* @name clay.core.color.parse
* @param {string} colorStr
* @param {Array.} out
* @return {Array.}
*/
colorUtil.parse = function (colorStr, rgbaArr) {
if (!colorStr) {
return;
}
rgbaArr = rgbaArr || [];
var cached = colorCache.get(colorStr);
if (cached) {
return copyRgba(rgbaArr, cached);
}
// colorStr may be not string
colorStr = colorStr + '';
// Remove all whitespace, not compliant, but should just be more accepting.
var str = colorStr.replace(/ /g, '').toLowerCase();
// Color keywords (and transparent) lookup.
if (str in kCSSColorTable) {
copyRgba(rgbaArr, kCSSColorTable[str]);
putToCache(colorStr, rgbaArr);
return rgbaArr;
}
// #abc and #abc123 syntax.
if (str.charAt(0) === '#') {
if (str.length === 4) {
var iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing.
if (!(iv >= 0 && iv <= 0xfff)) {
setRgba(rgbaArr, 0, 0, 0, 1);
return; // Covers NaN.
}
setRgba(rgbaArr,
((iv & 0xf00) >> 4) | ((iv & 0xf00) >> 8),
(iv & 0xf0) | ((iv & 0xf0) >> 4),
(iv & 0xf) | ((iv & 0xf) << 4),
1
);
putToCache(colorStr, rgbaArr);
return rgbaArr;
}
else if (str.length === 7) {
var iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing.
if (!(iv >= 0 && iv <= 0xffffff)) {
setRgba(rgbaArr, 0, 0, 0, 1);
return; // Covers NaN.
}
setRgba(rgbaArr,
(iv & 0xff0000) >> 16,
(iv & 0xff00) >> 8,
iv & 0xff,
1
);
putToCache(colorStr, rgbaArr);
return rgbaArr;
}
return;
}
var op = str.indexOf('('), ep = str.indexOf(')');
if (op !== -1 && ep + 1 === str.length) {
var fname = str.substr(0, op);
var params = str.substr(op + 1, ep - (op + 1)).split(',');
var alpha = 1; // To allow case fallthrough.
switch (fname) {
case 'rgba':
if (params.length !== 4) {
setRgba(rgbaArr, 0, 0, 0, 1);
return;
}
alpha = parseCssFloat(params.pop()); // jshint ignore:line
// Fall through.
case 'rgb':
if (params.length !== 3) {
setRgba(rgbaArr, 0, 0, 0, 1);
return;
}
setRgba(rgbaArr,
parseCssInt(params[0]),
parseCssInt(params[1]),
parseCssInt(params[2]),
alpha
);
putToCache(colorStr, rgbaArr);
return rgbaArr;
case 'hsla':
if (params.length !== 4) {
setRgba(rgbaArr, 0, 0, 0, 1);
return;
}
params[3] = parseCssFloat(params[3]);
hsla2rgba(params, rgbaArr);
putToCache(colorStr, rgbaArr);
return rgbaArr;
case 'hsl':
if (params.length !== 3) {
setRgba(rgbaArr, 0, 0, 0, 1);
return;
}
hsla2rgba(params, rgbaArr);
putToCache(colorStr, rgbaArr);
return rgbaArr;
default:
return;
}
}
setRgba(rgbaArr, 0, 0, 0, 1);
return;
};
colorUtil.parseToFloat = function (colorStr, rgbaArr) {
rgbaArr = colorUtil.parse(colorStr, rgbaArr);
if (!rgbaArr) {
return;
}
rgbaArr[0] /= 255;
rgbaArr[1] /= 255;
rgbaArr[2] /= 255;
return rgbaArr;
}
/**
* @name clay.core.color.hsla2rgba
* @param {Array.} hsla
* @param {Array.} rgba
* @return {Array.} rgba
*/
function hsla2rgba(hsla, rgba) {
var h = (((parseFloat(hsla[0]) % 360) + 360) % 360) / 360; // 0 .. 1
// NOTE(deanm): According to the CSS spec s/l should only be
// percentages, but we don't bother and let float or percentage.
var s = parseCssFloat(hsla[1]);
var l = parseCssFloat(hsla[2]);
var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
var m1 = l * 2 - m2;
rgba = rgba || [];
setRgba(rgba,
clampCssByte(cssHueToRgb(m1, m2, h + 1 / 3) * 255),
clampCssByte(cssHueToRgb(m1, m2, h) * 255),
clampCssByte(cssHueToRgb(m1, m2, h - 1 / 3) * 255),
1
);
if (hsla.length === 4) {
rgba[3] = hsla[3];
}
return rgba;
}
/**
* @name clay.core.color.rgba2hsla
* @param {Array.} rgba
* @return {Array.} hsla
*/
function rgba2hsla(rgba) {
if (!rgba) {
return;
}
// RGB from 0 to 255
var R = rgba[0] / 255;
var G = rgba[1] / 255;
var B = rgba[2] / 255;
var vMin = Math.min(R, G, B); // Min. value of RGB
var vMax = Math.max(R, G, B); // Max. value of RGB
var delta = vMax - vMin; // Delta RGB value
var L = (vMax + vMin) / 2;
var H;
var S;
// HSL results from 0 to 1
if (delta === 0) {
H = 0;
S = 0;
}
else {
if (L < 0.5) {
S = delta / (vMax + vMin);
}
else {
S = delta / (2 - vMax - vMin);
}
var deltaR = (((vMax - R) / 6) + (delta / 2)) / delta;
var deltaG = (((vMax - G) / 6) + (delta / 2)) / delta;
var deltaB = (((vMax - B) / 6) + (delta / 2)) / delta;
if (R === vMax) {
H = deltaB - deltaG;
}
else if (G === vMax) {
H = (1 / 3) + deltaR - deltaB;
}
else if (B === vMax) {
H = (2 / 3) + deltaG - deltaR;
}
if (H < 0) {
H += 1;
}
if (H > 1) {
H -= 1;
}
}
var hsla = [H * 360, S, L];
if (rgba[3] != null) {
hsla.push(rgba[3]);
}
return hsla;
}
/**
* @name clay.core.color.lift
* @param {string} color
* @param {number} level
* @return {string}
*/
colorUtil.lift = function (color, level) {
var colorArr = colorUtil.parse(color);
if (colorArr) {
for (var i = 0; i < 3; i++) {
if (level < 0) {
colorArr[i] = colorArr[i] * (1 - level) | 0;
}
else {
colorArr[i] = ((255 - colorArr[i]) * level + colorArr[i]) | 0;
}
}
return colorUtil.stringify(colorArr, colorArr.length === 4 ? 'rgba' : 'rgb');
}
}
/**
* @name clay.core.color.toHex
* @param {string} color
* @return {string}
*/
colorUtil.toHex = function (color) {
var colorArr = colorUtil.parse(color);
if (colorArr) {
return ((1 << 24) + (colorArr[0] << 16) + (colorArr[1] << 8) + (+colorArr[2])).toString(16).slice(1);
}
};
/**
* Map value to color. Faster than lerp methods because color is represented by rgba array.
* @name clay.core.color
* @param {number} normalizedValue A float between 0 and 1.
* @param {Array.>} colors List of rgba color array
* @param {Array.} [out] Mapped gba color array
* @return {Array.} will be null/undefined if input illegal.
*/
colorUtil.fastLerp = function (normalizedValue, colors, out) {
if (!(colors && colors.length)
|| !(normalizedValue >= 0 && normalizedValue <= 1)
) {
return;
}
out = out || [];
var value = normalizedValue * (colors.length - 1);
var leftIndex = Math.floor(value);
var rightIndex = Math.ceil(value);
var leftColor = colors[leftIndex];
var rightColor = colors[rightIndex];
var dv = value - leftIndex;
out[0] = clampCssByte(lerpNumber(leftColor[0], rightColor[0], dv));
out[1] = clampCssByte(lerpNumber(leftColor[1], rightColor[1], dv));
out[2] = clampCssByte(lerpNumber(leftColor[2], rightColor[2], dv));
out[3] = clampCssFloat(lerpNumber(leftColor[3], rightColor[3], dv));
return out;
}
colorUtil.fastMapToColor = colorUtil.fastLerp;
/**
* @param {number} normalizedValue A float between 0 and 1.
* @param {Array.} colors Color list.
* @param {boolean=} fullOutput Default false.
* @return {(string|Object)} Result color. If fullOutput,
* return {color: ..., leftIndex: ..., rightIndex: ..., value: ...},
*/
colorUtil.lerp = function (normalizedValue, colors, fullOutput) {
if (!(colors && colors.length)
|| !(normalizedValue >= 0 && normalizedValue <= 1)
) {
return;
}
var value = normalizedValue * (colors.length - 1);
var leftIndex = Math.floor(value);
var rightIndex = Math.ceil(value);
var leftColor = colorUtil.parse(colors[leftIndex]);
var rightColor = colorUtil.parse(colors[rightIndex]);
var dv = value - leftIndex;
var color = colorUtil.stringify(
[
clampCssByte(lerpNumber(leftColor[0], rightColor[0], dv)),
clampCssByte(lerpNumber(leftColor[1], rightColor[1], dv)),
clampCssByte(lerpNumber(leftColor[2], rightColor[2], dv)),
clampCssFloat(lerpNumber(leftColor[3], rightColor[3], dv))
],
'rgba'
);
return fullOutput
? {
color: color,
leftIndex: leftIndex,
rightIndex: rightIndex,
value: value
}
: color;
}
/**
* @deprecated
*/
colorUtil.mapToColor = colorUtil.lerp;
/**
* @name clay.core.color
* @param {string} color
* @param {number=} h 0 ~ 360, ignore when null.
* @param {number=} s 0 ~ 1, ignore when null.
* @param {number=} l 0 ~ 1, ignore when null.
* @return {string} Color string in rgba format.
*/
colorUtil.modifyHSL = function (color, h, s, l) {
color = colorUtil.parse(color);
if (color) {
color = rgba2hsla(color);
h != null && (color[0] = clampCssAngle(h));
s != null && (color[1] = parseCssFloat(s));
l != null && (color[2] = parseCssFloat(l));
return colorUtil.stringify(hsla2rgba(color), 'rgba');
}
}
/**
* @param {string} color
* @param {number=} alpha 0 ~ 1
* @return {string} Color string in rgba format.
*/
colorUtil.modifyAlpha = function (color, alpha) {
color = colorUtil.parse(color);
if (color && alpha != null) {
color[3] = clampCssFloat(alpha);
return colorUtil.stringify(color, 'rgba');
}
}
/**
* @param {Array.} arrColor like [12,33,44,0.4]
* @param {string} type 'rgba', 'hsva', ...
* @return {string} Result color. (If input illegal, return undefined).
*/
colorUtil.stringify = function (arrColor, type) {
if (!arrColor || !arrColor.length) {
return;
}
var colorStr = arrColor[0] + ',' + arrColor[1] + ',' + arrColor[2];
if (type === 'rgba' || type === 'hsva' || type === 'hsla') {
colorStr += ',' + arrColor[3];
}
return type + '(' + colorStr + ')';
};
/* harmony default export */ __webpack_exports__["a"] = (colorUtil);
/***/ }),
/* 106 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/**
* Simple double linked list. Compared with array, it has O(1) remove operation.
* @constructor
* @alias clay.core.LinkedList
*/
var LinkedList = function () {
/**
* @type {clay.core.LinkedList.Entry}
*/
this.head = null;
/**
* @type {clay.core.LinkedList.Entry}
*/
this.tail = null;
this._length = 0;
};
/**
* Insert a new value at the tail
* @param {} val
* @return {clay.core.LinkedList.Entry}
*/
LinkedList.prototype.insert = function (val) {
var entry = new LinkedList.Entry(val);
this.insertEntry(entry);
return entry;
};
/**
* Insert a new value at idx
* @param {number} idx
* @param {} val
* @return {clay.core.LinkedList.Entry}
*/
LinkedList.prototype.insertAt = function (idx, val) {
if (idx < 0) {
return;
}
var next = this.head;
var cursor = 0;
while (next && cursor != idx) {
next = next.next;
cursor++;
}
if (next) {
var entry = new LinkedList.Entry(val);
var prev = next.prev;
if (!prev) { //next is head
this.head = entry;
}
else {
prev.next = entry;
entry.prev = prev;
}
entry.next = next;
next.prev = entry;
}
else {
this.insert(val);
}
};
LinkedList.prototype.insertBeforeEntry = function (val, next) {
var entry = new LinkedList.Entry(val);
var prev = next.prev;
if (!prev) { //next is head
this.head = entry;
}
else {
prev.next = entry;
entry.prev = prev;
}
entry.next = next;
next.prev = entry;
this._length++;
};
/**
* Insert an entry at the tail
* @param {clay.core.LinkedList.Entry} entry
*/
LinkedList.prototype.insertEntry = function (entry) {
if (!this.head) {
this.head = this.tail = entry;
}
else {
this.tail.next = entry;
entry.prev = this.tail;
this.tail = entry;
}
this._length++;
};
/**
* Remove entry.
* @param {clay.core.LinkedList.Entry} entry
*/
LinkedList.prototype.remove = function (entry) {
var prev = entry.prev;
var next = entry.next;
if (prev) {
prev.next = next;
}
else {
// Is head
this.head = next;
}
if (next) {
next.prev = prev;
}
else {
// Is tail
this.tail = prev;
}
entry.next = entry.prev = null;
this._length--;
};
/**
* Remove entry at index.
* @param {number} idx
* @return {}
*/
LinkedList.prototype.removeAt = function (idx) {
if (idx < 0) {
return;
}
var curr = this.head;
var cursor = 0;
while (curr && cursor != idx) {
curr = curr.next;
cursor++;
}
if (curr) {
this.remove(curr);
return curr.value;
}
};
/**
* Get head value
* @return {}
*/
LinkedList.prototype.getHead = function () {
if (this.head) {
return this.head.value;
}
};
/**
* Get tail value
* @return {}
*/
LinkedList.prototype.getTail = function () {
if (this.tail) {
return this.tail.value;
}
};
/**
* Get value at idx
* @param {number} idx
* @return {}
*/
LinkedList.prototype.getAt = function (idx) {
if (idx < 0) {
return;
}
var curr = this.head;
var cursor = 0;
while (curr && cursor != idx) {
curr = curr.next;
cursor++;
}
return curr.value;
};
/**
* @param {} value
* @return {number}
*/
LinkedList.prototype.indexOf = function (value) {
var curr = this.head;
var cursor = 0;
while (curr) {
if (curr.value === value) {
return cursor;
}
curr = curr.next;
cursor++;
}
};
/**
* @return {number}
*/
LinkedList.prototype.length = function () {
return this._length;
};
/**
* If list is empty
*/
LinkedList.prototype.isEmpty = function () {
return this._length === 0;
};
/**
* @param {Function} cb
* @param {} context
*/
LinkedList.prototype.forEach = function (cb, context) {
var curr = this.head;
var idx = 0;
var haveContext = typeof(context) != 'undefined';
while (curr) {
if (haveContext) {
cb.call(context, curr.value, idx);
}
else {
cb(curr.value, idx);
}
curr = curr.next;
idx++;
}
};
/**
* Clear the list
*/
LinkedList.prototype.clear = function () {
this.tail = this.head = null;
this._length = 0;
};
/**
* @constructor
* @param {} val
*/
LinkedList.Entry = function (val) {
/**
* @type {}
*/
this.value = val;
/**
* @type {clay.core.LinkedList.Entry}
*/
this.next = null;
/**
* @type {clay.core.LinkedList.Entry}
*/
this.prev = null;
};
/* harmony default export */ __webpack_exports__["a"] = (LinkedList);
/***/ }),
/* 107 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__GLProgram__ = __webpack_require__(108);
var loopRegex = /for\s*?\(int\s*?_idx_\s*\=\s*([\w-]+)\;\s*_idx_\s*<\s*([\w-]+);\s*_idx_\s*\+\+\s*\)\s*\{\{([\s\S]+?)(?=\}\})\}\}/g;
function unrollLoop(shaderStr, defines, lightsNumbers) {
// Loop unroll from three.js, https://github.com/mrdoob/three.js/blob/master/src/renderers/webgl/WebGLProgram.js#L175
// In some case like shadowMap in loop use 'i' to index value much slower.
// Loop use _idx_ and increased with _idx_++ will be unrolled
// Use {{ }} to match the pair so the if statement will not be affected
// Write like following
// for (int _idx_ = 0; _idx_ < 4; _idx_++) {{
// vec3 color = texture2D(textures[_idx_], uv).rgb;
// }}
function replace(match, start, end, snippet) {
var unroll = '';
// Try to treat as define
if (isNaN(start)) {
if (start in defines) {
start = defines[start];
}
else {
start = lightNumberDefines[start];
}
}
if (isNaN(end)) {
if (end in defines) {
end = defines[end];
}
else {
end = lightNumberDefines[end];
}
}
// TODO Error checking
for (var idx = parseInt(start); idx < parseInt(end); idx++) {
// PENDING Add scope?
unroll += '{'
+ snippet
.replace(/float\s*\(\s*_idx_\s*\)/g, idx.toFixed(1))
.replace(/_idx_/g, idx)
+ '}';
}
return unroll;
}
var lightNumberDefines = {};
for (var lightType in lightsNumbers) {
lightNumberDefines[lightType + '_COUNT'] = lightsNumbers[lightType];
}
return shaderStr.replace(loopRegex, replace);
}
function getDefineCode(defines, lightsNumbers, enabledTextures) {
var defineStr = [];
if (lightsNumbers) {
for (var lightType in lightsNumbers) {
var count = lightsNumbers[lightType];
if (count > 0) {
defineStr.push('#define ' + lightType.toUpperCase() + '_COUNT ' + count);
}
}
}
if (enabledTextures) {
for (var i = 0; i < enabledTextures.length; i++) {
var symbol = enabledTextures[i];
defineStr.push('#define ' + symbol.toUpperCase() + '_ENABLED');
}
}
// Custom Defines
for (var symbol in defines) {
var value = defines[symbol];
if (value === null) {
defineStr.push('#define ' + symbol);
}
else{
defineStr.push('#define ' + symbol + ' ' + value.toString());
}
}
return defineStr.join('\n');
}
function getExtensionCode(exts) {
// Extension declaration must before all non-preprocessor codes
// TODO vertex ? extension enum ?
var extensionStr = [];
for (var i = 0; i < exts.length; i++) {
extensionStr.push('#extension GL_' + exts[i] + ' : enable');
}
return extensionStr.join('\n');
}
function getPrecisionCode(precision) {
return ['precision', precision, 'float'].join(' ') + ';\n'
+ ['precision', precision, 'int'].join(' ') + ';\n'
// depth texture may have precision problem on iOS device.
+ ['precision', precision, 'sampler2D'].join(' ') + ';\n';
}
function ProgramManager(renderer) {
this._renderer = renderer;
this._cache = {};
}
ProgramManager.prototype.getProgram = function (renderable, material, scene) {
var cache = this._cache;
var key = 's' + material.shader.shaderID + 'm' + material.getProgramKey();
if (scene) {
key += 'se' + scene.getProgramKey(renderable.lightGroup);
}
if (renderable.isSkinnedMesh()) {
key += ',' + renderable.joints.length;
}
var program = cache[key];
if (program) {
return program;
}
var lightsNumbers = scene ? scene.getLightsNumbers(renderable.lightGroup) : {};
var renderer = this._renderer;
var _gl = renderer.gl;
var enabledTextures = material.getEnabledTextures();
var skinDefineCode = '';
if (renderable.isSkinnedMesh()) {
// TODO Add skinning code?
skinDefineCode = '\n' + getDefineCode({
SKINNING: null,
JOINT_COUNT: renderable.joints.length
}) + '\n';
}
// TODO Optimize key generation
// VERTEX
var vertexDefineStr = skinDefineCode + getDefineCode(material.vertexDefines, lightsNumbers, enabledTextures);
// FRAGMENT
var fragmentDefineStr = skinDefineCode + getDefineCode(material.fragmentDefines, lightsNumbers, enabledTextures);
var vertexCode = vertexDefineStr + '\n' + material.shader.vertex;
var fragmentCode = getExtensionCode([
// TODO Not hard coded
'OES_standard_derivatives',
'EXT_shader_texture_lod'
]) + '\n'
+ getPrecisionCode(material.precision) + '\n'
+ fragmentDefineStr + '\n' + material.shader.fragment;
var finalVertexCode = unrollLoop(vertexCode, material.vertexDefines, lightsNumbers);
var finalFragmentCode = unrollLoop(fragmentCode, material.fragmentDefines, lightsNumbers);
var program = new __WEBPACK_IMPORTED_MODULE_0__GLProgram__["a" /* default */]();
program.uniformSemantics = material.shader.uniformSemantics;
program.attributes = material.shader.attributes;
var errorMsg = program.buildProgram(_gl, material.shader, finalVertexCode, finalFragmentCode);
program.__error = errorMsg;
cache[key] = program;
return program;
};
/* harmony default export */ __webpack_exports__["a"] = (ProgramManager);
/***/ }),
/* 108 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_vendor__ = __webpack_require__(18);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_Base__ = __webpack_require__(9);
var SHADER_STATE_TO_ENABLE = 1;
var SHADER_STATE_KEEP_ENABLE = 2;
var SHADER_STATE_PENDING = 3;
// Enable attribute operation is global to all programs
// Here saved the list of all enabled attribute index
// http://www.mjbshaw.com/2013/03/webgl-fixing-invalidoperation.html
var enabledAttributeList = {};
// some util functions
function addLineNumbers(string) {
var chunks = string.split('\n');
for (var i = 0, il = chunks.length; i < il; i ++) {
// Chrome reports shader errors on lines
// starting counting from 1
chunks[i] = (i + 1) + ': ' + chunks[i];
}
return chunks.join('\n');
}
// Return true or error msg if error happened
function checkShaderErrorMsg(_gl, shader, shaderString) {
if (!_gl.getShaderParameter(shader, _gl.COMPILE_STATUS)) {
return [_gl.getShaderInfoLog(shader), addLineNumbers(shaderString)].join('\n');
}
}
var tmpFloat32Array16 = new __WEBPACK_IMPORTED_MODULE_0__core_vendor__["a" /* default */].Float32Array(16);
var GLProgram = __WEBPACK_IMPORTED_MODULE_1__core_Base__["a" /* default */].extend({
uniformSemantics: {},
attributes: {}
}, function () {
this._locations = {};
this._textureSlot = 0;
this._program = null;
}, {
bind: function (renderer) {
this._textureSlot = 0;
renderer.gl.useProgram(this._program);
},
hasUniform: function (symbol) {
var location = this._locations[symbol];
return location !== null && location !== undefined;
},
useTextureSlot: function (renderer, texture, slot) {
if (texture) {
renderer.gl.activeTexture(renderer.gl.TEXTURE0 + slot);
// Maybe texture is not loaded yet;
if (texture.isRenderable()) {
texture.bind(renderer);
}
else {
// Bind texture to null
texture.unbind(renderer);
}
}
},
currentTextureSlot: function () {
return this._textureSlot;
},
resetTextureSlot: function (slot) {
this._textureSlot = slot || 0;
},
takeCurrentTextureSlot: function (renderer, texture) {
var textureSlot = this._textureSlot;
this.useTextureSlot(renderer, texture, textureSlot);
this._textureSlot++;
return textureSlot;
},
setUniform: function (_gl, type, symbol, value) {
var locationMap = this._locations;
var location = locationMap[symbol];
// Uniform is not existed in the shader
if (location === null || location === undefined) {
return false;
}
switch (type) {
case 'm4':
if (!(value instanceof Float32Array)) {
// Use Float32Array is much faster than array when uniformMatrix4fv.
for (var i = 0; i < value.length; i++) {
tmpFloat32Array16[i] = value[i];
}
value = tmpFloat32Array16;
}
_gl.uniformMatrix4fv(location, false, value);
break;
case '2i':
_gl.uniform2i(location, value[0], value[1]);
break;
case '2f':
_gl.uniform2f(location, value[0], value[1]);
break;
case '3i':
_gl.uniform3i(location, value[0], value[1], value[2]);
break;
case '3f':
_gl.uniform3f(location, value[0], value[1], value[2]);
break;
case '4i':
_gl.uniform4i(location, value[0], value[1], value[2], value[3]);
break;
case '4f':
_gl.uniform4f(location, value[0], value[1], value[2], value[3]);
break;
case '1i':
_gl.uniform1i(location, value);
break;
case '1f':
_gl.uniform1f(location, value);
break;
case '1fv':
_gl.uniform1fv(location, value);
break;
case '1iv':
_gl.uniform1iv(location, value);
break;
case '2iv':
_gl.uniform2iv(location, value);
break;
case '2fv':
_gl.uniform2fv(location, value);
break;
case '3iv':
_gl.uniform3iv(location, value);
break;
case '3fv':
_gl.uniform3fv(location, value);
break;
case '4iv':
_gl.uniform4iv(location, value);
break;
case '4fv':
_gl.uniform4fv(location, value);
break;
case 'm2':
case 'm2v':
_gl.uniformMatrix2fv(location, false, value);
break;
case 'm3':
case 'm3v':
_gl.uniformMatrix3fv(location, false, value);
break;
case 'm4v':
// Raw value
if (Array.isArray(value) && Array.isArray(value[0])) {
var array = new __WEBPACK_IMPORTED_MODULE_0__core_vendor__["a" /* default */].Float32Array(value.length * 16);
var cursor = 0;
for (var i = 0; i < value.length; i++) {
var item = value[i];
for (var j = 0; j < 16; j++) {
array[cursor++] = item[j];
}
}
_gl.uniformMatrix4fv(location, false, array);
}
else { // ArrayBufferView
_gl.uniformMatrix4fv(location, false, value);
}
break;
}
return true;
},
setUniformOfSemantic: function (_gl, semantic, val) {
var semanticInfo = this.uniformSemantics[semantic];
if (semanticInfo) {
return this.setUniform(_gl, semanticInfo.type, semanticInfo.symbol, val);
}
return false;
},
// Used for creating VAO
// Enable the attributes passed in and disable the rest
// Example Usage:
// enableAttributes(renderer, ["position", "texcoords"])
enableAttributes: function (renderer, attribList, vao) {
var _gl = renderer.gl;
var program = this._program;
var locationMap = this._locations;
var enabledAttributeListInContext;
if (vao) {
enabledAttributeListInContext = vao.__enabledAttributeList;
}
else {
enabledAttributeListInContext = enabledAttributeList[renderer.__uid__];
}
if (!enabledAttributeListInContext) {
// In vertex array object context
// PENDING Each vao object needs to enable attributes again?
if (vao) {
enabledAttributeListInContext
= vao.__enabledAttributeList
= [];
}
else {
enabledAttributeListInContext
= enabledAttributeList[renderer.__uid__]
= [];
}
}
var locationList = [];
for (var i = 0; i < attribList.length; i++) {
var symbol = attribList[i];
if (!this.attributes[symbol]) {
locationList[i] = -1;
continue;
}
var location = locationMap[symbol];
if (location == null) {
location = _gl.getAttribLocation(program, symbol);
// Attrib location is a number from 0 to ...
if (location === -1) {
locationList[i] = -1;
continue;
}
locationMap[symbol] = location;
}
locationList[i] = location;
if (!enabledAttributeListInContext[location]) {
enabledAttributeListInContext[location] = SHADER_STATE_TO_ENABLE;
}
else {
enabledAttributeListInContext[location] = SHADER_STATE_KEEP_ENABLE;
}
}
for (var i = 0; i < enabledAttributeListInContext.length; i++) {
switch(enabledAttributeListInContext[i]){
case SHADER_STATE_TO_ENABLE:
_gl.enableVertexAttribArray(i);
enabledAttributeListInContext[i] = SHADER_STATE_PENDING;
break;
case SHADER_STATE_KEEP_ENABLE:
enabledAttributeListInContext[i] = SHADER_STATE_PENDING;
break;
// Expired
case SHADER_STATE_PENDING:
_gl.disableVertexAttribArray(i);
enabledAttributeListInContext[i] = 0;
break;
}
}
return locationList;
},
buildProgram: function (_gl, shader, vertexShaderCode, fragmentShaderCode) {
var vertexShader = _gl.createShader(_gl.VERTEX_SHADER);
var program = _gl.createProgram();
_gl.shaderSource(vertexShader, vertexShaderCode);
_gl.compileShader(vertexShader);
var fragmentShader = _gl.createShader(_gl.FRAGMENT_SHADER);
_gl.shaderSource(fragmentShader, fragmentShaderCode);
_gl.compileShader(fragmentShader);
var msg = checkShaderErrorMsg(_gl, vertexShader, vertexShaderCode);
if (msg) {
return msg;
}
msg = checkShaderErrorMsg(_gl, fragmentShader, fragmentShaderCode);
if (msg) {
return msg;
}
_gl.attachShader(program, vertexShader);
_gl.attachShader(program, fragmentShader);
// Force the position bind to location 0;
if (shader.attributeSemantics['POSITION']) {
_gl.bindAttribLocation(program, 0, shader.attributeSemantics['POSITION'].symbol);
}
else {
// Else choose an attribute and bind to location 0;
var keys = Object.keys(this.attributes);
_gl.bindAttribLocation(program, 0, keys[0]);
}
_gl.linkProgram(program);
if (!_gl.getProgramParameter(program, _gl.LINK_STATUS)) {
return 'Could not link program\n' + 'VALIDATE_STATUS: ' + _gl.getProgramParameter(program, _gl.VALIDATE_STATUS) + ', gl error [' + _gl.getError() + ']';
}
// Cache uniform locations
for (var i = 0; i < shader.uniforms.length; i++) {
var uniformSymbol = shader.uniforms[i];
this._locations[uniformSymbol] = _gl.getUniformLocation(program, uniformSymbol);
}
_gl.deleteShader(vertexShader);
_gl.deleteShader(fragmentShader);
this._program = program;
// Save code.
this.vertexCode = vertexShaderCode;
this.fragmentCode = fragmentShaderCode;
}
});
/* harmony default export */ __webpack_exports__["a"] = (GLProgram);
/***/ }),
/* 109 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__calcAmbientSHLight_glsl_js__ = __webpack_require__(110);
var uniformVec3Prefix = 'uniform vec3 ';
var uniformFloatPrefix = 'uniform float ';
var exportHeaderPrefix = '@export clay.header.';
var exportEnd = '@end';
var unconfigurable = ':unconfigurable;';
/* harmony default export */ __webpack_exports__["a"] = ([
exportHeaderPrefix + 'directional_light',
uniformVec3Prefix + 'directionalLightDirection[DIRECTIONAL_LIGHT_COUNT]' + unconfigurable,
uniformVec3Prefix + 'directionalLightColor[DIRECTIONAL_LIGHT_COUNT]' + unconfigurable,
exportEnd,
exportHeaderPrefix + 'ambient_light',
uniformVec3Prefix + 'ambientLightColor[AMBIENT_LIGHT_COUNT]' + unconfigurable,
exportEnd,
exportHeaderPrefix + 'ambient_sh_light',
uniformVec3Prefix + 'ambientSHLightColor[AMBIENT_SH_LIGHT_COUNT]' + unconfigurable,
uniformVec3Prefix + 'ambientSHLightCoefficients[AMBIENT_SH_LIGHT_COUNT * 9]' + unconfigurable,
__WEBPACK_IMPORTED_MODULE_0__calcAmbientSHLight_glsl_js__["a" /* default */],
exportEnd,
exportHeaderPrefix + 'ambient_cubemap_light',
uniformVec3Prefix + 'ambientCubemapLightColor[AMBIENT_CUBEMAP_LIGHT_COUNT]' + unconfigurable,
'uniform samplerCube ambientCubemapLightCubemap[AMBIENT_CUBEMAP_LIGHT_COUNT]' + unconfigurable,
'uniform sampler2D ambientCubemapLightBRDFLookup[AMBIENT_CUBEMAP_LIGHT_COUNT]' + unconfigurable,
exportEnd,
exportHeaderPrefix + 'point_light',
uniformVec3Prefix + 'pointLightPosition[POINT_LIGHT_COUNT]' + unconfigurable,
uniformFloatPrefix + 'pointLightRange[POINT_LIGHT_COUNT]' + unconfigurable,
uniformVec3Prefix + 'pointLightColor[POINT_LIGHT_COUNT]' + unconfigurable,
exportEnd,
exportHeaderPrefix + 'spot_light',
uniformVec3Prefix + 'spotLightPosition[SPOT_LIGHT_COUNT]' + unconfigurable,
uniformVec3Prefix + 'spotLightDirection[SPOT_LIGHT_COUNT]' + unconfigurable,
uniformFloatPrefix + 'spotLightRange[SPOT_LIGHT_COUNT]' + unconfigurable,
uniformFloatPrefix + 'spotLightUmbraAngleCosine[SPOT_LIGHT_COUNT]' + unconfigurable,
uniformFloatPrefix + 'spotLightPenumbraAngleCosine[SPOT_LIGHT_COUNT]' + unconfigurable,
uniformFloatPrefix + 'spotLightFalloffFactor[SPOT_LIGHT_COUNT]' + unconfigurable,
uniformVec3Prefix + 'spotLightColor[SPOT_LIGHT_COUNT]' + unconfigurable,
exportEnd
].join('\n'));
/***/ }),
/* 110 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("vec3 calcAmbientSHLight(int idx, vec3 N) {\n int offset = 9 * idx;\n return ambientSHLightCoefficients[0]\n + ambientSHLightCoefficients[1] * N.x\n + ambientSHLightCoefficients[2] * N.y\n + ambientSHLightCoefficients[3] * N.z\n + ambientSHLightCoefficients[4] * N.x * N.z\n + ambientSHLightCoefficients[5] * N.z * N.y\n + ambientSHLightCoefficients[6] * N.y * N.x\n + ambientSHLightCoefficients[7] * (3.0 * N.z * N.z - 1.0)\n + ambientSHLightCoefficients[8] * (N.x * N.x - N.y * N.y);\n}");
/***/ }),
/* 111 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_Base__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__math_Ray__ = __webpack_require__(49);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__math_Vector2__ = __webpack_require__(23);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__math_Vector3__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__math_Matrix4__ = __webpack_require__(7);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__Renderable__ = __webpack_require__(66);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__core_glenum__ = __webpack_require__(11);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_7__dep_glmatrix__);
var vec3 = __WEBPACK_IMPORTED_MODULE_7__dep_glmatrix___default.a.vec3;
/**
* @constructor clay.picking.RayPicking
* @extends clay.core.Base
*/
var RayPicking = __WEBPACK_IMPORTED_MODULE_0__core_Base__["a" /* default */].extend(
/** @lends clay.picking.RayPicking# */
{
/**
* Target scene
* @type {clay.Scene}
*/
scene: null,
/**
* Target camera
* @type {clay.Camera}
*/
camera: null,
/**
* Target renderer
* @type {clay.Renderer}
*/
renderer: null
}, function () {
this._ray = new __WEBPACK_IMPORTED_MODULE_1__math_Ray__["a" /* default */]();
this._ndc = new __WEBPACK_IMPORTED_MODULE_2__math_Vector2__["a" /* default */]();
},
/** @lends clay.picking.RayPicking.prototype */
{
/**
* Pick the nearest intersection object in the scene
* @param {number} x Mouse position x
* @param {number} y Mouse position y
* @param {boolean} [forcePickAll=false] ignore ignorePicking
* @return {clay.picking.RayPicking~Intersection}
*/
pick: function (x, y, forcePickAll) {
var out = this.pickAll(x, y, [], forcePickAll);
return out[0] || null;
},
/**
* Pick all intersection objects, wich will be sorted from near to far
* @param {number} x Mouse position x
* @param {number} y Mouse position y
* @param {Array} [output]
* @param {boolean} [forcePickAll=false] ignore ignorePicking
* @return {Array.}
*/
pickAll: function (x, y, output, forcePickAll) {
this.renderer.screenToNDC(x, y, this._ndc);
this.camera.castRay(this._ndc, this._ray);
output = output || [];
this._intersectNode(this.scene, output, forcePickAll || false);
output.sort(this._intersectionCompareFunc);
return output;
},
_intersectNode: function (node, out, forcePickAll) {
if ((node instanceof __WEBPACK_IMPORTED_MODULE_5__Renderable__["a" /* default */]) && node.isRenderable()) {
if ((!node.ignorePicking || forcePickAll)
&& (
// Only triangle mesh support ray picking
(node.mode === __WEBPACK_IMPORTED_MODULE_6__core_glenum__["a" /* default */].TRIANGLES && node.geometry.isUseIndices())
// Or if geometry has it's own pickByRay, pick, implementation
|| node.geometry.pickByRay
|| node.geometry.pick
)
) {
this._intersectRenderable(node, out);
}
}
for (var i = 0; i < node._children.length; i++) {
this._intersectNode(node._children[i], out, forcePickAll);
}
},
_intersectRenderable: (function () {
var v1 = new __WEBPACK_IMPORTED_MODULE_3__math_Vector3__["a" /* default */]();
var v2 = new __WEBPACK_IMPORTED_MODULE_3__math_Vector3__["a" /* default */]();
var v3 = new __WEBPACK_IMPORTED_MODULE_3__math_Vector3__["a" /* default */]();
var ray = new __WEBPACK_IMPORTED_MODULE_1__math_Ray__["a" /* default */]();
var worldInverse = new __WEBPACK_IMPORTED_MODULE_4__math_Matrix4__["a" /* default */]();
return function (renderable, out) {
var isSkinnedMesh = renderable.isSkinnedMesh();
ray.copy(this._ray);
__WEBPACK_IMPORTED_MODULE_4__math_Matrix4__["a" /* default */].invert(worldInverse, renderable.worldTransform);
// Skinned mesh will ignore the world transform.
if (!isSkinnedMesh) {
ray.applyTransform(worldInverse);
}
var geometry = renderable.geometry;
// Ignore bounding box of skinned mesh?
if (!isSkinnedMesh) {
if (geometry.boundingBox) {
if (!ray.intersectBoundingBox(geometry.boundingBox)) {
return;
}
}
}
// Use user defined picking algorithm
if (geometry.pick) {
geometry.pick(
this._ndc.x, this._ndc.y,
this.renderer,
this.camera,
renderable, out
);
return;
}
// Use user defined ray picking algorithm
else if (geometry.pickByRay) {
geometry.pickByRay(ray, renderable, out);
return;
}
var cullBack = (renderable.cullFace === __WEBPACK_IMPORTED_MODULE_6__core_glenum__["a" /* default */].BACK && renderable.frontFace === __WEBPACK_IMPORTED_MODULE_6__core_glenum__["a" /* default */].CCW)
|| (renderable.cullFace === __WEBPACK_IMPORTED_MODULE_6__core_glenum__["a" /* default */].FRONT && renderable.frontFace === __WEBPACK_IMPORTED_MODULE_6__core_glenum__["a" /* default */].CW);
var point;
var indices = geometry.indices;
var positionAttr = geometry.attributes.position;
var weightAttr = geometry.attributes.weight;
var jointAttr = geometry.attributes.joint;
var skinMatricesArray;
var skinMatrices = [];
// Check if valid.
if (!positionAttr || !positionAttr.value || !indices) {
return;
}
if (isSkinnedMesh) {
skinMatricesArray = renderable.skeleton.getSubSkinMatrices(renderable.__uid__, renderable.joints);
for (var i = 0; i < renderable.joints.length; i++) {
skinMatrices[i] = skinMatrices[i] || [];
for (var k = 0; k < 16; k++) {
skinMatrices[i][k] = skinMatricesArray[i * 16 + k];
}
}
var pos = [];
var weight = [];
var joint = [];
var skinnedPos = [];
var tmp = [];
var skinnedPositionAttr = geometry.attributes.skinnedPosition;
if (!skinnedPositionAttr || !skinnedPositionAttr.value) {
geometry.createAttribute('skinnedPosition', 'f', 3);
skinnedPositionAttr = geometry.attributes.skinnedPosition;
skinnedPositionAttr.init(geometry.vertexCount);
}
for (var i = 0; i < geometry.vertexCount; i++) {
positionAttr.get(i, pos);
weightAttr.get(i, weight);
jointAttr.get(i, joint);
weight[3] = 1 - weight[0] - weight[1] - weight[2];
vec3.set(skinnedPos, 0, 0, 0);
for (var k = 0; k < 4; k++) {
if (joint[k] >= 0 && weight[k] > 1e-4) {
vec3.transformMat4(tmp, pos, skinMatrices[joint[k]]);
vec3.scaleAndAdd(skinnedPos, skinnedPos, tmp, weight[k]);
}
}
skinnedPositionAttr.set(i, skinnedPos);
}
}
for (var i = 0; i < indices.length; i += 3) {
var i1 = indices[i];
var i2 = indices[i + 1];
var i3 = indices[i + 2];
var finalPosAttr = isSkinnedMesh
? geometry.attributes.skinnedPosition
: positionAttr;
finalPosAttr.get(i1, v1.array);
finalPosAttr.get(i2, v2.array);
finalPosAttr.get(i3, v3.array);
if (cullBack) {
point = ray.intersectTriangle(v1, v2, v3, renderable.culling);
}
else {
point = ray.intersectTriangle(v1, v3, v2, renderable.culling);
}
if (point) {
var pointW = new __WEBPACK_IMPORTED_MODULE_3__math_Vector3__["a" /* default */]();
if (!isSkinnedMesh) {
__WEBPACK_IMPORTED_MODULE_3__math_Vector3__["a" /* default */].transformMat4(pointW, point, renderable.worldTransform);
}
else {
// TODO point maybe not right.
__WEBPACK_IMPORTED_MODULE_3__math_Vector3__["a" /* default */].copy(pointW, point);
}
out.push(new RayPicking.Intersection(
point, pointW, renderable, [i1, i2, i3], i / 3,
__WEBPACK_IMPORTED_MODULE_3__math_Vector3__["a" /* default */].dist(pointW, this._ray.origin)
));
}
}
};
})(),
_intersectionCompareFunc: function (a, b) {
return a.distance - b.distance;
}
});
/**
* @constructor clay.picking.RayPicking~Intersection
* @param {clay.Vector3} point
* @param {clay.Vector3} pointWorld
* @param {clay.Node} target
* @param {Array.} triangle
* @param {number} triangleIndex
* @param {number} distance
*/
RayPicking.Intersection = function (point, pointWorld, target, triangle, triangleIndex, distance) {
/**
* Intersection point in local transform coordinates
* @type {clay.Vector3}
*/
this.point = point;
/**
* Intersection point in world transform coordinates
* @type {clay.Vector3}
*/
this.pointWorld = pointWorld;
/**
* Intersection scene node
* @type {clay.Node}
*/
this.target = target;
/**
* Intersection triangle, which is an array of vertex index
* @type {Array.}
*/
this.triangle = triangle;
/**
* Index of intersection triangle.
*/
this.triangleIndex = triangleIndex;
/**
* Distance from intersection point to ray origin
* @type {number}
*/
this.distance = distance;
};
/* harmony default export */ __webpack_exports__["a"] = (RayPicking);
/***/ }),
/* 112 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
function get(options) {
var xhr = new XMLHttpRequest();
xhr.open('get', options.url);
// With response type set browser can get and put binary data
// https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Sending_and_Receiving_Binary_Data
// Default is text, and it can be set
// arraybuffer, blob, document, json, text
xhr.responseType = options.responseType || 'text';
if (options.onprogress) {
//https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest
xhr.onprogress = function(e) {
if (e.lengthComputable) {
var percent = e.loaded / e.total;
options.onprogress(percent, e.loaded, e.total);
}
else {
options.onprogress(null);
}
};
}
xhr.onload = function(e) {
if (xhr.status >= 400) {
options.onerror && options.onerror();
}
else {
options.onload && options.onload(xhr.response);
}
};
if (options.onerror) {
xhr.onerror = options.onerror;
}
xhr.send(null);
}
/* harmony default export */ __webpack_exports__["a"] = ({
get : get
});
/***/ }),
/* 113 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.skydome.vertex\n#define SHADER_NAME skydome\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nattribute vec2 texcoord : TEXCOORD_0;\nattribute vec3 position : POSITION;\nvarying vec2 v_Texcoord;\nvoid main()\n{\n gl_Position = worldViewProjection * vec4(position, 1.0);\n v_Texcoord = texcoord;\n}\n@end\n@export clay.skydome.fragment\nuniform sampler2D environmentMap;\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\n@import clay.util.srgb\n@import clay.util.ACES\nvoid main()\n{\n vec4 texel = decodeHDR(texture2D(environmentMap, v_Texcoord));\n#ifdef SRGB_DECODE\n texel = sRGBToLinear(texel);\n#endif\n#ifdef TONEMAPPING\n texel.rgb = ACESToneMapping(texel.rgb);\n#endif\n#ifdef SRGB_ENCODE\n texel = linearTosRGB(texel);\n#endif\n gl_FragColor = encodeHDR(vec4(texel.rgb, 1.0));\n}\n@end");
/***/ }),
/* 114 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Texture__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__TextureCube__ = __webpack_require__(24);
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb943991(v=vs.85).aspx
// https://github.com/toji/webgl-texture-utils/blob/master/texture-util/dds.js
var DDS_MAGIC = 0x20534444;
var DDSD_CAPS = 0x1;
var DDSD_HEIGHT = 0x2;
var DDSD_WIDTH = 0x4;
var DDSD_PITCH = 0x8;
var DDSD_PIXELFORMAT = 0x1000;
var DDSD_MIPMAPCOUNT = 0x20000;
var DDSD_LINEARSIZE = 0x80000;
var DDSD_DEPTH = 0x800000;
var DDSCAPS_COMPLEX = 0x8;
var DDSCAPS_MIPMAP = 0x400000;
var DDSCAPS_TEXTURE = 0x1000;
var DDSCAPS2_CUBEMAP = 0x200;
var DDSCAPS2_CUBEMAP_POSITIVEX = 0x400;
var DDSCAPS2_CUBEMAP_NEGATIVEX = 0x800;
var DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000;
var DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000;
var DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000;
var DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000;
var DDSCAPS2_VOLUME = 0x200000;
var DDPF_ALPHAPIXELS = 0x1;
var DDPF_ALPHA = 0x2;
var DDPF_FOURCC = 0x4;
var DDPF_RGB = 0x40;
var DDPF_YUV = 0x200;
var DDPF_LUMINANCE = 0x20000;
function fourCCToInt32(value) {
return value.charCodeAt(0) +
(value.charCodeAt(1) << 8) +
(value.charCodeAt(2) << 16) +
(value.charCodeAt(3) << 24);
}
function int32ToFourCC(value) {
return String.fromCharCode(
value & 0xff,
(value >> 8) & 0xff,
(value >> 16) & 0xff,
(value >> 24) & 0xff
);
}
var headerLengthInt = 31; // The header length in 32 bit ints
var FOURCC_DXT1 = fourCCToInt32('DXT1');
var FOURCC_DXT3 = fourCCToInt32('DXT3');
var FOURCC_DXT5 = fourCCToInt32('DXT5');
// Offsets into the header array
var off_magic = 0;
var off_size = 1;
var off_flags = 2;
var off_height = 3;
var off_width = 4;
var off_mipmapCount = 7;
var off_pfFlags = 20;
var off_pfFourCC = 21;
var off_caps = 27;
var off_caps2 = 28;
var off_caps3 = 29;
var off_caps4 = 30;
var ret = {
parse: function(arrayBuffer, out) {
var header = new Int32Array(arrayBuffer, 0, headerLengthInt);
if (header[off_magic] !== DDS_MAGIC) {
return null;
}
if (!header(off_pfFlags) & DDPF_FOURCC) {
return null;
}
var fourCC = header(off_pfFourCC);
var width = header[off_width];
var height = header[off_height];
var isCubeMap = header[off_caps2] & DDSCAPS2_CUBEMAP;
var hasMipmap = header[off_flags] & DDSD_MIPMAPCOUNT;
var blockBytes, internalFormat;
switch(fourCC) {
case FOURCC_DXT1:
blockBytes = 8;
internalFormat = __WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].COMPRESSED_RGB_S3TC_DXT1_EXT;
break;
case FOURCC_DXT3:
blockBytes = 16;
internalFormat = __WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].COMPRESSED_RGBA_S3TC_DXT3_EXT;
break;
case FOURCC_DXT5:
blockBytes = 16;
internalFormat = __WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].COMPRESSED_RGBA_S3TC_DXT5_EXT;
break;
default:
return null;
}
var dataOffset = header[off_size] + 4;
// TODO: Suppose all face are existed
var faceNumber = isCubeMap ? 6 : 1;
var mipmapCount = 1;
if (hasMipmap) {
mipmapCount = Math.max(1, header[off_mipmapCount]);
}
var textures = [];
for (var f = 0; f < faceNumber; f++) {
var _width = width;
var _height = height;
textures[f] = new __WEBPACK_IMPORTED_MODULE_1__Texture2D__["a" /* default */]({
width: _width,
height: _height,
format: internalFormat
});
var mipmaps = [];
for (var i = 0; i < mipmapCount; i++) {
var dataLength = Math.max(4, _width) / 4 * Math.max(4, _height) / 4 * blockBytes;
var byteArray = new Uint8Array(arrayBuffer, dataOffset, dataLength);
dataOffset += dataLength;
_width *= 0.5;
_height *= 0.5;
mipmaps[i] = byteArray;
}
textures[f].pixels = mipmaps[0];
if (hasMipmap) {
textures[f].mipmaps = mipmaps;
}
}
// TODO
// return isCubeMap ? textures : textures[0];
if (out) {
out.width = textures[0].width;
out.height = textures[0].height;
out.format = textures[0].format;
out.pixels = textures[0].pixels;
out.mipmaps = textures[0].mipmaps;
}
else {
return textures[0];
}
}
};
/* harmony default export */ __webpack_exports__["a"] = (ret);
/***/ }),
/* 115 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Texture__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Texture2D__ = __webpack_require__(5);
var toChar = String.fromCharCode;
var MINELEN = 8;
var MAXELEN = 0x7fff;
function rgbe2float(rgbe, buffer, offset, exposure) {
if (rgbe[3] > 0) {
var f = Math.pow(2.0, rgbe[3] - 128 - 8 + exposure);
buffer[offset + 0] = rgbe[0] * f;
buffer[offset + 1] = rgbe[1] * f;
buffer[offset + 2] = rgbe[2] * f;
}
else {
buffer[offset + 0] = 0;
buffer[offset + 1] = 0;
buffer[offset + 2] = 0;
}
buffer[offset + 3] = 1.0;
return buffer;
}
function uint82string(array, offset, size) {
var str = '';
for (var i = offset; i < size; i++) {
str += toChar(array[i]);
}
return str;
}
function copyrgbe(s, t) {
t[0] = s[0];
t[1] = s[1];
t[2] = s[2];
t[3] = s[3];
}
// TODO : check
function oldReadColors(scan, buffer, offset, xmax) {
var rshift = 0, x = 0, len = xmax;
while (len > 0) {
scan[x][0] = buffer[offset++];
scan[x][1] = buffer[offset++];
scan[x][2] = buffer[offset++];
scan[x][3] = buffer[offset++];
if (scan[x][0] === 1 && scan[x][1] === 1 && scan[x][2] === 1) {
// exp is count of repeated pixels
for (var i = (scan[x][3] << rshift) >>> 0; i > 0; i--) {
copyrgbe(scan[x-1], scan[x]);
x++;
len--;
}
rshift += 8;
} else {
x++;
len--;
rshift = 0;
}
}
return offset;
}
function readColors(scan, buffer, offset, xmax) {
if ((xmax < MINELEN) | (xmax > MAXELEN)) {
return oldReadColors(scan, buffer, offset, xmax);
}
var i = buffer[offset++];
if (i != 2) {
return oldReadColors(scan, buffer, offset - 1, xmax);
}
scan[0][1] = buffer[offset++];
scan[0][2] = buffer[offset++];
i = buffer[offset++];
if ((((scan[0][2] << 8) >>> 0) | i) >>> 0 !== xmax) {
return null;
}
for (var i = 0; i < 4; i++) {
for (var x = 0; x < xmax;) {
var code = buffer[offset++];
if (code > 128) {
code = (code & 127) >>> 0;
var val = buffer[offset++];
while (code--) {
scan[x++][i] = val;
}
} else {
while (code--) {
scan[x++][i] = buffer[offset++];
}
}
}
}
return offset;
}
var ret = {
// http://www.graphics.cornell.edu/~bjw/rgbe.html
// Blender source
// http://radsite.lbl.gov/radiance/refer/Notes/picture_format.html
parseRGBE: function(arrayBuffer, texture, exposure) {
if (exposure == null) {
exposure = 0;
}
var data = new Uint8Array(arrayBuffer);
var size = data.length;
if (uint82string(data, 0, 2) !== '#?') {
return;
}
// find empty line, next line is resolution info
for (var i = 2; i < size; i++) {
if (toChar(data[i]) === '\n' && toChar(data[i+1]) === '\n') {
break;
}
}
if (i >= size) { // not found
return;
}
// find resolution info line
i += 2;
var str = '';
for (; i < size; i++) {
var _char = toChar(data[i]);
if (_char === '\n') {
break;
}
str += _char;
}
// -Y M +X N
var tmp = str.split(' ');
var height = parseInt(tmp[1]);
var width = parseInt(tmp[3]);
if (!width || !height) {
return;
}
// read and decode actual data
var offset = i+1;
var scanline = [];
// memzero
for (var x = 0; x < width; x++) {
scanline[x] = [];
for (var j = 0; j < 4; j++) {
scanline[x][j] = 0;
}
}
var pixels = new Float32Array(width * height * 4);
var offset2 = 0;
for (var y = 0; y < height; y++) {
var offset = readColors(scanline, data, offset, width);
if (!offset) {
return null;
}
for (var x = 0; x < width; x++) {
rgbe2float(scanline[x], pixels, offset2, exposure);
offset2 += 4;
}
}
if (!texture) {
texture = new __WEBPACK_IMPORTED_MODULE_1__Texture2D__["a" /* default */]();
}
texture.width = width;
texture.height = height;
texture.pixels = pixels;
// HALF_FLOAT can't use Float32Array
texture.type = __WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].FLOAT;
return texture;
},
parseRGBEFromPNG: function(png) {
}
};
/* harmony default export */ __webpack_exports__["a"] = (ret);
/***/ }),
/* 116 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector3__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_math_Vector2__ = __webpack_require__(23);
/**
* Surface texture in the 3D scene.
* Provide management and rendering of zrender shapes and groups
*
* @module echarts-gl/util/EChartsSurface
* @author Yi Shen(http://github.com/pissang)
*/
var events = ['mousedown', 'mouseup', 'mousemove', 'mouseover', 'mouseout', 'click', 'dblclick', 'contextmenu'];
function makeHandlerName(eventName) {
return '_on' + eventName;
}
/**
* @constructor
* @alias echarts-gl/util/EChartsSurface
* @param {module:echarts~ECharts} chart
*/
var EChartsSurface = function (chart) {
var self = this;
this._texture = new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Texture2D__["a" /* default */]({
anisotropic: 32,
flipY: false,
surface: this,
dispose: function (renderer) {
self.dispose();
__WEBPACK_IMPORTED_MODULE_0_claygl_src_Texture2D__["a" /* default */].prototype.dispose.call(this, renderer);
}
});
events.forEach(function (eventName) {
this[makeHandlerName(eventName)] = function (eveObj) {
if (!eveObj.triangle) {
return;
}
this._meshes.forEach(function (mesh) {
this.dispatchEvent(eventName, mesh, eveObj.triangle, eveObj.point);
}, this);
};
}, this);
this._meshes = [];
if (chart) {
this.setECharts(chart);
}
// Texture updated callback;
this.onupdate = null;
};
EChartsSurface.prototype = {
constructor: EChartsSurface,
getTexture: function () {
return this._texture;
},
setECharts: function (chart) {
this._chart = chart;
var canvas = chart.getDom();
if (!(canvas instanceof HTMLCanvasElement)) {
console.error('ECharts must init on canvas if it is used as texture.');
// Use an empty canvas
canvas = document.createElement('canvas');
}
else {
var self = this;
// Wrap refreshImmediately
var zr = chart.getZr();
var oldRefreshImmediately = zr.__oldRefreshImmediately || zr.refreshImmediately;
zr.refreshImmediately = function () {
oldRefreshImmediately.call(this);
self._texture.dirty();
self.onupdate && self.onupdate();
};
zr.__oldRefreshImmediately = oldRefreshImmediately;
}
this._texture.image = canvas;
this._texture.dirty();
this.onupdate && this.onupdate();
},
/**
* @method
* @param {clay.Mesh} attachedMesh
* @param {Array.} triangle Triangle indices
* @param {clay.math.Vector3} point
*/
dispatchEvent: (function () {
var p0 = new __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector3__["a" /* default */]();
var p1 = new __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector3__["a" /* default */]();
var p2 = new __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector3__["a" /* default */]();
var uv0 = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_math_Vector2__["a" /* default */]();
var uv1 = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_math_Vector2__["a" /* default */]();
var uv2 = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_math_Vector2__["a" /* default */]();
var uv = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_math_Vector2__["a" /* default */]();
var vCross = new __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector3__["a" /* default */]();
return function (eventName, attachedMesh, triangle, point) {
var geo = attachedMesh.geometry;
var position = geo.attributes.position;
var texcoord = geo.attributes.texcoord0;
var dot = __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector3__["a" /* default */].dot;
var cross = __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector3__["a" /* default */].cross;
position.get(triangle[0], p0.array);
position.get(triangle[1], p1.array);
position.get(triangle[2], p2.array);
texcoord.get(triangle[0], uv0.array);
texcoord.get(triangle[1], uv1.array);
texcoord.get(triangle[2], uv2.array);
cross(vCross, p1, p2);
var det = dot(p0, vCross);
var t = dot(point, vCross) / det;
cross(vCross, p2, p0);
var u = dot(point, vCross) / det;
cross(vCross, p0, p1);
var v = dot(point, vCross) / det;
__WEBPACK_IMPORTED_MODULE_2_claygl_src_math_Vector2__["a" /* default */].scale(uv, uv0, t);
__WEBPACK_IMPORTED_MODULE_2_claygl_src_math_Vector2__["a" /* default */].scaleAndAdd(uv, uv, uv1, u);
__WEBPACK_IMPORTED_MODULE_2_claygl_src_math_Vector2__["a" /* default */].scaleAndAdd(uv, uv, uv2, v);
var x = uv.x * this._chart.getWidth();
var y = uv.y * this._chart.getHeight();
this._chart.getZr().handler.dispatch(eventName, {
zrX: x,
zrY: y
});
};
})(),
attachToMesh: function (mesh) {
if (this._meshes.indexOf(mesh) >= 0) {
return;
}
events.forEach(function (eventName) {
mesh.on(eventName, this[makeHandlerName(eventName)], this);
}, this);
this._meshes.push(mesh);
},
detachFromMesh: function (mesh) {
var idx = this._meshes.indexOf(mesh);
if (idx >= 0) {
this._meshes.splice(idx, 1);
}
events.forEach(function (eventName) {
mesh.off(eventName, this[makeHandlerName(eventName)]);
}, this);
},
dispose: function () {
this._meshes.forEach(function (mesh) {
this.detachFromMesh(mesh);
}, this);
}
};
/* harmony default export */ __webpack_exports__["a"] = (EChartsSurface);
/***/ }),
/* 117 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Light__ = __webpack_require__(21);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_cubemap__ = __webpack_require__(70);
// https://docs.unrealengine.com/latest/INT/Engine/Rendering/LightingAndShadows/AmbientCubemap/
/**
* Ambient cubemap light provides specular parts of Image Based Lighting.
* Which is a basic requirement for Physically Based Rendering
* @constructor clay.light.AmbientCubemap
* @extends clay.Light
*/
var AmbientCubemapLight = __WEBPACK_IMPORTED_MODULE_0__Light__["a" /* default */].extend({
/**
* @type {clay.TextureCube}
* @memberOf clay.light.AmbientCubemap#
*/
cubemap: null,
// TODO
// range: 100,
castShadow: false,
_normalDistribution: null,
_brdfLookup: null
}, /** @lends clay.light.AmbientCubemap# */ {
type: 'AMBIENT_CUBEMAP_LIGHT',
/**
* Do prefitering the cubemap
* @param {clay.Renderer} renderer
* @param {number} [size=32]
*/
prefilter: function (renderer, size) {
if (!this._brdfLookup) {
this._normalDistribution = __WEBPACK_IMPORTED_MODULE_1__util_cubemap__["a" /* default */].generateNormalDistribution();
this._brdfLookup = __WEBPACK_IMPORTED_MODULE_1__util_cubemap__["a" /* default */].integrateBRDF(renderer, this._normalDistribution);
}
var cubemap = this.cubemap;
if (cubemap.__prefiltered) {
return;
}
var result = __WEBPACK_IMPORTED_MODULE_1__util_cubemap__["a" /* default */].prefilterEnvironmentMap(
renderer, cubemap, {
encodeRGBM: true,
width: size,
height: size
}, this._normalDistribution, this._brdfLookup
);
this.cubemap = result.environmentMap;
this.cubemap.__prefiltered = true;
cubemap.dispose(renderer);
},
uniformTemplates: {
ambientCubemapLightColor: {
type: '3f',
value: function (instance) {
var color = instance.color;
var intensity = instance.intensity;
return [color[0]*intensity, color[1]*intensity, color[2]*intensity];
}
},
ambientCubemapLightCubemap: {
type: 't',
value: function (instance) {
return instance.cubemap;
}
},
ambientCubemapLightBRDFLookup: {
type: 't',
value: function (instance) {
return instance._brdfLookup;
}
}
}
/**
* @function
* @name clone
* @return {clay.light.AmbientCubemap}
* @memberOf clay.light.AmbientCubemap.prototype
*/
});
/* harmony default export */ __webpack_exports__["a"] = (AmbientCubemapLight);
/***/ }),
/* 118 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("\n@export clay.compositor.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nattribute vec3 position : POSITION;\nattribute vec2 texcoord : TEXCOORD_0;\nvarying vec2 v_Texcoord;\nvoid main()\n{\n v_Texcoord = texcoord;\n gl_Position = worldViewProjection * vec4(position, 1.0);\n}\n@end");
/***/ }),
/* 119 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.skybox.vertex\n#define SHADER_NAME skybox\nuniform mat4 world : WORLD;\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nattribute vec3 position : POSITION;\nvarying vec3 v_WorldPosition;\nvoid main()\n{\n v_WorldPosition = (world * vec4(position, 1.0)).xyz;\n gl_Position = worldViewProjection * vec4(position, 1.0);\n}\n@end\n@export clay.skybox.fragment\nuniform mat4 viewInverse : VIEWINVERSE;\nuniform samplerCube environmentMap;\nuniform float lod: 0.0;\nvarying vec3 v_WorldPosition;\n@import clay.util.rgbm\n@import clay.util.srgb\n@import clay.util.ACES\nvoid main()\n{\n vec3 eyePos = viewInverse[3].xyz;\n vec3 viewDirection = normalize(v_WorldPosition - eyePos);\n#ifdef LOD\n vec4 texel = decodeHDR(textureCubeLodEXT(environmentMap, viewDirection, lod));\n#else\n vec4 texel = decodeHDR(textureCube(environmentMap, viewDirection));\n#endif\n#ifdef SRGB_DECODE\n texel = sRGBToLinear(texel);\n#endif\n#ifdef TONEMAPPING\n texel.rgb = ACESToneMapping(texel.rgb);\n#endif\n#ifdef SRGB_ENCODE\n texel = linearTosRGB(texel);\n#endif\n gl_FragColor = encodeHDR(vec4(texel.rgb, 1.0));\n}\n@end");
/***/ }),
/* 120 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("#define SAMPLE_NUMBER 1024\n#define PI 3.14159265358979\nuniform sampler2D normalDistribution;\nuniform vec2 viewportSize : [512, 256];\nconst vec3 N = vec3(0.0, 0.0, 1.0);\nconst float fSampleNumber = float(SAMPLE_NUMBER);\nvec3 importanceSampleNormal(float i, float roughness, vec3 N) {\n vec3 H = texture2D(normalDistribution, vec2(roughness, i)).rgb;\n vec3 upVector = abs(N.y) > 0.999 ? vec3(1.0, 0.0, 0.0) : vec3(0.0, 1.0, 0.0);\n vec3 tangentX = normalize(cross(N, upVector));\n vec3 tangentZ = cross(N, tangentX);\n return normalize(tangentX * H.x + N * H.y + tangentZ * H.z);\n}\nfloat G_Smith(float roughness, float NoV, float NoL) {\n float k = roughness * roughness / 2.0;\n float G1V = NoV / (NoV * (1.0 - k) + k);\n float G1L = NoL / (NoL * (1.0 - k) + k);\n return G1L * G1V;\n}\nvoid main() {\n vec2 uv = gl_FragCoord.xy / viewportSize;\n float NoV = uv.x;\n float roughness = uv.y;\n vec3 V;\n V.x = sqrt(1.0 - NoV * NoV);\n V.y = 0.0;\n V.z = NoV;\n float A = 0.0;\n float B = 0.0;\n for (int i = 0; i < SAMPLE_NUMBER; i++) {\n vec3 H = importanceSampleNormal(float(i) / fSampleNumber, roughness, N);\n vec3 L = reflect(-V, H);\n float NoL = clamp(L.z, 0.0, 1.0);\n float NoH = clamp(H.z, 0.0, 1.0);\n float VoH = clamp(dot(V, H), 0.0, 1.0);\n if (NoL > 0.0) {\n float G = G_Smith(roughness, NoV, NoL);\n float G_Vis = G * VoH / (NoH * NoV);\n float Fc = pow(1.0 - VoH, 5.0);\n A += (1.0 - Fc) * G_Vis;\n B += Fc * G_Vis;\n }\n }\n gl_FragColor = vec4(vec2(A, B) / fSampleNumber, 0.0, 1.0);\n}\n");
/***/ }),
/* 121 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("#define SHADER_NAME prefilter\n#define SAMPLE_NUMBER 1024\n#define PI 3.14159265358979\nuniform mat4 viewInverse : VIEWINVERSE;\nuniform samplerCube environmentMap;\nuniform sampler2D normalDistribution;\nuniform float roughness : 0.5;\nuniform int maxSampleNumber: 1024\nvarying vec2 v_Texcoord;\nvarying vec3 v_WorldPosition;\n@import clay.util.rgbm\nvec3 importanceSampleNormal(float i, float roughness, vec3 N) {\n vec3 H = texture2D(normalDistribution, vec2(roughness, i)).rgb;\n vec3 upVector = abs(N.y) > 0.999 ? vec3(1.0, 0.0, 0.0) : vec3(0.0, 1.0, 0.0);\n vec3 tangentX = normalize(cross(N, upVector));\n vec3 tangentZ = cross(N, tangentX);\n return normalize(tangentX * H.x + N * H.y + tangentZ * H.z);\n}\nvoid main() {\n vec3 eyePos = viewInverse[3].xyz;\n vec3 V = normalize(v_WorldPosition - eyePos);\n vec3 N = V;\n vec3 prefilteredColor = vec3(0.0);\n float totalWeight = 0.0;\n float fMaxSampleNumber = float(maxSampleNumber);\n for (int i = 0; i < SAMPLE_NUMBER; i++) {\n if (i > maxSampleNumber) {\n break;\n }\n vec3 H = importanceSampleNormal(float(i) / fMaxSampleNumber, roughness, N);\n vec3 L = reflect(-V, H);\n float NoL = clamp(dot(N, L), 0.0, 1.0);\n if (NoL > 0.0) {\n prefilteredColor += decodeHDR(textureCube(environmentMap, L)).rgb * NoL;\n totalWeight += NoL;\n }\n }\n gl_FragColor = encodeHDR(vec4(prefilteredColor / totalWeight, 1.0));\n}\n");
/***/ }),
/* 122 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Light__ = __webpack_require__(21);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_vendor__ = __webpack_require__(18);
/**
* Spherical Harmonic Ambient Light
* @constructor clay.light.AmbientSH
* @extends clay.Light
*/
var AmbientSHLight = __WEBPACK_IMPORTED_MODULE_0__Light__["a" /* default */].extend({
castShadow: false,
/**
* Spherical Harmonic Coefficients
* @type {Array.}
* @memberOf clay.light.AmbientSH#
*/
coefficients: [],
}, function () {
this._coefficientsTmpArr = new __WEBPACK_IMPORTED_MODULE_1__core_vendor__["a" /* default */].Float32Array(9 * 3);
}, {
type: 'AMBIENT_SH_LIGHT',
uniformTemplates: {
ambientSHLightColor: {
type: '3f',
value: function (instance) {
var color = instance.color;
var intensity = instance.intensity;
return [color[0] * intensity, color[1] * intensity, color[2] * intensity];
}
},
ambientSHLightCoefficients: {
type: '3f',
value: function (instance) {
var coefficientsTmpArr = instance._coefficientsTmpArr;
for (var i = 0; i < instance.coefficients.length; i++) {
coefficientsTmpArr[i] = instance.coefficients[i];
}
return coefficientsTmpArr;
}
}
}
/**
* @function
* @name clone
* @return {clay.light.Ambient}
* @memberOf clay.light.Ambient.prototype
*/
});
/* harmony default export */ __webpack_exports__["a"] = (AmbientSHLight);
/***/ }),
/* 123 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Texture__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__FrameBuffer__ = __webpack_require__(10);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__compositor_Pass__ = __webpack_require__(14);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__core_vendor__ = __webpack_require__(18);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__plugin_Skybox__ = __webpack_require__(57);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__plugin_Skydome__ = __webpack_require__(56);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__prePass_EnvironmentMap__ = __webpack_require__(55);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__Scene__ = __webpack_require__(32);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_9__dep_glmatrix__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__shader_projectEnvMap_glsl_js__ = __webpack_require__(124);
// Spherical Harmonic Helpers
var vec3 = __WEBPACK_IMPORTED_MODULE_9__dep_glmatrix___default.a.vec3;
var sh = {};
var targets = ['px', 'nx', 'py', 'ny', 'pz', 'nz'];
// Project on gpu, but needs browser to support readPixels as Float32Array.
function projectEnvironmentMapGPU(renderer, envMap) {
var shTexture = new __WEBPACK_IMPORTED_MODULE_2__Texture2D__["a" /* default */]({
width: 9,
height: 1,
type: __WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].FLOAT
});
var pass = new __WEBPACK_IMPORTED_MODULE_3__compositor_Pass__["a" /* default */]({
fragment: __WEBPACK_IMPORTED_MODULE_10__shader_projectEnvMap_glsl_js__["a" /* default */]
});
pass.material.define('fragment', 'TEXTURE_SIZE', envMap.width);
pass.setUniform('environmentMap', envMap);
var framebuffer = new __WEBPACK_IMPORTED_MODULE_1__FrameBuffer__["a" /* default */]();
framebuffer.attach(shTexture);
pass.render(renderer, framebuffer);
framebuffer.bind(renderer);
// TODO Only chrome and firefox support Float32Array
var pixels = new __WEBPACK_IMPORTED_MODULE_4__core_vendor__["a" /* default */].Float32Array(9 * 4);
renderer.gl.readPixels(0, 0, 9, 1, __WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].RGBA, __WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].FLOAT, pixels);
var coeff = new __WEBPACK_IMPORTED_MODULE_4__core_vendor__["a" /* default */].Float32Array(9 * 3);
for (var i = 0; i < 9; i++) {
coeff[i * 3] = pixels[i * 4];
coeff[i * 3 + 1] = pixels[i * 4 + 1];
coeff[i * 3 + 2] = pixels[i * 4 + 2];
}
framebuffer.unbind(renderer);
framebuffer.dispose(renderer);
pass.dispose(renderer);
return coeff;
}
function harmonics(normal, index){
var x = normal[0];
var y = normal[1];
var z = normal[2];
if (index === 0) {
return 1.0;
}
else if (index === 1) {
return x;
}
else if (index === 2) {
return y;
}
else if (index === 3) {
return z;
}
else if (index === 4) {
return x * z;
}
else if (index === 5) {
return y * z;
}
else if (index === 6) {
return x * y;
}
else if (index === 7) {
return 3.0 * z * z - 1.0;
}
else {
return x * x - y * y;
}
}
var normalTransform = {
px: [2, 1, 0, -1, -1, 1],
nx: [2, 1, 0, 1, -1, -1],
py: [0, 2, 1, 1, -1, -1],
ny: [0, 2, 1, 1, 1, 1],
pz: [0, 1, 2, -1, -1, -1],
nz: [0, 1, 2, 1, -1, 1]
};
// Project on cpu.
function projectEnvironmentMapCPU(renderer, cubePixels, width, height) {
var coeff = new __WEBPACK_IMPORTED_MODULE_4__core_vendor__["a" /* default */].Float32Array(9 * 3);
var normal = vec3.create();
var texel = vec3.create();
var fetchNormal = vec3.create();
for (var m = 0; m < 9; m++) {
var result = vec3.create();
for (var k = 0; k < targets.length; k++) {
var pixels = cubePixels[targets[k]];
var sideResult = vec3.create();
var divider = 0;
var i = 0;
var transform = normalTransform[targets[k]];
for (var y = 0; y < height; y++) {
for (var x = 0; x < width; x++) {
normal[0] = x / (width - 1.0) * 2.0 - 1.0;
// TODO Flip y?
normal[1] = y / (height - 1.0) * 2.0 - 1.0;
normal[2] = -1.0;
vec3.normalize(normal, normal);
fetchNormal[0] = normal[transform[0]] * transform[3];
fetchNormal[1] = normal[transform[1]] * transform[4];
fetchNormal[2] = normal[transform[2]] * transform[5];
texel[0] = pixels[i++] / 255;
texel[1] = pixels[i++] / 255;
texel[2] = pixels[i++] / 255;
// RGBM Decode
var scale = pixels[i++] / 255 * 8.12;
texel[0] *= scale;
texel[1] *= scale;
texel[2] *= scale;
vec3.scaleAndAdd(sideResult, sideResult, texel, harmonics(fetchNormal, m) * -normal[2]);
// -normal.z equals cos(theta) of Lambertian
divider += -normal[2];
}
}
vec3.scaleAndAdd(result, result, sideResult, 1 / divider);
}
coeff[m * 3] = result[0] / 6.0;
coeff[m * 3 + 1] = result[1] / 6.0;
coeff[m * 3 + 2] = result[2] / 6.0;
}
return coeff;
}
/**
* @param {clay.Renderer} renderer
* @param {clay.Texture} envMap
* @param {Object} [textureOpts]
* @param {Object} [textureOpts.lod]
* @param {boolean} [textureOpts.decodeRGBM]
*/
sh.projectEnvironmentMap = function (renderer, envMap, opts) {
// TODO sRGB
opts = opts || {};
opts.lod = opts.lod || 0;
var skybox;
var dummyScene = new __WEBPACK_IMPORTED_MODULE_8__Scene__["a" /* default */]();
var size = 64;
if (envMap.textureType === 'texture2D') {
skybox = new __WEBPACK_IMPORTED_MODULE_6__plugin_Skydome__["a" /* default */]({
scene: dummyScene,
environmentMap: envMap
});
}
else {
size = (envMap.image && envMap.image.px) ? envMap.image.px.width : envMap.width;
skybox = new __WEBPACK_IMPORTED_MODULE_5__plugin_Skybox__["a" /* default */]({
scene: dummyScene,
environmentMap: envMap
});
}
// Convert to rgbm
var width = Math.ceil(size / Math.pow(2, opts.lod));
var height = Math.ceil(size / Math.pow(2, opts.lod));
var rgbmTexture = new __WEBPACK_IMPORTED_MODULE_2__Texture2D__["a" /* default */]({
width: width,
height: height
});
var framebuffer = new __WEBPACK_IMPORTED_MODULE_1__FrameBuffer__["a" /* default */]();
skybox.material.define('fragment', 'RGBM_ENCODE');
if (opts.decodeRGBM) {
skybox.material.define('fragment', 'RGBM_DECODE');
}
skybox.material.set('lod', opts.lod);
var envMapPass = new __WEBPACK_IMPORTED_MODULE_7__prePass_EnvironmentMap__["a" /* default */]({
texture: rgbmTexture
});
var cubePixels = {};
for (var i = 0; i < targets.length; i++) {
cubePixels[targets[i]] = new Uint8Array(width * height * 4);
var camera = envMapPass.getCamera(targets[i]);
camera.fov = 90;
framebuffer.attach(rgbmTexture);
framebuffer.bind(renderer);
renderer.render(dummyScene, camera);
renderer.gl.readPixels(
0, 0, width, height,
__WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].RGBA, __WEBPACK_IMPORTED_MODULE_0__Texture__["a" /* default */].UNSIGNED_BYTE, cubePixels[targets[i]]
);
framebuffer.unbind(renderer);
}
skybox.dispose(renderer);
framebuffer.dispose(renderer);
rgbmTexture.dispose(renderer);
return projectEnvironmentMapCPU(renderer, cubePixels, width, height);
};
/* harmony default export */ __webpack_exports__["a"] = (sh);
/***/ }),
/* 124 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("uniform samplerCube environmentMap;\nvarying vec2 v_Texcoord;\n#define TEXTURE_SIZE 16\nmat3 front = mat3(\n 1.0, 0.0, 0.0,\n 0.0, 1.0, 0.0,\n 0.0, 0.0, 1.0\n);\nmat3 back = mat3(\n -1.0, 0.0, 0.0,\n 0.0, 1.0, 0.0,\n 0.0, 0.0, -1.0\n);\nmat3 left = mat3(\n 0.0, 0.0, -1.0,\n 0.0, 1.0, 0.0,\n 1.0, 0.0, 0.0\n);\nmat3 right = mat3(\n 0.0, 0.0, 1.0,\n 0.0, 1.0, 0.0,\n -1.0, 0.0, 0.0\n);\nmat3 up = mat3(\n 1.0, 0.0, 0.0,\n 0.0, 0.0, 1.0,\n 0.0, -1.0, 0.0\n);\nmat3 down = mat3(\n 1.0, 0.0, 0.0,\n 0.0, 0.0, -1.0,\n 0.0, 1.0, 0.0\n);\nfloat harmonics(vec3 normal){\n int index = int(gl_FragCoord.x);\n float x = normal.x;\n float y = normal.y;\n float z = normal.z;\n if(index==0){\n return 1.0;\n }\n else if(index==1){\n return x;\n }\n else if(index==2){\n return y;\n }\n else if(index==3){\n return z;\n }\n else if(index==4){\n return x*z;\n }\n else if(index==5){\n return y*z;\n }\n else if(index==6){\n return x*y;\n }\n else if(index==7){\n return 3.0*z*z - 1.0;\n }\n else{\n return x*x - y*y;\n }\n}\nvec3 sampleSide(mat3 rot)\n{\n vec3 result = vec3(0.0);\n float divider = 0.0;\n for (int i = 0; i < TEXTURE_SIZE * TEXTURE_SIZE; i++) {\n float x = mod(float(i), float(TEXTURE_SIZE));\n float y = float(i / TEXTURE_SIZE);\n vec2 sidecoord = ((vec2(x, y) + vec2(0.5, 0.5)) / vec2(TEXTURE_SIZE)) * 2.0 - 1.0;\n vec3 normal = normalize(vec3(sidecoord, -1.0));\n vec3 fetchNormal = rot * normal;\n vec3 texel = textureCube(environmentMap, fetchNormal).rgb;\n result += harmonics(fetchNormal) * texel * -normal.z;\n divider += -normal.z;\n }\n return result / divider;\n}\nvoid main()\n{\n vec3 result = (\n sampleSide(front) +\n sampleSide(back) +\n sampleSide(left) +\n sampleSide(right) +\n sampleSide(up) +\n sampleSide(down)\n ) / 6.0;\n gl_FragColor = vec4(result, 1.0);\n}");
/***/ }),
/* 125 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Light__ = __webpack_require__(21);
/**
* @constructor clay.light.Ambient
* @extends clay.Light
*/
var AmbientLight = __WEBPACK_IMPORTED_MODULE_0__Light__["a" /* default */].extend({
castShadow: false
}, {
type: 'AMBIENT_LIGHT',
uniformTemplates: {
ambientLightColor: {
type: '3f',
value: function(instance) {
var color = instance.color;
var intensity = instance.intensity;
return [color[0]*intensity, color[1]*intensity, color[2]*intensity];
}
}
}
/**
* @function
* @name clone
* @return {clay.light.Ambient}
* @memberOf clay.light.Ambient.prototype
*/
});
/* harmony default export */ __webpack_exports__["a"] = (AmbientLight);
/***/ }),
/* 126 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Light__ = __webpack_require__(21);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__math_Vector3__ = __webpack_require__(4);
/**
* @constructor clay.light.Directional
* @extends clay.Light
*
* @example
* var light = new clay.light.Directional({
* intensity: 0.5,
* color: [1.0, 0.0, 0.0]
* });
* light.position.set(10, 10, 10);
* light.lookAt(clay.Vector3.ZERO);
* scene.add(light);
*/
var DirectionalLight = __WEBPACK_IMPORTED_MODULE_0__Light__["a" /* default */].extend(/** @lends clay.light.Directional# */ {
/**
* @type {number}
*/
shadowBias: 0.001,
/**
* @type {number}
*/
shadowSlopeScale: 2.0,
/**
* Shadow cascade.
* Use PSSM technique when it is larger than 1 and have a unique directional light in scene.
* @type {number}
*/
shadowCascade: 1,
/**
* Available when shadowCascade is larger than 1 and have a unique directional light in scene.
* @type {number}
*/
cascadeSplitLogFactor: 0.2
}, {
type: 'DIRECTIONAL_LIGHT',
uniformTemplates: {
directionalLightDirection: {
type: '3f',
value: function (instance) {
instance.__dir = instance.__dir || new __WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */]();
// Direction is target to eye
return instance.__dir.copy(instance.worldTransform.z).normalize().negate().array;
}
},
directionalLightColor: {
type: '3f',
value: function (instance) {
var color = instance.color;
var intensity = instance.intensity;
return [color[0] * intensity, color[1] * intensity, color[2] * intensity];
}
}
},
/**
* @return {clay.light.Directional}
* @memberOf clay.light.Directional.prototype
*/
clone: function () {
var light = __WEBPACK_IMPORTED_MODULE_0__Light__["a" /* default */].prototype.clone.call(this);
light.shadowBias = this.shadowBias;
light.shadowSlopeScale = this.shadowSlopeScale;
return light;
}
});
/* harmony default export */ __webpack_exports__["a"] = (DirectionalLight);
/***/ }),
/* 127 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Light__ = __webpack_require__(21);
/**
* @constructor clay.light.Point
* @extends clay.Light
*/
var PointLight = __WEBPACK_IMPORTED_MODULE_0__Light__["a" /* default */].extend(/** @lends clay.light.Point# */ {
/**
* @type {number}
*/
range: 100,
/**
* @type {number}
*/
castShadow: false
}, {
type: 'POINT_LIGHT',
uniformTemplates: {
pointLightPosition: {
type: '3f',
value: function(instance) {
return instance.getWorldPosition().array;
}
},
pointLightRange: {
type: '1f',
value: function(instance) {
return instance.range;
}
},
pointLightColor: {
type: '3f',
value: function(instance) {
var color = instance.color;
var intensity = instance.intensity;
return [color[0] * intensity, color[1] * intensity, color[2] * intensity];
}
}
},
/**
* @return {clay.light.Point}
* @memberOf clay.light.Point.prototype
*/
clone: function() {
var light = __WEBPACK_IMPORTED_MODULE_0__Light__["a" /* default */].prototype.clone.call(this);
light.range = this.range;
return light;
}
});
/* harmony default export */ __webpack_exports__["a"] = (PointLight);
/***/ }),
/* 128 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Light__ = __webpack_require__(21);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__math_Vector3__ = __webpack_require__(4);
/**
* @constructor clay.light.Spot
* @extends clay.Light
*/
var SpotLight = __WEBPACK_IMPORTED_MODULE_0__Light__["a" /* default */].extend(
/**@lends clay.light.Spot */
{
/**
* @type {number}
*/
range: 20,
/**
* @type {number}
*/
umbraAngle: 30,
/**
* @type {number}
*/
penumbraAngle: 45,
/**
* @type {number}
*/
falloffFactor: 2.0,
/**
* @type {number}
*/
shadowBias: 0.0002,
/**
* @type {number}
*/
shadowSlopeScale: 2.0
},{
type: 'SPOT_LIGHT',
uniformTemplates: {
spotLightPosition: {
type: '3f',
value: function (instance) {
return instance.getWorldPosition().array;
}
},
spotLightRange: {
type: '1f',
value: function (instance) {
return instance.range;
}
},
spotLightUmbraAngleCosine: {
type: '1f',
value: function (instance) {
return Math.cos(instance.umbraAngle * Math.PI / 180);
}
},
spotLightPenumbraAngleCosine: {
type: '1f',
value: function (instance) {
return Math.cos(instance.penumbraAngle * Math.PI / 180);
}
},
spotLightFalloffFactor: {
type: '1f',
value: function (instance) {
return instance.falloffFactor;
}
},
spotLightDirection: {
type: '3f',
value: function (instance) {
instance.__dir = instance.__dir || new __WEBPACK_IMPORTED_MODULE_1__math_Vector3__["a" /* default */]();
// Direction is target to eye
return instance.__dir.copy(instance.worldTransform.z).negate().array;
}
},
spotLightColor: {
type: '3f',
value: function (instance) {
var color = instance.color;
var intensity = instance.intensity;
return [color[0] * intensity, color[1] * intensity, color[2] * intensity];
}
}
},
/**
* @return {clay.light.Spot}
* @memberOf clay.light.Spot.prototype
*/
clone: function () {
var light = __WEBPACK_IMPORTED_MODULE_0__Light__["a" /* default */].prototype.clone.call(this);
light.range = this.range;
light.umbraAngle = this.umbraAngle;
light.penumbraAngle = this.penumbraAngle;
light.falloffFactor = this.falloffFactor;
light.shadowBias = this.shadowBias;
light.shadowSlopeScale = this.shadowSlopeScale;
return light;
}
});
/* harmony default export */ __webpack_exports__["a"] = (SpotLight);
/***/ }),
/* 129 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0__dep_glmatrix__);
var vec4 = __WEBPACK_IMPORTED_MODULE_0__dep_glmatrix___default.a.vec4;
/**
* @constructor
* @alias clay.Vector4
* @param {number} x
* @param {number} y
* @param {number} z
* @param {number} w
*/
var Vector4 = function(x, y, z, w) {
x = x || 0;
y = y || 0;
z = z || 0;
w = w || 0;
/**
* Storage of Vector4, read and write of x, y, z, w will change the values in array
* All methods also operate on the array instead of x, y, z, w components
* @name array
* @type {Float32Array}
* @memberOf clay.Vector4#
*/
this.array = vec4.fromValues(x, y, z, w);
/**
* Dirty flag is used by the Node to determine
* if the matrix is updated to latest
* @name _dirty
* @type {boolean}
* @memberOf clay.Vector4#
*/
this._dirty = true;
};
Vector4.prototype = {
constructor: Vector4,
/**
* Add b to self
* @param {clay.Vector4} b
* @return {clay.Vector4}
*/
add: function(b) {
vec4.add(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Set x, y and z components
* @param {number} x
* @param {number} y
* @param {number} z
* @param {number} w
* @return {clay.Vector4}
*/
set: function(x, y, z, w) {
this.array[0] = x;
this.array[1] = y;
this.array[2] = z;
this.array[3] = w;
this._dirty = true;
return this;
},
/**
* Set x, y, z and w components from array
* @param {Float32Array|number[]} arr
* @return {clay.Vector4}
*/
setArray: function(arr) {
this.array[0] = arr[0];
this.array[1] = arr[1];
this.array[2] = arr[2];
this.array[3] = arr[3];
this._dirty = true;
return this;
},
/**
* Clone a new Vector4
* @return {clay.Vector4}
*/
clone: function() {
return new Vector4(this.x, this.y, this.z, this.w);
},
/**
* Copy from b
* @param {clay.Vector4} b
* @return {clay.Vector4}
*/
copy: function(b) {
vec4.copy(this.array, b.array);
this._dirty = true;
return this;
},
/**
* Alias for distance
* @param {clay.Vector4} b
* @return {number}
*/
dist: function(b) {
return vec4.dist(this.array, b.array);
},
/**
* Distance between self and b
* @param {clay.Vector4} b
* @return {number}
*/
distance: function(b) {
return vec4.distance(this.array, b.array);
},
/**
* Alias for divide
* @param {clay.Vector4} b
* @return {clay.Vector4}
*/
div: function(b) {
vec4.div(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Divide self by b
* @param {clay.Vector4} b
* @return {clay.Vector4}
*/
divide: function(b) {
vec4.divide(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Dot product of self and b
* @param {clay.Vector4} b
* @return {number}
*/
dot: function(b) {
return vec4.dot(this.array, b.array);
},
/**
* Alias of length
* @return {number}
*/
len: function() {
return vec4.len(this.array);
},
/**
* Calculate the length
* @return {number}
*/
length: function() {
return vec4.length(this.array);
},
/**
* Linear interpolation between a and b
* @param {clay.Vector4} a
* @param {clay.Vector4} b
* @param {number} t
* @return {clay.Vector4}
*/
lerp: function(a, b, t) {
vec4.lerp(this.array, a.array, b.array, t);
this._dirty = true;
return this;
},
/**
* Minimum of self and b
* @param {clay.Vector4} b
* @return {clay.Vector4}
*/
min: function(b) {
vec4.min(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Maximum of self and b
* @param {clay.Vector4} b
* @return {clay.Vector4}
*/
max: function(b) {
vec4.max(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Alias for multiply
* @param {clay.Vector4} b
* @return {clay.Vector4}
*/
mul: function(b) {
vec4.mul(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Mutiply self and b
* @param {clay.Vector4} b
* @return {clay.Vector4}
*/
multiply: function(b) {
vec4.multiply(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Negate self
* @return {clay.Vector4}
*/
negate: function() {
vec4.negate(this.array, this.array);
this._dirty = true;
return this;
},
/**
* Normalize self
* @return {clay.Vector4}
*/
normalize: function() {
vec4.normalize(this.array, this.array);
this._dirty = true;
return this;
},
/**
* Generate random x, y, z, w components with a given scale
* @param {number} scale
* @return {clay.Vector4}
*/
random: function(scale) {
vec4.random(this.array, scale);
this._dirty = true;
return this;
},
/**
* Scale self
* @param {number} scale
* @return {clay.Vector4}
*/
scale: function(s) {
vec4.scale(this.array, this.array, s);
this._dirty = true;
return this;
},
/**
* Scale b and add to self
* @param {clay.Vector4} b
* @param {number} scale
* @return {clay.Vector4}
*/
scaleAndAdd: function(b, s) {
vec4.scaleAndAdd(this.array, this.array, b.array, s);
this._dirty = true;
return this;
},
/**
* Alias for squaredDistance
* @param {clay.Vector4} b
* @return {number}
*/
sqrDist: function(b) {
return vec4.sqrDist(this.array, b.array);
},
/**
* Squared distance between self and b
* @param {clay.Vector4} b
* @return {number}
*/
squaredDistance: function(b) {
return vec4.squaredDistance(this.array, b.array);
},
/**
* Alias for squaredLength
* @return {number}
*/
sqrLen: function() {
return vec4.sqrLen(this.array);
},
/**
* Squared length of self
* @return {number}
*/
squaredLength: function() {
return vec4.squaredLength(this.array);
},
/**
* Alias for subtract
* @param {clay.Vector4} b
* @return {clay.Vector4}
*/
sub: function(b) {
vec4.sub(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Subtract b from self
* @param {clay.Vector4} b
* @return {clay.Vector4}
*/
subtract: function(b) {
vec4.subtract(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Transform self with a Matrix4 m
* @param {clay.Matrix4} m
* @return {clay.Vector4}
*/
transformMat4: function(m) {
vec4.transformMat4(this.array, this.array, m.array);
this._dirty = true;
return this;
},
/**
* Transform self with a Quaternion q
* @param {clay.Quaternion} q
* @return {clay.Vector4}
*/
transformQuat: function(q) {
vec4.transformQuat(this.array, this.array, q.array);
this._dirty = true;
return this;
},
toString: function() {
return '[' + Array.prototype.join.call(this.array, ',') + ']';
},
toArray: function () {
return Array.prototype.slice.call(this.array);
}
};
var defineProperty = Object.defineProperty;
// Getter and Setter
if (defineProperty) {
var proto = Vector4.prototype;
/**
* @name x
* @type {number}
* @memberOf clay.Vector4
* @instance
*/
defineProperty(proto, 'x', {
get: function () {
return this.array[0];
},
set: function (value) {
this.array[0] = value;
this._dirty = true;
}
});
/**
* @name y
* @type {number}
* @memberOf clay.Vector4
* @instance
*/
defineProperty(proto, 'y', {
get: function () {
return this.array[1];
},
set: function (value) {
this.array[1] = value;
this._dirty = true;
}
});
/**
* @name z
* @type {number}
* @memberOf clay.Vector4
* @instance
*/
defineProperty(proto, 'z', {
get: function () {
return this.array[2];
},
set: function (value) {
this.array[2] = value;
this._dirty = true;
}
});
/**
* @name w
* @type {number}
* @memberOf clay.Vector4
* @instance
*/
defineProperty(proto, 'w', {
get: function () {
return this.array[3];
},
set: function (value) {
this.array[3] = value;
this._dirty = true;
}
});
}
// Supply methods that are not in place
/**
* @param {clay.Vector4} out
* @param {clay.Vector4} a
* @param {clay.Vector4} b
* @return {clay.Vector4}
*/
Vector4.add = function(out, a, b) {
vec4.add(out.array, a.array, b.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector4} out
* @param {number} x
* @param {number} y
* @param {number} z
* @return {clay.Vector4}
*/
Vector4.set = function(out, x, y, z, w) {
vec4.set(out.array, x, y, z, w);
out._dirty = true;
};
/**
* @param {clay.Vector4} out
* @param {clay.Vector4} b
* @return {clay.Vector4}
*/
Vector4.copy = function(out, b) {
vec4.copy(out.array, b.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector4} a
* @param {clay.Vector4} b
* @return {number}
*/
Vector4.dist = function(a, b) {
return vec4.distance(a.array, b.array);
};
/**
* @function
* @param {clay.Vector4} a
* @param {clay.Vector4} b
* @return {number}
*/
Vector4.distance = Vector4.dist;
/**
* @param {clay.Vector4} out
* @param {clay.Vector4} a
* @param {clay.Vector4} b
* @return {clay.Vector4}
*/
Vector4.div = function(out, a, b) {
vec4.divide(out.array, a.array, b.array);
out._dirty = true;
return out;
};
/**
* @function
* @param {clay.Vector4} out
* @param {clay.Vector4} a
* @param {clay.Vector4} b
* @return {clay.Vector4}
*/
Vector4.divide = Vector4.div;
/**
* @param {clay.Vector4} a
* @param {clay.Vector4} b
* @return {number}
*/
Vector4.dot = function(a, b) {
return vec4.dot(a.array, b.array);
};
/**
* @param {clay.Vector4} a
* @return {number}
*/
Vector4.len = function(b) {
return vec4.length(b.array);
};
// Vector4.length = Vector4.len;
/**
* @param {clay.Vector4} out
* @param {clay.Vector4} a
* @param {clay.Vector4} b
* @param {number} t
* @return {clay.Vector4}
*/
Vector4.lerp = function(out, a, b, t) {
vec4.lerp(out.array, a.array, b.array, t);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector4} out
* @param {clay.Vector4} a
* @param {clay.Vector4} b
* @return {clay.Vector4}
*/
Vector4.min = function(out, a, b) {
vec4.min(out.array, a.array, b.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector4} out
* @param {clay.Vector4} a
* @param {clay.Vector4} b
* @return {clay.Vector4}
*/
Vector4.max = function(out, a, b) {
vec4.max(out.array, a.array, b.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector4} out
* @param {clay.Vector4} a
* @param {clay.Vector4} b
* @return {clay.Vector4}
*/
Vector4.mul = function(out, a, b) {
vec4.multiply(out.array, a.array, b.array);
out._dirty = true;
return out;
};
/**
* @function
* @param {clay.Vector4} out
* @param {clay.Vector4} a
* @param {clay.Vector4} b
* @return {clay.Vector4}
*/
Vector4.multiply = Vector4.mul;
/**
* @param {clay.Vector4} out
* @param {clay.Vector4} a
* @return {clay.Vector4}
*/
Vector4.negate = function(out, a) {
vec4.negate(out.array, a.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector4} out
* @param {clay.Vector4} a
* @return {clay.Vector4}
*/
Vector4.normalize = function(out, a) {
vec4.normalize(out.array, a.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector4} out
* @param {number} scale
* @return {clay.Vector4}
*/
Vector4.random = function(out, scale) {
vec4.random(out.array, scale);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector4} out
* @param {clay.Vector4} a
* @param {number} scale
* @return {clay.Vector4}
*/
Vector4.scale = function(out, a, scale) {
vec4.scale(out.array, a.array, scale);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector4} out
* @param {clay.Vector4} a
* @param {clay.Vector4} b
* @param {number} scale
* @return {clay.Vector4}
*/
Vector4.scaleAndAdd = function(out, a, b, scale) {
vec4.scaleAndAdd(out.array, a.array, b.array, scale);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector4} a
* @param {clay.Vector4} b
* @return {number}
*/
Vector4.sqrDist = function(a, b) {
return vec4.sqrDist(a.array, b.array);
};
/**
* @function
* @param {clay.Vector4} a
* @param {clay.Vector4} b
* @return {number}
*/
Vector4.squaredDistance = Vector4.sqrDist;
/**
* @param {clay.Vector4} a
* @return {number}
*/
Vector4.sqrLen = function(a) {
return vec4.sqrLen(a.array);
};
/**
* @function
* @param {clay.Vector4} a
* @return {number}
*/
Vector4.squaredLength = Vector4.sqrLen;
/**
* @param {clay.Vector4} out
* @param {clay.Vector4} a
* @param {clay.Vector4} b
* @return {clay.Vector4}
*/
Vector4.sub = function(out, a, b) {
vec4.subtract(out.array, a.array, b.array);
out._dirty = true;
return out;
};
/**
* @function
* @param {clay.Vector4} out
* @param {clay.Vector4} a
* @param {clay.Vector4} b
* @return {clay.Vector4}
*/
Vector4.subtract = Vector4.sub;
/**
* @param {clay.Vector4} out
* @param {clay.Vector4} a
* @param {clay.Matrix4} m
* @return {clay.Vector4}
*/
Vector4.transformMat4 = function(out, a, m) {
vec4.transformMat4(out.array, a.array, m.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Vector4} out
* @param {clay.Vector4} a
* @param {clay.Quaternion} q
* @return {clay.Vector4}
*/
Vector4.transformQuat = function(out, a, q) {
vec4.transformQuat(out.array, a.array, q.array);
out._dirty = true;
return out;
};
/* harmony default export */ __webpack_exports__["a"] = (Vector4);
/***/ }),
/* 130 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0__dep_glmatrix__);
var mat2 = __WEBPACK_IMPORTED_MODULE_0__dep_glmatrix___default.a.mat2;
/**
* @constructor
* @alias clay.Matrix2
*/
var Matrix2 = function() {
/**
* Storage of Matrix2
* @name array
* @type {Float32Array}
* @memberOf clay.Matrix2#
*/
this.array = mat2.create();
/**
* @name _dirty
* @type {boolean}
* @memberOf clay.Matrix2#
*/
this._dirty = true;
};
Matrix2.prototype = {
constructor: Matrix2,
/**
* Set components from array
* @param {Float32Array|number[]} arr
*/
setArray: function (arr) {
for (var i = 0; i < this.array.length; i++) {
this.array[i] = arr[i];
}
this._dirty = true;
return this;
},
/**
* Clone a new Matrix2
* @return {clay.Matrix2}
*/
clone: function() {
return (new Matrix2()).copy(this);
},
/**
* Copy from b
* @param {clay.Matrix2} b
* @return {clay.Matrix2}
*/
copy: function(b) {
mat2.copy(this.array, b.array);
this._dirty = true;
return this;
},
/**
* Calculate the adjugate of self, in-place
* @return {clay.Matrix2}
*/
adjoint: function() {
mat2.adjoint(this.array, this.array);
this._dirty = true;
return this;
},
/**
* Calculate matrix determinant
* @return {number}
*/
determinant: function() {
return mat2.determinant(this.array);
},
/**
* Set to a identity matrix
* @return {clay.Matrix2}
*/
identity: function() {
mat2.identity(this.array);
this._dirty = true;
return this;
},
/**
* Invert self
* @return {clay.Matrix2}
*/
invert: function() {
mat2.invert(this.array, this.array);
this._dirty = true;
return this;
},
/**
* Alias for mutiply
* @param {clay.Matrix2} b
* @return {clay.Matrix2}
*/
mul: function(b) {
mat2.mul(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Alias for multiplyLeft
* @param {clay.Matrix2} a
* @return {clay.Matrix2}
*/
mulLeft: function(a) {
mat2.mul(this.array, a.array, this.array);
this._dirty = true;
return this;
},
/**
* Multiply self and b
* @param {clay.Matrix2} b
* @return {clay.Matrix2}
*/
multiply: function(b) {
mat2.multiply(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Multiply a and self, a is on the left
* @param {clay.Matrix2} a
* @return {clay.Matrix2}
*/
multiplyLeft: function(a) {
mat2.multiply(this.array, a.array, this.array);
this._dirty = true;
return this;
},
/**
* Rotate self by a given radian
* @param {number} rad
* @return {clay.Matrix2}
*/
rotate: function(rad) {
mat2.rotate(this.array, this.array, rad);
this._dirty = true;
return this;
},
/**
* Scale self by s
* @param {clay.Vector2} s
* @return {clay.Matrix2}
*/
scale: function(v) {
mat2.scale(this.array, this.array, v.array);
this._dirty = true;
return this;
},
/**
* Transpose self, in-place.
* @return {clay.Matrix2}
*/
transpose: function() {
mat2.transpose(this.array, this.array);
this._dirty = true;
return this;
},
toString: function() {
return '[' + Array.prototype.join.call(this.array, ',') + ']';
},
toArray: function () {
return Array.prototype.slice.call(this.array);
}
};
/**
* @param {Matrix2} out
* @param {Matrix2} a
* @return {Matrix2}
*/
Matrix2.adjoint = function(out, a) {
mat2.adjoint(out.array, a.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix2} out
* @param {clay.Matrix2} a
* @return {clay.Matrix2}
*/
Matrix2.copy = function(out, a) {
mat2.copy(out.array, a.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix2} a
* @return {number}
*/
Matrix2.determinant = function(a) {
return mat2.determinant(a.array);
};
/**
* @param {clay.Matrix2} out
* @return {clay.Matrix2}
*/
Matrix2.identity = function(out) {
mat2.identity(out.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix2} out
* @param {clay.Matrix2} a
* @return {clay.Matrix2}
*/
Matrix2.invert = function(out, a) {
mat2.invert(out.array, a.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix2} out
* @param {clay.Matrix2} a
* @param {clay.Matrix2} b
* @return {clay.Matrix2}
*/
Matrix2.mul = function(out, a, b) {
mat2.mul(out.array, a.array, b.array);
out._dirty = true;
return out;
};
/**
* @function
* @param {clay.Matrix2} out
* @param {clay.Matrix2} a
* @param {clay.Matrix2} b
* @return {clay.Matrix2}
*/
Matrix2.multiply = Matrix2.mul;
/**
* @param {clay.Matrix2} out
* @param {clay.Matrix2} a
* @param {number} rad
* @return {clay.Matrix2}
*/
Matrix2.rotate = function(out, a, rad) {
mat2.rotate(out.array, a.array, rad);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix2} out
* @param {clay.Matrix2} a
* @param {clay.Vector2} v
* @return {clay.Matrix2}
*/
Matrix2.scale = function(out, a, v) {
mat2.scale(out.array, a.array, v.array);
out._dirty = true;
return out;
};
/**
* @param {Matrix2} out
* @param {Matrix2} a
* @return {Matrix2}
*/
Matrix2.transpose = function(out, a) {
mat2.transpose(out.array, a.array);
out._dirty = true;
return out;
};
/* harmony default export */ __webpack_exports__["a"] = (Matrix2);
/***/ }),
/* 131 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0__dep_glmatrix__);
var mat2d = __WEBPACK_IMPORTED_MODULE_0__dep_glmatrix___default.a.mat2d;
/**
* @constructor
* @alias clay.Matrix2d
*/
var Matrix2d = function() {
/**
* Storage of Matrix2d
* @name array
* @type {Float32Array}
* @memberOf clay.Matrix2d#
*/
this.array = mat2d.create();
/**
* @name _dirty
* @type {boolean}
* @memberOf clay.Matrix2d#
*/
this._dirty = true;
};
Matrix2d.prototype = {
constructor: Matrix2d,
/**
* Set components from array
* @param {Float32Array|number[]} arr
*/
setArray: function (arr) {
for (var i = 0; i < this.array.length; i++) {
this.array[i] = arr[i];
}
this._dirty = true;
return this;
},
/**
* Clone a new Matrix2d
* @return {clay.Matrix2d}
*/
clone: function() {
return (new Matrix2d()).copy(this);
},
/**
* Copy from b
* @param {clay.Matrix2d} b
* @return {clay.Matrix2d}
*/
copy: function(b) {
mat2d.copy(this.array, b.array);
this._dirty = true;
return this;
},
/**
* Calculate matrix determinant
* @return {number}
*/
determinant: function() {
return mat2d.determinant(this.array);
},
/**
* Set to a identity matrix
* @return {clay.Matrix2d}
*/
identity: function() {
mat2d.identity(this.array);
this._dirty = true;
return this;
},
/**
* Invert self
* @return {clay.Matrix2d}
*/
invert: function() {
mat2d.invert(this.array, this.array);
this._dirty = true;
return this;
},
/**
* Alias for mutiply
* @param {clay.Matrix2d} b
* @return {clay.Matrix2d}
*/
mul: function(b) {
mat2d.mul(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Alias for multiplyLeft
* @param {clay.Matrix2d} a
* @return {clay.Matrix2d}
*/
mulLeft: function(b) {
mat2d.mul(this.array, b.array, this.array);
this._dirty = true;
return this;
},
/**
* Multiply self and b
* @param {clay.Matrix2d} b
* @return {clay.Matrix2d}
*/
multiply: function(b) {
mat2d.multiply(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Multiply a and self, a is on the left
* @param {clay.Matrix2d} a
* @return {clay.Matrix2d}
*/
multiplyLeft: function(b) {
mat2d.multiply(this.array, b.array, this.array);
this._dirty = true;
return this;
},
/**
* Rotate self by a given radian
* @param {number} rad
* @return {clay.Matrix2d}
*/
rotate: function(rad) {
mat2d.rotate(this.array, this.array, rad);
this._dirty = true;
return this;
},
/**
* Scale self by s
* @param {clay.Vector2} s
* @return {clay.Matrix2d}
*/
scale: function(s) {
mat2d.scale(this.array, this.array, s.array);
this._dirty = true;
return this;
},
/**
* Translate self by v
* @param {clay.Vector2} v
* @return {clay.Matrix2d}
*/
translate: function(v) {
mat2d.translate(this.array, this.array, v.array);
this._dirty = true;
return this;
},
toString: function() {
return '[' + Array.prototype.join.call(this.array, ',') + ']';
},
toArray: function () {
return Array.prototype.slice.call(this.array);
}
};
/**
* @param {clay.Matrix2d} out
* @param {clay.Matrix2d} a
* @return {clay.Matrix2d}
*/
Matrix2d.copy = function(out, a) {
mat2d.copy(out.array, a.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix2d} a
* @return {number}
*/
Matrix2d.determinant = function(a) {
return mat2d.determinant(a.array);
};
/**
* @param {clay.Matrix2d} out
* @return {clay.Matrix2d}
*/
Matrix2d.identity = function(out) {
mat2d.identity(out.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix2d} out
* @param {clay.Matrix2d} a
* @return {clay.Matrix2d}
*/
Matrix2d.invert = function(out, a) {
mat2d.invert(out.array, a.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix2d} out
* @param {clay.Matrix2d} a
* @param {clay.Matrix2d} b
* @return {clay.Matrix2d}
*/
Matrix2d.mul = function(out, a, b) {
mat2d.mul(out.array, a.array, b.array);
out._dirty = true;
return out;
};
/**
* @function
* @param {clay.Matrix2d} out
* @param {clay.Matrix2d} a
* @param {clay.Matrix2d} b
* @return {clay.Matrix2d}
*/
Matrix2d.multiply = Matrix2d.mul;
/**
* @param {clay.Matrix2d} out
* @param {clay.Matrix2d} a
* @param {number} rad
* @return {clay.Matrix2d}
*/
Matrix2d.rotate = function(out, a, rad) {
mat2d.rotate(out.array, a.array, rad);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix2d} out
* @param {clay.Matrix2d} a
* @param {clay.Vector2} v
* @return {clay.Matrix2d}
*/
Matrix2d.scale = function(out, a, v) {
mat2d.scale(out.array, a.array, v.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix2d} out
* @param {clay.Matrix2d} a
* @param {clay.Vector2} v
* @return {clay.Matrix2d}
*/
Matrix2d.translate = function(out, a, v) {
mat2d.translate(out.array, a.array, v.array);
out._dirty = true;
return out;
};
/* harmony default export */ __webpack_exports__["a"] = (Matrix2d);
/***/ }),
/* 132 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0__dep_glmatrix__);
var mat3 = __WEBPACK_IMPORTED_MODULE_0__dep_glmatrix___default.a.mat3;
/**
* @constructor
* @alias clay.Matrix3
*/
var Matrix3 = function () {
/**
* Storage of Matrix3
* @name array
* @type {Float32Array}
* @memberOf clay.Matrix3#
*/
this.array = mat3.create();
/**
* @name _dirty
* @type {boolean}
* @memberOf clay.Matrix3#
*/
this._dirty = true;
};
Matrix3.prototype = {
constructor: Matrix3,
/**
* Set components from array
* @param {Float32Array|number[]} arr
*/
setArray: function (arr) {
for (var i = 0; i < this.array.length; i++) {
this.array[i] = arr[i];
}
this._dirty = true;
return this;
},
/**
* Calculate the adjugate of self, in-place
* @return {clay.Matrix3}
*/
adjoint: function () {
mat3.adjoint(this.array, this.array);
this._dirty = true;
return this;
},
/**
* Clone a new Matrix3
* @return {clay.Matrix3}
*/
clone: function () {
return (new Matrix3()).copy(this);
},
/**
* Copy from b
* @param {clay.Matrix3} b
* @return {clay.Matrix3}
*/
copy: function (b) {
mat3.copy(this.array, b.array);
this._dirty = true;
return this;
},
/**
* Calculate matrix determinant
* @return {number}
*/
determinant: function () {
return mat3.determinant(this.array);
},
/**
* Copy the values from Matrix2d a
* @param {clay.Matrix2d} a
* @return {clay.Matrix3}
*/
fromMat2d: function (a) {
mat3.fromMat2d(this.array, a.array);
this._dirty = true;
return this;
},
/**
* Copies the upper-left 3x3 values of Matrix4
* @param {clay.Matrix4} a
* @return {clay.Matrix3}
*/
fromMat4: function (a) {
mat3.fromMat4(this.array, a.array);
this._dirty = true;
return this;
},
/**
* Calculates a rotation matrix from the given quaternion
* @param {clay.Quaternion} q
* @return {clay.Matrix3}
*/
fromQuat: function (q) {
mat3.fromQuat(this.array, q.array);
this._dirty = true;
return this;
},
/**
* Set to a identity matrix
* @return {clay.Matrix3}
*/
identity: function () {
mat3.identity(this.array);
this._dirty = true;
return this;
},
/**
* Invert self
* @return {clay.Matrix3}
*/
invert: function () {
mat3.invert(this.array, this.array);
this._dirty = true;
return this;
},
/**
* Alias for mutiply
* @param {clay.Matrix3} b
* @return {clay.Matrix3}
*/
mul: function (b) {
mat3.mul(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Alias for multiplyLeft
* @param {clay.Matrix3} a
* @return {clay.Matrix3}
*/
mulLeft: function (a) {
mat3.mul(this.array, a.array, this.array);
this._dirty = true;
return this;
},
/**
* Multiply self and b
* @param {clay.Matrix3} b
* @return {clay.Matrix3}
*/
multiply: function (b) {
mat3.multiply(this.array, this.array, b.array);
this._dirty = true;
return this;
},
/**
* Multiply a and self, a is on the left
* @param {clay.Matrix3} a
* @return {clay.Matrix3}
*/
multiplyLeft: function (a) {
mat3.multiply(this.array, a.array, this.array);
this._dirty = true;
return this;
},
/**
* Rotate self by a given radian
* @param {number} rad
* @return {clay.Matrix3}
*/
rotate: function (rad) {
mat3.rotate(this.array, this.array, rad);
this._dirty = true;
return this;
},
/**
* Scale self by s
* @param {clay.Vector2} s
* @return {clay.Matrix3}
*/
scale: function (v) {
mat3.scale(this.array, this.array, v.array);
this._dirty = true;
return this;
},
/**
* Translate self by v
* @param {clay.Vector2} v
* @return {clay.Matrix3}
*/
translate: function (v) {
mat3.translate(this.array, this.array, v.array);
this._dirty = true;
return this;
},
/**
* Calculates a 3x3 normal matrix (transpose inverse) from the 4x4 matrix
* @param {clay.Matrix4} a
*/
normalFromMat4: function (a) {
mat3.normalFromMat4(this.array, a.array);
this._dirty = true;
return this;
},
/**
* Transpose self, in-place.
* @return {clay.Matrix2}
*/
transpose: function () {
mat3.transpose(this.array, this.array);
this._dirty = true;
return this;
},
toString: function () {
return '[' + Array.prototype.join.call(this.array, ',') + ']';
},
toArray: function () {
return Array.prototype.slice.call(this.array);
}
};
/**
* @param {clay.Matrix3} out
* @param {clay.Matrix3} a
* @return {clay.Matrix3}
*/
Matrix3.adjoint = function (out, a) {
mat3.adjoint(out.array, a.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix3} out
* @param {clay.Matrix3} a
* @return {clay.Matrix3}
*/
Matrix3.copy = function (out, a) {
mat3.copy(out.array, a.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix3} a
* @return {number}
*/
Matrix3.determinant = function (a) {
return mat3.determinant(a.array);
};
/**
* @param {clay.Matrix3} out
* @return {clay.Matrix3}
*/
Matrix3.identity = function (out) {
mat3.identity(out.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix3} out
* @param {clay.Matrix3} a
* @return {clay.Matrix3}
*/
Matrix3.invert = function (out, a) {
mat3.invert(out.array, a.array);
return out;
};
/**
* @param {clay.Matrix3} out
* @param {clay.Matrix3} a
* @param {clay.Matrix3} b
* @return {clay.Matrix3}
*/
Matrix3.mul = function (out, a, b) {
mat3.mul(out.array, a.array, b.array);
out._dirty = true;
return out;
};
/**
* @function
* @param {clay.Matrix3} out
* @param {clay.Matrix3} a
* @param {clay.Matrix3} b
* @return {clay.Matrix3}
*/
Matrix3.multiply = Matrix3.mul;
/**
* @param {clay.Matrix3} out
* @param {clay.Matrix2d} a
* @return {clay.Matrix3}
*/
Matrix3.fromMat2d = function (out, a) {
mat3.fromMat2d(out.array, a.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix3} out
* @param {clay.Matrix4} a
* @return {clay.Matrix3}
*/
Matrix3.fromMat4 = function (out, a) {
mat3.fromMat4(out.array, a.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix3} out
* @param {clay.Quaternion} a
* @return {clay.Matrix3}
*/
Matrix3.fromQuat = function (out, q) {
mat3.fromQuat(out.array, q.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix3} out
* @param {clay.Matrix4} a
* @return {clay.Matrix3}
*/
Matrix3.normalFromMat4 = function (out, a) {
mat3.normalFromMat4(out.array, a.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix3} out
* @param {clay.Matrix3} a
* @param {number} rad
* @return {clay.Matrix3}
*/
Matrix3.rotate = function (out, a, rad) {
mat3.rotate(out.array, a.array, rad);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix3} out
* @param {clay.Matrix3} a
* @param {clay.Vector2} v
* @return {clay.Matrix3}
*/
Matrix3.scale = function (out, a, v) {
mat3.scale(out.array, a.array, v.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix3} out
* @param {clay.Matrix3} a
* @return {clay.Matrix3}
*/
Matrix3.transpose = function (out, a) {
mat3.transpose(out.array, a.array);
out._dirty = true;
return out;
};
/**
* @param {clay.Matrix3} out
* @param {clay.Matrix3} a
* @param {clay.Vector2} v
* @return {clay.Matrix3}
*/
Matrix3.translate = function (out, a, v) {
mat3.translate(out.array, a.array, v.array);
out._dirty = true;
return out;
};
/* harmony default export */ __webpack_exports__["a"] = (Matrix3);
/***/ }),
/* 133 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_zrender_lib_animation_Animator__ = __webpack_require__(134);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_zrender_lib_animation_Animator___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_zrender_lib_animation_Animator__);
var animatableMixin = {
_animators: null,
getAnimators: function () {
this._animators = this._animators || [];
return this._animators;
},
animate: function (path, opts) {
this._animators = this._animators || [];
var el = this;
var target;
if (path) {
var pathSplitted = path.split('.');
var prop = el;
for (var i = 0, l = pathSplitted.length; i < l; i++) {
if (!prop) {
continue;
}
prop = prop[pathSplitted[i]];
}
if (prop) {
target = prop;
}
}
else {
target = el;
}
if (target == null) {
throw new Error('Target ' + path + ' not exists');
}
var animators = this._animators;
var animator = new __WEBPACK_IMPORTED_MODULE_0_zrender_lib_animation_Animator___default.a(target, opts);
var self = this;
animator.during(function () {
if (self.__zr) {
self.__zr.refresh();
}
}).done(function () {
var idx = animators.indexOf(animator);
if (idx >= 0) {
animators.splice(idx, 1);
}
});
animators.push(animator);
if (this.__zr) {
this.__zr.animation.addAnimator(animator);
}
return animator;
},
stopAnimation: function (forwardToLast) {
this._animators = this._animators || [];
var animators = this._animators;
var len = animators.length;
for (var i = 0; i < len; i++) {
animators[i].stop(forwardToLast);
}
animators.length = 0;
return this;
},
addAnimatorsToZr: function (zr) {
if (this._animators) {
for (var i = 0; i < this._animators.length; i++) {
zr.animation.addAnimator(this._animators[i]);
}
}
},
removeAnimatorsFromZr: function (zr) {
if (this._animators) {
for (var i = 0; i < this._animators.length; i++) {
zr.animation.removeAnimator(this._animators[i]);
}
}
}
};
/* harmony default export */ __webpack_exports__["a"] = (animatableMixin);
/***/ }),
/* 134 */
/***/ (function(module, exports, __webpack_require__) {
var Clip = __webpack_require__(135);
var color = __webpack_require__(137);
var _util = __webpack_require__(12);
var isArrayLike = _util.isArrayLike;
/**
* @module echarts/animation/Animator
*/
var arraySlice = Array.prototype.slice;
function defaultGetter(target, key) {
return target[key];
}
function defaultSetter(target, key, value) {
target[key] = value;
}
/**
* @param {number} p0
* @param {number} p1
* @param {number} percent
* @return {number}
*/
function interpolateNumber(p0, p1, percent) {
return (p1 - p0) * percent + p0;
}
/**
* @param {string} p0
* @param {string} p1
* @param {number} percent
* @return {string}
*/
function interpolateString(p0, p1, percent) {
return percent > 0.5 ? p1 : p0;
}
/**
* @param {Array} p0
* @param {Array} p1
* @param {number} percent
* @param {Array} out
* @param {number} arrDim
*/
function interpolateArray(p0, p1, percent, out, arrDim) {
var len = p0.length;
if (arrDim == 1) {
for (var i = 0; i < len; i++) {
out[i] = interpolateNumber(p0[i], p1[i], percent);
}
} else {
var len2 = len && p0[0].length;
for (var i = 0; i < len; i++) {
for (var j = 0; j < len2; j++) {
out[i][j] = interpolateNumber(p0[i][j], p1[i][j], percent);
}
}
}
} // arr0 is source array, arr1 is target array.
// Do some preprocess to avoid error happened when interpolating from arr0 to arr1
function fillArr(arr0, arr1, arrDim) {
var arr0Len = arr0.length;
var arr1Len = arr1.length;
if (arr0Len !== arr1Len) {
// FIXME Not work for TypedArray
var isPreviousLarger = arr0Len > arr1Len;
if (isPreviousLarger) {
// Cut the previous
arr0.length = arr1Len;
} else {
// Fill the previous
for (var i = arr0Len; i < arr1Len; i++) {
arr0.push(arrDim === 1 ? arr1[i] : arraySlice.call(arr1[i]));
}
}
} // Handling NaN value
var len2 = arr0[0] && arr0[0].length;
for (var i = 0; i < arr0.length; i++) {
if (arrDim === 1) {
if (isNaN(arr0[i])) {
arr0[i] = arr1[i];
}
} else {
for (var j = 0; j < len2; j++) {
if (isNaN(arr0[i][j])) {
arr0[i][j] = arr1[i][j];
}
}
}
}
}
/**
* @param {Array} arr0
* @param {Array} arr1
* @param {number} arrDim
* @return {boolean}
*/
function isArraySame(arr0, arr1, arrDim) {
if (arr0 === arr1) {
return true;
}
var len = arr0.length;
if (len !== arr1.length) {
return false;
}
if (arrDim === 1) {
for (var i = 0; i < len; i++) {
if (arr0[i] !== arr1[i]) {
return false;
}
}
} else {
var len2 = arr0[0].length;
for (var i = 0; i < len; i++) {
for (var j = 0; j < len2; j++) {
if (arr0[i][j] !== arr1[i][j]) {
return false;
}
}
}
}
return true;
}
/**
* Catmull Rom interpolate array
* @param {Array} p0
* @param {Array} p1
* @param {Array} p2
* @param {Array} p3
* @param {number} t
* @param {number} t2
* @param {number} t3
* @param {Array} out
* @param {number} arrDim
*/
function catmullRomInterpolateArray(p0, p1, p2, p3, t, t2, t3, out, arrDim) {
var len = p0.length;
if (arrDim == 1) {
for (var i = 0; i < len; i++) {
out[i] = catmullRomInterpolate(p0[i], p1[i], p2[i], p3[i], t, t2, t3);
}
} else {
var len2 = p0[0].length;
for (var i = 0; i < len; i++) {
for (var j = 0; j < len2; j++) {
out[i][j] = catmullRomInterpolate(p0[i][j], p1[i][j], p2[i][j], p3[i][j], t, t2, t3);
}
}
}
}
/**
* Catmull Rom interpolate number
* @param {number} p0
* @param {number} p1
* @param {number} p2
* @param {number} p3
* @param {number} t
* @param {number} t2
* @param {number} t3
* @return {number}
*/
function catmullRomInterpolate(p0, p1, p2, p3, t, t2, t3) {
var v0 = (p2 - p0) * 0.5;
var v1 = (p3 - p1) * 0.5;
return (2 * (p1 - p2) + v0 + v1) * t3 + (-3 * (p1 - p2) - 2 * v0 - v1) * t2 + v0 * t + p1;
}
function cloneValue(value) {
if (isArrayLike(value)) {
var len = value.length;
if (isArrayLike(value[0])) {
var ret = [];
for (var i = 0; i < len; i++) {
ret.push(arraySlice.call(value[i]));
}
return ret;
}
return arraySlice.call(value);
}
return value;
}
function rgba2String(rgba) {
rgba[0] = Math.floor(rgba[0]);
rgba[1] = Math.floor(rgba[1]);
rgba[2] = Math.floor(rgba[2]);
return 'rgba(' + rgba.join(',') + ')';
}
function getArrayDim(keyframes) {
var lastValue = keyframes[keyframes.length - 1].value;
return isArrayLike(lastValue && lastValue[0]) ? 2 : 1;
}
function createTrackClip(animator, easing, oneTrackDone, keyframes, propName, forceAnimate) {
var getter = animator._getter;
var setter = animator._setter;
var useSpline = easing === 'spline';
var trackLen = keyframes.length;
if (!trackLen) {
return;
} // Guess data type
var firstVal = keyframes[0].value;
var isValueArray = isArrayLike(firstVal);
var isValueColor = false;
var isValueString = false; // For vertices morphing
var arrDim = isValueArray ? getArrayDim(keyframes) : 0;
var trackMaxTime; // Sort keyframe as ascending
keyframes.sort(function (a, b) {
return a.time - b.time;
});
trackMaxTime = keyframes[trackLen - 1].time; // Percents of each keyframe
var kfPercents = []; // Value of each keyframe
var kfValues = [];
var prevValue = keyframes[0].value;
var isAllValueEqual = true;
for (var i = 0; i < trackLen; i++) {
kfPercents.push(keyframes[i].time / trackMaxTime); // Assume value is a color when it is a string
var value = keyframes[i].value; // Check if value is equal, deep check if value is array
if (!(isValueArray && isArraySame(value, prevValue, arrDim) || !isValueArray && value === prevValue)) {
isAllValueEqual = false;
}
prevValue = value; // Try converting a string to a color array
if (typeof value == 'string') {
var colorArray = color.parse(value);
if (colorArray) {
value = colorArray;
isValueColor = true;
} else {
isValueString = true;
}
}
kfValues.push(value);
}
if (!forceAnimate && isAllValueEqual) {
return;
}
var lastValue = kfValues[trackLen - 1]; // Polyfill array and NaN value
for (var i = 0; i < trackLen - 1; i++) {
if (isValueArray) {
fillArr(kfValues[i], lastValue, arrDim);
} else {
if (isNaN(kfValues[i]) && !isNaN(lastValue) && !isValueString && !isValueColor) {
kfValues[i] = lastValue;
}
}
}
isValueArray && fillArr(getter(animator._target, propName), lastValue, arrDim); // Cache the key of last frame to speed up when
// animation playback is sequency
var lastFrame = 0;
var lastFramePercent = 0;
var start;
var w;
var p0;
var p1;
var p2;
var p3;
if (isValueColor) {
var rgba = [0, 0, 0, 0];
}
var onframe = function (target, percent) {
// Find the range keyframes
// kf1-----kf2---------current--------kf3
// find kf2 and kf3 and do interpolation
var frame; // In the easing function like elasticOut, percent may less than 0
if (percent < 0) {
frame = 0;
} else if (percent < lastFramePercent) {
// Start from next key
// PENDING start from lastFrame ?
start = Math.min(lastFrame + 1, trackLen - 1);
for (frame = start; frame >= 0; frame--) {
if (kfPercents[frame] <= percent) {
break;
}
} // PENDING really need to do this ?
frame = Math.min(frame, trackLen - 2);
} else {
for (frame = lastFrame; frame < trackLen; frame++) {
if (kfPercents[frame] > percent) {
break;
}
}
frame = Math.min(frame - 1, trackLen - 2);
}
lastFrame = frame;
lastFramePercent = percent;
var range = kfPercents[frame + 1] - kfPercents[frame];
if (range === 0) {
return;
} else {
w = (percent - kfPercents[frame]) / range;
}
if (useSpline) {
p1 = kfValues[frame];
p0 = kfValues[frame === 0 ? frame : frame - 1];
p2 = kfValues[frame > trackLen - 2 ? trackLen - 1 : frame + 1];
p3 = kfValues[frame > trackLen - 3 ? trackLen - 1 : frame + 2];
if (isValueArray) {
catmullRomInterpolateArray(p0, p1, p2, p3, w, w * w, w * w * w, getter(target, propName), arrDim);
} else {
var value;
if (isValueColor) {
value = catmullRomInterpolateArray(p0, p1, p2, p3, w, w * w, w * w * w, rgba, 1);
value = rgba2String(rgba);
} else if (isValueString) {
// String is step(0.5)
return interpolateString(p1, p2, w);
} else {
value = catmullRomInterpolate(p0, p1, p2, p3, w, w * w, w * w * w);
}
setter(target, propName, value);
}
} else {
if (isValueArray) {
interpolateArray(kfValues[frame], kfValues[frame + 1], w, getter(target, propName), arrDim);
} else {
var value;
if (isValueColor) {
interpolateArray(kfValues[frame], kfValues[frame + 1], w, rgba, 1);
value = rgba2String(rgba);
} else if (isValueString) {
// String is step(0.5)
return interpolateString(kfValues[frame], kfValues[frame + 1], w);
} else {
value = interpolateNumber(kfValues[frame], kfValues[frame + 1], w);
}
setter(target, propName, value);
}
}
};
var clip = new Clip({
target: animator._target,
life: trackMaxTime,
loop: animator._loop,
delay: animator._delay,
onframe: onframe,
ondestroy: oneTrackDone
});
if (easing && easing !== 'spline') {
clip.easing = easing;
}
return clip;
}
/**
* @alias module:zrender/animation/Animator
* @constructor
* @param {Object} target
* @param {boolean} loop
* @param {Function} getter
* @param {Function} setter
*/
var Animator = function (target, loop, getter, setter) {
this._tracks = {};
this._target = target;
this._loop = loop || false;
this._getter = getter || defaultGetter;
this._setter = setter || defaultSetter;
this._clipCount = 0;
this._delay = 0;
this._doneList = [];
this._onframeList = [];
this._clipList = [];
};
Animator.prototype = {
/**
* 设置动画关键帧
* @param {number} time 关键帧时间,单位是ms
* @param {Object} props 关键帧的属性值,key-value表示
* @return {module:zrender/animation/Animator}
*/
when: function (time
/* ms */
, props) {
var tracks = this._tracks;
for (var propName in props) {
if (!props.hasOwnProperty(propName)) {
continue;
}
if (!tracks[propName]) {
tracks[propName] = []; // Invalid value
var value = this._getter(this._target, propName);
if (value == null) {
// zrLog('Invalid property ' + propName);
continue;
} // If time is 0
// Then props is given initialize value
// Else
// Initialize value from current prop value
if (time !== 0) {
tracks[propName].push({
time: 0,
value: cloneValue(value)
});
}
}
tracks[propName].push({
time: time,
value: props[propName]
});
}
return this;
},
/**
* 添加动画每一帧的回调函数
* @param {Function} callback
* @return {module:zrender/animation/Animator}
*/
during: function (callback) {
this._onframeList.push(callback);
return this;
},
pause: function () {
for (var i = 0; i < this._clipList.length; i++) {
this._clipList[i].pause();
}
this._paused = true;
},
resume: function () {
for (var i = 0; i < this._clipList.length; i++) {
this._clipList[i].resume();
}
this._paused = false;
},
isPaused: function () {
return !!this._paused;
},
_doneCallback: function () {
// Clear all tracks
this._tracks = {}; // Clear all clips
this._clipList.length = 0;
var doneList = this._doneList;
var len = doneList.length;
for (var i = 0; i < len; i++) {
doneList[i].call(this);
}
},
/**
* 开始执行动画
* @param {string|Function} [easing]
* 动画缓动函数,详见{@link module:zrender/animation/easing}
* @param {boolean} forceAnimate
* @return {module:zrender/animation/Animator}
*/
start: function (easing, forceAnimate) {
var self = this;
var clipCount = 0;
var oneTrackDone = function () {
clipCount--;
if (!clipCount) {
self._doneCallback();
}
};
var lastClip;
for (var propName in this._tracks) {
if (!this._tracks.hasOwnProperty(propName)) {
continue;
}
var clip = createTrackClip(this, easing, oneTrackDone, this._tracks[propName], propName, forceAnimate);
if (clip) {
this._clipList.push(clip);
clipCount++; // If start after added to animation
if (this.animation) {
this.animation.addClip(clip);
}
lastClip = clip;
}
} // Add during callback on the last clip
if (lastClip) {
var oldOnFrame = lastClip.onframe;
lastClip.onframe = function (target, percent) {
oldOnFrame(target, percent);
for (var i = 0; i < self._onframeList.length; i++) {
self._onframeList[i](target, percent);
}
};
} // This optimization will help the case that in the upper application
// the view may be refreshed frequently, where animation will be
// called repeatly but nothing changed.
if (!clipCount) {
this._doneCallback();
}
return this;
},
/**
* 停止动画
* @param {boolean} forwardToLast If move to last frame before stop
*/
stop: function (forwardToLast) {
var clipList = this._clipList;
var animation = this.animation;
for (var i = 0; i < clipList.length; i++) {
var clip = clipList[i];
if (forwardToLast) {
// Move to last frame before stop
clip.onframe(this._target, 1);
}
animation && animation.removeClip(clip);
}
clipList.length = 0;
},
/**
* 设置动画延迟开始的时间
* @param {number} time 单位ms
* @return {module:zrender/animation/Animator}
*/
delay: function (time) {
this._delay = time;
return this;
},
/**
* 添加动画结束的回调
* @param {Function} cb
* @return {module:zrender/animation/Animator}
*/
done: function (cb) {
if (cb) {
this._doneList.push(cb);
}
return this;
},
/**
* @return {Array.}
*/
getClips: function () {
return this._clipList;
}
};
var _default = Animator;
module.exports = _default;
/***/ }),
/* 135 */
/***/ (function(module, exports, __webpack_require__) {
var easingFuncs = __webpack_require__(136);
/**
* 动画主控制器
* @config target 动画对象,可以是数组,如果是数组的话会批量分发onframe等事件
* @config life(1000) 动画时长
* @config delay(0) 动画延迟时间
* @config loop(true)
* @config gap(0) 循环的间隔时间
* @config onframe
* @config easing(optional)
* @config ondestroy(optional)
* @config onrestart(optional)
*
* TODO pause
*/
function Clip(options) {
this._target = options.target; // 生命周期
this._life = options.life || 1000; // 延时
this._delay = options.delay || 0; // 开始时间
// this._startTime = new Date().getTime() + this._delay;// 单位毫秒
this._initialized = false; // 是否循环
this.loop = options.loop == null ? false : options.loop;
this.gap = options.gap || 0;
this.easing = options.easing || 'Linear';
this.onframe = options.onframe;
this.ondestroy = options.ondestroy;
this.onrestart = options.onrestart;
this._pausedTime = 0;
this._paused = false;
}
Clip.prototype = {
constructor: Clip,
step: function (globalTime, deltaTime) {
// Set startTime on first step, or _startTime may has milleseconds different between clips
// PENDING
if (!this._initialized) {
this._startTime = globalTime + this._delay;
this._initialized = true;
}
if (this._paused) {
this._pausedTime += deltaTime;
return;
}
var percent = (globalTime - this._startTime - this._pausedTime) / this._life; // 还没开始
if (percent < 0) {
return;
}
percent = Math.min(percent, 1);
var easing = this.easing;
var easingFunc = typeof easing == 'string' ? easingFuncs[easing] : easing;
var schedule = typeof easingFunc === 'function' ? easingFunc(percent) : percent;
this.fire('frame', schedule); // 结束
if (percent == 1) {
if (this.loop) {
this.restart(globalTime); // 重新开始周期
// 抛出而不是直接调用事件直到 stage.update 后再统一调用这些事件
return 'restart';
} // 动画完成将这个控制器标识为待删除
// 在Animation.update中进行批量删除
this._needsRemove = true;
return 'destroy';
}
return null;
},
restart: function (globalTime) {
var remainder = (globalTime - this._startTime - this._pausedTime) % this._life;
this._startTime = globalTime - remainder + this.gap;
this._pausedTime = 0;
this._needsRemove = false;
},
fire: function (eventType, arg) {
eventType = 'on' + eventType;
if (this[eventType]) {
this[eventType](this._target, arg);
}
},
pause: function () {
this._paused = true;
},
resume: function () {
this._paused = false;
}
};
var _default = Clip;
module.exports = _default;
/***/ }),
/* 136 */
/***/ (function(module, exports) {
/**
* 缓动代码来自 https://github.com/sole/tween.js/blob/master/src/Tween.js
* @see http://sole.github.io/tween.js/examples/03_graphs.html
* @exports zrender/animation/easing
*/
var easing = {
/**
* @param {number} k
* @return {number}
*/
linear: function (k) {
return k;
},
/**
* @param {number} k
* @return {number}
*/
quadraticIn: function (k) {
return k * k;
},
/**
* @param {number} k
* @return {number}
*/
quadraticOut: function (k) {
return k * (2 - k);
},
/**
* @param {number} k
* @return {number}
*/
quadraticInOut: function (k) {
if ((k *= 2) < 1) {
return 0.5 * k * k;
}
return -0.5 * (--k * (k - 2) - 1);
},
// 三次方的缓动(t^3)
/**
* @param {number} k
* @return {number}
*/
cubicIn: function (k) {
return k * k * k;
},
/**
* @param {number} k
* @return {number}
*/
cubicOut: function (k) {
return --k * k * k + 1;
},
/**
* @param {number} k
* @return {number}
*/
cubicInOut: function (k) {
if ((k *= 2) < 1) {
return 0.5 * k * k * k;
}
return 0.5 * ((k -= 2) * k * k + 2);
},
// 四次方的缓动(t^4)
/**
* @param {number} k
* @return {number}
*/
quarticIn: function (k) {
return k * k * k * k;
},
/**
* @param {number} k
* @return {number}
*/
quarticOut: function (k) {
return 1 - --k * k * k * k;
},
/**
* @param {number} k
* @return {number}
*/
quarticInOut: function (k) {
if ((k *= 2) < 1) {
return 0.5 * k * k * k * k;
}
return -0.5 * ((k -= 2) * k * k * k - 2);
},
// 五次方的缓动(t^5)
/**
* @param {number} k
* @return {number}
*/
quinticIn: function (k) {
return k * k * k * k * k;
},
/**
* @param {number} k
* @return {number}
*/
quinticOut: function (k) {
return --k * k * k * k * k + 1;
},
/**
* @param {number} k
* @return {number}
*/
quinticInOut: function (k) {
if ((k *= 2) < 1) {
return 0.5 * k * k * k * k * k;
}
return 0.5 * ((k -= 2) * k * k * k * k + 2);
},
// 正弦曲线的缓动(sin(t))
/**
* @param {number} k
* @return {number}
*/
sinusoidalIn: function (k) {
return 1 - Math.cos(k * Math.PI / 2);
},
/**
* @param {number} k
* @return {number}
*/
sinusoidalOut: function (k) {
return Math.sin(k * Math.PI / 2);
},
/**
* @param {number} k
* @return {number}
*/
sinusoidalInOut: function (k) {
return 0.5 * (1 - Math.cos(Math.PI * k));
},
// 指数曲线的缓动(2^t)
/**
* @param {number} k
* @return {number}
*/
exponentialIn: function (k) {
return k === 0 ? 0 : Math.pow(1024, k - 1);
},
/**
* @param {number} k
* @return {number}
*/
exponentialOut: function (k) {
return k === 1 ? 1 : 1 - Math.pow(2, -10 * k);
},
/**
* @param {number} k
* @return {number}
*/
exponentialInOut: function (k) {
if (k === 0) {
return 0;
}
if (k === 1) {
return 1;
}
if ((k *= 2) < 1) {
return 0.5 * Math.pow(1024, k - 1);
}
return 0.5 * (-Math.pow(2, -10 * (k - 1)) + 2);
},
// 圆形曲线的缓动(sqrt(1-t^2))
/**
* @param {number} k
* @return {number}
*/
circularIn: function (k) {
return 1 - Math.sqrt(1 - k * k);
},
/**
* @param {number} k
* @return {number}
*/
circularOut: function (k) {
return Math.sqrt(1 - --k * k);
},
/**
* @param {number} k
* @return {number}
*/
circularInOut: function (k) {
if ((k *= 2) < 1) {
return -0.5 * (Math.sqrt(1 - k * k) - 1);
}
return 0.5 * (Math.sqrt(1 - (k -= 2) * k) + 1);
},
// 创建类似于弹簧在停止前来回振荡的动画
/**
* @param {number} k
* @return {number}
*/
elasticIn: function (k) {
var s;
var a = 0.1;
var p = 0.4;
if (k === 0) {
return 0;
}
if (k === 1) {
return 1;
}
if (!a || a < 1) {
a = 1;
s = p / 4;
} else {
s = p * Math.asin(1 / a) / (2 * Math.PI);
}
return -(a * Math.pow(2, 10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p));
},
/**
* @param {number} k
* @return {number}
*/
elasticOut: function (k) {
var s;
var a = 0.1;
var p = 0.4;
if (k === 0) {
return 0;
}
if (k === 1) {
return 1;
}
if (!a || a < 1) {
a = 1;
s = p / 4;
} else {
s = p * Math.asin(1 / a) / (2 * Math.PI);
}
return a * Math.pow(2, -10 * k) * Math.sin((k - s) * (2 * Math.PI) / p) + 1;
},
/**
* @param {number} k
* @return {number}
*/
elasticInOut: function (k) {
var s;
var a = 0.1;
var p = 0.4;
if (k === 0) {
return 0;
}
if (k === 1) {
return 1;
}
if (!a || a < 1) {
a = 1;
s = p / 4;
} else {
s = p * Math.asin(1 / a) / (2 * Math.PI);
}
if ((k *= 2) < 1) {
return -0.5 * (a * Math.pow(2, 10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p));
}
return a * Math.pow(2, -10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p) * 0.5 + 1;
},
// 在某一动画开始沿指示的路径进行动画处理前稍稍收回该动画的移动
/**
* @param {number} k
* @return {number}
*/
backIn: function (k) {
var s = 1.70158;
return k * k * ((s + 1) * k - s);
},
/**
* @param {number} k
* @return {number}
*/
backOut: function (k) {
var s = 1.70158;
return --k * k * ((s + 1) * k + s) + 1;
},
/**
* @param {number} k
* @return {number}
*/
backInOut: function (k) {
var s = 1.70158 * 1.525;
if ((k *= 2) < 1) {
return 0.5 * (k * k * ((s + 1) * k - s));
}
return 0.5 * ((k -= 2) * k * ((s + 1) * k + s) + 2);
},
// 创建弹跳效果
/**
* @param {number} k
* @return {number}
*/
bounceIn: function (k) {
return 1 - easing.bounceOut(1 - k);
},
/**
* @param {number} k
* @return {number}
*/
bounceOut: function (k) {
if (k < 1 / 2.75) {
return 7.5625 * k * k;
} else if (k < 2 / 2.75) {
return 7.5625 * (k -= 1.5 / 2.75) * k + 0.75;
} else if (k < 2.5 / 2.75) {
return 7.5625 * (k -= 2.25 / 2.75) * k + 0.9375;
} else {
return 7.5625 * (k -= 2.625 / 2.75) * k + 0.984375;
}
},
/**
* @param {number} k
* @return {number}
*/
bounceInOut: function (k) {
if (k < 0.5) {
return easing.bounceIn(k * 2) * 0.5;
}
return easing.bounceOut(k * 2 - 1) * 0.5 + 0.5;
}
};
var _default = easing;
module.exports = _default;
/***/ }),
/* 137 */
/***/ (function(module, exports, __webpack_require__) {
var LRU = __webpack_require__(53);
var kCSSColorTable = {
'transparent': [0, 0, 0, 0],
'aliceblue': [240, 248, 255, 1],
'antiquewhite': [250, 235, 215, 1],
'aqua': [0, 255, 255, 1],
'aquamarine': [127, 255, 212, 1],
'azure': [240, 255, 255, 1],
'beige': [245, 245, 220, 1],
'bisque': [255, 228, 196, 1],
'black': [0, 0, 0, 1],
'blanchedalmond': [255, 235, 205, 1],
'blue': [0, 0, 255, 1],
'blueviolet': [138, 43, 226, 1],
'brown': [165, 42, 42, 1],
'burlywood': [222, 184, 135, 1],
'cadetblue': [95, 158, 160, 1],
'chartreuse': [127, 255, 0, 1],
'chocolate': [210, 105, 30, 1],
'coral': [255, 127, 80, 1],
'cornflowerblue': [100, 149, 237, 1],
'cornsilk': [255, 248, 220, 1],
'crimson': [220, 20, 60, 1],
'cyan': [0, 255, 255, 1],
'darkblue': [0, 0, 139, 1],
'darkcyan': [0, 139, 139, 1],
'darkgoldenrod': [184, 134, 11, 1],
'darkgray': [169, 169, 169, 1],
'darkgreen': [0, 100, 0, 1],
'darkgrey': [169, 169, 169, 1],
'darkkhaki': [189, 183, 107, 1],
'darkmagenta': [139, 0, 139, 1],
'darkolivegreen': [85, 107, 47, 1],
'darkorange': [255, 140, 0, 1],
'darkorchid': [153, 50, 204, 1],
'darkred': [139, 0, 0, 1],
'darksalmon': [233, 150, 122, 1],
'darkseagreen': [143, 188, 143, 1],
'darkslateblue': [72, 61, 139, 1],
'darkslategray': [47, 79, 79, 1],
'darkslategrey': [47, 79, 79, 1],
'darkturquoise': [0, 206, 209, 1],
'darkviolet': [148, 0, 211, 1],
'deeppink': [255, 20, 147, 1],
'deepskyblue': [0, 191, 255, 1],
'dimgray': [105, 105, 105, 1],
'dimgrey': [105, 105, 105, 1],
'dodgerblue': [30, 144, 255, 1],
'firebrick': [178, 34, 34, 1],
'floralwhite': [255, 250, 240, 1],
'forestgreen': [34, 139, 34, 1],
'fuchsia': [255, 0, 255, 1],
'gainsboro': [220, 220, 220, 1],
'ghostwhite': [248, 248, 255, 1],
'gold': [255, 215, 0, 1],
'goldenrod': [218, 165, 32, 1],
'gray': [128, 128, 128, 1],
'green': [0, 128, 0, 1],
'greenyellow': [173, 255, 47, 1],
'grey': [128, 128, 128, 1],
'honeydew': [240, 255, 240, 1],
'hotpink': [255, 105, 180, 1],
'indianred': [205, 92, 92, 1],
'indigo': [75, 0, 130, 1],
'ivory': [255, 255, 240, 1],
'khaki': [240, 230, 140, 1],
'lavender': [230, 230, 250, 1],
'lavenderblush': [255, 240, 245, 1],
'lawngreen': [124, 252, 0, 1],
'lemonchiffon': [255, 250, 205, 1],
'lightblue': [173, 216, 230, 1],
'lightcoral': [240, 128, 128, 1],
'lightcyan': [224, 255, 255, 1],
'lightgoldenrodyellow': [250, 250, 210, 1],
'lightgray': [211, 211, 211, 1],
'lightgreen': [144, 238, 144, 1],
'lightgrey': [211, 211, 211, 1],
'lightpink': [255, 182, 193, 1],
'lightsalmon': [255, 160, 122, 1],
'lightseagreen': [32, 178, 170, 1],
'lightskyblue': [135, 206, 250, 1],
'lightslategray': [119, 136, 153, 1],
'lightslategrey': [119, 136, 153, 1],
'lightsteelblue': [176, 196, 222, 1],
'lightyellow': [255, 255, 224, 1],
'lime': [0, 255, 0, 1],
'limegreen': [50, 205, 50, 1],
'linen': [250, 240, 230, 1],
'magenta': [255, 0, 255, 1],
'maroon': [128, 0, 0, 1],
'mediumaquamarine': [102, 205, 170, 1],
'mediumblue': [0, 0, 205, 1],
'mediumorchid': [186, 85, 211, 1],
'mediumpurple': [147, 112, 219, 1],
'mediumseagreen': [60, 179, 113, 1],
'mediumslateblue': [123, 104, 238, 1],
'mediumspringgreen': [0, 250, 154, 1],
'mediumturquoise': [72, 209, 204, 1],
'mediumvioletred': [199, 21, 133, 1],
'midnightblue': [25, 25, 112, 1],
'mintcream': [245, 255, 250, 1],
'mistyrose': [255, 228, 225, 1],
'moccasin': [255, 228, 181, 1],
'navajowhite': [255, 222, 173, 1],
'navy': [0, 0, 128, 1],
'oldlace': [253, 245, 230, 1],
'olive': [128, 128, 0, 1],
'olivedrab': [107, 142, 35, 1],
'orange': [255, 165, 0, 1],
'orangered': [255, 69, 0, 1],
'orchid': [218, 112, 214, 1],
'palegoldenrod': [238, 232, 170, 1],
'palegreen': [152, 251, 152, 1],
'paleturquoise': [175, 238, 238, 1],
'palevioletred': [219, 112, 147, 1],
'papayawhip': [255, 239, 213, 1],
'peachpuff': [255, 218, 185, 1],
'peru': [205, 133, 63, 1],
'pink': [255, 192, 203, 1],
'plum': [221, 160, 221, 1],
'powderblue': [176, 224, 230, 1],
'purple': [128, 0, 128, 1],
'red': [255, 0, 0, 1],
'rosybrown': [188, 143, 143, 1],
'royalblue': [65, 105, 225, 1],
'saddlebrown': [139, 69, 19, 1],
'salmon': [250, 128, 114, 1],
'sandybrown': [244, 164, 96, 1],
'seagreen': [46, 139, 87, 1],
'seashell': [255, 245, 238, 1],
'sienna': [160, 82, 45, 1],
'silver': [192, 192, 192, 1],
'skyblue': [135, 206, 235, 1],
'slateblue': [106, 90, 205, 1],
'slategray': [112, 128, 144, 1],
'slategrey': [112, 128, 144, 1],
'snow': [255, 250, 250, 1],
'springgreen': [0, 255, 127, 1],
'steelblue': [70, 130, 180, 1],
'tan': [210, 180, 140, 1],
'teal': [0, 128, 128, 1],
'thistle': [216, 191, 216, 1],
'tomato': [255, 99, 71, 1],
'turquoise': [64, 224, 208, 1],
'violet': [238, 130, 238, 1],
'wheat': [245, 222, 179, 1],
'white': [255, 255, 255, 1],
'whitesmoke': [245, 245, 245, 1],
'yellow': [255, 255, 0, 1],
'yellowgreen': [154, 205, 50, 1]
};
function clampCssByte(i) {
// Clamp to integer 0 .. 255.
i = Math.round(i); // Seems to be what Chrome does (vs truncation).
return i < 0 ? 0 : i > 255 ? 255 : i;
}
function clampCssAngle(i) {
// Clamp to integer 0 .. 360.
i = Math.round(i); // Seems to be what Chrome does (vs truncation).
return i < 0 ? 0 : i > 360 ? 360 : i;
}
function clampCssFloat(f) {
// Clamp to float 0.0 .. 1.0.
return f < 0 ? 0 : f > 1 ? 1 : f;
}
function parseCssInt(str) {
// int or percentage.
if (str.length && str.charAt(str.length - 1) === '%') {
return clampCssByte(parseFloat(str) / 100 * 255);
}
return clampCssByte(parseInt(str, 10));
}
function parseCssFloat(str) {
// float or percentage.
if (str.length && str.charAt(str.length - 1) === '%') {
return clampCssFloat(parseFloat(str) / 100);
}
return clampCssFloat(parseFloat(str));
}
function cssHueToRgb(m1, m2, h) {
if (h < 0) {
h += 1;
} else if (h > 1) {
h -= 1;
}
if (h * 6 < 1) {
return m1 + (m2 - m1) * h * 6;
}
if (h * 2 < 1) {
return m2;
}
if (h * 3 < 2) {
return m1 + (m2 - m1) * (2 / 3 - h) * 6;
}
return m1;
}
function lerpNumber(a, b, p) {
return a + (b - a) * p;
}
function setRgba(out, r, g, b, a) {
out[0] = r;
out[1] = g;
out[2] = b;
out[3] = a;
return out;
}
function copyRgba(out, a) {
out[0] = a[0];
out[1] = a[1];
out[2] = a[2];
out[3] = a[3];
return out;
}
var colorCache = new LRU(20);
var lastRemovedArr = null;
function putToCache(colorStr, rgbaArr) {
// Reuse removed array
if (lastRemovedArr) {
copyRgba(lastRemovedArr, rgbaArr);
}
lastRemovedArr = colorCache.put(colorStr, lastRemovedArr || rgbaArr.slice());
}
/**
* @param {string} colorStr
* @param {Array.} out
* @return {Array.}
* @memberOf module:zrender/util/color
*/
function parse(colorStr, rgbaArr) {
if (!colorStr) {
return;
}
rgbaArr = rgbaArr || [];
var cached = colorCache.get(colorStr);
if (cached) {
return copyRgba(rgbaArr, cached);
} // colorStr may be not string
colorStr = colorStr + ''; // Remove all whitespace, not compliant, but should just be more accepting.
var str = colorStr.replace(/ /g, '').toLowerCase(); // Color keywords (and transparent) lookup.
if (str in kCSSColorTable) {
copyRgba(rgbaArr, kCSSColorTable[str]);
putToCache(colorStr, rgbaArr);
return rgbaArr;
} // #abc and #abc123 syntax.
if (str.charAt(0) === '#') {
if (str.length === 4) {
var iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing.
if (!(iv >= 0 && iv <= 0xfff)) {
setRgba(rgbaArr, 0, 0, 0, 1);
return; // Covers NaN.
}
setRgba(rgbaArr, (iv & 0xf00) >> 4 | (iv & 0xf00) >> 8, iv & 0xf0 | (iv & 0xf0) >> 4, iv & 0xf | (iv & 0xf) << 4, 1);
putToCache(colorStr, rgbaArr);
return rgbaArr;
} else if (str.length === 7) {
var iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing.
if (!(iv >= 0 && iv <= 0xffffff)) {
setRgba(rgbaArr, 0, 0, 0, 1);
return; // Covers NaN.
}
setRgba(rgbaArr, (iv & 0xff0000) >> 16, (iv & 0xff00) >> 8, iv & 0xff, 1);
putToCache(colorStr, rgbaArr);
return rgbaArr;
}
return;
}
var op = str.indexOf('('),
ep = str.indexOf(')');
if (op !== -1 && ep + 1 === str.length) {
var fname = str.substr(0, op);
var params = str.substr(op + 1, ep - (op + 1)).split(',');
var alpha = 1; // To allow case fallthrough.
switch (fname) {
case 'rgba':
if (params.length !== 4) {
setRgba(rgbaArr, 0, 0, 0, 1);
return;
}
alpha = parseCssFloat(params.pop());
// jshint ignore:line
// Fall through.
case 'rgb':
if (params.length !== 3) {
setRgba(rgbaArr, 0, 0, 0, 1);
return;
}
setRgba(rgbaArr, parseCssInt(params[0]), parseCssInt(params[1]), parseCssInt(params[2]), alpha);
putToCache(colorStr, rgbaArr);
return rgbaArr;
case 'hsla':
if (params.length !== 4) {
setRgba(rgbaArr, 0, 0, 0, 1);
return;
}
params[3] = parseCssFloat(params[3]);
hsla2rgba(params, rgbaArr);
putToCache(colorStr, rgbaArr);
return rgbaArr;
case 'hsl':
if (params.length !== 3) {
setRgba(rgbaArr, 0, 0, 0, 1);
return;
}
hsla2rgba(params, rgbaArr);
putToCache(colorStr, rgbaArr);
return rgbaArr;
default:
return;
}
}
setRgba(rgbaArr, 0, 0, 0, 1);
return;
}
/**
* @param {Array.} hsla
* @param {Array.} rgba
* @return {Array.} rgba
*/
function hsla2rgba(hsla, rgba) {
var h = (parseFloat(hsla[0]) % 360 + 360) % 360 / 360; // 0 .. 1
// NOTE(deanm): According to the CSS spec s/l should only be
// percentages, but we don't bother and let float or percentage.
var s = parseCssFloat(hsla[1]);
var l = parseCssFloat(hsla[2]);
var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
var m1 = l * 2 - m2;
rgba = rgba || [];
setRgba(rgba, clampCssByte(cssHueToRgb(m1, m2, h + 1 / 3) * 255), clampCssByte(cssHueToRgb(m1, m2, h) * 255), clampCssByte(cssHueToRgb(m1, m2, h - 1 / 3) * 255), 1);
if (hsla.length === 4) {
rgba[3] = hsla[3];
}
return rgba;
}
/**
* @param {Array.} rgba
* @return {Array.} hsla
*/
function rgba2hsla(rgba) {
if (!rgba) {
return;
} // RGB from 0 to 255
var R = rgba[0] / 255;
var G = rgba[1] / 255;
var B = rgba[2] / 255;
var vMin = Math.min(R, G, B); // Min. value of RGB
var vMax = Math.max(R, G, B); // Max. value of RGB
var delta = vMax - vMin; // Delta RGB value
var L = (vMax + vMin) / 2;
var H;
var S; // HSL results from 0 to 1
if (delta === 0) {
H = 0;
S = 0;
} else {
if (L < 0.5) {
S = delta / (vMax + vMin);
} else {
S = delta / (2 - vMax - vMin);
}
var deltaR = ((vMax - R) / 6 + delta / 2) / delta;
var deltaG = ((vMax - G) / 6 + delta / 2) / delta;
var deltaB = ((vMax - B) / 6 + delta / 2) / delta;
if (R === vMax) {
H = deltaB - deltaG;
} else if (G === vMax) {
H = 1 / 3 + deltaR - deltaB;
} else if (B === vMax) {
H = 2 / 3 + deltaG - deltaR;
}
if (H < 0) {
H += 1;
}
if (H > 1) {
H -= 1;
}
}
var hsla = [H * 360, S, L];
if (rgba[3] != null) {
hsla.push(rgba[3]);
}
return hsla;
}
/**
* @param {string} color
* @param {number} level
* @return {string}
* @memberOf module:zrender/util/color
*/
function lift(color, level) {
var colorArr = parse(color);
if (colorArr) {
for (var i = 0; i < 3; i++) {
if (level < 0) {
colorArr[i] = colorArr[i] * (1 - level) | 0;
} else {
colorArr[i] = (255 - colorArr[i]) * level + colorArr[i] | 0;
}
}
return stringify(colorArr, colorArr.length === 4 ? 'rgba' : 'rgb');
}
}
/**
* @param {string} color
* @return {string}
* @memberOf module:zrender/util/color
*/
function toHex(color) {
var colorArr = parse(color);
if (colorArr) {
return ((1 << 24) + (colorArr[0] << 16) + (colorArr[1] << 8) + +colorArr[2]).toString(16).slice(1);
}
}
/**
* Map value to color. Faster than lerp methods because color is represented by rgba array.
* @param {number} normalizedValue A float between 0 and 1.
* @param {Array.>} colors List of rgba color array
* @param {Array.} [out] Mapped gba color array
* @return {Array.} will be null/undefined if input illegal.
*/
function fastLerp(normalizedValue, colors, out) {
if (!(colors && colors.length) || !(normalizedValue >= 0 && normalizedValue <= 1)) {
return;
}
out = out || [];
var value = normalizedValue * (colors.length - 1);
var leftIndex = Math.floor(value);
var rightIndex = Math.ceil(value);
var leftColor = colors[leftIndex];
var rightColor = colors[rightIndex];
var dv = value - leftIndex;
out[0] = clampCssByte(lerpNumber(leftColor[0], rightColor[0], dv));
out[1] = clampCssByte(lerpNumber(leftColor[1], rightColor[1], dv));
out[2] = clampCssByte(lerpNumber(leftColor[2], rightColor[2], dv));
out[3] = clampCssFloat(lerpNumber(leftColor[3], rightColor[3], dv));
return out;
}
/**
* @deprecated
*/
var fastMapToColor = fastLerp;
/**
* @param {number} normalizedValue A float between 0 and 1.
* @param {Array.} colors Color list.
* @param {boolean=} fullOutput Default false.
* @return {(string|Object)} Result color. If fullOutput,
* return {color: ..., leftIndex: ..., rightIndex: ..., value: ...},
* @memberOf module:zrender/util/color
*/
function lerp(normalizedValue, colors, fullOutput) {
if (!(colors && colors.length) || !(normalizedValue >= 0 && normalizedValue <= 1)) {
return;
}
var value = normalizedValue * (colors.length - 1);
var leftIndex = Math.floor(value);
var rightIndex = Math.ceil(value);
var leftColor = parse(colors[leftIndex]);
var rightColor = parse(colors[rightIndex]);
var dv = value - leftIndex;
var color = stringify([clampCssByte(lerpNumber(leftColor[0], rightColor[0], dv)), clampCssByte(lerpNumber(leftColor[1], rightColor[1], dv)), clampCssByte(lerpNumber(leftColor[2], rightColor[2], dv)), clampCssFloat(lerpNumber(leftColor[3], rightColor[3], dv))], 'rgba');
return fullOutput ? {
color: color,
leftIndex: leftIndex,
rightIndex: rightIndex,
value: value
} : color;
}
/**
* @deprecated
*/
var mapToColor = lerp;
/**
* @param {string} color
* @param {number=} h 0 ~ 360, ignore when null.
* @param {number=} s 0 ~ 1, ignore when null.
* @param {number=} l 0 ~ 1, ignore when null.
* @return {string} Color string in rgba format.
* @memberOf module:zrender/util/color
*/
function modifyHSL(color, h, s, l) {
color = parse(color);
if (color) {
color = rgba2hsla(color);
h != null && (color[0] = clampCssAngle(h));
s != null && (color[1] = parseCssFloat(s));
l != null && (color[2] = parseCssFloat(l));
return stringify(hsla2rgba(color), 'rgba');
}
}
/**
* @param {string} color
* @param {number=} alpha 0 ~ 1
* @return {string} Color string in rgba format.
* @memberOf module:zrender/util/color
*/
function modifyAlpha(color, alpha) {
color = parse(color);
if (color && alpha != null) {
color[3] = clampCssFloat(alpha);
return stringify(color, 'rgba');
}
}
/**
* @param {Array.} arrColor like [12,33,44,0.4]
* @param {string} type 'rgba', 'hsva', ...
* @return {string} Result color. (If input illegal, return undefined).
*/
function stringify(arrColor, type) {
if (!arrColor || !arrColor.length) {
return;
}
var colorStr = arrColor[0] + ',' + arrColor[1] + ',' + arrColor[2];
if (type === 'rgba' || type === 'hsva' || type === 'hsla') {
colorStr += ',' + arrColor[3];
}
return type + '(' + colorStr + ')';
}
exports.parse = parse;
exports.lift = lift;
exports.toHex = toHex;
exports.fastLerp = fastLerp;
exports.fastMapToColor = fastMapToColor;
exports.lerp = lerp;
exports.mapToColor = mapToColor;
exports.modifyHSL = modifyHSL;
exports.modifyAlpha = modifyAlpha;
exports.stringify = stringify;
/***/ }),
/* 138 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("\n@export clay.util.rand\nhighp float rand(vec2 uv) {\n const highp float a = 12.9898, b = 78.233, c = 43758.5453;\n highp float dt = dot(uv.xy, vec2(a,b)), sn = mod(dt, 3.141592653589793);\n return fract(sin(sn) * c);\n}\n@end\n@export clay.util.calculate_attenuation\nuniform float attenuationFactor : 5.0;\nfloat lightAttenuation(float dist, float range)\n{\n float attenuation = 1.0;\n attenuation = dist*dist/(range*range+1.0);\n float att_s = attenuationFactor;\n attenuation = 1.0/(attenuation*att_s+1.0);\n att_s = 1.0/(att_s+1.0);\n attenuation = attenuation - att_s;\n attenuation /= 1.0 - att_s;\n return clamp(attenuation, 0.0, 1.0);\n}\n@end\n@export clay.util.edge_factor\nfloat edgeFactor(float width)\n{\n vec3 d = fwidth(v_Barycentric);\n vec3 a3 = smoothstep(vec3(0.0), d * width, v_Barycentric);\n return min(min(a3.x, a3.y), a3.z);\n}\n@end\n@export clay.util.encode_float\nvec4 encodeFloat(const in float depth)\n{\n const vec4 bitShifts = vec4(256.0*256.0*256.0, 256.0*256.0, 256.0, 1.0);\n const vec4 bit_mask = vec4(0.0, 1.0/256.0, 1.0/256.0, 1.0/256.0);\n vec4 res = fract(depth * bitShifts);\n res -= res.xxyz * bit_mask;\n return res;\n}\n@end\n@export clay.util.decode_float\nfloat decodeFloat(const in vec4 color)\n{\n const vec4 bitShifts = vec4(1.0/(256.0*256.0*256.0), 1.0/(256.0*256.0), 1.0/256.0, 1.0);\n return dot(color, bitShifts);\n}\n@end\n@export clay.util.float\n@import clay.util.encode_float\n@import clay.util.decode_float\n@end\n@export clay.util.rgbm_decode\nvec3 RGBMDecode(vec4 rgbm, float range) {\n return range * rgbm.rgb * rgbm.a;\n}\n@end\n@export clay.util.rgbm_encode\nvec4 RGBMEncode(vec3 color, float range) {\n if (dot(color, color) == 0.0) {\n return vec4(0.0);\n }\n vec4 rgbm;\n color /= range;\n rgbm.a = clamp(max(max(color.r, color.g), max(color.b, 1e-6)), 0.0, 1.0);\n rgbm.a = ceil(rgbm.a * 255.0) / 255.0;\n rgbm.rgb = color / rgbm.a;\n return rgbm;\n}\n@end\n@export clay.util.rgbm\n@import clay.util.rgbm_decode\n@import clay.util.rgbm_encode\nvec4 decodeHDR(vec4 color)\n{\n#if defined(RGBM_DECODE) || defined(RGBM)\n return vec4(RGBMDecode(color, 8.12), 1.0);\n#else\n return color;\n#endif\n}\nvec4 encodeHDR(vec4 color)\n{\n#if defined(RGBM_ENCODE) || defined(RGBM)\n return RGBMEncode(color.xyz, 8.12);\n#else\n return color;\n#endif\n}\n@end\n@export clay.util.srgb\nvec4 sRGBToLinear(in vec4 value) {\n return vec4(mix(pow(value.rgb * 0.9478672986 + vec3(0.0521327014), vec3(2.4)), value.rgb * 0.0773993808, vec3(lessThanEqual(value.rgb, vec3(0.04045)))), value.w);\n}\nvec4 linearTosRGB(in vec4 value) {\n return vec4(mix(pow(value.rgb, vec3(0.41666)) * 1.055 - vec3(0.055), value.rgb * 12.92, vec3(lessThanEqual(value.rgb, vec3(0.0031308)))), value.w);\n}\n@end\n@export clay.chunk.skinning_header\n#ifdef SKINNING\nattribute vec3 weight : WEIGHT;\nattribute vec4 joint : JOINT;\nuniform mat4 skinMatrix[JOINT_COUNT] : SKIN_MATRIX;\nmat4 getSkinMatrix(float idx) {\n return skinMatrix[int(idx)];\n}\n#endif\n@end\n@export clay.chunk.skin_matrix\nmat4 skinMatrixWS = getSkinMatrix(joint.x) * weight.x;\nif (weight.y > 1e-4)\n{\n skinMatrixWS += getSkinMatrix(joint.y) * weight.y;\n}\nif (weight.z > 1e-4)\n{\n skinMatrixWS += getSkinMatrix(joint.z) * weight.z;\n}\nfloat weightW = 1.0-weight.x-weight.y-weight.z;\nif (weightW > 1e-4)\n{\n skinMatrixWS += getSkinMatrix(joint.w) * weightW;\n}\n@end\n@export clay.util.parallax_correct\nvec3 parallaxCorrect(in vec3 dir, in vec3 pos, in vec3 boxMin, in vec3 boxMax) {\n vec3 first = (boxMax - pos) / dir;\n vec3 second = (boxMin - pos) / dir;\n vec3 further = max(first, second);\n float dist = min(further.x, min(further.y, further.z));\n vec3 fixedPos = pos + dir * dist;\n vec3 boxCenter = (boxMax + boxMin) * 0.5;\n return normalize(fixedPos - boxCenter);\n}\n@end\n@export clay.util.clamp_sample\nvec4 clampSample(const in sampler2D texture, const in vec2 coord)\n{\n#ifdef STEREO\n float eye = step(0.5, coord.x) * 0.5;\n vec2 coordClamped = clamp(coord, vec2(eye, 0.0), vec2(0.5 + eye, 1.0));\n#else\n vec2 coordClamped = clamp(coord, vec2(0.0), vec2(1.0));\n#endif\n return texture2D(texture, coordClamped);\n}\n@end\n@export clay.util.ACES\nvec3 ACESToneMapping(vec3 color)\n{\n const float A = 2.51;\n const float B = 0.03;\n const float C = 2.43;\n const float D = 0.59;\n const float E = 0.14;\n return (color * (A * color + B)) / (color * (C * color + D) + E);\n}\n@end");
/***/ }),
/* 139 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("\n@export ecgl.common.transformUniforms\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform mat4 worldInverseTranspose : WORLDINVERSETRANSPOSE;\nuniform mat4 world : WORLD;\n@end\n\n@export ecgl.common.attributes\nattribute vec3 position : POSITION;\nattribute vec2 texcoord : TEXCOORD_0;\nattribute vec3 normal : NORMAL;\n@end\n\n@export ecgl.common.uv.header\nuniform vec2 uvRepeat : [1.0, 1.0];\nuniform vec2 uvOffset : [0.0, 0.0];\nuniform vec2 detailUvRepeat : [1.0, 1.0];\nuniform vec2 detailUvOffset : [0.0, 0.0];\n\nvarying vec2 v_Texcoord;\nvarying vec2 v_DetailTexcoord;\n@end\n\n@export ecgl.common.uv.main\nv_Texcoord = texcoord * uvRepeat + uvOffset;\nv_DetailTexcoord = texcoord * detailUvRepeat + detailUvOffset;\n@end\n\n@export ecgl.common.uv.fragmentHeader\nvarying vec2 v_Texcoord;\nvarying vec2 v_DetailTexcoord;\n@end\n\n\n@export ecgl.common.albedo.main\n\n vec4 albedoTexel = vec4(1.0);\n#ifdef DIFFUSEMAP_ENABLED\n albedoTexel = texture2D(diffuseMap, v_Texcoord);\n #ifdef SRGB_DECODE\n albedoTexel = sRGBToLinear(albedoTexel);\n #endif\n#endif\n\n#ifdef DETAILMAP_ENABLED\n vec4 detailTexel = texture2D(detailMap, v_DetailTexcoord);\n #ifdef SRGB_DECODE\n detailTexel = sRGBToLinear(detailTexel);\n #endif\n albedoTexel.rgb = mix(albedoTexel.rgb, detailTexel.rgb, detailTexel.a);\n albedoTexel.a = detailTexel.a + (1.0 - detailTexel.a) * albedoTexel.a;\n#endif\n\n@end\n\n@export ecgl.common.wireframe.vertexHeader\n\n#ifdef WIREFRAME_QUAD\nattribute vec4 barycentric;\nvarying vec4 v_Barycentric;\n#elif defined(WIREFRAME_TRIANGLE)\nattribute vec3 barycentric;\nvarying vec3 v_Barycentric;\n#endif\n\n@end\n\n@export ecgl.common.wireframe.vertexMain\n\n#if defined(WIREFRAME_QUAD) || defined(WIREFRAME_TRIANGLE)\n v_Barycentric = barycentric;\n#endif\n\n@end\n\n\n@export ecgl.common.wireframe.fragmentHeader\n\nuniform float wireframeLineWidth : 1;\nuniform vec4 wireframeLineColor: [0, 0, 0, 0.5];\n\n#ifdef WIREFRAME_QUAD\nvarying vec4 v_Barycentric;\nfloat edgeFactor () {\n vec4 d = fwidth(v_Barycentric);\n vec4 a4 = smoothstep(vec4(0.0), d * wireframeLineWidth, v_Barycentric);\n return min(min(min(a4.x, a4.y), a4.z), a4.w);\n}\n#elif defined(WIREFRAME_TRIANGLE)\nvarying vec3 v_Barycentric;\nfloat edgeFactor () {\n vec3 d = fwidth(v_Barycentric);\n vec3 a3 = smoothstep(vec3(0.0), d * wireframeLineWidth, v_Barycentric);\n return min(min(a3.x, a3.y), a3.z);\n}\n#endif\n\n@end\n\n\n@export ecgl.common.wireframe.fragmentMain\n\n#if defined(WIREFRAME_QUAD) || defined(WIREFRAME_TRIANGLE)\n if (wireframeLineWidth > 0.) {\n vec4 lineColor = wireframeLineColor;\n#ifdef SRGB_DECODE\n lineColor = sRGBToLinear(lineColor);\n#endif\n\n gl_FragColor.rgb = mix(gl_FragColor.rgb, lineColor.rgb, (1.0 - edgeFactor()) * lineColor.a);\n }\n#endif\n@end\n\n\n\n\n@export ecgl.common.bumpMap.header\n\n#ifdef BUMPMAP_ENABLED\nuniform sampler2D bumpMap;\nuniform float bumpScale : 1.0;\n\n\nvec3 bumpNormal(vec3 surfPos, vec3 surfNormal, vec3 baseNormal)\n{\n vec2 dSTdx = dFdx(v_Texcoord);\n vec2 dSTdy = dFdy(v_Texcoord);\n\n float Hll = bumpScale * texture2D(bumpMap, v_Texcoord).x;\n float dHx = bumpScale * texture2D(bumpMap, v_Texcoord + dSTdx).x - Hll;\n float dHy = bumpScale * texture2D(bumpMap, v_Texcoord + dSTdy).x - Hll;\n\n vec3 vSigmaX = dFdx(surfPos);\n vec3 vSigmaY = dFdy(surfPos);\n vec3 vN = surfNormal;\n\n vec3 R1 = cross(vSigmaY, vN);\n vec3 R2 = cross(vN, vSigmaX);\n\n float fDet = dot(vSigmaX, R1);\n\n vec3 vGrad = sign(fDet) * (dHx * R1 + dHy * R2);\n return normalize(abs(fDet) * baseNormal - vGrad);\n\n}\n#endif\n\n@end\n\n@export ecgl.common.normalMap.vertexHeader\n\n#ifdef NORMALMAP_ENABLED\nattribute vec4 tangent : TANGENT;\nvarying vec3 v_Tangent;\nvarying vec3 v_Bitangent;\n#endif\n\n@end\n\n@export ecgl.common.normalMap.vertexMain\n\n#ifdef NORMALMAP_ENABLED\n if (dot(tangent, tangent) > 0.0) {\n v_Tangent = normalize((worldInverseTranspose * vec4(tangent.xyz, 0.0)).xyz);\n v_Bitangent = normalize(cross(v_Normal, v_Tangent) * tangent.w);\n }\n#endif\n\n@end\n\n\n@export ecgl.common.normalMap.fragmentHeader\n\n#ifdef NORMALMAP_ENABLED\nuniform sampler2D normalMap;\nvarying vec3 v_Tangent;\nvarying vec3 v_Bitangent;\n#endif\n\n@end\n\n@export ecgl.common.normalMap.fragmentMain\n#ifdef NORMALMAP_ENABLED\n if (dot(v_Tangent, v_Tangent) > 0.0) {\n vec3 normalTexel = texture2D(normalMap, v_DetailTexcoord).xyz;\n if (dot(normalTexel, normalTexel) > 0.0) { N = normalTexel * 2.0 - 1.0;\n mat3 tbn = mat3(v_Tangent, v_Bitangent, v_Normal);\n N = normalize(tbn * N);\n }\n }\n#endif\n@end\n\n\n\n@export ecgl.common.vertexAnimation.header\n\n#ifdef VERTEX_ANIMATION\nattribute vec3 prevPosition;\nattribute vec3 prevNormal;\nuniform float percent;\n#endif\n\n@end\n\n@export ecgl.common.vertexAnimation.main\n\n#ifdef VERTEX_ANIMATION\n vec3 pos = mix(prevPosition, position, percent);\n vec3 norm = mix(prevNormal, normal, percent);\n#else\n vec3 pos = position;\n vec3 norm = normal;\n#endif\n\n@end\n\n\n@export ecgl.common.ssaoMap.header\n#ifdef SSAOMAP_ENABLED\nuniform sampler2D ssaoMap;\nuniform vec4 viewport : VIEWPORT;\n#endif\n@end\n\n@export ecgl.common.ssaoMap.main\n float ao = 1.0;\n#ifdef SSAOMAP_ENABLED\n ao = texture2D(ssaoMap, (gl_FragCoord.xy - viewport.xy) / viewport.zw).r;\n#endif\n@end\n\n\n\n\n@export ecgl.common.diffuseLayer.header\n\n#if (LAYER_DIFFUSEMAP_COUNT > 0)\nuniform float layerDiffuseIntensity[LAYER_DIFFUSEMAP_COUNT];\nuniform sampler2D layerDiffuseMap[LAYER_DIFFUSEMAP_COUNT];\n#endif\n\n@end\n\n@export ecgl.common.emissiveLayer.header\n\n#if (LAYER_EMISSIVEMAP_COUNT > 0)\nuniform float layerEmissionIntensity[LAYER_EMISSIVEMAP_COUNT];\nuniform sampler2D layerEmissiveMap[LAYER_EMISSIVEMAP_COUNT];\n#endif\n\n@end\n\n@export ecgl.common.layers.header\n@import ecgl.common.diffuseLayer.header\n@import ecgl.common.emissiveLayer.header\n@end\n\n@export ecgl.common.diffuseLayer.main\n\n#if (LAYER_DIFFUSEMAP_COUNT > 0)\n for (int _idx_ = 0; _idx_ < LAYER_DIFFUSEMAP_COUNT; _idx_++) {{\n float intensity = layerDiffuseIntensity[_idx_];\n vec4 texel2 = texture2D(layerDiffuseMap[_idx_], v_Texcoord);\n #ifdef SRGB_DECODE\n texel2 = sRGBToLinear(texel2);\n #endif\n albedoTexel.rgb = mix(albedoTexel.rgb, texel2.rgb * intensity, texel2.a);\n albedoTexel.a = texel2.a + (1.0 - texel2.a) * albedoTexel.a;\n }}\n#endif\n\n@end\n\n@export ecgl.common.emissiveLayer.main\n\n#if (LAYER_EMISSIVEMAP_COUNT > 0)\n for (int _idx_ = 0; _idx_ < LAYER_EMISSIVEMAP_COUNT; _idx_++)\n {{\n vec4 texel2 = texture2D(layerEmissiveMap[_idx_], v_Texcoord) * layerEmissionIntensity[_idx_];\n #ifdef SRGB_DECODE\n texel2 = sRGBToLinear(texel2);\n #endif\n float intensity = layerEmissionIntensity[_idx_];\n gl_FragColor.rgb += texel2.rgb * texel2.a * intensity;\n }}\n#endif\n\n@end\n");
/***/ }),
/* 140 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.color.vertex\n\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\n\n@import ecgl.common.uv.header\n\nattribute vec2 texcoord : TEXCOORD_0;\nattribute vec3 position: POSITION;\n\n@import ecgl.common.wireframe.vertexHeader\n\n#ifdef VERTEX_COLOR\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n#endif\n\n#ifdef VERTEX_ANIMATION\nattribute vec3 prevPosition;\nuniform float percent : 1.0;\n#endif\n\nvoid main()\n{\n#ifdef VERTEX_ANIMATION\n vec3 pos = mix(prevPosition, position, percent);\n#else\n vec3 pos = position;\n#endif\n\n gl_Position = worldViewProjection * vec4(pos, 1.0);\n\n @import ecgl.common.uv.main\n\n#ifdef VERTEX_COLOR\n v_Color = a_Color;\n#endif\n\n @import ecgl.common.wireframe.vertexMain\n\n}\n\n@end\n\n@export ecgl.color.fragment\n\n#define LAYER_DIFFUSEMAP_COUNT 0\n#define LAYER_EMISSIVEMAP_COUNT 0\n\nuniform sampler2D diffuseMap;\nuniform sampler2D detailMap;\n\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\n\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\n\n@import ecgl.common.layers.header\n\n@import ecgl.common.uv.fragmentHeader\n\n@import ecgl.common.wireframe.fragmentHeader\n\n@import clay.util.srgb\n\nvoid main()\n{\n#ifdef SRGB_DECODE\n gl_FragColor = sRGBToLinear(color);\n#else\n gl_FragColor = color;\n#endif\n\n#ifdef VERTEX_COLOR\n gl_FragColor *= v_Color;\n#endif\n\n @import ecgl.common.albedo.main\n\n @import ecgl.common.diffuseLayer.main\n\n gl_FragColor *= albedoTexel;\n\n @import ecgl.common.emissiveLayer.main\n\n @import ecgl.common.wireframe.fragmentMain\n\n}\n@end");
/***/ }),
/* 141 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("/**\n * http: */\n\n@export ecgl.lambert.vertex\n\n@import ecgl.common.transformUniforms\n\n@import ecgl.common.uv.header\n\n\n@import ecgl.common.attributes\n\n@import ecgl.common.wireframe.vertexHeader\n\n#ifdef VERTEX_COLOR\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n#endif\n\n\n@import ecgl.common.vertexAnimation.header\n\n\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\n\nvoid main()\n{\n @import ecgl.common.uv.main\n\n @import ecgl.common.vertexAnimation.main\n\n\n gl_Position = worldViewProjection * vec4(pos, 1.0);\n\n v_Normal = normalize((worldInverseTranspose * vec4(norm, 0.0)).xyz);\n v_WorldPosition = (world * vec4(pos, 1.0)).xyz;\n\n#ifdef VERTEX_COLOR\n v_Color = a_Color;\n#endif\n\n @import ecgl.common.wireframe.vertexMain\n}\n\n@end\n\n\n@export ecgl.lambert.fragment\n\n#define LAYER_DIFFUSEMAP_COUNT 0\n#define LAYER_EMISSIVEMAP_COUNT 0\n\n#define NORMAL_UP_AXIS 1\n#define NORMAL_FRONT_AXIS 2\n\n@import ecgl.common.uv.fragmentHeader\n\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\n\nuniform sampler2D diffuseMap;\nuniform sampler2D detailMap;\n\n@import ecgl.common.layers.header\n\nuniform float emissionIntensity: 1.0;\n\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\n\nuniform mat4 viewInverse : VIEWINVERSE;\n\n#ifdef AMBIENT_LIGHT_COUNT\n@import clay.header.ambient_light\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n@import clay.header.ambient_sh_light\n#endif\n\n#ifdef DIRECTIONAL_LIGHT_COUNT\n@import clay.header.directional_light\n#endif\n\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\n\n\n@import ecgl.common.ssaoMap.header\n\n@import ecgl.common.bumpMap.header\n\n@import clay.util.srgb\n\n@import ecgl.common.wireframe.fragmentHeader\n\n@import clay.plugin.compute_shadow_map\n\nvoid main()\n{\n#ifdef SRGB_DECODE\n gl_FragColor = sRGBToLinear(color);\n#else\n gl_FragColor = color;\n#endif\n\n#ifdef VERTEX_COLOR\n #ifdef SRGB_DECODE\n gl_FragColor *= sRGBToLinear(v_Color);\n #else\n gl_FragColor *= v_Color;\n #endif\n#endif\n\n @import ecgl.common.albedo.main\n\n @import ecgl.common.diffuseLayer.main\n\n gl_FragColor *= albedoTexel;\n\n vec3 N = v_Normal;\n#ifdef DOUBLE_SIDED\n vec3 eyePos = viewInverse[3].xyz;\n vec3 V = normalize(eyePos - v_WorldPosition);\n\n if (dot(N, V) < 0.0) {\n N = -N;\n }\n#endif\n\n float ambientFactor = 1.0;\n\n#ifdef BUMPMAP_ENABLED\n N = bumpNormal(v_WorldPosition, v_Normal, N);\n ambientFactor = dot(v_Normal, N);\n#endif\n\n vec3 N2 = vec3(N.x, N[NORMAL_UP_AXIS], N[NORMAL_FRONT_AXIS]);\n\n vec3 diffuseColor = vec3(0.0, 0.0, 0.0);\n\n @import ecgl.common.ssaoMap.main\n\n#ifdef AMBIENT_LIGHT_COUNT\n for(int i = 0; i < AMBIENT_LIGHT_COUNT; i++)\n {\n diffuseColor += ambientLightColor[i] * ambientFactor * ao;\n }\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_SH_LIGHT_COUNT; _idx_++)\n {{\n diffuseColor += calcAmbientSHLight(_idx_, N2) * ambientSHLightColor[_idx_] * ao;\n }}\n#endif\n#ifdef DIRECTIONAL_LIGHT_COUNT\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsDir[DIRECTIONAL_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfDirectionalLights(v_WorldPosition, shadowContribsDir);\n }\n#endif\n for(int i = 0; i < DIRECTIONAL_LIGHT_COUNT; i++)\n {\n vec3 lightDirection = -directionalLightDirection[i];\n vec3 lightColor = directionalLightColor[i];\n\n float shadowContrib = 1.0;\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n if (shadowEnabled)\n {\n shadowContrib = shadowContribsDir[i];\n }\n#endif\n\n float ndl = dot(N, normalize(lightDirection)) * shadowContrib;\n\n diffuseColor += lightColor * clamp(ndl, 0.0, 1.0);\n }\n#endif\n\n gl_FragColor.rgb *= diffuseColor;\n\n @import ecgl.common.emissiveLayer.main\n\n @import ecgl.common.wireframe.fragmentMain\n}\n\n@end");
/***/ }),
/* 142 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.realistic.vertex\n\n@import ecgl.common.transformUniforms\n\n@import ecgl.common.uv.header\n\n@import ecgl.common.attributes\n\n\n@import ecgl.common.wireframe.vertexHeader\n\n#ifdef VERTEX_COLOR\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n#endif\n\n#ifdef NORMALMAP_ENABLED\nattribute vec4 tangent : TANGENT;\nvarying vec3 v_Tangent;\nvarying vec3 v_Bitangent;\n#endif\n\n@import ecgl.common.vertexAnimation.header\n\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\n\nvoid main()\n{\n\n @import ecgl.common.uv.main\n\n @import ecgl.common.vertexAnimation.main\n\n gl_Position = worldViewProjection * vec4(pos, 1.0);\n\n v_Normal = normalize((worldInverseTranspose * vec4(norm, 0.0)).xyz);\n v_WorldPosition = (world * vec4(pos, 1.0)).xyz;\n\n#ifdef VERTEX_COLOR\n v_Color = a_Color;\n#endif\n\n#ifdef NORMALMAP_ENABLED\n v_Tangent = normalize((worldInverseTranspose * vec4(tangent.xyz, 0.0)).xyz);\n v_Bitangent = normalize(cross(v_Normal, v_Tangent) * tangent.w);\n#endif\n\n @import ecgl.common.wireframe.vertexMain\n\n}\n\n@end\n\n\n\n@export ecgl.realistic.fragment\n\n#define LAYER_DIFFUSEMAP_COUNT 0\n#define LAYER_EMISSIVEMAP_COUNT 0\n#define PI 3.14159265358979\n#define ROUGHNESS_CHANEL 0\n#define METALNESS_CHANEL 1\n\n#define NORMAL_UP_AXIS 1\n#define NORMAL_FRONT_AXIS 2\n\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\n\n@import ecgl.common.uv.fragmentHeader\n\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\n\nuniform sampler2D diffuseMap;\n\nuniform sampler2D detailMap;\nuniform sampler2D metalnessMap;\nuniform sampler2D roughnessMap;\n\n@import ecgl.common.layers.header\n\nuniform float emissionIntensity: 1.0;\n\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\n\nuniform float metalness : 0.0;\nuniform float roughness : 0.5;\n\nuniform mat4 viewInverse : VIEWINVERSE;\n\n#ifdef AMBIENT_LIGHT_COUNT\n@import clay.header.ambient_light\n#endif\n\n#ifdef AMBIENT_SH_LIGHT_COUNT\n@import clay.header.ambient_sh_light\n#endif\n\n#ifdef AMBIENT_CUBEMAP_LIGHT_COUNT\n@import clay.header.ambient_cubemap_light\n#endif\n\n#ifdef DIRECTIONAL_LIGHT_COUNT\n@import clay.header.directional_light\n#endif\n\n@import ecgl.common.normalMap.fragmentHeader\n\n@import ecgl.common.ssaoMap.header\n\n@import ecgl.common.bumpMap.header\n\n@import clay.util.srgb\n\n@import clay.util.rgbm\n\n@import ecgl.common.wireframe.fragmentHeader\n\n@import clay.plugin.compute_shadow_map\n\nvec3 F_Schlick(float ndv, vec3 spec) {\n return spec + (1.0 - spec) * pow(1.0 - ndv, 5.0);\n}\n\nfloat D_Phong(float g, float ndh) {\n float a = pow(8192.0, g);\n return (a + 2.0) / 8.0 * pow(ndh, a);\n}\n\nvoid main()\n{\n vec4 albedoColor = color;\n\n vec3 eyePos = viewInverse[3].xyz;\n vec3 V = normalize(eyePos - v_WorldPosition);\n#ifdef VERTEX_COLOR\n #ifdef SRGB_DECODE\n albedoColor *= sRGBToLinear(v_Color);\n #else\n albedoColor *= v_Color;\n #endif\n#endif\n\n @import ecgl.common.albedo.main\n\n @import ecgl.common.diffuseLayer.main\n\n albedoColor *= albedoTexel;\n\n float m = metalness;\n\n#ifdef METALNESSMAP_ENABLED\n float m2 = texture2D(metalnessMap, v_DetailTexcoord)[METALNESS_CHANEL];\n m = clamp(m2 + (m - 0.5) * 2.0, 0.0, 1.0);\n#endif\n\n vec3 baseColor = albedoColor.rgb;\n albedoColor.rgb = baseColor * (1.0 - m);\n vec3 specFactor = mix(vec3(0.04), baseColor, m);\n\n float g = 1.0 - roughness;\n\n#ifdef ROUGHNESSMAP_ENABLED\n float g2 = 1.0 - texture2D(roughnessMap, v_DetailTexcoord)[ROUGHNESS_CHANEL];\n g = clamp(g2 + (g - 0.5) * 2.0, 0.0, 1.0);\n#endif\n\n vec3 N = v_Normal;\n\n#ifdef DOUBLE_SIDED\n if (dot(N, V) < 0.0) {\n N = -N;\n }\n#endif\n\n float ambientFactor = 1.0;\n\n#ifdef BUMPMAP_ENABLED\n N = bumpNormal(v_WorldPosition, v_Normal, N);\n ambientFactor = dot(v_Normal, N);\n#endif\n\n@import ecgl.common.normalMap.fragmentMain\n\n vec3 N2 = vec3(N.x, N[NORMAL_UP_AXIS], N[NORMAL_FRONT_AXIS]);\n\n vec3 diffuseTerm = vec3(0.0);\n vec3 specularTerm = vec3(0.0);\n\n float ndv = clamp(dot(N, V), 0.0, 1.0);\n vec3 fresnelTerm = F_Schlick(ndv, specFactor);\n\n @import ecgl.common.ssaoMap.main\n\n#ifdef AMBIENT_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_LIGHT_COUNT; _idx_++)\n {{\n diffuseTerm += ambientLightColor[_idx_] * ambientFactor * ao;\n }}\n#endif\n\n#ifdef AMBIENT_SH_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_SH_LIGHT_COUNT; _idx_++)\n {{\n diffuseTerm += calcAmbientSHLight(_idx_, N2) * ambientSHLightColor[_idx_] * ao;\n }}\n#endif\n\n#ifdef DIRECTIONAL_LIGHT_COUNT\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsDir[DIRECTIONAL_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfDirectionalLights(v_WorldPosition, shadowContribsDir);\n }\n#endif\n for(int _idx_ = 0; _idx_ < DIRECTIONAL_LIGHT_COUNT; _idx_++)\n {{\n vec3 L = -directionalLightDirection[_idx_];\n vec3 lc = directionalLightColor[_idx_];\n\n vec3 H = normalize(L + V);\n float ndl = clamp(dot(N, normalize(L)), 0.0, 1.0);\n float ndh = clamp(dot(N, H), 0.0, 1.0);\n\n float shadowContrib = 1.0;\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n if (shadowEnabled)\n {\n shadowContrib = shadowContribsDir[_idx_];\n }\n#endif\n\n vec3 li = lc * ndl * shadowContrib;\n\n diffuseTerm += li;\n specularTerm += li * fresnelTerm * D_Phong(g, ndh);\n }}\n#endif\n\n\n#ifdef AMBIENT_CUBEMAP_LIGHT_COUNT\n vec3 L = reflect(-V, N);\n L = vec3(L.x, L[NORMAL_UP_AXIS], L[NORMAL_FRONT_AXIS]);\n float rough2 = clamp(1.0 - g, 0.0, 1.0);\n float bias2 = rough2 * 5.0;\n vec2 brdfParam2 = texture2D(ambientCubemapLightBRDFLookup[0], vec2(rough2, ndv)).xy;\n vec3 envWeight2 = specFactor * brdfParam2.x + brdfParam2.y;\n vec3 envTexel2;\n for(int _idx_ = 0; _idx_ < AMBIENT_CUBEMAP_LIGHT_COUNT; _idx_++)\n {{\n envTexel2 = RGBMDecode(textureCubeLodEXT(ambientCubemapLightCubemap[_idx_], L, bias2), 8.12);\n specularTerm += ambientCubemapLightColor[_idx_] * envTexel2 * envWeight2 * ao;\n }}\n#endif\n\n gl_FragColor.rgb = albedoColor.rgb * diffuseTerm + specularTerm;\n gl_FragColor.a = albedoColor.a;\n\n#ifdef SRGB_ENCODE\n gl_FragColor = linearTosRGB(gl_FragColor);\n#endif\n\n @import ecgl.common.emissiveLayer.main\n\n @import ecgl.common.wireframe.fragmentMain\n}\n\n@end");
/***/ }),
/* 143 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.hatching.vertex\n\n@import ecgl.realistic.vertex\n\n@end\n\n\n@export ecgl.hatching.fragment\n\n#define NORMAL_UP_AXIS 1\n#define NORMAL_FRONT_AXIS 2\n\n@import ecgl.common.uv.fragmentHeader\n\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\n\nuniform vec4 color : [0.0, 0.0, 0.0, 1.0];\nuniform vec4 paperColor : [1.0, 1.0, 1.0, 1.0];\n\nuniform mat4 viewInverse : VIEWINVERSE;\n\n#ifdef AMBIENT_LIGHT_COUNT\n@import clay.header.ambient_light\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n@import clay.header.ambient_sh_light\n#endif\n\n#ifdef DIRECTIONAL_LIGHT_COUNT\n@import clay.header.directional_light\n#endif\n\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\n\n\n@import ecgl.common.ssaoMap.header\n\n@import ecgl.common.bumpMap.header\n\n@import clay.util.srgb\n\n@import ecgl.common.wireframe.fragmentHeader\n\n@import clay.plugin.compute_shadow_map\n\nuniform sampler2D hatch1;\nuniform sampler2D hatch2;\nuniform sampler2D hatch3;\nuniform sampler2D hatch4;\nuniform sampler2D hatch5;\nuniform sampler2D hatch6;\n\nfloat shade(in float tone) {\n vec4 c = vec4(1. ,1., 1., 1.);\n float step = 1. / 6.;\n vec2 uv = v_DetailTexcoord;\n if (tone <= step / 2.0) {\n c = mix(vec4(0.), texture2D(hatch6, uv), 12. * tone);\n }\n else if (tone <= step) {\n c = mix(texture2D(hatch6, uv), texture2D(hatch5, uv), 6. * tone);\n }\n if(tone > step && tone <= 2. * step){\n c = mix(texture2D(hatch5, uv), texture2D(hatch4, uv) , 6. * (tone - step));\n }\n if(tone > 2. * step && tone <= 3. * step){\n c = mix(texture2D(hatch4, uv), texture2D(hatch3, uv), 6. * (tone - 2. * step));\n }\n if(tone > 3. * step && tone <= 4. * step){\n c = mix(texture2D(hatch3, uv), texture2D(hatch2, uv), 6. * (tone - 3. * step));\n }\n if(tone > 4. * step && tone <= 5. * step){\n c = mix(texture2D(hatch2, uv), texture2D(hatch1, uv), 6. * (tone - 4. * step));\n }\n if(tone > 5. * step){\n c = mix(texture2D(hatch1, uv), vec4(1.), 6. * (tone - 5. * step));\n }\n\n return c.r;\n}\n\nconst vec3 w = vec3(0.2125, 0.7154, 0.0721);\n\nvoid main()\n{\n#ifdef SRGB_DECODE\n vec4 inkColor = sRGBToLinear(color);\n#else\n vec4 inkColor = color;\n#endif\n\n#ifdef VERTEX_COLOR\n #ifdef SRGB_DECODE\n inkColor *= sRGBToLinear(v_Color);\n #else\n inkColor *= v_Color;\n #endif\n#endif\n\n vec3 N = v_Normal;\n#ifdef DOUBLE_SIDED\n vec3 eyePos = viewInverse[3].xyz;\n vec3 V = normalize(eyePos - v_WorldPosition);\n\n if (dot(N, V) < 0.0) {\n N = -N;\n }\n#endif\n\n float tone = 0.0;\n\n float ambientFactor = 1.0;\n\n#ifdef BUMPMAP_ENABLED\n N = bumpNormal(v_WorldPosition, v_Normal, N);\n ambientFactor = dot(v_Normal, N);\n#endif\n\n vec3 N2 = vec3(N.x, N[NORMAL_UP_AXIS], N[NORMAL_FRONT_AXIS]);\n\n @import ecgl.common.ssaoMap.main\n\n#ifdef AMBIENT_LIGHT_COUNT\n for(int i = 0; i < AMBIENT_LIGHT_COUNT; i++)\n {\n tone += dot(ambientLightColor[i], w) * ambientFactor * ao;\n }\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_SH_LIGHT_COUNT; _idx_++)\n {{\n tone += dot(calcAmbientSHLight(_idx_, N2) * ambientSHLightColor[_idx_], w) * ao;\n }}\n#endif\n#ifdef DIRECTIONAL_LIGHT_COUNT\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsDir[DIRECTIONAL_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfDirectionalLights(v_WorldPosition, shadowContribsDir);\n }\n#endif\n for(int i = 0; i < DIRECTIONAL_LIGHT_COUNT; i++)\n {\n vec3 lightDirection = -directionalLightDirection[i];\n float lightTone = dot(directionalLightColor[i], w);\n\n float shadowContrib = 1.0;\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n if (shadowEnabled)\n {\n shadowContrib = shadowContribsDir[i];\n }\n#endif\n\n float ndl = dot(N, normalize(lightDirection)) * shadowContrib;\n\n tone += lightTone * clamp(ndl, 0.0, 1.0);\n }\n#endif\n\n gl_FragColor = mix(inkColor, paperColor, shade(clamp(tone, 0.0, 1.0)));\n }\n@end\n");
/***/ }),
/* 144 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.sm.depth.vertex\n\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\n\nattribute vec3 position : POSITION;\n\n#ifdef VERTEX_ANIMATION\nattribute vec3 prevPosition;\nuniform float percent : 1.0;\n#endif\n\nvarying vec4 v_ViewPosition;\n\nvoid main(){\n\n#ifdef VERTEX_ANIMATION\n vec3 pos = mix(prevPosition, position, percent);\n#else\n vec3 pos = position;\n#endif\n\n v_ViewPosition = worldViewProjection * vec4(pos, 1.0);\n gl_Position = v_ViewPosition;\n\n}\n@end\n\n\n\n@export ecgl.sm.depth.fragment\n\n@import clay.sm.depth.fragment\n\n@end");
/***/ }),
/* 145 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
var GL_SERIES = ['bar3D', 'line3D', 'map3D', 'scatter3D', 'surface', 'lines3D', 'scatterGL', 'scatter3D'];
function convertNormalEmphasis(option, optType) {
if (option && option[optType] && (option[optType].normal || option[optType].emphasis)) {
var normalOpt = option[optType].normal;
var emphasisOpt = option[optType].emphasis;
if (normalOpt) {
option[optType] = normalOpt;
}
if (emphasisOpt) {
option.emphasis = option.emphasis || {};
option.emphasis[optType] = emphasisOpt;
}
}
}
function convertNormalEmphasisForEach(option) {
convertNormalEmphasis(option, 'itemStyle');
convertNormalEmphasis(option, 'lineStyle');
convertNormalEmphasis(option, 'areaStyle');
convertNormalEmphasis(option, 'label');
}
function removeTextStyleInAxis(axesOpt) {
if (!axesOpt) {
return;
}
if (!(axesOpt instanceof Array)) {
axesOpt = [axesOpt];
}
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.each(axesOpt, function (axisOpt) {
if (axisOpt.axisLabel) {
var labelOpt = axisOpt.axisLabel;
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.extend(labelOpt, labelOpt.textStyle);
labelOpt.textStyle = null;
}
});
}
/* harmony default export */ __webpack_exports__["a"] = (function (option) {
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.each(option.series, function (series) {
if (__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.indexOf(GL_SERIES, series.type) >= 0) {
convertNormalEmphasisForEach(series);
// Compatitable with original mapbox
if (series.coordinateSystem === 'mapbox') {
series.coordinateSystem = 'mapbox3D';
option.mapbox3D = option.mapbox;
}
}
});
removeTextStyleInAxis(option.xAxis3D);
removeTextStyleInAxis(option.yAxis3D);
removeTextStyleInAxis(option.zAxis3D);
removeTextStyleInAxis(option.grid3D);
convertNormalEmphasis(option.geo3D);
});;
/***/ }),
/* 146 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__grid3D_Axis3DModel__ = __webpack_require__(147);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__grid3D_Grid3DModel__ = __webpack_require__(151);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__grid3D_Grid3DView__ = __webpack_require__(152);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__coord_grid3DCreator__ = __webpack_require__(158);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_echarts_lib_echarts__);
__WEBPACK_IMPORTED_MODULE_4_echarts_lib_echarts___default.a.registerAction({
type: 'grid3DChangeCamera',
event: 'grid3dcamerachanged',
update: 'series:updateCamera'
}, function (payload, ecModel) {
ecModel.eachComponent({
mainType: 'grid3D', query: payload
}, function (componentModel) {
componentModel.setView(payload);
});
});
__WEBPACK_IMPORTED_MODULE_4_echarts_lib_echarts___default.a.registerAction({
type: 'grid3DShowAxisPointer',
event: 'grid3dshowaxispointer',
update: 'grid3D:showAxisPointer'
}, function (payload, ecModel) {
});
__WEBPACK_IMPORTED_MODULE_4_echarts_lib_echarts___default.a.registerAction({
type: 'grid3DHideAxisPointer',
event: 'grid3dhideaxispointer',
update: 'grid3D:hideAxisPointer'
}, function (payload, ecModel) {
});
/***/ }),
/* 147 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__createAxis3DModel__ = __webpack_require__(148);
var Axis3DModel = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendComponentModel({
type: 'cartesian3DAxis',
axis: null,
/**
* @override
*/
getCoordSysModel: function () {
return this.ecModel.queryComponents({
mainType: 'grid3D',
index: this.option.gridIndex,
id: this.option.gridId
})[0];
}
});
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.helper.mixinAxisModelCommonMethods(Axis3DModel);
function getAxisType(axisDim, option) {
// Default axis with data is category axis
return option.type || (option.data ? 'category' : 'value');
}
Object(__WEBPACK_IMPORTED_MODULE_1__createAxis3DModel__["a" /* default */])('x', Axis3DModel, getAxisType, {
name: 'X'
});
Object(__WEBPACK_IMPORTED_MODULE_1__createAxis3DModel__["a" /* default */])('y', Axis3DModel, getAxisType, {
name: 'Y'
});
Object(__WEBPACK_IMPORTED_MODULE_1__createAxis3DModel__["a" /* default */])('z', Axis3DModel, getAxisType, {
name: 'Z'
});
/***/ }),
/* 148 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__axis3DDefault__ = __webpack_require__(149);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_data_OrdinalMeta__ = __webpack_require__(150);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_data_OrdinalMeta___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_echarts_lib_data_OrdinalMeta__);
var AXIS_TYPES = ['value', 'category', 'time', 'log'];
/**
* Generate sub axis model class
* @param {string} dim 'x' 'y' 'radius' 'angle' 'parallel'
* @param {module:echarts/model/Component} BaseAxisModelClass
* @param {Function} axisTypeDefaulter
* @param {Object} [extraDefaultOption]
*/
/* harmony default export */ __webpack_exports__["a"] = (function (dim, BaseAxisModelClass, axisTypeDefaulter, extraDefaultOption) {
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.each(AXIS_TYPES, function (axisType) {
BaseAxisModelClass.extend({
type: dim + 'Axis3D.' + axisType,
/**
* @type readOnly
*/
__ordinalMeta: null,
mergeDefaultAndTheme: function (option, ecModel) {
var themeModel = ecModel.getTheme();
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(option, themeModel.get(axisType + 'Axis3D'));
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(option, this.getDefaultOption());
option.type = axisTypeDefaulter(dim, option);
},
/**
* @override
*/
optionUpdated: function () {
var thisOption = this.option;
if (thisOption.type === 'category') {
this.__ordinalMeta = __WEBPACK_IMPORTED_MODULE_2_echarts_lib_data_OrdinalMeta___default.a.createByAxisModel(this);
}
},
getCategories: function () {
if (this.option.type === 'category') {
return this.__ordinalMeta.categories;
}
},
getOrdinalMeta: function () {
return this.__ordinalMeta;
},
defaultOption: __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.clone(__WEBPACK_IMPORTED_MODULE_1__axis3DDefault__["a" /* default */][axisType + 'Axis3D']),
extraDefaultOption || {},
true
)
});
});
// TODO
BaseAxisModelClass.superClass.registerSubTypeDefaulter(
dim + 'Axis3D',
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.curry(axisTypeDefaulter, dim)
);
});;
/***/ }),
/* 149 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
var defaultOption = {
show: true,
grid3DIndex: 0,
// 反向坐标轴
inverse: false,
// 坐标轴名字
name: '',
// 坐标轴名字位置
nameLocation: 'middle',
nameTextStyle: {
fontSize: 16
},
// 文字与轴线距离
nameGap: 20,
axisPointer: {},
axisLine: {},
// 坐标轴小标记
axisTick: {},
axisLabel: {},
// 分隔区域
splitArea: {}
};
var categoryAxis = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge({
// 类目起始和结束两端空白策略
boundaryGap: true,
// splitArea: {
// show: false
// },
// 坐标轴小标记
axisTick: {
// If tick is align with label when boundaryGap is true
// Default with axisTick
alignWithLabel: false,
interval: 'auto'
},
// 坐标轴文本标签,详见axis.axisLabel
axisLabel: {
interval: 'auto'
},
axisPointer: {
label: {
show: false
}
}
}, defaultOption);
var valueAxis = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge({
// 数值起始和结束两端空白策略
boundaryGap: [0, 0],
// 最小值, 设置成 'dataMin' 则从数据中计算最小值
// min: null,
// 最大值,设置成 'dataMax' 则从数据中计算最大值
// max: null,
// 脱离0值比例,放大聚焦到最终_min,_max区间
// scale: false,
// 分割段数,默认为5
splitNumber: 5,
// Minimum interval
// minInterval: null
axisPointer: {
label: {
}
}
}, defaultOption);
// FIXME
var timeAxis = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.defaults({
scale: true,
min: 'dataMin',
max: 'dataMax'
}, valueAxis);
var logAxis = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.defaults({
logBase: 10
}, valueAxis);
logAxis.scale = true;
/* harmony default export */ __webpack_exports__["a"] = ({
categoryAxis3D: categoryAxis,
valueAxis3D: valueAxis,
timeAxis3D: timeAxis,
logAxis3D: logAxis
});
/***/ }),
/* 150 */
/***/ (function(module, exports, __webpack_require__) {
var _util = __webpack_require__(12);
var createHashMap = _util.createHashMap;
var isObject = _util.isObject;
var map = _util.map;
/**
* @constructor
* @param {Object} [opt]
* @param {Object} [opt.categories=[]]
* @param {Object} [opt.needCollect=false]
* @param {Object} [opt.deduplication=false]
*/
function OrdinalMeta(opt) {
/**
* @readOnly
* @type {Array.}
*/
this.categories = opt.categories || [];
/**
* @private
* @type {boolean}
*/
this._needCollect = opt.needCollect;
/**
* @private
* @type {boolean}
*/
this._deduplication = opt.deduplication;
/**
* @private
* @type {boolean}
*/
this._map;
}
/**
* @param {module:echarts/model/Model} axisModel
* @return {module:echarts/data/OrdinalMeta}
*/
OrdinalMeta.createByAxisModel = function (axisModel) {
var option = axisModel.option;
var data = option.data;
var categories = data && map(data, getName);
return new OrdinalMeta({
categories: categories,
needCollect: !categories,
// deduplication is default in axis.
deduplication: option.dedplication !== false
});
};
var proto = OrdinalMeta.prototype;
/**
* @param {string} category
* @return {number} ordinal
*/
proto.getOrdinal = function (category) {
return getOrCreateMap(this).get(category);
};
/**
* @param {*} category
* @return {number} The ordinal. If not found, return NaN.
*/
proto.parseAndCollect = function (category) {
var index;
var needCollect = this._needCollect; // The value of category dim can be the index of the given category set.
// This feature is only supported when !needCollect, because we should
// consider a common case: a value is 2017, which is a number but is
// expected to be tread as a category. This case usually happen in dataset,
// where it happent to be no need of the index feature.
if (typeof category !== 'string' && !needCollect) {
return category;
} // Optimize for the scenario:
// category is ['2012-01-01', '2012-01-02', ...], where the input
// data has been ensured not duplicate and is large data.
// Notice, if a dataset dimension provide categroies, usually echarts
// should remove duplication except user tell echarts dont do that
// (set axis.deduplication = false), because echarts do not know whether
// the values in the category dimension has duplication (consider the
// parallel-aqi example)
if (needCollect && !this._deduplication) {
index = this.categories.length;
this.categories[index] = category;
return index;
}
var map = getOrCreateMap(this);
index = map.get(category);
if (index == null) {
if (needCollect) {
index = this.categories.length;
this.categories[index] = category;
map.set(category, index);
} else {
index = NaN;
}
}
return index;
}; // Consider big data, do not create map until needed.
function getOrCreateMap(ordinalMeta) {
return ordinalMeta._map || (ordinalMeta._map = createHashMap(ordinalMeta.categories));
}
function getName(obj) {
if (isObject(obj) && obj.value != null) {
return obj.value;
} else {
return obj + '';
}
}
var _default = OrdinalMeta;
module.exports = _default;
/***/ }),
/* 151 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__common_componentViewControlMixin__ = __webpack_require__(38);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__common_componentPostEffectMixin__ = __webpack_require__(25);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__common_componentLightMixin__ = __webpack_require__(26);
var Grid3DModel = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendComponentModel({
type: 'grid3D',
dependencies: ['xAxis3D', 'yAxis3D', 'zAxis3D'],
defaultOption: {
show: true,
zlevel: -10,
// Layout used for viewport
left: 0,
top: 0,
width: '100%',
height: '100%',
environment: 'auto',
// Dimension of grid3D
boxWidth: 100,
boxHeight: 100,
boxDepth: 100,
// Common axis options.
axisPointer: {
show: true,
lineStyle: {
color: 'rgba(0, 0, 0, 0.8)',
width: 1
},
label: {
show: true,
// (dimValue: number, value: Array) => string
formatter: null,
// TODO, Consider boxWidth
margin: 8,
// backgroundColor: '#ffbd67',
// borderColor: '#000',
// borderWidth: 0,
textStyle: {
fontSize: 14,
color: '#fff',
backgroundColor: 'rgba(0,0,0,0.5)',
padding: 3,
borderRadius: 3
}
}
},
axisLine: {
show: true,
lineStyle: {
color: '#333',
width: 2,
type: 'solid'
}
},
axisTick: {
show: true,
inside: false,
length: 3,
lineStyle: {
width: 1
}
},
axisLabel: {
show: true,
inside: false,
rotate: 0,
margin: 8,
textStyle: {
fontSize: 12
}
},
splitLine: {
show: true,
lineStyle: {
color: ['#ccc'],
width: 1,
type: 'solid'
}
},
splitArea: {
show: false,
areaStyle: {
color: ['rgba(250,250,250,0.3)','rgba(200,200,200,0.3)']
}
},
// Light options
light: {
main: {
// Alpha angle for top-down rotation
// Positive to rotate to top.
alpha: 30,
// beta angle for left-right rotation
// Positive to rotate to right.
beta: 40
},
ambient: {
intensity: 0.4
}
},
viewControl: {
// Small damping for precise control.
// damping: 0.1,
// Alpha angle for top-down rotation
// Positive to rotate to top.
alpha: 20,
// beta angle for left-right rotation
// Positive to rotate to right.
beta: 40,
autoRotate: false,
// Distance to the surface of grid3D.
distance: 200,
// Min distance to the surface of grid3D
minDistance: 40,
// Max distance to the surface of grid3D
maxDistance: 400
}
}
});
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Grid3DModel.prototype, __WEBPACK_IMPORTED_MODULE_1__common_componentViewControlMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Grid3DModel.prototype, __WEBPACK_IMPORTED_MODULE_2__common_componentPostEffectMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Grid3DModel.prototype, __WEBPACK_IMPORTED_MODULE_3__common_componentLightMixin__["a" /* default */]);
/* unused harmony default export */ var _unused_webpack_default_export = (Grid3DModel);
/***/ }),
/* 152 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_OrbitControl__ = __webpack_require__(39);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_geometry_Lines3D__ = __webpack_require__(22);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_retrieve__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__util_ZRTextureAtlasSurface__ = __webpack_require__(73);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__common_SceneHelper__ = __webpack_require__(27);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__Grid3DFace__ = __webpack_require__(153);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__Grid3DAxis__ = __webpack_require__(155);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__util_mesh_LabelsMesh__ = __webpack_require__(58);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__util_shader_lines3D_glsl_js__ = __webpack_require__(40);
// TODO orthographic camera
var firstNotNull = __WEBPACK_IMPORTED_MODULE_4__util_retrieve__["a" /* default */].firstNotNull;
__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.import(__WEBPACK_IMPORTED_MODULE_10__util_shader_lines3D_glsl_js__["a" /* default */]);
['x', 'y', 'z'].forEach(function (dim) {
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendComponentView({
type: dim + 'Axis3D'
});
});
var dimIndicesMap = {
// Left to right
x: 0,
// Far to near
y: 2,
// Bottom to up
z: 1
};
/* unused harmony default export */ var _unused_webpack_default_export = (__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendComponentView({
type: 'grid3D',
__ecgl__: true,
init: function (ecModel, api) {
var FACES = [
// planeDim0, planeDim1, offsetDim, dir on dim3 axis(gl), plane.
['y', 'z', 'x', -1, 'left'],
['y', 'z', 'x', 1, 'right'],
['x', 'y', 'z', -1, 'bottom'],
['x', 'y','z', 1, 'top'],
['x', 'z', 'y', -1, 'far'],
['x', 'z','y', 1, 'near']
];
var DIMS = ['x', 'y', 'z'];
var quadsMaterial = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
// transparent: true,
shader: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createShader('ecgl.color'),
depthMask: false,
transparent: true
});
var linesMaterial = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
// transparent: true,
shader: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createShader('ecgl.meshLines3D'),
depthMask: false,
transparent: true
});
quadsMaterial.define('fragment', 'DOUBLE_SIDED');
quadsMaterial.define('both', 'VERTEX_COLOR');
this.groupGL = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();
this._control = new __WEBPACK_IMPORTED_MODULE_2__util_OrbitControl__["a" /* default */]({
zr: api.getZr()
});
this._control.init();
// Save mesh and other infos for each face.
this._faces = FACES.map(function (faceInfo) {
var face = new __WEBPACK_IMPORTED_MODULE_7__Grid3DFace__["a" /* default */](faceInfo, linesMaterial, quadsMaterial);
this.groupGL.add(face.rootNode);
return face;
}, this);
// Save mesh and other infos for each axis.
this._axes = DIMS.map(function (dim) {
var axis = new __WEBPACK_IMPORTED_MODULE_8__Grid3DAxis__["a" /* default */](dim, linesMaterial);
this.groupGL.add(axis.rootNode);
return axis;
}, this);
var dpr = api.getDevicePixelRatio();
// Texture surface for label.
this._axisLabelSurface = new __WEBPACK_IMPORTED_MODULE_5__util_ZRTextureAtlasSurface__["a" /* default */]({
width: 256, height: 256,
devicePixelRatio: dpr
});
this._axisLabelSurface.onupdate = function () {
api.getZr().refresh();
};
this._axisPointerLineMesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
geometry: new __WEBPACK_IMPORTED_MODULE_3__util_geometry_Lines3D__["a" /* default */]({ useNativeLine: false }),
material: linesMaterial,
castShadow: false,
// PENDING
ignorePicking: true,
renderOrder: 3
});
this.groupGL.add(this._axisPointerLineMesh);
this._axisPointerLabelsSurface = new __WEBPACK_IMPORTED_MODULE_5__util_ZRTextureAtlasSurface__["a" /* default */]({
width: 128, height: 128,
devicePixelRatio: dpr
});
this._axisPointerLabelsMesh = new __WEBPACK_IMPORTED_MODULE_9__util_mesh_LabelsMesh__["a" /* default */]({
ignorePicking: true, renderOrder: 4,
castShadow: false
});
this._axisPointerLabelsMesh.material.set('textureAtlas', this._axisPointerLabelsSurface.getTexture());
this.groupGL.add(this._axisPointerLabelsMesh);
this._lightRoot = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();
this._sceneHelper = new __WEBPACK_IMPORTED_MODULE_6__common_SceneHelper__["a" /* default */]();
this._sceneHelper.initLight(this._lightRoot);
},
render: function (grid3DModel, ecModel, api) {
this._model = grid3DModel;
this._api = api;
var cartesian = grid3DModel.coordinateSystem;
// Always have light.
cartesian.viewGL.add(this._lightRoot);
if (grid3DModel.get('show')) {
cartesian.viewGL.add(this.groupGL);
}
else {
cartesian.viewGL.remove(this.groupGL);
}
// cartesian.viewGL.setCameraType(grid3DModel.get('viewControl.projection'));
var control = this._control;
control.setViewGL(cartesian.viewGL);
var viewControlModel = grid3DModel.getModel('viewControl');
control.setFromViewControlModel(viewControlModel, 0);
this._axisLabelSurface.clear();
var labelIntervalFuncs = ['x', 'y', 'z'].reduce(function (obj, axisDim) {
var axis = cartesian.getAxis(axisDim);
var axisModel = axis.model;
obj[axisDim] = firstNotNull(
axisModel.get('axisLabel.interval'),
grid3DModel.get('axisLabel.interval')
);
if (axis.scale.type === 'ordinal') {
// TODO consider label length
if (obj[axisDim] == null || obj[axisDim] == 'auto') {
obj[axisDim] = Math.floor(axis.scale.getTicks().length / 8);
}
}
return obj;
}, {});
control.off('update');
if (grid3DModel.get('show')) {
this._faces.forEach(function (face) {
face.update(labelIntervalFuncs, grid3DModel, ecModel, api);
}, this);
this._axes.forEach(function (axis) {
axis.update(grid3DModel, labelIntervalFuncs, this._axisLabelSurface, api);
}, this);
}
control.on('update', this._onCameraChange.bind(this, grid3DModel, api), this);
this._sceneHelper.setScene(cartesian.viewGL.scene);
this._sceneHelper.updateLight(grid3DModel);
// Set post effect
cartesian.viewGL.setPostEffect(grid3DModel.getModel('postEffect'), api);
cartesian.viewGL.setTemporalSuperSampling(grid3DModel.getModel('temporalSuperSampling'));
this._initMouseHandler(grid3DModel);
},
afterRender: function (grid3DModel, ecModel, api, layerGL) {
// Create ambient cubemap after render because we need to know the renderer.
// TODO
var renderer = layerGL.renderer;
this._sceneHelper.updateAmbientCubemap(renderer, grid3DModel, api);
this._sceneHelper.updateSkybox(renderer, grid3DModel, api);
},
/**
* showAxisPointer will be triggered by action.
*/
showAxisPointer: function (grid3dModel, ecModel, api, payload) {
this._doShowAxisPointer();
this._updateAxisPointer(payload.value);
},
/**
* hideAxisPointer will be triggered by action.
*/
hideAxisPointer: function (grid3dModel, ecModel, api, payload) {
this._doHideAxisPointer();
},
_initMouseHandler: function (grid3DModel) {
var cartesian = grid3DModel.coordinateSystem;
var viewGL = cartesian.viewGL;
// TODO xAxis3D.axisPointer.show ?
if (grid3DModel.get('show') && grid3DModel.get('axisPointer.show')) {
viewGL.on('mousemove', this._updateAxisPointerOnMousePosition, this);
}
else {
viewGL.off('mousemove', this._updateAxisPointerOnMousePosition);
}
},
/**
* Try find and show axisPointer on the intersect point
* of mouse ray with grid plane.
*/
_updateAxisPointerOnMousePosition: function (e) {
// Ignore if mouse is on the element.
if (e.target) {
return;
}
var grid3DModel = this._model;
var cartesian = grid3DModel.coordinateSystem;
var viewGL = cartesian.viewGL;
var ray = viewGL.castRay(e.offsetX, e.offsetY, new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Ray());
var nearestIntersectPoint;
for (var i = 0; i < this._faces.length; i++) {
var face = this._faces[i];
if (face.rootNode.invisible) {
continue;
}
// Plane is not face the camera. flip it
if (face.plane.normal.dot(viewGL.camera.worldTransform.z) < 0) {
face.plane.normal.negate();
}
var point = ray.intersectPlane(face.plane);
if (!point) {
continue;
}
var axis0 = cartesian.getAxis(face.faceInfo[0]);
var axis1 = cartesian.getAxis(face.faceInfo[1]);
var idx0 = dimIndicesMap[face.faceInfo[0]];
var idx1 = dimIndicesMap[face.faceInfo[1]];
if (axis0.contain(point.array[idx0]) && axis1.contain(point.array[idx1])) {
nearestIntersectPoint = point;
}
}
if (nearestIntersectPoint) {
var data = cartesian.pointToData(nearestIntersectPoint.array, [], true);
this._updateAxisPointer(data);
this._doShowAxisPointer();
}
else {
this._doHideAxisPointer();
}
},
_onCameraChange: function (grid3DModel, api) {
if (grid3DModel.get('show')) {
this._updateFaceVisibility();
this._updateAxisLinePosition();
}
var control = this._control;
api.dispatchAction({
type: 'grid3DChangeCamera',
alpha: control.getAlpha(),
beta: control.getBeta(),
distance: control.getDistance(),
center: control.getCenter(),
from: this.uid,
grid3DId: grid3DModel.id
});
},
/**
* Update visibility of each face when camera view changed, front face will be invisible.
* @private
*/
_updateFaceVisibility: function () {
var camera = this._control.getCamera();
var viewSpacePos = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Vector3();
camera.update();
for (var idx = 0; idx < this._faces.length / 2; idx++) {
var depths = [];
for (var k = 0; k < 2; k++) {
var face = this._faces[idx * 2 + k];
face.rootNode.getWorldPosition(viewSpacePos);
viewSpacePos.transformMat4(camera.viewMatrix);
depths[k] = viewSpacePos.z;
}
// Set the front face invisible
var frontIndex = depths[0] > depths[1] ? 0 : 1;
var frontFace = this._faces[idx * 2 + frontIndex];
var backFace = this._faces[idx * 2 + 1 - frontIndex];
// Update rotation.
frontFace.rootNode.invisible = true;
backFace.rootNode.invisible = false;
}
},
/**
* Update axis line position when camera view changed.
* @private
*/
_updateAxisLinePosition: function () {
// Put xAxis, yAxis on x, y visible plane.
// Put zAxis on the left.
// TODO
var cartesian = this._model.coordinateSystem;
var xAxis = cartesian.getAxis('x');
var yAxis = cartesian.getAxis('y');
var zAxis = cartesian.getAxis('z');
var top = zAxis.getExtentMax();
var bottom = zAxis.getExtentMin();
var left = xAxis.getExtentMin();
var right = xAxis.getExtentMax();
var near = yAxis.getExtentMax();
var far = yAxis.getExtentMin();
var xAxisNode = this._axes[0].rootNode;
var yAxisNode = this._axes[1].rootNode;
var zAxisNode = this._axes[2].rootNode;
var faces = this._faces;
// Notice: in cartesian up axis is z, but in webgl up axis is y.
var xAxisZOffset = (faces[4].rootNode.invisible ? far : near);
var xAxisYOffset = (faces[2].rootNode.invisible ? top : bottom);
var yAxisXOffset = (faces[0].rootNode.invisible ? left : right);
var yAxisYOffset = (faces[2].rootNode.invisible ? top : bottom);
var zAxisXOffset = (faces[0].rootNode.invisible ? right : left);
var zAxisZOffset = (faces[4].rootNode.invisible ? far : near);
xAxisNode.rotation.identity();
yAxisNode.rotation.identity();
zAxisNode.rotation.identity();
if (faces[4].rootNode.invisible) {
this._axes[0].flipped = true;
xAxisNode.rotation.rotateX(Math.PI);
}
if (faces[0].rootNode.invisible) {
this._axes[1].flipped = true;
yAxisNode.rotation.rotateZ(Math.PI);
}
if (faces[4].rootNode.invisible) {
this._axes[2].flipped = true;
zAxisNode.rotation.rotateY(Math.PI);
}
xAxisNode.position.set(0, xAxisYOffset, xAxisZOffset);
yAxisNode.position.set(yAxisXOffset, yAxisYOffset, 0); // Actually z
zAxisNode.position.set(zAxisXOffset, 0, zAxisZOffset); // Actually y
xAxisNode.update();
yAxisNode.update();
zAxisNode.update();
this._updateAxisLabelAlign();
},
/**
* Update label align on axis when axisLine position changed.
* @private
*/
_updateAxisLabelAlign: function () {
// var cartesian = this._model.coordinateSystem;
var camera = this._control.getCamera();
var coords = [new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Vector4(), new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Vector4()];
var center = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Vector4();
this.groupGL.getWorldPosition(center);
center.w = 1.0;
center.transformMat4(camera.viewMatrix)
.transformMat4(camera.projectionMatrix);
center.x /= center.w;
center.y /= center.w;
this._axes.forEach(function (axisInfo) {
var lineCoords = axisInfo.axisLineCoords;
var labelGeo = axisInfo.labelsMesh.geometry;
for (var i = 0; i < coords.length; i++) {
coords[i].setArray(lineCoords[i]);
coords[i].w = 1.0;
coords[i].transformMat4(axisInfo.rootNode.worldTransform)
.transformMat4(camera.viewMatrix)
.transformMat4(camera.projectionMatrix);
coords[i].x /= coords[i].w;
coords[i].y /= coords[i].w;
}
var dx = coords[1].x - coords[0].x;
var dy = coords[1].y - coords[0].y;
var cx = (coords[1].x + coords[0].x) / 2;
var cy = (coords[1].y + coords[0].y) / 2;
var textAlign;
var verticalAlign;
if (Math.abs(dy / dx) < 0.5) {
textAlign = 'center';
verticalAlign = cy > center.y ? 'bottom' : 'top';
}
else {
verticalAlign = 'middle';
textAlign = cx > center.x ? 'left' : 'right';
}
// axis labels
axisInfo.setSpriteAlign(textAlign, verticalAlign, this._api);
}, this);
},
_doShowAxisPointer: function () {
if (!this._axisPointerLineMesh.invisible) {
return;
}
this._axisPointerLineMesh.invisible = false;
this._axisPointerLabelsMesh.invisible = false;
this._api.getZr().refresh();
},
_doHideAxisPointer: function () {
if (this._axisPointerLineMesh.invisible) {
return;
}
this._axisPointerLineMesh.invisible = true;
this._axisPointerLabelsMesh.invisible = true;
this._api.getZr().refresh();
},
/**
* @private updateAxisPointer.
*/
_updateAxisPointer: function (data) {
var cartesian = this._model.coordinateSystem;
var point = cartesian.dataToPoint(data);
var axisPointerLineMesh = this._axisPointerLineMesh;
var linesGeo = axisPointerLineMesh.geometry;
var axisPointerParentModel = this._model.getModel('axisPointer');
var dpr = this._api.getDevicePixelRatio();
linesGeo.convertToDynamicArray(true);
function ifShowAxisPointer(axis) {
return __WEBPACK_IMPORTED_MODULE_4__util_retrieve__["a" /* default */].firstNotNull(
axis.model.get('axisPointer.show'),
axisPointerParentModel.get('show')
);
}
function getAxisColorAndLineWidth(axis) {
var axisPointerModel = axis.model.getModel('axisPointer', axisPointerParentModel);
var lineStyleModel = axisPointerModel.getModel('lineStyle');
var color = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(lineStyleModel.get('color'));
var lineWidth = firstNotNull(lineStyleModel.get('width'), 1);
var opacity = firstNotNull(lineStyleModel.get('opacity'), 1);
color[3] *= opacity;
return {
color: color,
lineWidth: lineWidth
};
}
for (var k = 0; k < this._faces.length; k++) {
var face = this._faces[k];
if (face.rootNode.invisible) {
continue;
}
var faceInfo = face.faceInfo;
var otherCoord = faceInfo[3] < 0
? cartesian.getAxis(faceInfo[2]).getExtentMin()
: cartesian.getAxis(faceInfo[2]).getExtentMax();
var otherDimIdx = dimIndicesMap[faceInfo[2]];
// Line on face.
for (var i = 0; i < 2; i++) {
var dim = faceInfo[i];
var faceOtherDim = faceInfo[1 - i];
var axis = cartesian.getAxis(dim);
var faceOtherAxis = cartesian.getAxis(faceOtherDim);
if (!ifShowAxisPointer(axis)) {
continue;
}
var p0 = [0, 0, 0]; var p1 = [0, 0, 0];
var dimIdx = dimIndicesMap[dim];
var faceOtherDimIdx = dimIndicesMap[faceOtherDim];
p0[dimIdx] = p1[dimIdx] = point[dimIdx];
p0[otherDimIdx] = p1[otherDimIdx] = otherCoord;
p0[faceOtherDimIdx] = faceOtherAxis.getExtentMin();
p1[faceOtherDimIdx] = faceOtherAxis.getExtentMax();
var colorAndLineWidth = getAxisColorAndLineWidth(axis);
linesGeo.addLine(p0, p1, colorAndLineWidth.color, colorAndLineWidth.lineWidth * dpr);
}
// Project line.
if (ifShowAxisPointer(cartesian.getAxis(faceInfo[2]))) {
var p0 = point.slice();
var p1 = point.slice();
p1[otherDimIdx] = otherCoord;
var colorAndLineWidth = getAxisColorAndLineWidth(cartesian.getAxis(faceInfo[2]));
linesGeo.addLine(p0, p1, colorAndLineWidth.color, colorAndLineWidth.lineWidth * dpr);
}
}
linesGeo.convertToTypedArray();
this._updateAxisPointerLabelsMesh(data);
this._api.getZr().refresh();
},
_updateAxisPointerLabelsMesh: function (data) {
var grid3dModel = this._model;
var axisPointerLabelsMesh = this._axisPointerLabelsMesh;
var axisPointerLabelsSurface = this._axisPointerLabelsSurface;
var cartesian = grid3dModel.coordinateSystem;
var axisPointerParentModel = grid3dModel.getModel('axisPointer');
axisPointerLabelsMesh.geometry.convertToDynamicArray(true);
axisPointerLabelsSurface.clear();
var otherDim = {
x: 'y', y: 'x', z: 'y'
};
this._axes.forEach(function (axisInfo, idx) {
var axis = cartesian.getAxis(axisInfo.dim);
var axisModel = axis.model;
var axisPointerModel = axisModel.getModel('axisPointer', axisPointerParentModel);
var labelModel = axisPointerModel.getModel('label');
var lineColor = axisPointerModel.get('lineStyle.color');
if (!labelModel.get('show') || !axisPointerModel.get('show')) {
return;
}
var val = data[idx];
var formatter = labelModel.get('formatter');
var text = axis.scale.getLabel(val);
if (formatter != null) {
text = formatter(text, data);
}
else {
if (axis.scale.type === 'interval' || axis.scale.type === 'log') {
var precision = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.number.getPrecisionSafe(axis.scale.getTicks()[0]);
text = val.toFixed(precision + 2);
}
}
var textStyleModel = labelModel.getModel('textStyle');
var labelColor = textStyleModel.get('color');
var textEl = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.graphic.Text();
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.graphic.setTextStyle(textEl.style, textStyleModel, {
text: text,
textFill: labelColor || lineColor,
textAlign: 'left',
textVerticalAlign: 'top'
});
var coords = axisPointerLabelsSurface.add(textEl);
var rect = textEl.getBoundingRect();
var dpr = this._api.getDevicePixelRatio();
var pos = axisInfo.rootNode.position.toArray();
var otherIdx = dimIndicesMap[otherDim[axisInfo.dim]];
pos[otherIdx] += (axisInfo.flipped ? -1 : 1) * labelModel.get('margin');
pos[dimIndicesMap[axisInfo.dim]] = axis.dataToCoord(data[idx]);
axisPointerLabelsMesh.geometry.addSprite(
pos, [rect.width * dpr, rect.height * dpr], coords,
axisInfo.textAlign, axisInfo.textVerticalAlign
);
}, this);
axisPointerLabelsSurface.getZr().refreshImmediately();
axisPointerLabelsMesh.material.set('uvScale', axisPointerLabelsSurface.getCoordsScale());
axisPointerLabelsMesh.geometry.convertToTypedArray();
},
dispose: function () {
this.groupGL.removeAll();
this._control.dispose();
}
}));
/***/ }),
/* 153 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_retrieve__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_geometry_Lines3D__ = __webpack_require__(22);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_geometry_Quads__ = __webpack_require__(154);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__ifIgnoreOnTick__ = __webpack_require__(74);
var firstNotNull = __WEBPACK_IMPORTED_MODULE_2__util_retrieve__["a" /* default */].firstNotNull;
var dimIndicesMap = {
// Left to right
x: 0,
// Far to near
y: 2,
// Bottom to up
z: 1
};
function updateFacePlane(node, plane, otherAxis, dir) {
var coord = [0, 0, 0];
var distance = dir < 0 ? otherAxis.getExtentMin() : otherAxis.getExtentMax();
coord[dimIndicesMap[otherAxis.dim]] = distance;
node.position.setArray(coord);
node.rotation.identity();
// Negative distance because on the opposite of normal direction.
plane.distance = -Math.abs(distance);
plane.normal.set(0, 0, 0);
if (otherAxis.dim === 'x') {
node.rotation.rotateY(dir * Math.PI / 2);
plane.normal.x = -dir;
}
else if (otherAxis.dim === 'z') {
node.rotation.rotateX(-dir * Math.PI / 2);
plane.normal.y = -dir;
}
else {
if (dir > 0) {
node.rotation.rotateY(Math.PI);
}
plane.normal.z = -dir;
}
}
function Grid3DFace(faceInfo, linesMaterial, quadsMaterial) {
this.rootNode = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();
var linesMesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
geometry: new __WEBPACK_IMPORTED_MODULE_3__util_geometry_Lines3D__["a" /* default */]({ useNativeLine: false }),
material: linesMaterial,
castShadow: false,
ignorePicking: true,
$ignorePicking: true,
renderOrder: 1
});
var quadsMesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
geometry: new __WEBPACK_IMPORTED_MODULE_4__util_geometry_Quads__["a" /* default */](),
material: quadsMaterial,
castShadow: false,
culling: false,
ignorePicking: true,
$ignorePicking: true,
renderOrder: 0
});
// Quads are behind lines.
this.rootNode.add(quadsMesh);
this.rootNode.add(linesMesh);
this.faceInfo = faceInfo;
this.plane =new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Plane();
this.linesMesh =linesMesh;
this.quadsMesh =quadsMesh;
}
Grid3DFace.prototype.update = function (labelIntervalFuncs, grid3DModel, ecModel, api) {
var cartesian = grid3DModel.coordinateSystem;
var axes = [
cartesian.getAxis(this.faceInfo[0]),
cartesian.getAxis(this.faceInfo[1])
];
var lineGeometry = this.linesMesh.geometry;
var quadsGeometry = this.quadsMesh.geometry;
lineGeometry.convertToDynamicArray(true);
quadsGeometry.convertToDynamicArray(true);
this._updateSplitLines(lineGeometry, axes, grid3DModel, labelIntervalFuncs, api);
this._udpateSplitAreas(quadsGeometry, axes, grid3DModel, labelIntervalFuncs, api);
lineGeometry.convertToTypedArray();
quadsGeometry.convertToTypedArray();
var otherAxis = cartesian.getAxis(this.faceInfo[2]);
updateFacePlane(this.rootNode, this.plane, otherAxis, this.faceInfo[3]);
};
Grid3DFace.prototype._updateSplitLines = function (geometry, axes, grid3DModel, labelIntervalFuncs, api) {
var dpr = api.getDevicePixelRatio();
axes.forEach(function (axis, idx) {
var axisModel = axis.model;
var otherExtent = axes[1 - idx].getExtent();
if (axis.scale.isBlank()) {
return;
}
var splitLineModel = axisModel.getModel('splitLine', grid3DModel.getModel('splitLine'));
// Render splitLines
if (splitLineModel.get('show')) {
var lineStyleModel = splitLineModel.getModel('lineStyle');
var lineColors = lineStyleModel.get('color');
var opacity = firstNotNull(lineStyleModel.get('opacity'), 1.0);
var lineWidth = firstNotNull(lineStyleModel.get('width'), 1.0);
// TODO Automatic interval
var intervalFunc = splitLineModel.get('interval');
if (intervalFunc == null || intervalFunc === 'auto') {
intervalFunc = labelIntervalFuncs[axis.dim];
}
lineColors = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.isArray(lineColors) ? lineColors : [lineColors];
var ticksCoords = axis.getTicksCoords();
var count = 0;
for (var i = 0; i < ticksCoords.length; i++) {
if (Object(__WEBPACK_IMPORTED_MODULE_5__ifIgnoreOnTick__["a" /* default */])(axis, i, intervalFunc)) {
continue;
}
var tickCoord = ticksCoords[i];
var lineColor = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(lineColors[count % lineColors.length]);
lineColor[3] *= opacity;
var p0 = [0, 0, 0]; var p1 = [0, 0, 0];
// 0 - x, 1 - y
p0[idx] = p1[idx] = tickCoord;
p0[1 - idx] = otherExtent[0];
p1[1 - idx] = otherExtent[1];
geometry.addLine(p0, p1, lineColor, lineWidth * dpr);
count++;
}
}
});
};
Grid3DFace.prototype._udpateSplitAreas = function (geometry, axes, grid3DModel, labelIntervalFuncs, api) {
axes.forEach(function (axis, idx) {
var axisModel = axis.model;
var otherExtent = axes[1 - idx].getExtent();
if (axis.scale.isBlank()) {
return;
}
var splitAreaModel = axisModel.getModel('splitArea', grid3DModel.getModel('splitArea'));
// Render splitAreas
if (splitAreaModel.get('show')) {
var areaStyleModel = splitAreaModel.getModel('areaStyle');
var colors = areaStyleModel.get('color');
var opacity = firstNotNull(areaStyleModel.get('opacity'), 1.0);
// TODO Automatic interval
var intervalFunc = splitAreaModel.get('interval');
if (intervalFunc == null || intervalFunc === 'auto') {
intervalFunc = labelIntervalFuncs[axis.dim];
}
colors = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.isArray(colors) ? colors : [colors];
var ticksCoords = axis.getTicksCoords();
var count = 0;
var prevP0 = [0, 0, 0];
var prevP1 = [0, 0, 0];
// 0 - x, 1 - y
for (var i = 0; i < ticksCoords.length; i++) {
var tickCoord = ticksCoords[i];
var p0 = [0, 0, 0]; var p1 = [0, 0, 0];
// 0 - x, 1 - y
p0[idx] = p1[idx] = tickCoord;
p0[1 - idx] = otherExtent[0];
p1[1 - idx] = otherExtent[1];
if (i === 0) {
prevP0 = p0;
prevP1 = p1;
continue;
}
if (Object(__WEBPACK_IMPORTED_MODULE_5__ifIgnoreOnTick__["a" /* default */])(axis, i, intervalFunc)) {
continue;
}
var color = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(colors[count % colors.length]);
color[3] *= opacity;
geometry.addQuad([prevP0, p0, p1, prevP1], color);
prevP0 = p0;
prevP1 = p1;
count++;
}
}
});
};
/* harmony default export */ __webpack_exports__["a"] = (Grid3DFace);
/***/ }),
/* 154 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__ = __webpack_require__(13);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__dynamicConvertMixin__ = __webpack_require__(34);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix__);
/**
* @module echarts-gl/util/geometry/QuadsGeometry
* @author Yi Shen(http://github.com/pissang)
*/
var vec3 = __WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix___default.a.vec3;
/**
* @constructor
* @alias module:echarts-gl/util/geometry/QuadsGeometry
* @extends clay.Geometry
*/
var QuadsGeometry = __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].extend(function () {
return {
segmentScale: 1,
/**
* Need to use mesh to expand lines if lineWidth > MAX_LINE_WIDTH
*/
useNativeLine: true,
attributes: {
position: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('position', 'float', 3, 'POSITION'),
normal: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('normal', 'float', 3, 'NORMAL'),
color: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('color', 'float', 4, 'COLOR')
}
};
},
/** @lends module: echarts-gl/util/geometry/QuadsGeometry.prototype */
{
/**
* Reset offset
*/
resetOffset: function () {
this._vertexOffset = 0;
this._faceOffset = 0;
},
/**
* @param {number} nQuad
*/
setQuadCount: function (nQuad) {
var attributes = this.attributes;
var vertexCount = this.getQuadVertexCount() * nQuad;
var triangleCount = this.getQuadTriangleCount() * nQuad;
if (this.vertexCount !== vertexCount) {
attributes.position.init(vertexCount);
attributes.normal.init(vertexCount);
attributes.color.init(vertexCount);
}
if (this.triangleCount !== triangleCount) {
this.indices = vertexCount > 0xffff ? new Uint32Array(triangleCount * 3) : new Uint16Array(triangleCount * 3);
}
},
getQuadVertexCount: function () {
return 4;
},
getQuadTriangleCount: function () {
return 2;
},
/**
* Add a quad, which in following order:
* 0-----1
* 3-----2
*/
addQuad: (function () {
var a = vec3.create();
var b = vec3.create();
var normal = vec3.create();
var indices = [0, 3, 1, 3, 2, 1];
return function (coords, color) {
var positionAttr = this.attributes.position;
var normalAttr = this.attributes.normal;
var colorAttr = this.attributes.color;
vec3.sub(a, coords[1], coords[0]);
vec3.sub(b, coords[2], coords[1]);
vec3.cross(normal, a, b);
vec3.normalize(normal, normal);
for (var i = 0; i < 4; i++) {
positionAttr.set(this._vertexOffset + i, coords[i]);
colorAttr.set(this._vertexOffset + i, color);
normalAttr.set(this._vertexOffset + i, normal);
}
var idx = this._faceOffset * 3;
for (var i = 0; i < 6; i++) {
this.indices[idx + i] = indices[i] + this._vertexOffset;
}
this._vertexOffset += 4;
this._faceOffset += 2;
};
})()
});
__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default.a.util.defaults(QuadsGeometry.prototype, __WEBPACK_IMPORTED_MODULE_2__dynamicConvertMixin__["a" /* default */]);
/* harmony default export */ __webpack_exports__["a"] = (QuadsGeometry);
/***/ }),
/* 155 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_geometry_Lines3D__ = __webpack_require__(22);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_retrieve__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_mesh_LabelsMesh__ = __webpack_require__(58);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__ifIgnoreOnTick__ = __webpack_require__(74);
var firstNotNull = __WEBPACK_IMPORTED_MODULE_3__util_retrieve__["a" /* default */].firstNotNull;
var dimIndicesMap = {
// Left to right
x: 0,
// Far to near
y: 2,
// Bottom to up
z: 1
};
function Grid3DAxis(dim, linesMaterial) {
var linesMesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
geometry: new __WEBPACK_IMPORTED_MODULE_2__util_geometry_Lines3D__["a" /* default */]({ useNativeLine: false }),
material: linesMaterial,
castShadow: false,
ignorePicking: true, renderOrder: 2
});
var axisLabelsMesh = new __WEBPACK_IMPORTED_MODULE_4__util_mesh_LabelsMesh__["a" /* default */]();
axisLabelsMesh.material.depthMask = false;
var rootNode = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();
rootNode.add(linesMesh);
rootNode.add(axisLabelsMesh);
this.rootNode = rootNode;
this.dim = dim;
this.linesMesh = linesMesh;
this.labelsMesh = axisLabelsMesh;
this.axisLineCoords = null;
this.labelElements = [];
}
var otherDim = {
x: 'y', y: 'x', z: 'y'
};
Grid3DAxis.prototype.update = function (
grid3DModel, labelIntervalFuncs, axisLabelSurface, api
) {
var cartesian = grid3DModel.coordinateSystem;
var axis = cartesian.getAxis(this.dim);
var labelIntervalFunc = labelIntervalFuncs[this.dim];
var linesGeo = this.linesMesh.geometry;
var labelsGeo = this.labelsMesh.geometry;
linesGeo.convertToDynamicArray(true);
labelsGeo.convertToDynamicArray(true);
var axisModel = axis.model;
var extent = axis.getExtent();
var dpr = api.getDevicePixelRatio();
var axisLineModel = axisModel.getModel('axisLine', grid3DModel.getModel('axisLine'));
var axisTickModel = axisModel.getModel('axisTick', grid3DModel.getModel('axisTick'));
var axisLabelModel = axisModel.getModel('axisLabel', grid3DModel.getModel('axisLabel'));
var axisLineColor = axisLineModel.get('lineStyle.color');
// Render axisLine
if (axisLineModel.get('show')) {
var axisLineStyleModel = axisLineModel.getModel('lineStyle');
var p0 = [0, 0, 0]; var p1 = [0, 0, 0];
var idx = dimIndicesMap[axis.dim];
p0[idx] = extent[0];
p1[idx] = extent[1];
// Save some useful info.
this.axisLineCoords =[p0, p1];
var color = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(axisLineColor);
var lineWidth = firstNotNull(axisLineStyleModel.get('width'), 1.0);
var opacity = firstNotNull(axisLineStyleModel.get('opacity'), 1.0);
color[3] *= opacity;
linesGeo.addLine(p0, p1, color, lineWidth * dpr);
}
// Render axis ticksCoords
if (axisTickModel.get('show')) {
var lineStyleModel = axisTickModel.getModel('lineStyle');
var lineColor = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(
firstNotNull(lineStyleModel.get('color'), axisLineColor)
);
var lineWidth = firstNotNull(lineStyleModel.get('width'), 1.0);
lineColor[3] *= firstNotNull(lineStyleModel.get('opacity'), 1.0);
var ticksCoords = axis.getTicksCoords();
// TODO Automatic interval
var intervalFunc = axisTickModel.get('interval');
if (intervalFunc == null || intervalFunc === 'auto') {
intervalFunc = labelIntervalFunc;
}
var tickLength = axisTickModel.get('length');
for (var i = 0; i < ticksCoords.length; i++) {
if (Object(__WEBPACK_IMPORTED_MODULE_5__ifIgnoreOnTick__["a" /* default */])(axis, i, intervalFunc)) {
continue;
}
var tickCoord = ticksCoords[i];
var p0 = [0, 0, 0]; var p1 = [0, 0, 0];
var idx = dimIndicesMap[axis.dim];
var otherIdx = dimIndicesMap[otherDim[axis.dim]];
// 0 : x, 1 : y
p0[idx] = p1[idx] = tickCoord;
p1[otherIdx] = tickLength;
linesGeo.addLine(p0, p1, lineColor, lineWidth * dpr);
}
}
this.labelElements = [];
var dpr = api.getDevicePixelRatio();
if (axisLabelModel.get('show')) {
var labelsCoords = axis.getLabelsCoords();
var categoryData = axisModel.get('data');
// TODO Automatic interval
var intervalFunc = labelIntervalFunc;
var labelMargin = axisLabelModel.get('margin');
var labels = axisModel.getFormattedLabels();
var ticks = axis.scale.getTicks();
for (var i = 0; i < labelsCoords.length; i++) {
if (Object(__WEBPACK_IMPORTED_MODULE_5__ifIgnoreOnTick__["a" /* default */])(axis, i, intervalFunc)) {
continue;
}
var tickCoord = labelsCoords[i];
var p = [0, 0, 0];
var idx = dimIndicesMap[axis.dim];
var otherIdx = dimIndicesMap[otherDim[axis.dim]];
// 0 : x, 1 : y
p[idx] = p[idx] = tickCoord;
p[otherIdx] = labelMargin;
var itemTextStyleModel = axisLabelModel;
if (categoryData && categoryData[ticks[i]] && categoryData[ticks[i]].textStyle) {
itemTextStyleModel = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.Model(
categoryData[ticks[i]].textStyle, axisLabelModel, axisModel.ecModel
);
}
var textColor = firstNotNull(itemTextStyleModel.get('color'), axisLineColor);
var textEl = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.graphic.Text();
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.graphic.setTextStyle(textEl.style, itemTextStyleModel, {
text: labels[i],
textFill: typeof textColor === 'function'
? textColor(
// (1) In category axis with data zoom, tick is not the original
// index of axis.data. So tick should not be exposed to user
// in category axis.
// (2) Compatible with previous version, which always returns labelStr.
// But in interval scale labelStr is like '223,445', which maked
// user repalce ','. So we modify it to return original val but remain
// it as 'string' to avoid error in replacing.
axis.type === 'category' ? labels[i] : axis.type === 'value' ? ticks[i] + '' : ticks[i],
i
)
: textColor,
textVerticalAlign: 'top',
textAlign: 'left'
});
var coords = axisLabelSurface.add(textEl);
var rect = textEl.getBoundingRect();
labelsGeo.addSprite(p, [rect.width * dpr, rect.height * dpr], coords);
this.labelElements.push(textEl);
}
}
if (axisModel.get('name')) {
var nameTextStyleModel = axisModel.getModel('nameTextStyle');
var p = [0, 0, 0];
var idx = dimIndicesMap[axis.dim];
var otherIdx = dimIndicesMap[otherDim[axis.dim]];
var labelColor = firstNotNull(nameTextStyleModel.get('color'), axisLineColor);
var strokeColor = nameTextStyleModel.get('borderColor');
var lineWidth = nameTextStyleModel.get('borderWidth');
// TODO start and end
p[idx] = p[idx] = (extent[0] + extent[1]) / 2;
p[otherIdx] = axisModel.get('nameGap');
var textEl = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.graphic.Text();
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.graphic.setTextStyle(textEl.style, nameTextStyleModel, {
text: axisModel.get('name'),
textFill: labelColor,
textStroke: strokeColor,
lineWidth: lineWidth
});
var coords = axisLabelSurface.add(textEl);
var rect = textEl.getBoundingRect();
labelsGeo.addSprite(p, [rect.width * dpr, rect.height * dpr], coords);
textEl.__idx = this.labelElements.length;
this.nameLabelElement = textEl;
}
this.labelsMesh.material.set('textureAtlas', axisLabelSurface.getTexture());
this.labelsMesh.material.set('uvScale', axisLabelSurface.getCoordsScale());
linesGeo.convertToTypedArray();
labelsGeo.convertToTypedArray();
};
Grid3DAxis.prototype.setSpriteAlign = function (textAlign, textVerticalAlign, api) {
var dpr = api.getDevicePixelRatio();
var labelGeo = this.labelsMesh.geometry;
for (var i = 0; i < this.labelElements.length; i++) {
var labelEl = this.labelElements[i];
var rect = labelEl.getBoundingRect();
labelGeo.setSpriteAlign(i, [rect.width * dpr, rect.height * dpr], textAlign, textVerticalAlign);
}
// name label
var nameLabelEl = this.nameLabelElement;
if (nameLabelEl) {
var rect = nameLabelEl.getBoundingRect();
labelGeo.setSpriteAlign(nameLabelEl.__idx, [rect.width * dpr, rect.height * dpr], textAlign, textVerticalAlign);
labelGeo.dirty();
}
this.textAlign = textAlign;
this.textVerticalAlign = textVerticalAlign;
};
/* harmony default export */ __webpack_exports__["a"] = (Grid3DAxis);
/***/ }),
/* 156 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_Geometry__ = __webpack_require__(13);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__dynamicConvertMixin__ = __webpack_require__(34);
/**
* Geometry collecting sprites
*
* @module echarts-gl/util/geometry/Sprites
* @author Yi Shen(https://github.com/pissang)
*/
var squareTriangles = [
0, 1, 2, 0, 2, 3
];
var SpritesGeometry = __WEBPACK_IMPORTED_MODULE_1_claygl_src_Geometry__["a" /* default */].extend(function () {
return {
attributes: {
position: new __WEBPACK_IMPORTED_MODULE_1_claygl_src_Geometry__["a" /* default */].Attribute('position', 'float', 3, 'POSITION'),
texcoord: new __WEBPACK_IMPORTED_MODULE_1_claygl_src_Geometry__["a" /* default */].Attribute('texcoord', 'float', 2, 'TEXCOORD_0'),
offset: new __WEBPACK_IMPORTED_MODULE_1_claygl_src_Geometry__["a" /* default */].Attribute('offset', 'float', 2),
color: new __WEBPACK_IMPORTED_MODULE_1_claygl_src_Geometry__["a" /* default */].Attribute('color', 'float', 4, 'COLOR')
}
};
}, {
resetOffset: function () {
this._vertexOffset = 0;
this._faceOffset = 0;
},
setSpriteCount: function (spriteCount) {
this._spriteCount = spriteCount;
var vertexCount = spriteCount * 4;
var triangleCount = spriteCount * 2;
if (this.vertexCount !== vertexCount) {
this.attributes.position.init(vertexCount);
this.attributes.offset.init(vertexCount);
this.attributes.color.init(vertexCount);
}
if (this.triangleCount !== triangleCount) {
this.indices = vertexCount > 0xffff ? new Uint32Array(triangleCount * 3) : new Uint16Array(triangleCount * 3);
}
},
setSpriteAlign: function (spriteOffset, size, align, verticalAlign, margin) {
if (align == null) {
align = 'left';
}
if (verticalAlign == null) {
verticalAlign = 'top';
}
var leftOffset, topOffset, rightOffset, bottomOffset;
margin = margin || 0;
switch (align) {
case 'left':
leftOffset = margin;
rightOffset = size[0] + margin;
break;
case 'center':
case 'middle':
leftOffset = -size[0] / 2;
rightOffset = size[0] / 2;
break;
case 'right':
leftOffset = -size[0] - margin;
rightOffset = -margin;
break;
}
switch (verticalAlign) {
case 'bottom':
topOffset = margin;
bottomOffset = size[1] + margin;
break;
case 'middle':
topOffset = -size[1] / 2;
bottomOffset = size[1] / 2;
break;
case 'top':
topOffset = -size[1] - margin;
bottomOffset = -margin;
break;
}
// 3----2
// 0----1
var vertexOffset = spriteOffset * 4;
var offsetAttr = this.attributes.offset;
offsetAttr.set(vertexOffset, [leftOffset, bottomOffset]);
offsetAttr.set(vertexOffset + 1, [rightOffset, bottomOffset]);
offsetAttr.set(vertexOffset + 2, [rightOffset, topOffset]);
offsetAttr.set(vertexOffset + 3, [leftOffset, topOffset]);
},
/**
* Add sprite
* @param {Array.} position
* @param {Array.} size [width, height]
* @param {Array.} coords [leftBottom, rightTop]
* @param {string} [align='left'] 'left' 'center' 'right'
* @param {string} [verticalAlign='top'] 'top' 'middle' 'bottom'
* @param {number} [screenMargin=0]
*/
addSprite: function (position, size, coords, align, verticalAlign, screenMargin) {
var vertexOffset = this._vertexOffset;
this.setSprite(
this._vertexOffset / 4, position, size, coords, align, verticalAlign, screenMargin
)
for (var i = 0; i < squareTriangles.length; i++) {
this.indices[this._faceOffset * 3 + i] = squareTriangles[i] + vertexOffset;
}
this._faceOffset += 2;
this._vertexOffset += 4;
return vertexOffset / 4;
},
setSprite: function (spriteOffset, position, size, coords, align, verticalAlign, screenMargin) {
var vertexOffset = spriteOffset * 4;
var attributes = this.attributes;
for (var i = 0; i < 4; i++) {
attributes.position.set(vertexOffset + i, position);
}
// 3----2
// 0----1
var texcoordAttr = attributes.texcoord;
texcoordAttr.set(vertexOffset, [coords[0][0], coords[0][1]]);
texcoordAttr.set(vertexOffset + 1, [coords[1][0], coords[0][1]]);
texcoordAttr.set(vertexOffset + 2, [coords[1][0], coords[1][1]]);
texcoordAttr.set(vertexOffset + 3, [coords[0][0], coords[1][1]]);
this.setSpriteAlign(spriteOffset, size, align, verticalAlign, screenMargin);
}
});
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.defaults(SpritesGeometry.prototype, __WEBPACK_IMPORTED_MODULE_2__dynamicConvertMixin__["a" /* default */]);
/* harmony default export */ __webpack_exports__["a"] = (SpritesGeometry);
/***/ }),
/* 157 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.labels.vertex\n\nattribute vec3 position: POSITION;\nattribute vec2 texcoord: TEXCOORD_0;\nattribute vec2 offset;\n#ifdef VERTEX_COLOR\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n#endif\n\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform vec4 viewport : VIEWPORT;\n\nvarying vec2 v_Texcoord;\n\nvoid main()\n{\n vec4 proj = worldViewProjection * vec4(position, 1.0);\n\n vec2 screen = (proj.xy / abs(proj.w) + 1.0) * 0.5 * viewport.zw;\n\n screen += offset;\n\n proj.xy = (screen / viewport.zw - 0.5) * 2.0 * abs(proj.w);\n gl_Position = proj;\n#ifdef VERTEX_COLOR\n v_Color = a_Color;\n#endif\n v_Texcoord = texcoord;\n}\n@end\n\n\n@export ecgl.labels.fragment\n\nuniform vec3 color : [1.0, 1.0, 1.0];\nuniform float alpha : 1.0;\nuniform sampler2D textureAtlas;\nuniform vec2 uvScale: [1.0, 1.0];\n\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\nvarying float v_Miter;\n\nvarying vec2 v_Texcoord;\n\nvoid main()\n{\n gl_FragColor = vec4(color, alpha) * texture2D(textureAtlas, v_Texcoord * uvScale);\n#ifdef VERTEX_COLOR\n gl_FragColor *= v_Color;\n#endif\n}\n\n@end");
/***/ }),
/* 158 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__grid3D_Cartesian3D__ = __webpack_require__(159);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__grid3D_Axis3D__ = __webpack_require__(161);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_echarts_lib_util_layout__ = __webpack_require__(41);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_echarts_lib_util_layout___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_echarts_lib_util_layout__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__core_ViewGL__ = __webpack_require__(19);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__util_retrieve__ = __webpack_require__(3);
function resizeCartesian3D(grid3DModel, api) {
// Use left/top/width/height
var boxLayoutOption = grid3DModel.getBoxLayoutParams();
var viewport = __WEBPACK_IMPORTED_MODULE_3_echarts_lib_util_layout___default.a.getLayoutRect(boxLayoutOption, {
width: api.getWidth(),
height: api.getHeight()
});
// Flip Y
viewport.y = api.getHeight() - viewport.y - viewport.height;
this.viewGL.setViewport(viewport.x, viewport.y, viewport.width, viewport.height, api.getDevicePixelRatio());
var boxWidth = grid3DModel.get('boxWidth');
var boxHeight = grid3DModel.get('boxHeight');
var boxDepth = grid3DModel.get('boxDepth');
if (true) {
['x', 'y', 'z'].forEach(function (dim) {
if (!this.getAxis(dim)) {
throw new Error('Grid' + grid3DModel.id + ' don\'t have ' + dim + 'Axis');
}
}, this);
}
this.getAxis('x').setExtent(-boxWidth / 2, boxWidth / 2);
// From near to far
this.getAxis('y').setExtent(boxDepth / 2, -boxDepth / 2);
this.getAxis('z').setExtent(-boxHeight / 2, boxHeight / 2);
this.size = [boxWidth, boxHeight, boxDepth];
}
function updateCartesian3D(ecModel, api) {
var dataExtents = {};
function unionDataExtents(dim, extent) {
dataExtents[dim] = dataExtents[dim] || [Infinity, -Infinity];
dataExtents[dim][0] = Math.min(extent[0], dataExtents[dim][0]);
dataExtents[dim][1] = Math.max(extent[1], dataExtents[dim][1]);
}
// Get data extents for scale.
ecModel.eachSeries(function (seriesModel) {
if (seriesModel.coordinateSystem !== this) {
return;
}
var data = seriesModel.getData();
['x', 'y', 'z'].forEach(function (coordDim) {
data.mapDimension(coordDim, true).forEach(function (dataDim) {
unionDataExtents(
coordDim, data.getDataExtent(dataDim, true)
);
});
});
}, this);
['xAxis3D', 'yAxis3D', 'zAxis3D'].forEach(function (axisType) {
ecModel.eachComponent(axisType, function (axisModel) {
var dim = axisType.charAt(0);
var grid3DModel = axisModel.getReferringComponents('grid3D')[0];
var cartesian3D = grid3DModel.coordinateSystem;
if (cartesian3D !== this) {
return;
}
var axis = cartesian3D.getAxis(dim);
if (axis) {
if (true) {
console.warn('Can\'t have two %s in one grid3D', axisType);
}
return;
}
var scale = __WEBPACK_IMPORTED_MODULE_2_echarts_lib_echarts___default.a.helper.createScale(
dataExtents[dim] || [Infinity, -Infinity], axisModel
);
axis = new __WEBPACK_IMPORTED_MODULE_1__grid3D_Axis3D__["a" /* default */](dim, scale);
axis.type = axisModel.get('type');
var isCategory = axis.type === 'category';
axis.onBand = isCategory && axisModel.get('boundaryGap');
axis.inverse = axisModel.get('inverse');
axisModel.axis = axis;
axis.model = axisModel;
cartesian3D.addAxis(axis);
}, this);
}, this);
this.resize(this.model, api);
}
var grid3DCreator = {
dimensions: __WEBPACK_IMPORTED_MODULE_0__grid3D_Cartesian3D__["a" /* default */].prototype.dimensions,
create: function (ecModel, api) {
var cartesian3DList = [];
ecModel.eachComponent('grid3D', function (grid3DModel) {
// FIXME
grid3DModel.__viewGL = grid3DModel.__viewGL || new __WEBPACK_IMPORTED_MODULE_4__core_ViewGL__["a" /* default */]();
var cartesian3D = new __WEBPACK_IMPORTED_MODULE_0__grid3D_Cartesian3D__["a" /* default */]();
cartesian3D.model = grid3DModel;
cartesian3D.viewGL = grid3DModel.__viewGL;
grid3DModel.coordinateSystem = cartesian3D;
cartesian3DList.push(cartesian3D);
// Inject resize and update
cartesian3D.resize = resizeCartesian3D;
cartesian3D.update = updateCartesian3D;
});
var axesTypes = ['xAxis3D', 'yAxis3D', 'zAxis3D'];
function findAxesModels(seriesModel, ecModel) {
return axesTypes.map(function (axisType) {
var axisModel = seriesModel.getReferringComponents(axisType)[0];
if (axisModel == null) {
axisModel = ecModel.getComponent(axisType);
}
if (true) {
if (!axisModel) {
throw new Error(axisType + ' "' + __WEBPACK_IMPORTED_MODULE_5__util_retrieve__["a" /* default */].firstNotNull(
seriesModel.get(axisType + 'Index'),
seriesModel.get(axisType + 'Id'),
0
) + '" not found');
}
}
return axisModel;
});
}
ecModel.eachSeries(function (seriesModel) {
if (seriesModel.get('coordinateSystem') !== 'cartesian3D') {
return;
}
var firstGridModel = seriesModel.getReferringComponents('grid3D')[0];
if (firstGridModel == null) {
var axesModels = findAxesModels(seriesModel, ecModel);
var firstGridModel = axesModels[0].getCoordSysModel();
axesModels.forEach(function (axisModel) {
var grid3DModel = axisModel.getCoordSysModel();
if (true) {
if (!grid3DModel) {
throw new Error(
'grid3D "' + __WEBPACK_IMPORTED_MODULE_5__util_retrieve__["a" /* default */].firstNotNull(
axisModel.get('gridIndex'),
axisModel.get('gridId'),
0
) + '" not found'
);
}
if (grid3DModel !== firstGridModel) {
throw new Error('xAxis3D, yAxis3D, zAxis3D must use the same grid');
}
}
});
}
var coordSys = firstGridModel.coordinateSystem;
seriesModel.coordinateSystem = coordSys;
});
return cartesian3DList;
}
};
__WEBPACK_IMPORTED_MODULE_2_echarts_lib_echarts___default.a.registerCoordinateSystem('grid3D', grid3DCreator);
/* unused harmony default export */ var _unused_webpack_default_export = (grid3DCreator);
/***/ }),
/* 159 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_coord_cartesian_Cartesian__ = __webpack_require__(160);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_coord_cartesian_Cartesian___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_echarts_lib_coord_cartesian_Cartesian__);
function Cartesian3D(name) {
__WEBPACK_IMPORTED_MODULE_1_echarts_lib_coord_cartesian_Cartesian___default.a.call(this, name);
this.size = [0, 0, 0];
}
Cartesian3D.prototype = {
constructor: Cartesian3D,
type: 'cartesian3D',
dimensions: ['x', 'y', 'z'],
model: null,
containPoint: function (point) {
return this.getAxis('x').contain(point[0])
&& this.getAxis('y').contain(point[2])
&& this.getAxis('z').contain(point[1]);
},
containData: function (data) {
return this.getAxis('x').containData(data[0])
&& this.getAxis('y').containData(data[1])
&& this.getAxis('z').containData(data[2]);
},
dataToPoint: function (data, out, clamp) {
out = out || [];
out[0] = this.getAxis('x').dataToCoord(data[0], clamp);
out[2] = this.getAxis('y').dataToCoord(data[1], clamp);
out[1] = this.getAxis('z').dataToCoord(data[2], clamp);
return out;
},
pointToData: function (point, out, clamp) {
out = out || [];
out[0] = this.getAxis('x').coordToData(point[0], clamp);
out[1] = this.getAxis('y').coordToData(point[2], clamp);
out[2] = this.getAxis('z').coordToData(point[1], clamp);
return out;
}
};
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.inherits(Cartesian3D, __WEBPACK_IMPORTED_MODULE_1_echarts_lib_coord_cartesian_Cartesian___default.a);
/* harmony default export */ __webpack_exports__["a"] = (Cartesian3D);
/***/ }),
/* 160 */
/***/ (function(module, exports, __webpack_require__) {
var zrUtil = __webpack_require__(12);
/**
* Cartesian coordinate system
* @module echarts/coord/Cartesian
*
*/
function dimAxisMapper(dim) {
return this._axes[dim];
}
/**
* @alias module:echarts/coord/Cartesian
* @constructor
*/
var Cartesian = function (name) {
this._axes = {};
this._dimList = [];
/**
* @type {string}
*/
this.name = name || '';
};
Cartesian.prototype = {
constructor: Cartesian,
type: 'cartesian',
/**
* Get axis
* @param {number|string} dim
* @return {module:echarts/coord/Cartesian~Axis}
*/
getAxis: function (dim) {
return this._axes[dim];
},
/**
* Get axes list
* @return {Array.}
*/
getAxes: function () {
return zrUtil.map(this._dimList, dimAxisMapper, this);
},
/**
* Get axes list by given scale type
*/
getAxesByScale: function (scaleType) {
scaleType = scaleType.toLowerCase();
return zrUtil.filter(this.getAxes(), function (axis) {
return axis.scale.type === scaleType;
});
},
/**
* Add axis
* @param {module:echarts/coord/Cartesian.Axis}
*/
addAxis: function (axis) {
var dim = axis.dim;
this._axes[dim] = axis;
this._dimList.push(dim);
},
/**
* Convert data to coord in nd space
* @param {Array.|Object.} val
* @return {Array.|Object.}
*/
dataToCoord: function (val) {
return this._dataCoordConvert(val, 'dataToCoord');
},
/**
* Convert coord in nd space to data
* @param {Array.|Object.} val
* @return {Array.|Object.}
*/
coordToData: function (val) {
return this._dataCoordConvert(val, 'coordToData');
},
_dataCoordConvert: function (input, method) {
var dimList = this._dimList;
var output = input instanceof Array ? [] : {};
for (var i = 0; i < dimList.length; i++) {
var dim = dimList[i];
var axis = this._axes[dim];
output[dim] = axis[method](input[dim]);
}
return output;
}
};
var _default = Cartesian;
module.exports = _default;
/***/ }),
/* 161 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
function Axis3D(dim, scale, extent) {
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.Axis.call(this, dim, scale, extent);
}
Axis3D.prototype = {
constructor: Axis3D,
getExtentMin: function () {
var extent = this._extent;
return Math.min(extent[0], extent[1]);
},
getExtentMax: function () {
var extent = this._extent;
return Math.max(extent[0], extent[1]);
}
};
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.inherits(Axis3D, __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.Axis);
/* harmony default export */ __webpack_exports__["a"] = (Axis3D);
/***/ }),
/* 162 */
/***/ (function(module, exports, __webpack_require__) {
var zrUtil = __webpack_require__(12);
var textContain = __webpack_require__(163);
var numberUtil = __webpack_require__(78);
/**
* 每三位默认加,格式化
* @param {string|number} x
* @return {string}
*/
function addCommas(x) {
if (isNaN(x)) {
return '-';
}
x = (x + '').split('.');
return x[0].replace(/(\d{1,3})(?=(?:\d{3})+(?!\d))/g, '$1,') + (x.length > 1 ? '.' + x[1] : '');
}
/**
* @param {string} str
* @param {boolean} [upperCaseFirst=false]
* @return {string} str
*/
function toCamelCase(str, upperCaseFirst) {
str = (str || '').toLowerCase().replace(/-(.)/g, function (match, group1) {
return group1.toUpperCase();
});
if (upperCaseFirst && str) {
str = str.charAt(0).toUpperCase() + str.slice(1);
}
return str;
}
var normalizeCssArray = zrUtil.normalizeCssArray;
function encodeHTML(source) {
return String(source).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"').replace(/'/g, ''');
}
var TPL_VAR_ALIAS = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
var wrapVar = function (varName, seriesIdx) {
return '{' + varName + (seriesIdx == null ? '' : seriesIdx) + '}';
};
/**
* Template formatter
* @param {string} tpl
* @param {Array.|Object} paramsList
* @param {boolean} [encode=false]
* @return {string}
*/
function formatTpl(tpl, paramsList, encode) {
if (!zrUtil.isArray(paramsList)) {
paramsList = [paramsList];
}
var seriesLen = paramsList.length;
if (!seriesLen) {
return '';
}
var $vars = paramsList[0].$vars || [];
for (var i = 0; i < $vars.length; i++) {
var alias = TPL_VAR_ALIAS[i];
tpl = tpl.replace(wrapVar(alias), wrapVar(alias, 0));
}
for (var seriesIdx = 0; seriesIdx < seriesLen; seriesIdx++) {
for (var k = 0; k < $vars.length; k++) {
var val = paramsList[seriesIdx][$vars[k]];
tpl = tpl.replace(wrapVar(TPL_VAR_ALIAS[k], seriesIdx), encode ? encodeHTML(val) : val);
}
}
return tpl;
}
/**
* simple Template formatter
*
* @param {string} tpl
* @param {Object} param
* @param {boolean} [encode=false]
* @return {string}
*/
function formatTplSimple(tpl, param, encode) {
zrUtil.each(param, function (value, key) {
tpl = tpl.replace('{' + key + '}', encode ? encodeHTML(value) : value);
});
return tpl;
}
/**
* @param {Object|string} [opt] If string, means color.
* @param {string} [opt.color]
* @param {string} [opt.extraCssText]
* @param {string} [opt.type='item'] 'item' or 'subItem'
* @return {string}
*/
function getTooltipMarker(opt, extraCssText) {
opt = zrUtil.isString(opt) ? {
color: opt,
extraCssText: extraCssText
} : opt || {};
var color = opt.color;
var type = opt.type;
var extraCssText = opt.extraCssText;
if (!color) {
return '';
}
return type === 'subItem' ? ' ' : ' ';
}
function pad(str, len) {
str += '';
return '0000'.substr(0, len - str.length) + str;
}
/**
* ISO Date format
* @param {string} tpl
* @param {number} value
* @param {boolean} [isUTC=false] Default in local time.
* see `module:echarts/scale/Time`
* and `module:echarts/util/number#parseDate`.
* @inner
*/
function formatTime(tpl, value, isUTC) {
if (tpl === 'week' || tpl === 'month' || tpl === 'quarter' || tpl === 'half-year' || tpl === 'year') {
tpl = 'MM-dd\nyyyy';
}
var date = numberUtil.parseDate(value);
var utc = isUTC ? 'UTC' : '';
var y = date['get' + utc + 'FullYear']();
var M = date['get' + utc + 'Month']() + 1;
var d = date['get' + utc + 'Date']();
var h = date['get' + utc + 'Hours']();
var m = date['get' + utc + 'Minutes']();
var s = date['get' + utc + 'Seconds']();
var S = date['get' + utc + 'Milliseconds']();
tpl = tpl.replace('MM', pad(M, 2)).replace('M', M).replace('yyyy', y).replace('yy', y % 100).replace('dd', pad(d, 2)).replace('d', d).replace('hh', pad(h, 2)).replace('h', h).replace('mm', pad(m, 2)).replace('m', m).replace('ss', pad(s, 2)).replace('s', s).replace('SSS', pad(S, 3));
return tpl;
}
/**
* Capital first
* @param {string} str
* @return {string}
*/
function capitalFirst(str) {
return str ? str.charAt(0).toUpperCase() + str.substr(1) : str;
}
var truncateText = textContain.truncateText;
var getTextRect = textContain.getBoundingRect;
exports.addCommas = addCommas;
exports.toCamelCase = toCamelCase;
exports.normalizeCssArray = normalizeCssArray;
exports.encodeHTML = encodeHTML;
exports.formatTpl = formatTpl;
exports.formatTplSimple = formatTplSimple;
exports.getTooltipMarker = getTooltipMarker;
exports.formatTime = formatTime;
exports.capitalFirst = capitalFirst;
exports.truncateText = truncateText;
exports.getTextRect = getTextRect;
/***/ }),
/* 163 */
/***/ (function(module, exports, __webpack_require__) {
var BoundingRect = __webpack_require__(75);
var imageHelper = __webpack_require__(164);
var _util = __webpack_require__(12);
var getContext = _util.getContext;
var extend = _util.extend;
var retrieve2 = _util.retrieve2;
var retrieve3 = _util.retrieve3;
var trim = _util.trim;
var textWidthCache = {};
var textWidthCacheCounter = 0;
var TEXT_CACHE_MAX = 5000;
var STYLE_REG = /\{([a-zA-Z0-9_]+)\|([^}]*)\}/g;
var DEFAULT_FONT = '12px sans-serif'; // Avoid assign to an exported variable, for transforming to cjs.
var methods = {};
function $override(name, fn) {
methods[name] = fn;
}
/**
* @public
* @param {string} text
* @param {string} font
* @return {number} width
*/
function getWidth(text, font) {
font = font || DEFAULT_FONT;
var key = text + ':' + font;
if (textWidthCache[key]) {
return textWidthCache[key];
}
var textLines = (text + '').split('\n');
var width = 0;
for (var i = 0, l = textLines.length; i < l; i++) {
// textContain.measureText may be overrided in SVG or VML
width = Math.max(measureText(textLines[i], font).width, width);
}
if (textWidthCacheCounter > TEXT_CACHE_MAX) {
textWidthCacheCounter = 0;
textWidthCache = {};
}
textWidthCacheCounter++;
textWidthCache[key] = width;
return width;
}
/**
* @public
* @param {string} text
* @param {string} font
* @param {string} [textAlign='left']
* @param {string} [textVerticalAlign='top']
* @param {Array.} [textPadding]
* @param {Object} [rich]
* @param {Object} [truncate]
* @return {Object} {x, y, width, height, lineHeight}
*/
function getBoundingRect(text, font, textAlign, textVerticalAlign, textPadding, rich, truncate) {
return rich ? getRichTextRect(text, font, textAlign, textVerticalAlign, textPadding, rich, truncate) : getPlainTextRect(text, font, textAlign, textVerticalAlign, textPadding, truncate);
}
function getPlainTextRect(text, font, textAlign, textVerticalAlign, textPadding, truncate) {
var contentBlock = parsePlainText(text, font, textPadding, truncate);
var outerWidth = getWidth(text, font);
if (textPadding) {
outerWidth += textPadding[1] + textPadding[3];
}
var outerHeight = contentBlock.outerHeight;
var x = adjustTextX(0, outerWidth, textAlign);
var y = adjustTextY(0, outerHeight, textVerticalAlign);
var rect = new BoundingRect(x, y, outerWidth, outerHeight);
rect.lineHeight = contentBlock.lineHeight;
return rect;
}
function getRichTextRect(text, font, textAlign, textVerticalAlign, textPadding, rich, truncate) {
var contentBlock = parseRichText(text, {
rich: rich,
truncate: truncate,
font: font,
textAlign: textAlign,
textPadding: textPadding
});
var outerWidth = contentBlock.outerWidth;
var outerHeight = contentBlock.outerHeight;
var x = adjustTextX(0, outerWidth, textAlign);
var y = adjustTextY(0, outerHeight, textVerticalAlign);
return new BoundingRect(x, y, outerWidth, outerHeight);
}
/**
* @public
* @param {number} x
* @param {number} width
* @param {string} [textAlign='left']
* @return {number} Adjusted x.
*/
function adjustTextX(x, width, textAlign) {
// FIXME Right to left language
if (textAlign === 'right') {
x -= width;
} else if (textAlign === 'center') {
x -= width / 2;
}
return x;
}
/**
* @public
* @param {number} y
* @param {number} height
* @param {string} [textVerticalAlign='top']
* @return {number} Adjusted y.
*/
function adjustTextY(y, height, textVerticalAlign) {
if (textVerticalAlign === 'middle') {
y -= height / 2;
} else if (textVerticalAlign === 'bottom') {
y -= height;
}
return y;
}
/**
* @public
* @param {stirng} textPosition
* @param {Object} rect {x, y, width, height}
* @param {number} distance
* @return {Object} {x, y, textAlign, textVerticalAlign}
*/
function adjustTextPositionOnRect(textPosition, rect, distance) {
var x = rect.x;
var y = rect.y;
var height = rect.height;
var width = rect.width;
var halfHeight = height / 2;
var textAlign = 'left';
var textVerticalAlign = 'top';
switch (textPosition) {
case 'left':
x -= distance;
y += halfHeight;
textAlign = 'right';
textVerticalAlign = 'middle';
break;
case 'right':
x += distance + width;
y += halfHeight;
textVerticalAlign = 'middle';
break;
case 'top':
x += width / 2;
y -= distance;
textAlign = 'center';
textVerticalAlign = 'bottom';
break;
case 'bottom':
x += width / 2;
y += height + distance;
textAlign = 'center';
break;
case 'inside':
x += width / 2;
y += halfHeight;
textAlign = 'center';
textVerticalAlign = 'middle';
break;
case 'insideLeft':
x += distance;
y += halfHeight;
textVerticalAlign = 'middle';
break;
case 'insideRight':
x += width - distance;
y += halfHeight;
textAlign = 'right';
textVerticalAlign = 'middle';
break;
case 'insideTop':
x += width / 2;
y += distance;
textAlign = 'center';
break;
case 'insideBottom':
x += width / 2;
y += height - distance;
textAlign = 'center';
textVerticalAlign = 'bottom';
break;
case 'insideTopLeft':
x += distance;
y += distance;
break;
case 'insideTopRight':
x += width - distance;
y += distance;
textAlign = 'right';
break;
case 'insideBottomLeft':
x += distance;
y += height - distance;
textVerticalAlign = 'bottom';
break;
case 'insideBottomRight':
x += width - distance;
y += height - distance;
textAlign = 'right';
textVerticalAlign = 'bottom';
break;
}
return {
x: x,
y: y,
textAlign: textAlign,
textVerticalAlign: textVerticalAlign
};
}
/**
* Show ellipsis if overflow.
*
* @public
* @param {string} text
* @param {string} containerWidth
* @param {string} font
* @param {number} [ellipsis='...']
* @param {Object} [options]
* @param {number} [options.maxIterations=3]
* @param {number} [options.minChar=0] If truncate result are less
* then minChar, ellipsis will not show, which is
* better for user hint in some cases.
* @param {number} [options.placeholder=''] When all truncated, use the placeholder.
* @return {string}
*/
function truncateText(text, containerWidth, font, ellipsis, options) {
if (!containerWidth) {
return '';
}
var textLines = (text + '').split('\n');
options = prepareTruncateOptions(containerWidth, font, ellipsis, options); // FIXME
// It is not appropriate that every line has '...' when truncate multiple lines.
for (var i = 0, len = textLines.length; i < len; i++) {
textLines[i] = truncateSingleLine(textLines[i], options);
}
return textLines.join('\n');
}
function prepareTruncateOptions(containerWidth, font, ellipsis, options) {
options = extend({}, options);
options.font = font;
var ellipsis = retrieve2(ellipsis, '...');
options.maxIterations = retrieve2(options.maxIterations, 2);
var minChar = options.minChar = retrieve2(options.minChar, 0); // FIXME
// Other languages?
options.cnCharWidth = getWidth('国', font); // FIXME
// Consider proportional font?
var ascCharWidth = options.ascCharWidth = getWidth('a', font);
options.placeholder = retrieve2(options.placeholder, ''); // Example 1: minChar: 3, text: 'asdfzxcv', truncate result: 'asdf', but not: 'a...'.
// Example 2: minChar: 3, text: '维度', truncate result: '维', but not: '...'.
var contentWidth = containerWidth = Math.max(0, containerWidth - 1); // Reserve some gap.
for (var i = 0; i < minChar && contentWidth >= ascCharWidth; i++) {
contentWidth -= ascCharWidth;
}
var ellipsisWidth = getWidth(ellipsis);
if (ellipsisWidth > contentWidth) {
ellipsis = '';
ellipsisWidth = 0;
}
contentWidth = containerWidth - ellipsisWidth;
options.ellipsis = ellipsis;
options.ellipsisWidth = ellipsisWidth;
options.contentWidth = contentWidth;
options.containerWidth = containerWidth;
return options;
}
function truncateSingleLine(textLine, options) {
var containerWidth = options.containerWidth;
var font = options.font;
var contentWidth = options.contentWidth;
if (!containerWidth) {
return '';
}
var lineWidth = getWidth(textLine, font);
if (lineWidth <= containerWidth) {
return textLine;
}
for (var j = 0;; j++) {
if (lineWidth <= contentWidth || j >= options.maxIterations) {
textLine += options.ellipsis;
break;
}
var subLength = j === 0 ? estimateLength(textLine, contentWidth, options.ascCharWidth, options.cnCharWidth) : lineWidth > 0 ? Math.floor(textLine.length * contentWidth / lineWidth) : 0;
textLine = textLine.substr(0, subLength);
lineWidth = getWidth(textLine, font);
}
if (textLine === '') {
textLine = options.placeholder;
}
return textLine;
}
function estimateLength(text, contentWidth, ascCharWidth, cnCharWidth) {
var width = 0;
var i = 0;
for (var len = text.length; i < len && width < contentWidth; i++) {
var charCode = text.charCodeAt(i);
width += 0 <= charCode && charCode <= 127 ? ascCharWidth : cnCharWidth;
}
return i;
}
/**
* @public
* @param {string} font
* @return {number} line height
*/
function getLineHeight(font) {
// FIXME A rough approach.
return getWidth('国', font);
}
/**
* @public
* @param {string} text
* @param {string} font
* @return {Object} width
*/
function measureText(text, font) {
return methods.measureText(text, font);
} // Avoid assign to an exported variable, for transforming to cjs.
methods.measureText = function (text, font) {
var ctx = getContext();
ctx.font = font || DEFAULT_FONT;
return ctx.measureText(text);
};
/**
* @public
* @param {string} text
* @param {string} font
* @param {Object} [truncate]
* @return {Object} block: {lineHeight, lines, height, outerHeight}
* Notice: for performance, do not calculate outerWidth util needed.
*/
function parsePlainText(text, font, padding, truncate) {
text != null && (text += '');
var lineHeight = getLineHeight(font);
var lines = text ? text.split('\n') : [];
var height = lines.length * lineHeight;
var outerHeight = height;
if (padding) {
outerHeight += padding[0] + padding[2];
}
if (text && truncate) {
var truncOuterHeight = truncate.outerHeight;
var truncOuterWidth = truncate.outerWidth;
if (truncOuterHeight != null && outerHeight > truncOuterHeight) {
text = '';
lines = [];
} else if (truncOuterWidth != null) {
var options = prepareTruncateOptions(truncOuterWidth - (padding ? padding[1] + padding[3] : 0), font, truncate.ellipsis, {
minChar: truncate.minChar,
placeholder: truncate.placeholder
}); // FIXME
// It is not appropriate that every line has '...' when truncate multiple lines.
for (var i = 0, len = lines.length; i < len; i++) {
lines[i] = truncateSingleLine(lines[i], options);
}
}
}
return {
lines: lines,
height: height,
outerHeight: outerHeight,
lineHeight: lineHeight
};
}
/**
* For example: 'some text {a|some text}other text{b|some text}xxx{c|}xxx'
* Also consider 'bbbb{a|xxx\nzzz}xxxx\naaaa'.
*
* @public
* @param {string} text
* @param {Object} style
* @return {Object} block
* {
* width,
* height,
* lines: [{
* lineHeight,
* width,
* tokens: [[{
* styleName,
* text,
* width, // include textPadding
* height, // include textPadding
* textWidth, // pure text width
* textHeight, // pure text height
* lineHeihgt,
* font,
* textAlign,
* textVerticalAlign
* }], [...], ...]
* }, ...]
* }
* If styleName is undefined, it is plain text.
*/
function parseRichText(text, style) {
var contentBlock = {
lines: [],
width: 0,
height: 0
};
text != null && (text += '');
if (!text) {
return contentBlock;
}
var lastIndex = STYLE_REG.lastIndex = 0;
var result;
while ((result = STYLE_REG.exec(text)) != null) {
var matchedIndex = result.index;
if (matchedIndex > lastIndex) {
pushTokens(contentBlock, text.substring(lastIndex, matchedIndex));
}
pushTokens(contentBlock, result[2], result[1]);
lastIndex = STYLE_REG.lastIndex;
}
if (lastIndex < text.length) {
pushTokens(contentBlock, text.substring(lastIndex, text.length));
}
var lines = contentBlock.lines;
var contentHeight = 0;
var contentWidth = 0; // For `textWidth: 100%`
var pendingList = [];
var stlPadding = style.textPadding;
var truncate = style.truncate;
var truncateWidth = truncate && truncate.outerWidth;
var truncateHeight = truncate && truncate.outerHeight;
if (stlPadding) {
truncateWidth != null && (truncateWidth -= stlPadding[1] + stlPadding[3]);
truncateHeight != null && (truncateHeight -= stlPadding[0] + stlPadding[2]);
} // Calculate layout info of tokens.
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
var lineHeight = 0;
var lineWidth = 0;
for (var j = 0; j < line.tokens.length; j++) {
var token = line.tokens[j];
var tokenStyle = token.styleName && style.rich[token.styleName] || {}; // textPadding should not inherit from style.
var textPadding = token.textPadding = tokenStyle.textPadding; // textFont has been asigned to font by `normalizeStyle`.
var font = token.font = tokenStyle.font || style.font; // textHeight can be used when textVerticalAlign is specified in token.
var tokenHeight = token.textHeight = retrieve2( // textHeight should not be inherited, consider it can be specified
// as box height of the block.
tokenStyle.textHeight, getLineHeight(font));
textPadding && (tokenHeight += textPadding[0] + textPadding[2]);
token.height = tokenHeight;
token.lineHeight = retrieve3(tokenStyle.textLineHeight, style.textLineHeight, tokenHeight);
token.textAlign = tokenStyle && tokenStyle.textAlign || style.textAlign;
token.textVerticalAlign = tokenStyle && tokenStyle.textVerticalAlign || 'middle';
if (truncateHeight != null && contentHeight + token.lineHeight > truncateHeight) {
return {
lines: [],
width: 0,
height: 0
};
}
token.textWidth = getWidth(token.text, font);
var tokenWidth = tokenStyle.textWidth;
var tokenWidthNotSpecified = tokenWidth == null || tokenWidth === 'auto'; // Percent width, can be `100%`, can be used in drawing separate
// line when box width is needed to be auto.
if (typeof tokenWidth === 'string' && tokenWidth.charAt(tokenWidth.length - 1) === '%') {
token.percentWidth = tokenWidth;
pendingList.push(token);
tokenWidth = 0; // Do not truncate in this case, because there is no user case
// and it is too complicated.
} else {
if (tokenWidthNotSpecified) {
tokenWidth = token.textWidth; // FIXME: If image is not loaded and textWidth is not specified, calling
// `getBoundingRect()` will not get correct result.
var textBackgroundColor = tokenStyle.textBackgroundColor;
var bgImg = textBackgroundColor && textBackgroundColor.image; // Use cases:
// (1) If image is not loaded, it will be loaded at render phase and call
// `dirty()` and `textBackgroundColor.image` will be replaced with the loaded
// image, and then the right size will be calculated here at the next tick.
// See `graphic/helper/text.js`.
// (2) If image loaded, and `textBackgroundColor.image` is image src string,
// use `imageHelper.findExistImage` to find cached image.
// `imageHelper.findExistImage` will always be called here before
// `imageHelper.createOrUpdateImage` in `graphic/helper/text.js#renderRichText`
// which ensures that image will not be rendered before correct size calcualted.
if (bgImg) {
bgImg = imageHelper.findExistImage(bgImg);
if (imageHelper.isImageReady(bgImg)) {
tokenWidth = Math.max(tokenWidth, bgImg.width * tokenHeight / bgImg.height);
}
}
}
var paddingW = textPadding ? textPadding[1] + textPadding[3] : 0;
tokenWidth += paddingW;
var remianTruncWidth = truncateWidth != null ? truncateWidth - lineWidth : null;
if (remianTruncWidth != null && remianTruncWidth < tokenWidth) {
if (!tokenWidthNotSpecified || remianTruncWidth < paddingW) {
token.text = '';
token.textWidth = tokenWidth = 0;
} else {
token.text = truncateText(token.text, remianTruncWidth - paddingW, font, truncate.ellipsis, {
minChar: truncate.minChar
});
token.textWidth = getWidth(token.text, font);
tokenWidth = token.textWidth + paddingW;
}
}
}
lineWidth += token.width = tokenWidth;
tokenStyle && (lineHeight = Math.max(lineHeight, token.lineHeight));
}
line.width = lineWidth;
line.lineHeight = lineHeight;
contentHeight += lineHeight;
contentWidth = Math.max(contentWidth, lineWidth);
}
contentBlock.outerWidth = contentBlock.width = retrieve2(style.textWidth, contentWidth);
contentBlock.outerHeight = contentBlock.height = retrieve2(style.textHeight, contentHeight);
if (stlPadding) {
contentBlock.outerWidth += stlPadding[1] + stlPadding[3];
contentBlock.outerHeight += stlPadding[0] + stlPadding[2];
}
for (var i = 0; i < pendingList.length; i++) {
var token = pendingList[i];
var percentWidth = token.percentWidth; // Should not base on outerWidth, because token can not be placed out of padding.
token.width = parseInt(percentWidth, 10) / 100 * contentWidth;
}
return contentBlock;
}
function pushTokens(block, str, styleName) {
var isEmptyStr = str === '';
var strs = str.split('\n');
var lines = block.lines;
for (var i = 0; i < strs.length; i++) {
var text = strs[i];
var token = {
styleName: styleName,
text: text,
isLineHolder: !text && !isEmptyStr
}; // The first token should be appended to the last line.
if (!i) {
var tokens = (lines[lines.length - 1] || (lines[0] = {
tokens: []
})).tokens; // Consider cases:
// (1) ''.split('\n') => ['', '\n', ''], the '' at the first item
// (which is a placeholder) should be replaced by new token.
// (2) A image backage, where token likes {a|}.
// (3) A redundant '' will affect textAlign in line.
// (4) tokens with the same tplName should not be merged, because
// they should be displayed in different box (with border and padding).
var tokensLen = tokens.length;
tokensLen === 1 && tokens[0].isLineHolder ? tokens[0] = token : // Consider text is '', only insert when it is the "lineHolder" or
// "emptyStr". Otherwise a redundant '' will affect textAlign in line.
(text || !tokensLen || isEmptyStr) && tokens.push(token);
} // Other tokens always start a new line.
else {
// If there is '', insert it as a placeholder.
lines.push({
tokens: [token]
});
}
}
}
function makeFont(style) {
// FIXME in node-canvas fontWeight is before fontStyle
// Use `fontSize` `fontFamily` to check whether font properties are defined.
var font = (style.fontSize || style.fontFamily) && [style.fontStyle, style.fontWeight, (style.fontSize || 12) + 'px', // If font properties are defined, `fontFamily` should not be ignored.
style.fontFamily || 'sans-serif'].join(' ');
return font && trim(font) || style.textFont || style.font;
}
exports.DEFAULT_FONT = DEFAULT_FONT;
exports.$override = $override;
exports.getWidth = getWidth;
exports.getBoundingRect = getBoundingRect;
exports.adjustTextX = adjustTextX;
exports.adjustTextY = adjustTextY;
exports.adjustTextPositionOnRect = adjustTextPositionOnRect;
exports.truncateText = truncateText;
exports.getLineHeight = getLineHeight;
exports.measureText = measureText;
exports.parsePlainText = parsePlainText;
exports.parseRichText = parseRichText;
exports.makeFont = makeFont;
/***/ }),
/* 164 */
/***/ (function(module, exports, __webpack_require__) {
var LRU = __webpack_require__(53);
var globalImageCache = new LRU(50);
/**
* @param {string|HTMLImageElement|HTMLCanvasElement|Canvas} newImageOrSrc
* @return {HTMLImageElement|HTMLCanvasElement|Canvas} image
*/
function findExistImage(newImageOrSrc) {
if (typeof newImageOrSrc === 'string') {
var cachedImgObj = globalImageCache.get(newImageOrSrc);
return cachedImgObj && cachedImgObj.image;
} else {
return newImageOrSrc;
}
}
/**
* Caution: User should cache loaded images, but not just count on LRU.
* Consider if required images more than LRU size, will dead loop occur?
*
* @param {string|HTMLImageElement|HTMLCanvasElement|Canvas} newImageOrSrc
* @param {HTMLImageElement|HTMLCanvasElement|Canvas} image Existent image.
* @param {module:zrender/Element} [hostEl] For calling `dirty`.
* @param {Function} [cb] params: (image, cbPayload)
* @param {Object} [cbPayload] Payload on cb calling.
* @return {HTMLImageElement|HTMLCanvasElement|Canvas} image
*/
function createOrUpdateImage(newImageOrSrc, image, hostEl, cb, cbPayload) {
if (!newImageOrSrc) {
return image;
} else if (typeof newImageOrSrc === 'string') {
// Image should not be loaded repeatly.
if (image && image.__zrImageSrc === newImageOrSrc || !hostEl) {
return image;
} // Only when there is no existent image or existent image src
// is different, this method is responsible for load.
var cachedImgObj = globalImageCache.get(newImageOrSrc);
var pendingWrap = {
hostEl: hostEl,
cb: cb,
cbPayload: cbPayload
};
if (cachedImgObj) {
image = cachedImgObj.image;
!isImageReady(image) && cachedImgObj.pending.push(pendingWrap);
} else {
!image && (image = new Image());
image.onload = imageOnLoad;
globalImageCache.put(newImageOrSrc, image.__cachedImgObj = {
image: image,
pending: [pendingWrap]
});
image.src = image.__zrImageSrc = newImageOrSrc;
}
return image;
} // newImageOrSrc is an HTMLImageElement or HTMLCanvasElement or Canvas
else {
return newImageOrSrc;
}
}
function imageOnLoad() {
var cachedImgObj = this.__cachedImgObj;
this.onload = this.__cachedImgObj = null;
for (var i = 0; i < cachedImgObj.pending.length; i++) {
var pendingWrap = cachedImgObj.pending[i];
var cb = pendingWrap.cb;
cb && cb(this, pendingWrap.cbPayload);
pendingWrap.hostEl.dirty();
}
cachedImgObj.pending.length = 0;
}
function isImageReady(image) {
return image && image.width && image.height;
}
exports.findExistImage = findExistImage;
exports.createOrUpdateImage = createOrUpdateImage;
exports.isImageReady = isImageReady;
/***/ }),
/* 165 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_Base__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_glenum__ = __webpack_require__(11);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__math_Vector3__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__math_BoundingBox__ = __webpack_require__(15);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__math_Frustum__ = __webpack_require__(52);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__math_Matrix4__ = __webpack_require__(7);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__Renderer__ = __webpack_require__(46);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__Material__ = __webpack_require__(17);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__FrameBuffer__ = __webpack_require__(10);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__Texture__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__TextureCube__ = __webpack_require__(24);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_13__camera_Perspective__ = __webpack_require__(36);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_14__camera_Orthographic__ = __webpack_require__(33);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_15__compositor_Pass__ = __webpack_require__(14);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_16__compositor_TexturePool__ = __webpack_require__(79);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_17__dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_17__dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_17__dep_glmatrix__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_18__shader_source_shadowmap_glsl_js__ = __webpack_require__(166);
var mat4 = __WEBPACK_IMPORTED_MODULE_17__dep_glmatrix___default.a.mat4;
var targets = ['px', 'nx', 'py', 'ny', 'pz', 'nz'];
__WEBPACK_IMPORTED_MODULE_7__Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_18__shader_source_shadowmap_glsl_js__["a" /* default */]);
/**
* Pass rendering shadow map.
*
* @constructor clay.prePass.ShadowMap
* @extends clay.core.Base
* @example
* var shadowMapPass = new clay.prePass.ShadowMap({
* softShadow: clay.prePass.ShadowMap.VSM
* });
* ...
* animation.on('frame', function (frameTime) {
* shadowMapPass.render(renderer, scene, camera);
* renderer.render(scene, camera);
* });
*/
var ShadowMapPass = __WEBPACK_IMPORTED_MODULE_0__core_Base__["a" /* default */].extend(function () {
return /** @lends clay.prePass.ShadowMap# */ {
/**
* Soft shadow technique.
* Can be {@link clay.prePass.ShadowMap.PCF} or {@link clay.prePass.ShadowMap.VSM}
* @type {number}
*/
softShadow: ShadowMapPass.PCF,
/**
* Soft shadow blur size
* @type {number}
*/
shadowBlur: 1.0,
lightFrustumBias: 'auto',
kernelPCF: new Float32Array([
1, 0,
1, 1,
-1, 1,
0, 1,
-1, 0,
-1, -1,
1, -1,
0, -1
]),
precision: 'highp',
_lastRenderNotCastShadow: false,
_frameBuffer: new __WEBPACK_IMPORTED_MODULE_9__FrameBuffer__["a" /* default */](),
_textures: {},
_shadowMapNumber: {
'POINT_LIGHT': 0,
'DIRECTIONAL_LIGHT': 0,
'SPOT_LIGHT': 0
},
_depthMaterials: {},
_distanceMaterials: {},
_receivers: [],
_lightsCastShadow: [],
_lightCameras: {},
_lightMaterials: {},
_texturePool: new __WEBPACK_IMPORTED_MODULE_16__compositor_TexturePool__["a" /* default */]()
};
}, function () {
// Gaussian filter pass for VSM
this._gaussianPassH = new __WEBPACK_IMPORTED_MODULE_15__compositor_Pass__["a" /* default */]({
fragment: __WEBPACK_IMPORTED_MODULE_7__Shader__["a" /* default */].source('clay.compositor.gaussian_blur')
});
this._gaussianPassV = new __WEBPACK_IMPORTED_MODULE_15__compositor_Pass__["a" /* default */]({
fragment: __WEBPACK_IMPORTED_MODULE_7__Shader__["a" /* default */].source('clay.compositor.gaussian_blur')
});
this._gaussianPassH.setUniform('blurSize', this.shadowBlur);
this._gaussianPassH.setUniform('blurDir', 0.0);
this._gaussianPassV.setUniform('blurSize', this.shadowBlur);
this._gaussianPassV.setUniform('blurDir', 1.0);
this._outputDepthPass = new __WEBPACK_IMPORTED_MODULE_15__compositor_Pass__["a" /* default */]({
fragment: __WEBPACK_IMPORTED_MODULE_7__Shader__["a" /* default */].source('clay.sm.debug_depth')
});
}, {
/**
* Render scene to shadow textures
* @param {clay.Renderer} renderer
* @param {clay.Scene} scene
* @param {clay.Camera} sceneCamera
* @param {boolean} [notUpdateScene=false]
* @memberOf clay.prePass.ShadowMap.prototype
*/
render: function (renderer, scene, sceneCamera, notUpdateScene) {
if (!sceneCamera) {
sceneCamera = scene.getMainCamera();
}
this.trigger('beforerender', this, renderer, scene, sceneCamera);
this._renderShadowPass(renderer, scene, sceneCamera, notUpdateScene);
this.trigger('afterrender', this, renderer, scene, sceneCamera);
},
/**
* Debug rendering of shadow textures
* @param {clay.Renderer} renderer
* @param {number} size
* @memberOf clay.prePass.ShadowMap.prototype
*/
renderDebug: function (renderer, size) {
renderer.saveClear();
var viewport = renderer.viewport;
var x = 0, y = 0;
var width = size || viewport.width / 4;
var height = width;
if (this.softShadow === ShadowMapPass.VSM) {
this._outputDepthPass.material.define('fragment', 'USE_VSM');
}
else {
this._outputDepthPass.material.undefine('fragment', 'USE_VSM');
}
for (var name in this._textures) {
var texture = this._textures[name];
renderer.setViewport(x, y, width * texture.width / texture.height, height);
this._outputDepthPass.setUniform('depthMap', texture);
this._outputDepthPass.render(renderer);
x += width * texture.width / texture.height;
}
renderer.setViewport(viewport);
renderer.restoreClear();
},
_updateReceivers: function (renderer, mesh) {
if (mesh.receiveShadow) {
this._receivers.push(mesh);
mesh.material.set('shadowEnabled', 1);
mesh.material.set('pcfKernel', this.kernelPCF);
}
else {
mesh.material.set('shadowEnabled', 0);
}
if (this.softShadow === ShadowMapPass.VSM) {
mesh.material.define('fragment', 'USE_VSM');
mesh.material.undefine('fragment', 'PCF_KERNEL_SIZE');
}
else {
mesh.material.undefine('fragment', 'USE_VSM');
var kernelPCF = this.kernelPCF;
if (kernelPCF && kernelPCF.length) {
mesh.material.define('fragment', 'PCF_KERNEL_SIZE', kernelPCF.length / 2);
}
else {
mesh.material.undefine('fragment', 'PCF_KERNEL_SIZE');
}
}
},
_update: function (renderer, scene) {
var self = this;
scene.traverse(function (renderable) {
if (renderable.isRenderable()) {
self._updateReceivers(renderer, renderable);
}
});
for (var i = 0; i < scene.lights.length; i++) {
var light = scene.lights[i];
if (light.castShadow && !light.invisible) {
this._lightsCastShadow.push(light);
}
}
},
_renderShadowPass: function (renderer, scene, sceneCamera, notUpdateScene) {
// reset
for (var name in this._shadowMapNumber) {
this._shadowMapNumber[name] = 0;
}
this._lightsCastShadow.length = 0;
this._receivers.length = 0;
var _gl = renderer.gl;
if (!notUpdateScene) {
scene.update();
}
if (sceneCamera) {
sceneCamera.update();
}
scene.updateLights();
this._update(renderer, scene);
// Needs to update the receivers again if shadows come from 1 to 0.
if (!this._lightsCastShadow.length && this._lastRenderNotCastShadow) {
return;
}
this._lastRenderNotCastShadow = this._lightsCastShadow === 0;
_gl.enable(_gl.DEPTH_TEST);
_gl.depthMask(true);
_gl.disable(_gl.BLEND);
// Clear with high-z, so the part not rendered will not been shadowed
// TODO
// TODO restore
_gl.clearColor(1.0, 1.0, 1.0, 1.0);
// Shadow uniforms
var spotLightShadowMaps = [];
var spotLightMatrices = [];
var directionalLightShadowMaps = [];
var directionalLightMatrices = [];
var shadowCascadeClips = [];
var pointLightShadowMaps = [];
var dirLightHasCascade;
// Create textures for shadow map
for (var i = 0; i < this._lightsCastShadow.length; i++) {
var light = this._lightsCastShadow[i];
if (light.type === 'DIRECTIONAL_LIGHT') {
if (dirLightHasCascade) {
console.warn('Only one direectional light supported with shadow cascade');
continue;
}
if (light.shadowCascade > 4) {
console.warn('Support at most 4 cascade');
continue;
}
if (light.shadowCascade > 1) {
dirLightHasCascade = light;
}
this.renderDirectionalLightShadow(
renderer,
scene,
sceneCamera,
light,
shadowCascadeClips,
directionalLightMatrices,
directionalLightShadowMaps
);
}
else if (light.type === 'SPOT_LIGHT') {
this.renderSpotLightShadow(
renderer,
scene,
light,
spotLightMatrices,
spotLightShadowMaps
);
}
else if (light.type === 'POINT_LIGHT') {
this.renderPointLightShadow(
renderer,
scene,
light,
pointLightShadowMaps
);
}
this._shadowMapNumber[light.type]++;
}
for (var lightType in this._shadowMapNumber) {
var number = this._shadowMapNumber[lightType];
var key = lightType + '_SHADOWMAP_COUNT';
for (var i = 0; i < this._receivers.length; i++) {
var mesh = this._receivers[i];
var material = mesh.material;
if (material.fragmentDefines[key] !== number) {
if (number > 0) {
material.define('fragment', key, number);
}
else if (material.isDefined('fragment', key)) {
material.undefine('fragment', key);
}
}
}
}
for (var i = 0; i < this._receivers.length; i++) {
var mesh = this._receivers[i];
var material = mesh.material;
if (dirLightHasCascade) {
material.define('fragment', 'SHADOW_CASCADE', dirLightHasCascade.shadowCascade);
}
else {
material.undefine('fragment', 'SHADOW_CASCADE');
}
}
var shadowUniforms = scene.shadowUniforms;
function getSize(texture) {
return texture.height;
}
if (directionalLightShadowMaps.length > 0) {
var directionalLightShadowMapSizes = directionalLightShadowMaps.map(getSize);
shadowUniforms.directionalLightShadowMaps = { value: directionalLightShadowMaps, type: 'tv' };
shadowUniforms.directionalLightMatrices = { value: directionalLightMatrices, type: 'm4v' };
shadowUniforms.directionalLightShadowMapSizes = { value: directionalLightShadowMapSizes, type: '1fv' };
if (dirLightHasCascade) {
var shadowCascadeClipsNear = shadowCascadeClips.slice();
var shadowCascadeClipsFar = shadowCascadeClips.slice();
shadowCascadeClipsNear.pop();
shadowCascadeClipsFar.shift();
// Iterate from far to near
shadowCascadeClipsNear.reverse();
shadowCascadeClipsFar.reverse();
// directionalLightShadowMaps.reverse();
directionalLightMatrices.reverse();
shadowUniforms.shadowCascadeClipsNear = { value: shadowCascadeClipsNear, type: '1fv' };
shadowUniforms.shadowCascadeClipsFar = { value: shadowCascadeClipsFar, type: '1fv' };
}
}
if (spotLightShadowMaps.length > 0) {
var spotLightShadowMapSizes = spotLightShadowMaps.map(getSize);
var shadowUniforms = scene.shadowUniforms;
shadowUniforms.spotLightShadowMaps = { value: spotLightShadowMaps, type: 'tv' };
shadowUniforms.spotLightMatrices = { value: spotLightMatrices, type: 'm4v' };
shadowUniforms.spotLightShadowMapSizes = { value: spotLightShadowMapSizes, type: '1fv' };
}
if (pointLightShadowMaps.length > 0) {
shadowUniforms.pointLightShadowMaps = { value: pointLightShadowMaps, type: 'tv' };
}
},
renderDirectionalLightShadow: (function () {
var splitFrustum = new __WEBPACK_IMPORTED_MODULE_4__math_Frustum__["a" /* default */]();
var splitProjMatrix = new __WEBPACK_IMPORTED_MODULE_5__math_Matrix4__["a" /* default */]();
var cropBBox = new __WEBPACK_IMPORTED_MODULE_3__math_BoundingBox__["a" /* default */]();
var cropMatrix = new __WEBPACK_IMPORTED_MODULE_5__math_Matrix4__["a" /* default */]();
var lightViewMatrix = new __WEBPACK_IMPORTED_MODULE_5__math_Matrix4__["a" /* default */]();
var lightViewProjMatrix = new __WEBPACK_IMPORTED_MODULE_5__math_Matrix4__["a" /* default */]();
var lightProjMatrix = new __WEBPACK_IMPORTED_MODULE_5__math_Matrix4__["a" /* default */]();
return function (renderer, scene, sceneCamera, light, shadowCascadeClips, directionalLightMatrices, directionalLightShadowMaps) {
var defaultShadowMaterial = this._getDepthMaterial(light);
var passConfig = {
getMaterial: function (renderable) {
return renderable.shadowDepthMaterial || defaultShadowMaterial;
},
ifRender: function (renderable) {
return renderable.castShadow;
},
sortCompare: __WEBPACK_IMPORTED_MODULE_6__Renderer__["a" /* default */].opaqueSortCompare
};
// First frame
if (!scene.viewBoundingBoxLastFrame.isFinite()) {
var boundingBox = scene.getBoundingBox();
scene.viewBoundingBoxLastFrame
.copy(boundingBox).applyTransform(sceneCamera.viewMatrix);
}
// Considering moving speed since the bounding box is from last frame
// TODO: add a bias
var clippedFar = Math.min(-scene.viewBoundingBoxLastFrame.min.z, sceneCamera.far);
var clippedNear = Math.max(-scene.viewBoundingBoxLastFrame.max.z, sceneCamera.near);
var lightCamera = this._getDirectionalLightCamera(light, scene, sceneCamera);
var lvpMat4Arr = lightViewProjMatrix.array;
lightProjMatrix.copy(lightCamera.projectionMatrix);
mat4.invert(lightViewMatrix.array, lightCamera.worldTransform.array);
mat4.multiply(lightViewMatrix.array, lightViewMatrix.array, sceneCamera.worldTransform.array);
mat4.multiply(lvpMat4Arr, lightProjMatrix.array, lightViewMatrix.array);
var clipPlanes = [];
var isPerspective = sceneCamera instanceof __WEBPACK_IMPORTED_MODULE_13__camera_Perspective__["a" /* default */];
var scaleZ = (sceneCamera.near + sceneCamera.far) / (sceneCamera.near - sceneCamera.far);
var offsetZ = 2 * sceneCamera.near * sceneCamera.far / (sceneCamera.near - sceneCamera.far);
for (var i = 0; i <= light.shadowCascade; i++) {
var clog = clippedNear * Math.pow(clippedFar / clippedNear, i / light.shadowCascade);
var cuni = clippedNear + (clippedFar - clippedNear) * i / light.shadowCascade;
var c = clog * light.cascadeSplitLogFactor + cuni * (1 - light.cascadeSplitLogFactor);
clipPlanes.push(c);
shadowCascadeClips.push(-(-c * scaleZ + offsetZ) / -c);
}
var texture = this._getTexture(light, light.shadowCascade);
directionalLightShadowMaps.push(texture);
var viewport = renderer.viewport;
var _gl = renderer.gl;
this._frameBuffer.attach(texture);
this._frameBuffer.bind(renderer);
_gl.clear(_gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT);
for (var i = 0; i < light.shadowCascade; i++) {
// Get the splitted frustum
var nearPlane = clipPlanes[i];
var farPlane = clipPlanes[i + 1];
if (isPerspective) {
mat4.perspective(splitProjMatrix.array, sceneCamera.fov / 180 * Math.PI, sceneCamera.aspect, nearPlane, farPlane);
}
else {
mat4.ortho(
splitProjMatrix.array,
sceneCamera.left, sceneCamera.right, sceneCamera.bottom, sceneCamera.top,
nearPlane, farPlane
);
}
splitFrustum.setFromProjection(splitProjMatrix);
splitFrustum.getTransformedBoundingBox(cropBBox, lightViewMatrix);
cropBBox.applyProjection(lightProjMatrix);
var _min = cropBBox.min.array;
var _max = cropBBox.max.array;
_min[0] = Math.max(_min[0], -1);
_min[1] = Math.max(_min[1], -1);
_max[0] = Math.min(_max[0], 1);
_max[1] = Math.min(_max[1], 1);
cropMatrix.ortho(_min[0], _max[0], _min[1], _max[1], 1, -1);
lightCamera.projectionMatrix.multiplyLeft(cropMatrix);
var shadowSize = light.shadowResolution || 512;
// Reversed, left to right => far to near
renderer.setViewport((light.shadowCascade - i - 1) * shadowSize, 0, shadowSize, shadowSize, 1);
var renderList = scene.updateRenderList(lightCamera);
renderer.renderPass(renderList.opaque, lightCamera, passConfig);
// Filter for VSM
if (this.softShadow === ShadowMapPass.VSM) {
this._gaussianFilter(renderer, texture, texture.width);
}
var matrix = new __WEBPACK_IMPORTED_MODULE_5__math_Matrix4__["a" /* default */]();
matrix.copy(lightCamera.viewMatrix)
.multiplyLeft(lightCamera.projectionMatrix);
directionalLightMatrices.push(matrix.array);
lightCamera.projectionMatrix.copy(lightProjMatrix);
}
this._frameBuffer.unbind(renderer);
renderer.setViewport(viewport);
};
})(),
renderSpotLightShadow: function (renderer, scene, light, spotLightMatrices, spotLightShadowMaps) {
var texture = this._getTexture(light);
var lightCamera = this._getSpotLightCamera(light);
var _gl = renderer.gl;
this._frameBuffer.attach(texture);
this._frameBuffer.bind(renderer);
_gl.clear(_gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT);
var defaultShadowMaterial = this._getDepthMaterial(light);
var passConfig = {
getMaterial: function (renderable) {
return renderable.shadowDepthMaterial || defaultShadowMaterial;
},
ifRender: function (renderable) {
return renderable.castShadow;
},
sortCompare: __WEBPACK_IMPORTED_MODULE_6__Renderer__["a" /* default */].opaqueSortCompare
};
var renderList = scene.updateRenderList(lightCamera);
renderer.renderPass(renderList.opaque, lightCamera, passConfig);
this._frameBuffer.unbind(renderer);
// Filter for VSM
if (this.softShadow === ShadowMapPass.VSM) {
this._gaussianFilter(renderer, texture, texture.width);
}
var matrix = new __WEBPACK_IMPORTED_MODULE_5__math_Matrix4__["a" /* default */]();
matrix.copy(lightCamera.worldTransform)
.invert()
.multiplyLeft(lightCamera.projectionMatrix);
spotLightShadowMaps.push(texture);
spotLightMatrices.push(matrix.array);
},
renderPointLightShadow: function (renderer, scene, light, pointLightShadowMaps) {
var texture = this._getTexture(light);
var _gl = renderer.gl;
pointLightShadowMaps.push(texture);
var defaultShadowMaterial = this._getDepthMaterial(light);
var passConfig = {
getMaterial: function (renderable) {
return renderable.shadowDepthMaterial || defaultShadowMaterial;
},
sortCompare: __WEBPACK_IMPORTED_MODULE_6__Renderer__["a" /* default */].opaqueSortCompare
};
var renderListEachSide = {
px: [], py: [], pz: [], nx: [], ny: [], nz: []
};
var bbox = new __WEBPACK_IMPORTED_MODULE_3__math_BoundingBox__["a" /* default */]();
var lightWorldPosition = light.getWorldPosition().array;
var lightBBox = new __WEBPACK_IMPORTED_MODULE_3__math_BoundingBox__["a" /* default */]();
var range = light.range;
lightBBox.min.setArray(lightWorldPosition);
lightBBox.max.setArray(lightWorldPosition);
var extent = new __WEBPACK_IMPORTED_MODULE_2__math_Vector3__["a" /* default */](range, range, range);
lightBBox.max.add(extent);
lightBBox.min.sub(extent);
var targetsNeedRender = { px: false, py: false, pz: false, nx: false, ny: false, nz: false };
scene.traverse(function (renderable) {
if (renderable.isRenderable() && renderable.castShadow) {
var geometry = renderable.geometry;
if (!geometry.boundingBox) {
for (var i = 0; i < targets.length; i++) {
renderListEachSide[targets[i]].push(renderable);
}
return;
}
bbox.transformFrom(geometry.boundingBox, renderable.worldTransform);
if (!bbox.intersectBoundingBox(lightBBox)) {
return;
}
bbox.updateVertices();
for (var i = 0; i < targets.length; i++) {
targetsNeedRender[targets[i]] = false;
}
for (var i = 0; i < 8; i++) {
var vtx = bbox.vertices[i];
var x = vtx[0] - lightWorldPosition[0];
var y = vtx[1] - lightWorldPosition[1];
var z = vtx[2] - lightWorldPosition[2];
var absx = Math.abs(x);
var absy = Math.abs(y);
var absz = Math.abs(z);
if (absx > absy) {
if (absx > absz) {
targetsNeedRender[x > 0 ? 'px' : 'nx'] = true;
}
else {
targetsNeedRender[z > 0 ? 'pz' : 'nz'] = true;
}
}
else {
if (absy > absz) {
targetsNeedRender[y > 0 ? 'py' : 'ny'] = true;
}
else {
targetsNeedRender[z > 0 ? 'pz' : 'nz'] = true;
}
}
}
for (var i = 0; i < targets.length; i++) {
if (targetsNeedRender[targets[i]]) {
renderListEachSide[targets[i]].push(renderable);
}
}
}
});
for (var i = 0; i < 6; i++) {
var target = targets[i];
var camera = this._getPointLightCamera(light, target);
this._frameBuffer.attach(texture, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i);
this._frameBuffer.bind(renderer);
_gl.clear(_gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT);
renderer.renderPass(renderListEachSide[target], camera, passConfig);
}
this._frameBuffer.unbind(renderer);
},
_getDepthMaterial: function (light) {
var shadowMaterial = this._lightMaterials[light.__uid__];
var isPointLight = light.type === 'POINT_LIGHT';
if (!shadowMaterial) {
var shaderPrefix = isPointLight ? 'clay.sm.distance.' : 'clay.sm.depth.';
shadowMaterial = new __WEBPACK_IMPORTED_MODULE_8__Material__["a" /* default */]({
precision: this.precision,
shader: new __WEBPACK_IMPORTED_MODULE_7__Shader__["a" /* default */](__WEBPACK_IMPORTED_MODULE_7__Shader__["a" /* default */].source(shaderPrefix + 'vertex'), __WEBPACK_IMPORTED_MODULE_7__Shader__["a" /* default */].source(shaderPrefix + 'fragment'))
});
this._lightMaterials[light.__uid__] = shadowMaterial;
}
if (light.shadowSlopeScale != null) {
shadowMaterial.setUniform('slopeScale', light.shadowSlopeScale);
}
if (light.shadowBias != null) {
shadowMaterial.setUniform('bias', light.shadowBias);
}
if (this.softShadow === ShadowMapPass.VSM) {
shadowMaterial.define('fragment', 'USE_VSM');
}
else {
shadowMaterial.undefine('fragment', 'USE_VSM');
}
if (isPointLight) {
shadowMaterial.set('lightPosition', light.getWorldPosition().array);
shadowMaterial.set('range', light.range);
}
return shadowMaterial;
},
_gaussianFilter: function (renderer, texture, size) {
var parameter = {
width: size,
height: size,
type: __WEBPACK_IMPORTED_MODULE_10__Texture__["a" /* default */].FLOAT
};
var tmpTexture = this._texturePool.get(parameter);
this._frameBuffer.attach(tmpTexture);
this._frameBuffer.bind(renderer);
this._gaussianPassH.setUniform('texture', texture);
this._gaussianPassH.setUniform('textureWidth', size);
this._gaussianPassH.render(renderer);
this._frameBuffer.attach(texture);
this._gaussianPassV.setUniform('texture', tmpTexture);
this._gaussianPassV.setUniform('textureHeight', size);
this._gaussianPassV.render(renderer);
this._frameBuffer.unbind(renderer);
this._texturePool.put(tmpTexture);
},
_getTexture: function (light, cascade) {
var key = light.__uid__;
var texture = this._textures[key];
var resolution = light.shadowResolution || 512;
cascade = cascade || 1;
if (!texture) {
if (light.type === 'POINT_LIGHT') {
texture = new __WEBPACK_IMPORTED_MODULE_12__TextureCube__["a" /* default */]();
}
else {
texture = new __WEBPACK_IMPORTED_MODULE_11__Texture2D__["a" /* default */]();
}
// At most 4 cascade
// TODO share with height ?
texture.width = resolution * cascade;
texture.height = resolution;
if (this.softShadow === ShadowMapPass.VSM) {
texture.type = __WEBPACK_IMPORTED_MODULE_10__Texture__["a" /* default */].FLOAT;
texture.anisotropic = 4;
}
else {
texture.minFilter = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].NEAREST;
texture.magFilter = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].NEAREST;
texture.useMipmap = false;
}
this._textures[key] = texture;
}
return texture;
},
_getPointLightCamera: function (light, target) {
if (!this._lightCameras.point) {
this._lightCameras.point = {
px: new __WEBPACK_IMPORTED_MODULE_13__camera_Perspective__["a" /* default */](),
nx: new __WEBPACK_IMPORTED_MODULE_13__camera_Perspective__["a" /* default */](),
py: new __WEBPACK_IMPORTED_MODULE_13__camera_Perspective__["a" /* default */](),
ny: new __WEBPACK_IMPORTED_MODULE_13__camera_Perspective__["a" /* default */](),
pz: new __WEBPACK_IMPORTED_MODULE_13__camera_Perspective__["a" /* default */](),
nz: new __WEBPACK_IMPORTED_MODULE_13__camera_Perspective__["a" /* default */]()
};
}
var camera = this._lightCameras.point[target];
camera.far = light.range;
camera.fov = 90;
camera.position.set(0, 0, 0);
switch (target) {
case 'px':
camera.lookAt(__WEBPACK_IMPORTED_MODULE_2__math_Vector3__["a" /* default */].POSITIVE_X, __WEBPACK_IMPORTED_MODULE_2__math_Vector3__["a" /* default */].NEGATIVE_Y);
break;
case 'nx':
camera.lookAt(__WEBPACK_IMPORTED_MODULE_2__math_Vector3__["a" /* default */].NEGATIVE_X, __WEBPACK_IMPORTED_MODULE_2__math_Vector3__["a" /* default */].NEGATIVE_Y);
break;
case 'py':
camera.lookAt(__WEBPACK_IMPORTED_MODULE_2__math_Vector3__["a" /* default */].POSITIVE_Y, __WEBPACK_IMPORTED_MODULE_2__math_Vector3__["a" /* default */].POSITIVE_Z);
break;
case 'ny':
camera.lookAt(__WEBPACK_IMPORTED_MODULE_2__math_Vector3__["a" /* default */].NEGATIVE_Y, __WEBPACK_IMPORTED_MODULE_2__math_Vector3__["a" /* default */].NEGATIVE_Z);
break;
case 'pz':
camera.lookAt(__WEBPACK_IMPORTED_MODULE_2__math_Vector3__["a" /* default */].POSITIVE_Z, __WEBPACK_IMPORTED_MODULE_2__math_Vector3__["a" /* default */].NEGATIVE_Y);
break;
case 'nz':
camera.lookAt(__WEBPACK_IMPORTED_MODULE_2__math_Vector3__["a" /* default */].NEGATIVE_Z, __WEBPACK_IMPORTED_MODULE_2__math_Vector3__["a" /* default */].NEGATIVE_Y);
break;
}
light.getWorldPosition(camera.position);
camera.update();
return camera;
},
_getDirectionalLightCamera: (function () {
var lightViewMatrix = new __WEBPACK_IMPORTED_MODULE_5__math_Matrix4__["a" /* default */]();
var sceneViewBoundingBox = new __WEBPACK_IMPORTED_MODULE_3__math_BoundingBox__["a" /* default */]();
var lightViewBBox = new __WEBPACK_IMPORTED_MODULE_3__math_BoundingBox__["a" /* default */]();
// Camera of directional light will be adjusted
// to contain the view frustum and scene bounding box as tightly as possible
return function (light, scene, sceneCamera) {
if (!this._lightCameras.directional) {
this._lightCameras.directional = new __WEBPACK_IMPORTED_MODULE_14__camera_Orthographic__["a" /* default */]();
}
var camera = this._lightCameras.directional;
sceneViewBoundingBox.copy(scene.viewBoundingBoxLastFrame);
sceneViewBoundingBox.intersection(sceneCamera.frustum.boundingBox);
// Move to the center of frustum(in world space)
camera.position
.copy(sceneViewBoundingBox.min)
.add(sceneViewBoundingBox.max)
.scale(0.5)
.transformMat4(sceneCamera.worldTransform);
camera.rotation.copy(light.rotation);
camera.scale.copy(light.scale);
camera.updateWorldTransform();
// Transform to light view space
__WEBPACK_IMPORTED_MODULE_5__math_Matrix4__["a" /* default */].invert(lightViewMatrix, camera.worldTransform);
__WEBPACK_IMPORTED_MODULE_5__math_Matrix4__["a" /* default */].multiply(lightViewMatrix, lightViewMatrix, sceneCamera.worldTransform);
lightViewBBox.copy(sceneViewBoundingBox).applyTransform(lightViewMatrix);
var min = lightViewBBox.min.array;
var max = lightViewBBox.max.array;
// Move camera to adjust the near to 0
camera.position.set((min[0] + max[0]) / 2, (min[1] + max[1]) / 2, max[2])
.transformMat4(camera.worldTransform);
camera.near = 0;
camera.far = -min[2] + max[2];
// Make sure receivers not in the frustum will stil receive the shadow.
if (isNaN(this.lightFrustumBias)) {
camera.far *= 4;
}
else {
camera.far += this.lightFrustumBias;
}
camera.left = min[0];
camera.right = max[0];
camera.top = max[1];
camera.bottom = min[1];
camera.update(true);
return camera;
};
})(),
_getSpotLightCamera: function (light) {
if (!this._lightCameras.spot) {
this._lightCameras.spot = new __WEBPACK_IMPORTED_MODULE_13__camera_Perspective__["a" /* default */]();
}
var camera = this._lightCameras.spot;
// Update properties
camera.fov = light.penumbraAngle * 2;
camera.far = light.range;
camera.worldTransform.copy(light.worldTransform);
camera.updateProjectionMatrix();
mat4.invert(camera.viewMatrix.array, camera.worldTransform.array);
return camera;
},
/**
* @param {clay.Renderer|WebGLRenderingContext} [renderer]
* @memberOf clay.prePass.ShadowMap.prototype
*/
// PENDING Renderer or WebGLRenderingContext
dispose: function (renderer) {
var _gl = renderer.gl || renderer;
if (this._frameBuffer) {
this._frameBuffer.dispose(_gl);
}
for (var name in this._textures) {
this._textures[name].dispose(_gl);
}
this._texturePool.clear(renderer.gl);
this._depthMaterials = {};
this._distanceMaterials = {};
this._textures = {};
this._lightCameras = {};
this._shadowMapNumber = {
'POINT_LIGHT': 0,
'DIRECTIONAL_LIGHT': 0,
'SPOT_LIGHT': 0
};
this._meshMaterials = {};
for (var i = 0; i < this._receivers.length; i++) {
var mesh = this._receivers[i];
// Mesh may be disposed
if (mesh.material) {
var material = mesh.material;
material.undefine('fragment', 'POINT_LIGHT_SHADOW_COUNT');
material.undefine('fragment', 'DIRECTIONAL_LIGHT_SHADOW_COUNT');
material.undefine('fragment', 'AMBIENT_LIGHT_SHADOW_COUNT');
material.set('shadowEnabled', 0);
}
}
this._receivers = [];
this._lightsCastShadow = [];
}
});
/**
* @name clay.prePass.ShadowMap.VSM
* @type {number}
*/
ShadowMapPass.VSM = 1;
/**
* @name clay.prePass.ShadowMap.PCF
* @type {number}
*/
ShadowMapPass.PCF = 2;
/* harmony default export */ __webpack_exports__["a"] = (ShadowMapPass);
/***/ }),
/* 166 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.sm.depth.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nattribute vec3 position : POSITION;\n#ifdef SHADOW_TRANSPARENT\nattribute vec2 texcoord : TEXCOORD_0;\n#endif\n@import clay.chunk.skinning_header\nvarying vec4 v_ViewPosition;\n#ifdef SHADOW_TRANSPARENT\nvarying vec2 v_Texcoord;\n#endif\nvoid main(){\n vec3 skinnedPosition = position;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n#endif\n v_ViewPosition = worldViewProjection * vec4(skinnedPosition, 1.0);\n gl_Position = v_ViewPosition;\n#ifdef SHADOW_TRANSPARENT\n v_Texcoord = texcoord;\n#endif\n}\n@end\n@export clay.sm.depth.fragment\nvarying vec4 v_ViewPosition;\n#ifdef SHADOW_TRANSPARENT\nvarying vec2 v_Texcoord;\n#endif\nuniform float bias : 0.001;\nuniform float slopeScale : 1.0;\n#ifdef SHADOW_TRANSPARENT\nuniform sampler2D transparentMap;\n#endif\n@import clay.util.encode_float\nvoid main(){\n float depth = v_ViewPosition.z / v_ViewPosition.w;\n#ifdef USE_VSM\n depth = depth * 0.5 + 0.5;\n float moment1 = depth;\n float moment2 = depth * depth;\n float dx = dFdx(depth);\n float dy = dFdy(depth);\n moment2 += 0.25*(dx*dx+dy*dy);\n gl_FragColor = vec4(moment1, moment2, 0.0, 1.0);\n#else\n float dx = dFdx(depth);\n float dy = dFdy(depth);\n depth += sqrt(dx*dx + dy*dy) * slopeScale + bias;\n#ifdef SHADOW_TRANSPARENT\n if (texture2D(transparentMap, v_Texcoord).a <= 0.1) {\n gl_FragColor = encodeFloat(0.9999);\n return;\n }\n#endif\n gl_FragColor = encodeFloat(depth * 0.5 + 0.5);\n#endif\n}\n@end\n@export clay.sm.debug_depth\nuniform sampler2D depthMap;\nvarying vec2 v_Texcoord;\n@import clay.util.decode_float\nvoid main() {\n vec4 tex = texture2D(depthMap, v_Texcoord);\n#ifdef USE_VSM\n gl_FragColor = vec4(tex.rgb, 1.0);\n#else\n float depth = decodeFloat(tex);\n gl_FragColor = vec4(depth, depth, depth, 1.0);\n#endif\n}\n@end\n@export clay.sm.distance.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform mat4 world : WORLD;\nattribute vec3 position : POSITION;\n@import clay.chunk.skinning_header\nvarying vec3 v_WorldPosition;\nvoid main (){\n vec3 skinnedPosition = position;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n#endif\n gl_Position = worldViewProjection * vec4(skinnedPosition , 1.0);\n v_WorldPosition = (world * vec4(skinnedPosition, 1.0)).xyz;\n}\n@end\n@export clay.sm.distance.fragment\nuniform vec3 lightPosition;\nuniform float range : 100;\nvarying vec3 v_WorldPosition;\n@import clay.util.encode_float\nvoid main(){\n float dist = distance(lightPosition, v_WorldPosition);\n#ifdef USE_VSM\n gl_FragColor = vec4(dist, dist * dist, 0.0, 0.0);\n#else\n dist = dist / range;\n gl_FragColor = encodeFloat(dist);\n#endif\n}\n@end\n@export clay.plugin.shadow_map_common\n@import clay.util.decode_float\nfloat tapShadowMap(sampler2D map, vec2 uv, float z){\n vec4 tex = texture2D(map, uv);\n return step(z, decodeFloat(tex) * 2.0 - 1.0);\n}\nfloat pcf(sampler2D map, vec2 uv, float z, float textureSize, vec2 scale) {\n float shadowContrib = tapShadowMap(map, uv, z);\n vec2 offset = vec2(1.0 / textureSize) * scale;\n#ifdef PCF_KERNEL_SIZE\n for (int _idx_ = 0; _idx_ < PCF_KERNEL_SIZE; _idx_++) {{\n shadowContrib += tapShadowMap(map, uv + offset * pcfKernel[_idx_], z);\n }}\n return shadowContrib / float(PCF_KERNEL_SIZE + 1);\n#else\n shadowContrib += tapShadowMap(map, uv+vec2(offset.x, 0.0), z);\n shadowContrib += tapShadowMap(map, uv+vec2(offset.x, offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(-offset.x, offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(0.0, offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(-offset.x, 0.0), z);\n shadowContrib += tapShadowMap(map, uv+vec2(-offset.x, -offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(offset.x, -offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(0.0, -offset.y), z);\n return shadowContrib / 9.0;\n#endif\n}\nfloat pcf(sampler2D map, vec2 uv, float z, float textureSize) {\n return pcf(map, uv, z, textureSize, vec2(1.0));\n}\nfloat chebyshevUpperBound(vec2 moments, float z){\n float p = 0.0;\n z = z * 0.5 + 0.5;\n if (z <= moments.x) {\n p = 1.0;\n }\n float variance = moments.y - moments.x * moments.x;\n variance = max(variance, 0.0000001);\n float mD = moments.x - z;\n float pMax = variance / (variance + mD * mD);\n pMax = clamp((pMax-0.4)/(1.0-0.4), 0.0, 1.0);\n return max(p, pMax);\n}\nfloat computeShadowContrib(\n sampler2D map, mat4 lightVPM, vec3 position, float textureSize, vec2 scale, vec2 offset\n) {\n vec4 posInLightSpace = lightVPM * vec4(position, 1.0);\n posInLightSpace.xyz /= posInLightSpace.w;\n float z = posInLightSpace.z;\n if(all(greaterThan(posInLightSpace.xyz, vec3(-0.99, -0.99, -1.0))) &&\n all(lessThan(posInLightSpace.xyz, vec3(0.99, 0.99, 1.0)))){\n vec2 uv = (posInLightSpace.xy+1.0) / 2.0;\n #ifdef USE_VSM\n vec2 moments = texture2D(map, uv * scale + offset).xy;\n return chebyshevUpperBound(moments, z);\n #else\n return pcf(map, uv * scale + offset, z, textureSize, scale);\n #endif\n }\n return 1.0;\n}\nfloat computeShadowContrib(sampler2D map, mat4 lightVPM, vec3 position, float textureSize) {\n return computeShadowContrib(map, lightVPM, position, textureSize, vec2(1.0), vec2(0.0));\n}\nfloat computeShadowContribOmni(samplerCube map, vec3 direction, float range)\n{\n float dist = length(direction);\n vec4 shadowTex = textureCube(map, direction);\n#ifdef USE_VSM\n vec2 moments = shadowTex.xy;\n float variance = moments.y - moments.x * moments.x;\n float mD = moments.x - dist;\n float p = variance / (variance + mD * mD);\n if(moments.x + 0.001 < dist){\n return clamp(p, 0.0, 1.0);\n }else{\n return 1.0;\n }\n#else\n return step(dist, (decodeFloat(shadowTex) + 0.0002) * range);\n#endif\n}\n@end\n@export clay.plugin.compute_shadow_map\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT) || defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT) || defined(POINT_LIGHT_SHADOWMAP_COUNT)\n#ifdef SPOT_LIGHT_SHADOWMAP_COUNT\nuniform sampler2D spotLightShadowMaps[SPOT_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\nuniform mat4 spotLightMatrices[SPOT_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\nuniform float spotLightShadowMapSizes[SPOT_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\n#endif\n#ifdef DIRECTIONAL_LIGHT_SHADOWMAP_COUNT\n#if defined(SHADOW_CASCADE)\nuniform sampler2D directionalLightShadowMaps[1]:unconfigurable;\nuniform mat4 directionalLightMatrices[SHADOW_CASCADE]:unconfigurable;\nuniform float directionalLightShadowMapSizes[1]:unconfigurable;\nuniform float shadowCascadeClipsNear[SHADOW_CASCADE]:unconfigurable;\nuniform float shadowCascadeClipsFar[SHADOW_CASCADE]:unconfigurable;\n#else\nuniform sampler2D directionalLightShadowMaps[DIRECTIONAL_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\nuniform mat4 directionalLightMatrices[DIRECTIONAL_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\nuniform float directionalLightShadowMapSizes[DIRECTIONAL_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\n#endif\n#endif\n#ifdef POINT_LIGHT_SHADOWMAP_COUNT\nuniform samplerCube pointLightShadowMaps[POINT_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\n#endif\nuniform bool shadowEnabled : true;\n#ifdef PCF_KERNEL_SIZE\nuniform vec2 pcfKernel[PCF_KERNEL_SIZE];\n#endif\n@import clay.plugin.shadow_map_common\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT)\nvoid computeShadowOfSpotLights(vec3 position, inout float shadowContribs[SPOT_LIGHT_COUNT] ) {\n float shadowContrib;\n for(int _idx_ = 0; _idx_ < SPOT_LIGHT_SHADOWMAP_COUNT; _idx_++) {{\n shadowContrib = computeShadowContrib(\n spotLightShadowMaps[_idx_], spotLightMatrices[_idx_], position,\n spotLightShadowMapSizes[_idx_]\n );\n shadowContribs[_idx_] = shadowContrib;\n }}\n for(int _idx_ = SPOT_LIGHT_SHADOWMAP_COUNT; _idx_ < SPOT_LIGHT_COUNT; _idx_++){{\n shadowContribs[_idx_] = 1.0;\n }}\n}\n#endif\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n#ifdef SHADOW_CASCADE\nvoid computeShadowOfDirectionalLights(vec3 position, inout float shadowContribs[DIRECTIONAL_LIGHT_COUNT]){\n float depth = (2.0 * gl_FragCoord.z - gl_DepthRange.near - gl_DepthRange.far)\n / (gl_DepthRange.far - gl_DepthRange.near);\n float shadowContrib;\n shadowContribs[0] = 1.0;\n for (int _idx_ = 0; _idx_ < SHADOW_CASCADE; _idx_++) {{\n if (\n depth >= shadowCascadeClipsNear[_idx_] &&\n depth <= shadowCascadeClipsFar[_idx_]\n ) {\n shadowContrib = computeShadowContrib(\n directionalLightShadowMaps[0], directionalLightMatrices[_idx_], position,\n directionalLightShadowMapSizes[0],\n vec2(1.0 / float(SHADOW_CASCADE), 1.0),\n vec2(float(_idx_) / float(SHADOW_CASCADE), 0.0)\n );\n shadowContribs[0] = shadowContrib;\n }\n }}\n for(int _idx_ = DIRECTIONAL_LIGHT_SHADOWMAP_COUNT; _idx_ < DIRECTIONAL_LIGHT_COUNT; _idx_++) {{\n shadowContribs[_idx_] = 1.0;\n }}\n}\n#else\nvoid computeShadowOfDirectionalLights(vec3 position, inout float shadowContribs[DIRECTIONAL_LIGHT_COUNT]){\n float shadowContrib;\n for(int _idx_ = 0; _idx_ < DIRECTIONAL_LIGHT_SHADOWMAP_COUNT; _idx_++) {{\n shadowContrib = computeShadowContrib(\n directionalLightShadowMaps[_idx_], directionalLightMatrices[_idx_], position,\n directionalLightShadowMapSizes[_idx_]\n );\n shadowContribs[_idx_] = shadowContrib;\n }}\n for(int _idx_ = DIRECTIONAL_LIGHT_SHADOWMAP_COUNT; _idx_ < DIRECTIONAL_LIGHT_COUNT; _idx_++) {{\n shadowContribs[_idx_] = 1.0;\n }}\n}\n#endif\n#endif\n#if defined(POINT_LIGHT_SHADOWMAP_COUNT)\nvoid computeShadowOfPointLights(vec3 position, inout float shadowContribs[POINT_LIGHT_COUNT] ){\n vec3 lightPosition;\n vec3 direction;\n for(int _idx_ = 0; _idx_ < POINT_LIGHT_SHADOWMAP_COUNT; _idx_++) {{\n lightPosition = pointLightPosition[_idx_];\n direction = position - lightPosition;\n shadowContribs[_idx_] = computeShadowContribOmni(pointLightShadowMaps[_idx_], direction, pointLightRange[_idx_]);\n }}\n for(int _idx_ = POINT_LIGHT_SHADOWMAP_COUNT; _idx_ < POINT_LIGHT_COUNT; _idx_++) {{\n shadowContribs[_idx_] = 1.0;\n }}\n}\n#endif\n#endif\n@end");
/***/ }),
/* 167 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_FrameBuffer__ = __webpack_require__(10);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_claygl_src_compositor_createCompositor__ = __webpack_require__(168);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__SSAOPass__ = __webpack_require__(181);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__SSRPass__ = __webpack_require__(183);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__poissonKernel__ = __webpack_require__(185);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__util_graphicGL__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__NormalPass__ = __webpack_require__(186);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__EdgePass__ = __webpack_require__(188);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11_claygl_src_math_Matrix4__ = __webpack_require__(7);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__composite_js__ = __webpack_require__(189);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_13_claygl_src_shader_source_compositor_blur_glsl_js__ = __webpack_require__(80);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_14_claygl_src_shader_source_compositor_lut_glsl_js__ = __webpack_require__(81);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_15_claygl_src_shader_source_compositor_output_glsl_js__ = __webpack_require__(82);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_16_claygl_src_shader_source_compositor_bright_glsl_js__ = __webpack_require__(83);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_17_claygl_src_shader_source_compositor_downsample_glsl_js__ = __webpack_require__(84);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_18_claygl_src_shader_source_compositor_upsample_glsl_js__ = __webpack_require__(85);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_19_claygl_src_shader_source_compositor_hdr_glsl_js__ = __webpack_require__(86);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_20_claygl_src_shader_source_compositor_blend_glsl_js__ = __webpack_require__(87);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_21_claygl_src_shader_source_compositor_fxaa_glsl_js__ = __webpack_require__(88);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_22__DOF_glsl_js__ = __webpack_require__(190);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_23__edge_glsl_js__ = __webpack_require__(191);
__WEBPACK_IMPORTED_MODULE_0_claygl_src_Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_13_claygl_src_shader_source_compositor_blur_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_claygl_src_Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_14_claygl_src_shader_source_compositor_lut_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_claygl_src_Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_15_claygl_src_shader_source_compositor_output_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_claygl_src_Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_16_claygl_src_shader_source_compositor_bright_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_claygl_src_Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_17_claygl_src_shader_source_compositor_downsample_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_claygl_src_Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_18_claygl_src_shader_source_compositor_upsample_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_claygl_src_Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_19_claygl_src_shader_source_compositor_hdr_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_claygl_src_Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_20_claygl_src_shader_source_compositor_blend_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_claygl_src_Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_21_claygl_src_shader_source_compositor_fxaa_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_claygl_src_Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_22__DOF_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_claygl_src_Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_23__edge_glsl_js__["a" /* default */]);
var commonOutputs = {
color : {
parameters : {
width : function (renderer) {
return renderer.getWidth();
},
height : function (renderer) {
return renderer.getHeight();
}
}
}
}
var FINAL_NODES_CHAIN = ['composite', 'FXAA'];
function EffectCompositor() {
this._sourceTexture = new __WEBPACK_IMPORTED_MODULE_1_claygl_src_Texture2D__["a" /* default */]({
type: __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture__["a" /* default */].HALF_FLOAT
});
this._depthTexture = new __WEBPACK_IMPORTED_MODULE_1_claygl_src_Texture2D__["a" /* default */]({
format: __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture__["a" /* default */].DEPTH_COMPONENT,
type: __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture__["a" /* default */].UNSIGNED_INT
});
this._framebuffer = new __WEBPACK_IMPORTED_MODULE_3_claygl_src_FrameBuffer__["a" /* default */]();
this._framebuffer.attach(this._sourceTexture);
this._framebuffer.attach(this._depthTexture, __WEBPACK_IMPORTED_MODULE_3_claygl_src_FrameBuffer__["a" /* default */].DEPTH_ATTACHMENT);
this._normalPass = new __WEBPACK_IMPORTED_MODULE_9__NormalPass__["a" /* default */]();
this._compositor = Object(__WEBPACK_IMPORTED_MODULE_4_claygl_src_compositor_createCompositor__["a" /* default */])(__WEBPACK_IMPORTED_MODULE_12__composite_js__["a" /* default */]);
var sourceNode = this._compositor.getNodeByName('source');
sourceNode.texture = this._sourceTexture;
var cocNode = this._compositor.getNodeByName('coc');
this._sourceNode = sourceNode;
this._cocNode = cocNode;
this._compositeNode = this._compositor.getNodeByName('composite');
this._fxaaNode = this._compositor.getNodeByName('FXAA');
this._dofBlurNodes = ['dof_far_blur', 'dof_near_blur', 'dof_coc_blur'].map(function (name) {
return this._compositor.getNodeByName(name);
}, this);
this._dofBlurKernel = 0;
this._dofBlurKernelSize = new Float32Array(0);
this._finalNodesChain = FINAL_NODES_CHAIN.map(function (name) {
return this._compositor.getNodeByName(name);
}, this);
var gBufferObj = {
normalTexture: this._normalPass.getNormalTexture(),
depthTexture: this._normalPass.getDepthTexture()
};
this._ssaoPass = new __WEBPACK_IMPORTED_MODULE_5__SSAOPass__["a" /* default */](gBufferObj);
this._ssrPass = new __WEBPACK_IMPORTED_MODULE_6__SSRPass__["a" /* default */](gBufferObj);
this._edgePass = new __WEBPACK_IMPORTED_MODULE_10__EdgePass__["a" /* default */](gBufferObj);
}
EffectCompositor.prototype.resize = function (width, height, dpr) {
dpr = dpr || 1;
var width = width * dpr;
var height = height * dpr;
var sourceTexture = this._sourceTexture;
var depthTexture = this._depthTexture;
sourceTexture.width = width;
sourceTexture.height = height;
depthTexture.width = width;
depthTexture.height = height;
};
EffectCompositor.prototype._ifRenderNormalPass = function () {
return this._enableSSAO || this._enableEdge || this._enableSSR;
};
EffectCompositor.prototype._getPrevNode = function (node) {
var idx = FINAL_NODES_CHAIN.indexOf(node.name) - 1;
var prevNode = this._finalNodesChain[idx];
while (prevNode && !this._compositor.getNodeByName(prevNode.name)) {
idx -= 1;
prevNode = this._finalNodesChain[idx];
}
return prevNode;
};
EffectCompositor.prototype._getNextNode = function (node) {
var idx = FINAL_NODES_CHAIN.indexOf(node.name) + 1;
var nextNode = this._finalNodesChain[idx];
while (nextNode && !this._compositor.getNodeByName(nextNode.name)) {
idx += 1;
nextNode = this._finalNodesChain[idx];
}
return nextNode;
};
EffectCompositor.prototype._addChainNode = function (node) {
var prevNode = this._getPrevNode(node);
var nextNode = this._getNextNode(node);
if (!prevNode) {
return;
}
prevNode.outputs = commonOutputs;
node.inputs.texture = prevNode.name;
if (nextNode) {
node.outputs = commonOutputs;
nextNode.inputs.texture = node.name;
}
else {
node.outputs = null;
}
this._compositor.addNode(node);
};
EffectCompositor.prototype._removeChainNode = function (node) {
var prevNode = this._getPrevNode(node);
var nextNode = this._getNextNode(node);
if (!prevNode) {
return;
}
if (nextNode) {
prevNode.outputs = commonOutputs;
nextNode.inputs.texture = prevNode.name;
}
else {
prevNode.outputs = null;
}
this._compositor.removeNode(node);
};
/**
* Update normal
*/
EffectCompositor.prototype.updateNormal = function (renderer, scene, camera, frame) {
if (this._ifRenderNormalPass()) {
this._normalPass.update(renderer, scene, camera);
}
};
/**
* Render SSAO after render the scene, before compositing
*/
EffectCompositor.prototype.updateSSAO = function (renderer, scene, camera, frame) {
this._ssaoPass.update(renderer, camera, frame);
};
/**
* Enable SSAO effect
*/
EffectCompositor.prototype.enableSSAO = function () {
this._enableSSAO = true;
};
/**
* Disable SSAO effect
*/
EffectCompositor.prototype.disableSSAO = function () {
this._enableSSAO = false;
};
/**
* Enable SSR effect
*/
EffectCompositor.prototype.enableSSR = function () {
this._enableSSR = true;
// this._normalPass.enableTargetTexture3 = true;
};
/**
* Disable SSR effect
*/
EffectCompositor.prototype.disableSSR = function () {
this._enableSSR = false;
// this._normalPass.enableTargetTexture3 = false;
};
/**
* Render SSAO after render the scene, before compositing
*/
EffectCompositor.prototype.getSSAOTexture = function () {
return this._ssaoPass.getTargetTexture();
};
/**
* @return {clay.FrameBuffer}
*/
EffectCompositor.prototype.getSourceFrameBuffer = function () {
return this._framebuffer;
};
/**
* @return {clay.Texture2D}
*/
EffectCompositor.prototype.getSourceTexture = function () {
return this._sourceTexture;
};
/**
* Disable fxaa effect
*/
EffectCompositor.prototype.disableFXAA = function () {
this._removeChainNode(this._fxaaNode);
};
/**
* Enable fxaa effect
*/
EffectCompositor.prototype.enableFXAA = function () {
this._addChainNode(this._fxaaNode);
};
/**
* Enable bloom effect
*/
EffectCompositor.prototype.enableBloom = function () {
this._compositeNode.inputs.bloom = 'bloom_composite';
this._compositor.dirty();
};
/**
* Disable bloom effect
*/
EffectCompositor.prototype.disableBloom = function () {
this._compositeNode.inputs.bloom = null;
this._compositor.dirty();
};
/**
* Enable depth of field effect
*/
EffectCompositor.prototype.enableDOF = function () {
this._compositeNode.inputs.texture = 'dof_composite';
this._compositor.dirty();
};
/**
* Disable depth of field effect
*/
EffectCompositor.prototype.disableDOF = function () {
this._compositeNode.inputs.texture = 'source';
this._compositor.dirty();
};
/**
* Enable color correction
*/
EffectCompositor.prototype.enableColorCorrection = function () {
this._compositeNode.define('COLOR_CORRECTION');
this._enableColorCorrection = true;
};
/**
* Disable color correction
*/
EffectCompositor.prototype.disableColorCorrection = function () {
this._compositeNode.undefine('COLOR_CORRECTION');
this._enableColorCorrection = false;
};
/**
* Enable edge detection
*/
EffectCompositor.prototype.enableEdge = function () {
this._enableEdge = true;
};
/**
* Disable edge detection
*/
EffectCompositor.prototype.disableEdge = function () {
this._enableEdge = false;
};
/**
* Set bloom intensity
* @param {number} value
*/
EffectCompositor.prototype.setBloomIntensity = function (value) {
this._compositeNode.setParameter('bloomIntensity', value);
};
EffectCompositor.prototype.setSSAOParameter = function (name, value) {
switch (name) {
case 'quality':
// PENDING
var kernelSize = ({
low: 6,
medium: 12,
high: 32,
ultra: 62
})[value] || 12;
this._ssaoPass.setParameter('kernelSize', kernelSize);
break;
case 'radius':
this._ssaoPass.setParameter(name, value);
this._ssaoPass.setParameter('bias', value / 200);
break;
case 'intensity':
this._ssaoPass.setParameter(name, value);
break;
default:
if (true) {
console.warn('Unkown SSAO parameter ' + name);
}
}
};
EffectCompositor.prototype.setDOFParameter = function (name, value) {
switch (name) {
case 'focalDistance':
case 'focalRange':
case 'fstop':
this._cocNode.setParameter(name, value);
break;
case 'blurRadius':
for (var i = 0; i < this._dofBlurNodes.length; i++) {
this._dofBlurNodes[i].setParameter('blurRadius', value);
}
break;
case 'quality':
var kernelSize = ({
low: 4, medium: 8, high: 16, ultra: 32
})[value] || 8;
this._dofBlurKernelSize = kernelSize;
for (var i = 0; i < this._dofBlurNodes.length; i++) {
this._dofBlurNodes[i].pass.material.define('POISSON_KERNEL_SIZE', kernelSize);
}
this._dofBlurKernel = new Float32Array(kernelSize * 2);
break;
default:
if (true) {
console.warn('Unkown DOF parameter ' + name);
}
}
};
EffectCompositor.prototype.setSSRParameter = function (name, value) {
if (value == null) {
return;
}
switch (name) {
case 'quality':
// PENDING
var maxIteration = ({
low: 10,
medium: 15,
high: 30,
ultra: 80
})[value] || 20;
var pixelStride = ({
low: 32,
medium: 16,
high: 8,
ultra: 4
})[value] || 16;
this._ssrPass.setParameter('maxIteration', maxIteration);
this._ssrPass.setParameter('pixelStride', pixelStride);
break;
case 'maxRoughness':
this._ssrPass.setParameter('minGlossiness', Math.max(Math.min(1.0 - value, 1.0), 0.0));
break;
case 'physical':
this.setPhysicallyCorrectSSR(value);
break;
default:
console.warn('Unkown SSR parameter ' + name);
}
};
EffectCompositor.prototype.setPhysicallyCorrectSSR = function (physical) {
this._ssrPass.setPhysicallyCorrect(physical);
};
/**
* Set color of edge
*/
EffectCompositor.prototype.setEdgeColor = function (value) {
var color = __WEBPACK_IMPORTED_MODULE_8__util_graphicGL__["a" /* default */].parseColor(value);
this._edgePass.setParameter('edgeColor', color);
};
EffectCompositor.prototype.setExposure = function (value) {
this._compositeNode.setParameter('exposure', Math.pow(2, value));
};
EffectCompositor.prototype.setColorLookupTexture = function (image, api) {
this._compositeNode.pass.material.setTextureImage('lut', this._enableColorCorrection ? image : 'none', api, {
minFilter: __WEBPACK_IMPORTED_MODULE_8__util_graphicGL__["a" /* default */].Texture.NEAREST,
magFilter: __WEBPACK_IMPORTED_MODULE_8__util_graphicGL__["a" /* default */].Texture.NEAREST,
flipY: false
});
};
EffectCompositor.prototype.setColorCorrection = function (type, value) {
this._compositeNode.setParameter(type, value);
};
EffectCompositor.prototype.isSSREnabled = function () {
return this._enableSSR;
};
EffectCompositor.prototype.composite = function (renderer, scene, camera, framebuffer, frame) {
var sourceTexture = this._sourceTexture;
var targetTexture = sourceTexture;
if (this._enableEdge) {
this._edgePass.update(renderer, camera, sourceTexture, frame);
sourceTexture = targetTexture = this._edgePass.getTargetTexture();
}
if (this._enableSSR) {
this._ssrPass.update(renderer, camera, sourceTexture, frame);
targetTexture = this._ssrPass.getTargetTexture();
this._ssrPass.setSSAOTexture(
this._enableSSAO ? this._ssaoPass.getTargetTexture() : null
);
// var lights = scene.getLights();
// for (var i = 0; i < lights.length; i++) {
// if (lights[i].cubemap) {
// this._ssrPass.setAmbientCubemap(lights[i].cubemap, lights[i].intensity);
// }
// }
}
this._sourceNode.texture = targetTexture;
this._cocNode.setParameter('depth', this._depthTexture);
var blurKernel = this._dofBlurKernel;
var blurKernelSize = this._dofBlurKernelSize;
var frameAll = Math.floor(__WEBPACK_IMPORTED_MODULE_7__poissonKernel__["a" /* default */].length / 2 / blurKernelSize);
var kernelOffset = frame % frameAll;
for (var i = 0; i < blurKernelSize * 2; i++) {
blurKernel[i] = __WEBPACK_IMPORTED_MODULE_7__poissonKernel__["a" /* default */][i + kernelOffset * blurKernelSize * 2];
}
for (var i = 0; i < this._dofBlurNodes.length; i++) {
this._dofBlurNodes[i].setParameter('percent', frame / 30.0);
this._dofBlurNodes[i].setParameter('poissonKernel', blurKernel);
}
this._cocNode.setParameter('zNear', camera.near);
this._cocNode.setParameter('zFar', camera.far);
this._compositor.render(renderer, framebuffer);
};
EffectCompositor.prototype.dispose = function (renderer) {
this._sourceTexture.dispose(renderer);
this._depthTexture.dispose(renderer);
this._framebuffer.dispose(renderer);
this._compositor.dispose(renderer);
this._normalPass.dispose(renderer);
this._ssaoPass.dispose(renderer);
};
/* harmony default export */ __webpack_exports__["a"] = (EffectCompositor);
/***/ }),
/* 168 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__createCompositor__ = __webpack_require__(169);
// Alias
/* harmony default export */ __webpack_exports__["a"] = (__WEBPACK_IMPORTED_MODULE_0__createCompositor__["a" /* default */]);
/***/ }),
/* 169 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_util__ = __webpack_require__(20);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__compositor_Compositor__ = __webpack_require__(170);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__compositor_SceneNode__ = __webpack_require__(172);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__compositor_TextureNode__ = __webpack_require__(173);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__compositor_FilterNode__ = __webpack_require__(174);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__Texture__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__TextureCube__ = __webpack_require__(24);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__shader_builtinCompositor__ = __webpack_require__(175);
var shaderSourceReg = /^#source\((.*?)\)/;
/**
* @name clay.createCompositor
* @function
* @param {Object} json
* @param {Object} [opts]
* @return {clay.compositor.Compositor}
*/
function createCompositor(json, opts) {
var compositor = new __WEBPACK_IMPORTED_MODULE_1__compositor_Compositor__["a" /* default */]();
opts = opts || {};
var lib = {
textures: {},
parameters: {}
};
var afterLoad = function(shaderLib, textureLib) {
for (var i = 0; i < json.nodes.length; i++) {
var nodeInfo = json.nodes[i];
var node = createNode(nodeInfo, lib, opts);
if (node) {
compositor.addNode(node);
}
}
};
for (var name in json.parameters) {
var paramInfo = json.parameters[name];
lib.parameters[name] = convertParameter(paramInfo);
}
// TODO load texture asynchronous
loadTextures(json, lib, opts, function(textureLib) {
lib.textures = textureLib;
afterLoad();
});
return compositor;
}
function createNode(nodeInfo, lib, opts) {
var type = nodeInfo.type || 'filter';
var shaderSource;
var inputs;
var outputs;
if (type === 'filter') {
var shaderExp = nodeInfo.shader.trim();
var res = shaderSourceReg.exec(shaderExp);
if (res) {
shaderSource = __WEBPACK_IMPORTED_MODULE_5__Shader__["a" /* default */].source(res[1].trim());
}
else if (shaderExp.charAt(0) === '#') {
shaderSource = lib.shaders[shaderExp.substr(1)];
}
if (!shaderSource) {
shaderSource = shaderExp;
}
if (!shaderSource) {
return;
}
}
if (nodeInfo.inputs) {
inputs = {};
for (var name in nodeInfo.inputs) {
if (typeof nodeInfo.inputs[name] === 'string') {
inputs[name] = nodeInfo.inputs[name];
}
else {
inputs[name] = {
node: nodeInfo.inputs[name].node,
pin: nodeInfo.inputs[name].pin
};
}
}
}
if (nodeInfo.outputs) {
outputs = {};
for (var name in nodeInfo.outputs) {
var outputInfo = nodeInfo.outputs[name];
outputs[name] = {};
if (outputInfo.attachment != null) {
outputs[name].attachment = outputInfo.attachment;
}
if (outputInfo.keepLastFrame != null) {
outputs[name].keepLastFrame = outputInfo.keepLastFrame;
}
if (outputInfo.outputLastFrame != null) {
outputs[name].outputLastFrame = outputInfo.outputLastFrame;
}
if (outputInfo.parameters) {
outputs[name].parameters = convertParameter(outputInfo.parameters);
}
}
}
var node;
if (type === 'scene') {
node = new __WEBPACK_IMPORTED_MODULE_2__compositor_SceneNode__["a" /* default */]({
name: nodeInfo.name,
scene: opts.scene,
camera: opts.camera,
outputs: outputs
});
}
else if (type === 'texture') {
node = new __WEBPACK_IMPORTED_MODULE_3__compositor_TextureNode__["a" /* default */]({
name: nodeInfo.name,
outputs: outputs
});
}
// Default is filter
else {
node = new __WEBPACK_IMPORTED_MODULE_4__compositor_FilterNode__["a" /* default */]({
name: nodeInfo.name,
shader: shaderSource,
inputs: inputs,
outputs: outputs
});
}
if (node) {
if (nodeInfo.parameters) {
for (var name in nodeInfo.parameters) {
var val = nodeInfo.parameters[name];
if (typeof(val) === 'string') {
val = val.trim();
if (val.charAt(0) === '#') {
val = lib.textures[val.substr(1)];
}
else {
node.on(
'beforerender', createSizeSetHandler(
name, tryConvertExpr(val)
)
);
}
}
node.setParameter(name, val);
}
}
if (nodeInfo.defines && node.pass) {
for (var name in nodeInfo.defines) {
var val = nodeInfo.defines[name];
node.pass.material.define('fragment', name, val);
}
}
}
return node;
}
function convertParameter(paramInfo) {
var param = {};
if (!paramInfo) {
return param;
}
['type', 'minFilter', 'magFilter', 'wrapS', 'wrapT', 'flipY', 'useMipmap']
.forEach(function(name) {
var val = paramInfo[name];
if (val != null) {
// Convert string to enum
if (typeof val === 'string') {
val = __WEBPACK_IMPORTED_MODULE_6__Texture__["a" /* default */][val];
}
param[name] = val;
}
});
['width', 'height']
.forEach(function(name) {
if (paramInfo[name] != null) {
var val = paramInfo[name];
if (typeof val === 'string') {
val = val.trim();
param[name] = createSizeParser(
name, tryConvertExpr(val)
);
}
else {
param[name] = val;
}
}
});
if (paramInfo.useMipmap != null) {
param.useMipmap = paramInfo.useMipmap;
}
return param;
}
function loadTextures(json, lib, opts, callback) {
if (!json.textures) {
callback({});
return;
}
var textures = {};
var loading = 0;
var cbd = false;
var textureRootPath = opts.textureRootPath;
__WEBPACK_IMPORTED_MODULE_0__core_util__["a" /* default */].each(json.textures, function(textureInfo, name) {
var texture;
var path = textureInfo.path;
var parameters = convertParameter(textureInfo.parameters);
if (Array.isArray(path) && path.length === 6) {
if (textureRootPath) {
path = path.map(function(item) {
return __WEBPACK_IMPORTED_MODULE_0__core_util__["a" /* default */].relative2absolute(item, textureRootPath);
});
}
texture = new __WEBPACK_IMPORTED_MODULE_8__TextureCube__["a" /* default */](parameters);
}
else if(typeof path === 'string') {
if (textureRootPath) {
path = __WEBPACK_IMPORTED_MODULE_0__core_util__["a" /* default */].relative2absolute(path, textureRootPath);
}
texture = new __WEBPACK_IMPORTED_MODULE_7__Texture2D__["a" /* default */](parameters);
}
else {
return;
}
texture.load(path);
loading++;
texture.once('success', function() {
textures[name] = texture;
loading--;
if (loading === 0) {
callback(textures);
cbd = true;
}
});
});
if (loading === 0 && !cbd) {
callback(textures);
}
}
function createSizeSetHandler(name, exprFunc) {
return function (renderer) {
// PENDING viewport size or window size
var dpr = renderer.getDevicePixelRatio();
// PENDING If multiply dpr ?
var width = renderer.getWidth();
var height = renderer.getHeight();
var result = exprFunc(width, height, dpr);
this.setParameter(name, result);
};
}
function createSizeParser(name, exprFunc) {
return function (renderer) {
var dpr = renderer.getDevicePixelRatio();
var width = renderer.getWidth();
var height = renderer.getHeight();
return exprFunc(width, height, dpr);
};
}
function tryConvertExpr(string) {
// PENDING
var exprRes = /^expr\((.*)\)$/.exec(string);
if (exprRes) {
try {
var func = new Function('width', 'height', 'dpr', 'return ' + exprRes[1]);
// Try run t
func(1, 1);
return func;
}
catch (e) {
throw new Error('Invalid expression.');
}
}
}
/* harmony default export */ __webpack_exports__["a"] = (createCompositor);
/***/ }),
/* 170 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Graph__ = __webpack_require__(171);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__TexturePool__ = __webpack_require__(79);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__FrameBuffer__ = __webpack_require__(10);
/**
* Compositor provide graph based post processing
*
* @constructor clay.compositor.Compositor
* @extends clay.compositor.Graph
*
*/
var Compositor = __WEBPACK_IMPORTED_MODULE_0__Graph__["a" /* default */].extend(function() {
return {
// Output node
_outputs: [],
_texturePool: new __WEBPACK_IMPORTED_MODULE_1__TexturePool__["a" /* default */](),
_frameBuffer: new __WEBPACK_IMPORTED_MODULE_2__FrameBuffer__["a" /* default */]({
depthBuffer: false
})
};
},
/** @lends clay.compositor.Compositor.prototype */
{
addNode: function(node) {
__WEBPACK_IMPORTED_MODULE_0__Graph__["a" /* default */].prototype.addNode.call(this, node);
node._compositor = this;
},
/**
* @param {clay.Renderer} renderer
*/
render: function(renderer, frameBuffer) {
if (this._dirty) {
this.update();
this._dirty = false;
this._outputs.length = 0;
for (var i = 0; i < this.nodes.length; i++) {
if (!this.nodes[i].outputs) {
this._outputs.push(this.nodes[i]);
}
}
}
for (var i = 0; i < this.nodes.length; i++) {
// Update the reference number of each output texture
this.nodes[i].beforeFrame();
}
for (var i = 0; i < this._outputs.length; i++) {
this._outputs[i].updateReference();
}
for (var i = 0; i < this._outputs.length; i++) {
this._outputs[i].render(renderer, frameBuffer);
}
for (var i = 0; i < this.nodes.length; i++) {
// Clear up
this.nodes[i].afterFrame();
}
},
allocateTexture: function (parameters) {
return this._texturePool.get(parameters);
},
releaseTexture: function (parameters) {
this._texturePool.put(parameters);
},
getFrameBuffer: function () {
return this._frameBuffer;
},
/**
* Dispose compositor
* @param {clay.Renderer} renderer
*/
dispose: function (renderer) {
this._texturePool.clear(renderer);
}
});
/* harmony default export */ __webpack_exports__["a"] = (Compositor);
/***/ }),
/* 171 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_Base__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__CompositorNode__ = __webpack_require__(42);
/**
* @constructor clay.compositor.Graph
* @extends clay.core.Base
*/
var Graph = __WEBPACK_IMPORTED_MODULE_0__core_Base__["a" /* default */].extend(function () {
return /** @lends clay.compositor.Graph# */ {
/**
* @type {Array.}
*/
nodes: []
};
},
/** @lends clay.compositor.Graph.prototype */
{
/**
* Mark to update
*/
dirty: function () {
this._dirty = true;
},
/**
* @param {clay.compositor.CompositorNode} node
*/
addNode: function (node) {
if (this.nodes.indexOf(node) >= 0) {
return;
}
this.nodes.push(node);
this._dirty = true;
},
/**
* @param {clay.compositor.CompositorNode|string} node
*/
removeNode: function (node) {
if (typeof node === 'string') {
node = this.getNodeByName(node);
}
var idx = this.nodes.indexOf(node);
if (idx >= 0) {
this.nodes.splice(idx, 1);
this._dirty = true;
}
},
/**
* @param {string} name
* @return {clay.compositor.CompositorNode}
*/
getNodeByName: function (name) {
for (var i = 0; i < this.nodes.length; i++) {
if (this.nodes[i].name === name) {
return this.nodes[i];
}
}
},
/**
* Update links of graph
*/
update: function () {
for (var i = 0; i < this.nodes.length; i++) {
this.nodes[i].clear();
}
// Traverse all the nodes and build the graph
for (var i = 0; i < this.nodes.length; i++) {
var node = this.nodes[i];
if (!node.inputs) {
continue;
}
for (var inputName in node.inputs) {
if (!node.inputs[inputName]) {
continue;
}
if (node.pass && !node.pass.material.isUniformEnabled(inputName)) {
console.warn('Pin ' + node.name + '.' + inputName + ' not used.');
continue;
}
var fromPinInfo = node.inputs[inputName];
var fromPin = this.findPin(fromPinInfo);
if (fromPin) {
node.link(inputName, fromPin.node, fromPin.pin);
}
else {
if (typeof fromPinInfo === 'string') {
console.warn('Node ' + fromPinInfo + ' not exist');
}
else {
console.warn('Pin of ' + fromPinInfo.node + '.' + fromPinInfo.pin + ' not exist');
}
}
}
}
},
findPin: function (input) {
var node;
// Try to take input as a directly a node
if (typeof input === 'string' || input instanceof __WEBPACK_IMPORTED_MODULE_1__CompositorNode__["a" /* default */]) {
input = {
node: input
};
}
if (typeof input.node === 'string') {
for (var i = 0; i < this.nodes.length; i++) {
var tmp = this.nodes[i];
if (tmp.name === input.node) {
node = tmp;
}
}
}
else {
node = input.node;
}
if (node) {
var inputPin = input.pin;
if (!inputPin) {
// Use first pin defaultly
if (node.outputs) {
inputPin = Object.keys(node.outputs)[0];
}
}
if (node.outputs[inputPin]) {
return {
node: node,
pin: inputPin
};
}
}
}
});
/* harmony default export */ __webpack_exports__["a"] = (Graph);
/***/ }),
/* 172 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__CompositorNode__ = __webpack_require__(42);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__core_glenum__ = __webpack_require__(11);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__FrameBuffer__ = __webpack_require__(10);
/**
* @constructor clay.compositor.SceneNode
* @extends clay.compositor.CompositorNode
*/
var SceneNode = __WEBPACK_IMPORTED_MODULE_0__CompositorNode__["a" /* default */].extend(
/** @lends clay.compositor.SceneNode# */
{
name: 'scene',
/**
* @type {clay.Scene}
*/
scene: null,
/**
* @type {clay.Camera}
*/
camera: null,
/**
* @type {boolean}
*/
autoUpdateScene: true,
/**
* @type {boolean}
*/
preZ: false
}, function() {
this.frameBuffer = new __WEBPACK_IMPORTED_MODULE_2__FrameBuffer__["a" /* default */]();
}, {
render: function(renderer) {
this._rendering = true;
var _gl = renderer.gl;
this.trigger('beforerender');
var renderInfo;
if (!this.outputs) {
renderInfo = renderer.render(this.scene, this.camera, !this.autoUpdateScene, this.preZ);
}
else {
var frameBuffer = this.frameBuffer;
for (var name in this.outputs) {
var parameters = this.updateParameter(name, renderer);
var outputInfo = this.outputs[name];
var texture = this._compositor.allocateTexture(parameters);
this._outputTextures[name] = texture;
var attachment = outputInfo.attachment || _gl.COLOR_ATTACHMENT0;
if (typeof(attachment) == 'string') {
attachment = _gl[attachment];
}
frameBuffer.attach(texture, attachment);
}
frameBuffer.bind(renderer);
// MRT Support in chrome
// https://www.khronos.org/registry/webgl/sdk/tests/conformance/extensions/ext-draw-buffers.html
var ext = renderer.getGLExtension('EXT_draw_buffers');
if (ext) {
var bufs = [];
for (var attachment in this.outputs) {
attachment = parseInt(attachment);
if (attachment >= _gl.COLOR_ATTACHMENT0 && attachment <= _gl.COLOR_ATTACHMENT0 + 8) {
bufs.push(attachment);
}
}
ext.drawBuffersEXT(bufs);
}
// Always clear
// PENDING
renderer.saveClear();
renderer.clearBit = __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].DEPTH_BUFFER_BIT | __WEBPACK_IMPORTED_MODULE_1__core_glenum__["a" /* default */].COLOR_BUFFER_BIT;
renderInfo = renderer.render(this.scene, this.camera, !this.autoUpdateScene, this.preZ);
renderer.restoreClear();
frameBuffer.unbind(renderer);
}
this.trigger('afterrender', renderInfo);
this._rendering = false;
this._rendered = true;
}
});
/* harmony default export */ __webpack_exports__["a"] = (SceneNode);
/***/ }),
/* 173 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__CompositorNode__ = __webpack_require__(42);
/**
* @constructor clay.compositor.TextureNode
* @extends clay.compositor.CompositorNode
*/
var TextureNode = __WEBPACK_IMPORTED_MODULE_0__CompositorNode__["a" /* default */].extend(function() {
return /** @lends clay.compositor.TextureNode# */ {
/**
* @type {clay.Texture2D}
*/
texture: null,
// Texture node must have output without parameters
outputs: {
color: {}
}
};
}, function () {
}, {
getOutput: function (renderer, name) {
return this.texture;
},
// Do nothing
beforeFrame: function () {},
afterFrame: function () {}
});
/* harmony default export */ __webpack_exports__["a"] = (TextureNode);
/***/ }),
/* 174 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Pass__ = __webpack_require__(14);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__CompositorNode__ = __webpack_require__(42);
// TODO Shader library
// TODO curlnoise demo wrong
// PENDING
// Use topological sort ?
/**
* Filter node
*
* @constructor clay.compositor.FilterNode
* @extends clay.compositor.CompositorNode
*
* @example
var node = new clay.compositor.FilterNode({
name: 'fxaa',
shader: clay.Shader.source('clay.compositor.fxaa'),
inputs: {
texture: {
node: 'scene',
pin: 'color'
}
},
// Multiple outputs is preserved for MRT support in WebGL2.0
outputs: {
color: {
attachment: clay.FrameBuffer.COLOR_ATTACHMENT0
parameters: {
format: clay.Texture.RGBA,
width: 512,
height: 512
},
// Node will keep the RTT rendered in last frame
keepLastFrame: true,
// Force the node output the RTT rendered in last frame
outputLastFrame: true
}
}
});
*
*/
var FilterNode = __WEBPACK_IMPORTED_MODULE_1__CompositorNode__["a" /* default */].extend(function () {
return /** @lends clay.compositor.FilterNode# */ {
/**
* @type {string}
*/
name: '',
/**
* @type {Object}
*/
inputs: {},
/**
* @type {Object}
*/
outputs: null,
/**
* @type {string}
*/
shader: '',
/**
* Input links, will be updated by the graph
* @example:
* inputName: {
* node: someNode,
* pin: 'xxxx'
* }
* @type {Object}
*/
inputLinks: {},
/**
* Output links, will be updated by the graph
* @example:
* outputName: {
* node: someNode,
* pin: 'xxxx'
* }
* @type {Object}
*/
outputLinks: {},
/**
* @type {clay.compositor.Pass}
*/
pass: null,
// Save the output texture of previous frame
// Will be used when there exist a circular reference
_prevOutputTextures: {},
_outputTextures: {},
// Example: { name: 2 }
_outputReferences: {},
_rendering: false,
// If rendered in this frame
_rendered: false,
_compositor: null
};
}, function () {
var pass = new __WEBPACK_IMPORTED_MODULE_0__Pass__["a" /* default */]({
fragment: this.shader
});
this.pass = pass;
},
/** @lends clay.compositor.FilterNode.prototype */
{
/**
* @param {clay.Renderer} renderer
*/
render: function (renderer, frameBuffer) {
this.trigger('beforerender', renderer);
this._rendering = true;
var _gl = renderer.gl;
for (var inputName in this.inputLinks) {
var link = this.inputLinks[inputName];
var inputTexture = link.node.getOutput(renderer, link.pin);
this.pass.setUniform(inputName, inputTexture);
}
// Output
if (!this.outputs) {
this.pass.outputs = null;
this._compositor.getFrameBuffer().unbind(renderer);
this.pass.render(renderer, frameBuffer);
}
else {
this.pass.outputs = {};
var attachedTextures = {};
for (var name in this.outputs) {
var parameters = this.updateParameter(name, renderer);
if (isNaN(parameters.width)) {
this.updateParameter(name, renderer);
}
var outputInfo = this.outputs[name];
var texture = this._compositor.allocateTexture(parameters);
this._outputTextures[name] = texture;
var attachment = outputInfo.attachment || _gl.COLOR_ATTACHMENT0;
if (typeof(attachment) == 'string') {
attachment = _gl[attachment];
}
attachedTextures[attachment] = texture;
}
this._compositor.getFrameBuffer().bind(renderer);
for (var attachment in attachedTextures) {
// FIXME attachment changes in different nodes
this._compositor.getFrameBuffer().attach(
attachedTextures[attachment], attachment
);
}
this.pass.render(renderer);
// Because the data of texture is changed over time,
// Here update the mipmaps of texture each time after rendered;
this._compositor.getFrameBuffer().updateMipmap(renderer.gl);
}
for (var inputName in this.inputLinks) {
var link = this.inputLinks[inputName];
link.node.removeReference(link.pin);
}
this._rendering = false;
this._rendered = true;
this.trigger('afterrender', renderer);
},
// TODO Remove parameter function callback
updateParameter: function (outputName, renderer) {
var outputInfo = this.outputs[outputName];
var parameters = outputInfo.parameters;
var parametersCopy = outputInfo._parametersCopy;
if (!parametersCopy) {
parametersCopy = outputInfo._parametersCopy = {};
}
if (parameters) {
for (var key in parameters) {
if (key !== 'width' && key !== 'height') {
parametersCopy[key] = parameters[key];
}
}
}
var width, height;
if (parameters.width instanceof Function) {
width = parameters.width.call(this, renderer);
}
else {
width = parameters.width;
}
if (parameters.height instanceof Function) {
height = parameters.height.call(this, renderer);
}
else {
height = parameters.height;
}
if (
parametersCopy.width !== width
|| parametersCopy.height !== height
) {
if (this._outputTextures[outputName]) {
this._outputTextures[outputName].dispose(renderer);
}
}
parametersCopy.width = width;
parametersCopy.height = height;
return parametersCopy;
},
/**
* Set parameter
* @param {string} name
* @param {} value
*/
setParameter: function (name, value) {
this.pass.setUniform(name, value);
},
/**
* Get parameter value
* @param {string} name
* @return {}
*/
getParameter: function (name) {
return this.pass.getUniform(name);
},
/**
* Set parameters
* @param {Object} obj
*/
setParameters: function (obj) {
for (var name in obj) {
this.setParameter(name, obj[name]);
}
},
// /**
// * Set shader code
// * @param {string} shaderStr
// */
// setShader: function (shaderStr) {
// var material = this.pass.material;
// material.shader.setFragment(shaderStr);
// material.attachShader(material.shader, true);
// },
/**
* Proxy of pass.material.define('fragment', xxx);
* @param {string} symbol
* @param {number} [val]
*/
define: function (symbol, val) {
this.pass.material.define('fragment', symbol, val);
},
/**
* Proxy of pass.material.undefine('fragment', xxx)
* @param {string} symbol
*/
undefine: function (symbol) {
this.pass.material.undefine('fragment', symbol);
},
removeReference: function (outputName) {
this._outputReferences[outputName]--;
if (this._outputReferences[outputName] === 0) {
var outputInfo = this.outputs[outputName];
if (outputInfo.keepLastFrame) {
if (this._prevOutputTextures[outputName]) {
this._compositor.releaseTexture(this._prevOutputTextures[outputName]);
}
this._prevOutputTextures[outputName] = this._outputTextures[outputName];
}
else {
// Output of this node have alreay been used by all other nodes
// Put the texture back to the pool.
this._compositor.releaseTexture(this._outputTextures[outputName]);
}
}
},
clear: function () {
__WEBPACK_IMPORTED_MODULE_1__CompositorNode__["a" /* default */].prototype.clear.call(this);
// Default disable all texture
this.pass.material.disableTexturesAll();
}
});
/* harmony default export */ __webpack_exports__["a"] = (FilterNode);
/***/ }),
/* 175 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__source_compositor_coloradjust_glsl_js__ = __webpack_require__(176);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__source_compositor_blur_glsl_js__ = __webpack_require__(80);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__source_compositor_lum_glsl_js__ = __webpack_require__(177);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__source_compositor_lut_glsl_js__ = __webpack_require__(81);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__source_compositor_vignette_glsl_js__ = __webpack_require__(178);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__source_compositor_output_glsl_js__ = __webpack_require__(82);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__source_compositor_bright_glsl_js__ = __webpack_require__(83);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__source_compositor_downsample_glsl_js__ = __webpack_require__(84);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__source_compositor_upsample_glsl_js__ = __webpack_require__(85);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__source_compositor_hdr_glsl_js__ = __webpack_require__(86);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__source_compositor_dof_glsl_js__ = __webpack_require__(179);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__source_compositor_lensflare_glsl_js__ = __webpack_require__(180);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_13__source_compositor_blend_glsl_js__ = __webpack_require__(87);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_14__source_compositor_fxaa_glsl_js__ = __webpack_require__(88);
// import fxaa3Essl from './source/compositor/fxaa3.glsl.js';
// Some build in shaders
__WEBPACK_IMPORTED_MODULE_0__Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_1__source_compositor_coloradjust_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0__Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_2__source_compositor_blur_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0__Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_3__source_compositor_lum_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0__Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_4__source_compositor_lut_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0__Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_5__source_compositor_vignette_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0__Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_6__source_compositor_output_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0__Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_7__source_compositor_bright_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0__Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_8__source_compositor_downsample_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0__Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_9__source_compositor_upsample_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0__Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_10__source_compositor_hdr_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0__Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_11__source_compositor_dof_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0__Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_12__source_compositor_lensflare_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0__Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_13__source_compositor_blend_glsl_js__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0__Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_14__source_compositor_fxaa_glsl_js__["a" /* default */]);
// Shader['import'](fxaa3Essl);
/***/ }),
/* 176 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.compositor.coloradjust\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float brightness : 0.0;\nuniform float contrast : 1.0;\nuniform float exposure : 0.0;\nuniform float gamma : 1.0;\nuniform float saturation : 1.0;\nconst vec3 w = vec3(0.2125, 0.7154, 0.0721);\nvoid main()\n{\n vec4 tex = texture2D( texture, v_Texcoord);\n vec3 color = clamp(tex.rgb + vec3(brightness), 0.0, 1.0);\n color = clamp( (color-vec3(0.5))*contrast+vec3(0.5), 0.0, 1.0);\n color = clamp( color * pow(2.0, exposure), 0.0, 1.0);\n color = clamp( pow(color, vec3(gamma)), 0.0, 1.0);\n float luminance = dot( color, w );\n color = mix(vec3(luminance), color, saturation);\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.brightness\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float brightness : 0.0;\nvoid main()\n{\n vec4 tex = texture2D( texture, v_Texcoord);\n vec3 color = tex.rgb + vec3(brightness);\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.contrast\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float contrast : 1.0;\nvoid main()\n{\n vec4 tex = texture2D( texture, v_Texcoord);\n vec3 color = (tex.rgb-vec3(0.5))*contrast+vec3(0.5);\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.exposure\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float exposure : 0.0;\nvoid main()\n{\n vec4 tex = texture2D(texture, v_Texcoord);\n vec3 color = tex.rgb * pow(2.0, exposure);\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.gamma\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float gamma : 1.0;\nvoid main()\n{\n vec4 tex = texture2D(texture, v_Texcoord);\n vec3 color = pow(tex.rgb, vec3(gamma));\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.saturation\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float saturation : 1.0;\nconst vec3 w = vec3(0.2125, 0.7154, 0.0721);\nvoid main()\n{\n vec4 tex = texture2D(texture, v_Texcoord);\n vec3 color = tex.rgb;\n float luminance = dot(color, w);\n color = mix(vec3(luminance), color, saturation);\n gl_FragColor = vec4(color, tex.a);\n}\n@end");
/***/ }),
/* 177 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.compositor.hdr.log_lum\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nconst vec3 w = vec3(0.2125, 0.7154, 0.0721);\n@import clay.util.rgbm\nvoid main()\n{\n vec4 tex = decodeHDR(texture2D(texture, v_Texcoord));\n float luminance = dot(tex.rgb, w);\n luminance = log(luminance + 0.001);\n gl_FragColor = encodeHDR(vec4(vec3(luminance), 1.0));\n}\n@end\n@export clay.compositor.hdr.lum_adaption\nvarying vec2 v_Texcoord;\nuniform sampler2D adaptedLum;\nuniform sampler2D currentLum;\nuniform float frameTime : 0.02;\n@import clay.util.rgbm\nvoid main()\n{\n float fAdaptedLum = decodeHDR(texture2D(adaptedLum, vec2(0.5, 0.5))).r;\n float fCurrentLum = exp(encodeHDR(texture2D(currentLum, vec2(0.5, 0.5))).r);\n fAdaptedLum += (fCurrentLum - fAdaptedLum) * (1.0 - pow(0.98, 30.0 * frameTime));\n gl_FragColor = encodeHDR(vec4(vec3(fAdaptedLum), 1.0));\n}\n@end\n@export clay.compositor.lum\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nconst vec3 w = vec3(0.2125, 0.7154, 0.0721);\nvoid main()\n{\n vec4 tex = texture2D( texture, v_Texcoord );\n float luminance = dot(tex.rgb, w);\n gl_FragColor = vec4(vec3(luminance), 1.0);\n}\n@end");
/***/ }),
/* 178 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.compositor.vignette\n#define OUTPUT_ALPHA\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float darkness: 1;\nuniform float offset: 1;\n@import clay.util.rgbm\nvoid main()\n{\n vec4 texel = decodeHDR(texture2D(texture, v_Texcoord));\n gl_FragColor.rgb = texel.rgb;\n vec2 uv = (v_Texcoord - vec2(0.5)) * vec2(offset);\n gl_FragColor = encodeHDR(vec4(mix(texel.rgb, vec3(1.0 - darkness), dot(uv, uv)), texel.a));\n}\n@end");
/***/ }),
/* 179 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.compositor.dof.coc\nuniform sampler2D depth;\nuniform float zNear: 0.1;\nuniform float zFar: 2000;\nuniform float focalDist: 3;\nuniform float focalRange: 1;\nuniform float focalLength: 30;\nuniform float fstop: 2.8;\nvarying vec2 v_Texcoord;\n@import clay.util.encode_float\nvoid main()\n{\n float z = texture2D(depth, v_Texcoord).r * 2.0 - 1.0;\n float dist = 2.0 * zNear * zFar / (zFar + zNear - z * (zFar - zNear));\n float aperture = focalLength / fstop;\n float coc;\n float uppper = focalDist + focalRange;\n float lower = focalDist - focalRange;\n if (dist <= uppper && dist >= lower) {\n coc = 0.5;\n }\n else {\n float focalAdjusted = dist > uppper ? uppper : lower;\n coc = abs(aperture * (focalLength * (dist - focalAdjusted)) / (dist * (focalAdjusted - focalLength)));\n coc = clamp(coc, 0.0, 0.4) / 0.4000001;\n if (dist < lower) {\n coc = -coc;\n }\n coc = coc * 0.5 + 0.5;\n }\n gl_FragColor = encodeFloat(coc);\n}\n@end\n@export clay.compositor.dof.premultiply\nuniform sampler2D texture;\nuniform sampler2D coc;\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\n@import clay.util.decode_float\nvoid main() {\n float fCoc = max(abs(decodeFloat(texture2D(coc, v_Texcoord)) * 2.0 - 1.0), 0.1);\n gl_FragColor = encodeHDR(\n vec4(decodeHDR(texture2D(texture, v_Texcoord)).rgb * fCoc, 1.0)\n );\n}\n@end\n@export clay.compositor.dof.min_coc\nuniform sampler2D coc;\nvarying vec2 v_Texcoord;\nuniform vec2 textureSize : [512.0, 512.0];\n@import clay.util.float\nvoid main()\n{\n vec4 d = vec4(-1.0, -1.0, 1.0, 1.0) / textureSize.xyxy;\n float fCoc = decodeFloat(texture2D(coc, v_Texcoord + d.xy));\n fCoc = min(fCoc, decodeFloat(texture2D(coc, v_Texcoord + d.zy)));\n fCoc = min(fCoc, decodeFloat(texture2D(coc, v_Texcoord + d.xw)));\n fCoc = min(fCoc, decodeFloat(texture2D(coc, v_Texcoord + d.zw)));\n gl_FragColor = encodeFloat(fCoc);\n}\n@end\n@export clay.compositor.dof.max_coc\nuniform sampler2D coc;\nvarying vec2 v_Texcoord;\nuniform vec2 textureSize : [512.0, 512.0];\n@import clay.util.float\nvoid main()\n{\n vec4 d = vec4(-1.0, -1.0, 1.0, 1.0) / textureSize.xyxy;\n float fCoc = decodeFloat(texture2D(coc, v_Texcoord + d.xy));\n fCoc = max(fCoc, decodeFloat(texture2D(coc, v_Texcoord + d.zy)));\n fCoc = max(fCoc, decodeFloat(texture2D(coc, v_Texcoord + d.xw)));\n fCoc = max(fCoc, decodeFloat(texture2D(coc, v_Texcoord + d.zw)));\n gl_FragColor = encodeFloat(fCoc);\n}\n@end\n@export clay.compositor.dof.coc_upsample\n#define HIGH_QUALITY\nuniform sampler2D coc;\nuniform vec2 textureSize : [512, 512];\nuniform float sampleScale: 0.5;\nvarying vec2 v_Texcoord;\n@import clay.util.float\nvoid main()\n{\n#ifdef HIGH_QUALITY\n vec4 d = vec4(1.0, 1.0, -1.0, 0.0) / textureSize.xyxy * sampleScale;\n float s;\n s = decodeFloat(texture2D(coc, v_Texcoord - d.xy));\n s += decodeFloat(texture2D(coc, v_Texcoord - d.wy)) * 2.0;\n s += decodeFloat(texture2D(coc, v_Texcoord - d.zy));\n s += decodeFloat(texture2D(coc, v_Texcoord + d.zw)) * 2.0;\n s += decodeFloat(texture2D(coc, v_Texcoord )) * 4.0;\n s += decodeFloat(texture2D(coc, v_Texcoord + d.xw)) * 2.0;\n s += decodeFloat(texture2D(coc, v_Texcoord + d.zy));\n s += decodeFloat(texture2D(coc, v_Texcoord + d.wy)) * 2.0;\n s += decodeFloat(texture2D(coc, v_Texcoord + d.xy));\n gl_FragColor = encodeFloat(s / 16.0);\n#else\n vec4 d = vec4(-1.0, -1.0, +1.0, +1.0) / textureSize.xyxy;\n float s;\n s = decodeFloat(texture2D(coc, v_Texcoord + d.xy));\n s += decodeFloat(texture2D(coc, v_Texcoord + d.zy));\n s += decodeFloat(texture2D(coc, v_Texcoord + d.xw));\n s += decodeFloat(texture2D(coc, v_Texcoord + d.zw));\n gl_FragColor = encodeFloat(s / 4.0);\n#endif\n}\n@end\n@export clay.compositor.dof.upsample\n#define HIGH_QUALITY\nuniform sampler2D coc;\nuniform sampler2D texture;\nuniform vec2 textureSize : [512, 512];\nuniform float sampleScale: 0.5;\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\n@import clay.util.decode_float\nfloat tap(vec2 uv, inout vec4 color, float baseWeight) {\n float weight = abs(decodeFloat(texture2D(coc, uv)) * 2.0 - 1.0) * baseWeight;\n color += decodeHDR(texture2D(texture, uv)) * weight;\n return weight;\n}\nvoid main()\n{\n#ifdef HIGH_QUALITY\n vec4 d = vec4(1.0, 1.0, -1.0, 0.0) / textureSize.xyxy * sampleScale;\n vec4 color = vec4(0.0);\n float baseWeight = 1.0 / 16.0;\n float w = tap(v_Texcoord - d.xy, color, baseWeight);\n w += tap(v_Texcoord - d.wy, color, baseWeight * 2.0);\n w += tap(v_Texcoord - d.zy, color, baseWeight);\n w += tap(v_Texcoord + d.zw, color, baseWeight * 2.0);\n w += tap(v_Texcoord , color, baseWeight * 4.0);\n w += tap(v_Texcoord + d.xw, color, baseWeight * 2.0);\n w += tap(v_Texcoord + d.zy, color, baseWeight);\n w += tap(v_Texcoord + d.wy, color, baseWeight * 2.0);\n w += tap(v_Texcoord + d.xy, color, baseWeight);\n gl_FragColor = encodeHDR(color / w);\n#else\n vec4 d = vec4(-1.0, -1.0, +1.0, +1.0) / textureSize.xyxy;\n vec4 color = vec4(0.0);\n float baseWeight = 1.0 / 4.0;\n float w = tap(v_Texcoord + d.xy, color, baseWeight);\n w += tap(v_Texcoord + d.zy, color, baseWeight);\n w += tap(v_Texcoord + d.xw, color, baseWeight);\n w += tap(v_Texcoord + d.zw, color, baseWeight);\n gl_FragColor = encodeHDR(color / w);\n#endif\n}\n@end\n@export clay.compositor.dof.downsample\nuniform sampler2D texture;\nuniform sampler2D coc;\nuniform vec2 textureSize : [512, 512];\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\n@import clay.util.decode_float\nfloat tap(vec2 uv, inout vec4 color) {\n float weight = abs(decodeFloat(texture2D(coc, uv)) * 2.0 - 1.0) * 0.25;\n color += decodeHDR(texture2D(texture, uv)) * weight;\n return weight;\n}\nvoid main()\n{\n vec4 d = vec4(-1.0, -1.0, 1.0, 1.0) / textureSize.xyxy;\n vec4 color = vec4(0.0);\n float weight = tap(v_Texcoord + d.xy, color);\n weight += tap(v_Texcoord + d.zy, color);\n weight += tap(v_Texcoord + d.xw, color);\n weight += tap(v_Texcoord + d.zw, color);\n color /= weight;\n gl_FragColor = encodeHDR(color);\n}\n@end\n@export clay.compositor.dof.hexagonal_blur_frag\n@import clay.util.float\nvec4 doBlur(sampler2D targetTexture, vec2 offset) {\n#ifdef BLUR_COC\n float cocSum = 0.0;\n#else\n vec4 color = vec4(0.0);\n#endif\n float weightSum = 0.0;\n float kernelWeight = 1.0 / float(KERNEL_SIZE);\n for (int i = 0; i < KERNEL_SIZE; i++) {\n vec2 coord = v_Texcoord + offset * float(i);\n float w = kernelWeight;\n#ifdef BLUR_COC\n float fCoc = decodeFloat(texture2D(targetTexture, coord)) * 2.0 - 1.0;\n cocSum += clamp(fCoc, -1.0, 0.0) * w;\n#else\n float fCoc = decodeFloat(texture2D(coc, coord)) * 2.0 - 1.0;\n vec4 texel = texture2D(targetTexture, coord);\n #if !defined(BLUR_NEARFIELD)\n w *= abs(fCoc);\n #endif\n color += decodeHDR(texel) * w;\n#endif\n weightSum += w;\n }\n#ifdef BLUR_COC\n return encodeFloat(clamp(cocSum / weightSum, -1.0, 0.0) * 0.5 + 0.5);\n#else\n return color / weightSum;\n#endif\n}\n@end\n@export clay.compositor.dof.hexagonal_blur_1\n#define KERNEL_SIZE 5\nuniform sampler2D texture;\nuniform sampler2D coc;\nvarying vec2 v_Texcoord;\nuniform float blurSize : 1.0;\nuniform vec2 textureSize : [512.0, 512.0];\n@import clay.util.rgbm\n@import clay.compositor.dof.hexagonal_blur_frag\nvoid main()\n{\n vec2 offset = blurSize / textureSize;\n#if !defined(BLUR_NEARFIELD) && !defined(BLUR_COC)\n offset *= abs(decodeFloat(texture2D(coc, v_Texcoord)) * 2.0 - 1.0);\n#endif\n gl_FragColor = doBlur(texture, vec2(0.0, offset.y));\n#if !defined(BLUR_COC)\n gl_FragColor = encodeHDR(gl_FragColor);\n#endif\n}\n@end\n@export clay.compositor.dof.hexagonal_blur_2\n#define KERNEL_SIZE 5\nuniform sampler2D texture;\nuniform sampler2D coc;\nvarying vec2 v_Texcoord;\nuniform float blurSize : 1.0;\nuniform vec2 textureSize : [512.0, 512.0];\n@import clay.util.rgbm\n@import clay.compositor.dof.hexagonal_blur_frag\nvoid main()\n{\n vec2 offset = blurSize / textureSize;\n#if !defined(BLUR_NEARFIELD) && !defined(BLUR_COC)\n offset *= abs(decodeFloat(texture2D(coc, v_Texcoord)) * 2.0 - 1.0);\n#endif\n offset.y /= 2.0;\n gl_FragColor = doBlur(texture, -offset);\n#if !defined(BLUR_COC)\n gl_FragColor = encodeHDR(gl_FragColor);\n#endif\n}\n@end\n@export clay.compositor.dof.hexagonal_blur_3\n#define KERNEL_SIZE 5\nuniform sampler2D texture1;\nuniform sampler2D texture2;\nuniform sampler2D coc;\nvarying vec2 v_Texcoord;\nuniform float blurSize : 1.0;\nuniform vec2 textureSize : [512.0, 512.0];\n@import clay.util.rgbm\n@import clay.compositor.dof.hexagonal_blur_frag\nvoid main()\n{\n vec2 offset = blurSize / textureSize;\n#if !defined(BLUR_NEARFIELD) && !defined(BLUR_COC)\n offset *= abs(decodeFloat(texture2D(coc, v_Texcoord)) * 2.0 - 1.0);\n#endif\n offset.y /= 2.0;\n vec2 vDownRight = vec2(offset.x, -offset.y);\n vec4 texel1 = doBlur(texture1, -offset);\n vec4 texel2 = doBlur(texture1, vDownRight);\n vec4 texel3 = doBlur(texture2, vDownRight);\n#ifdef BLUR_COC\n float coc1 = decodeFloat(texel1) * 2.0 - 1.0;\n float coc2 = decodeFloat(texel2) * 2.0 - 1.0;\n float coc3 = decodeFloat(texel3) * 2.0 - 1.0;\n gl_FragColor = encodeFloat(\n ((coc1 + coc2 + coc3) / 3.0) * 0.5 + 0.5\n );\n#else\n vec4 color = (texel1 + texel2 + texel3) / 3.0;\n gl_FragColor = encodeHDR(color);\n#endif\n}\n@end\n@export clay.compositor.dof.composite\n#define DEBUG 0\nuniform sampler2D original;\nuniform sampler2D blurred;\nuniform sampler2D nearfield;\nuniform sampler2D coc;\nuniform sampler2D nearcoc;\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\n@import clay.util.float\nvoid main()\n{\n vec4 blurredColor = decodeHDR(texture2D(blurred, v_Texcoord));\n vec4 originalColor = decodeHDR(texture2D(original, v_Texcoord));\n float fCoc = decodeFloat(texture2D(coc, v_Texcoord));\n fCoc = abs(fCoc * 2.0 - 1.0);\n float weight = smoothstep(0.0, 1.0, fCoc);\n#ifdef NEARFIELD_ENABLED\n vec4 nearfieldColor = decodeHDR(texture2D(nearfield, v_Texcoord));\n float fNearCoc = decodeFloat(texture2D(nearcoc, v_Texcoord));\n fNearCoc = abs(fNearCoc * 2.0 - 1.0);\n gl_FragColor = encodeHDR(\n mix(\n nearfieldColor, mix(originalColor, blurredColor, weight),\n pow(1.0 - fNearCoc, 4.0)\n )\n );\n#else\n gl_FragColor = encodeHDR(mix(originalColor, blurredColor, weight));\n#endif\n#if DEBUG == 1\n gl_FragColor = vec4(vec3(fCoc), 1.0);\n#elif DEBUG == 2\n gl_FragColor = vec4(vec3(fNearCoc), 1.0);\n#elif DEBUG == 3\n gl_FragColor = encodeHDR(blurredColor);\n#elif DEBUG == 4\n gl_FragColor = encodeHDR(nearfieldColor);\n#endif\n}\n@end");
/***/ }),
/* 180 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export clay.compositor.lensflare\n#define SAMPLE_NUMBER 8\nuniform sampler2D texture;\nuniform sampler2D lenscolor;\nuniform vec2 textureSize : [512, 512];\nuniform float dispersal : 0.3;\nuniform float haloWidth : 0.4;\nuniform float distortion : 1.0;\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\nvec4 textureDistorted(\n in vec2 texcoord,\n in vec2 direction,\n in vec3 distortion\n) {\n return vec4(\n decodeHDR(texture2D(texture, texcoord + direction * distortion.r)).r,\n decodeHDR(texture2D(texture, texcoord + direction * distortion.g)).g,\n decodeHDR(texture2D(texture, texcoord + direction * distortion.b)).b,\n 1.0\n );\n}\nvoid main()\n{\n vec2 texcoord = -v_Texcoord + vec2(1.0); vec2 textureOffset = 1.0 / textureSize;\n vec2 ghostVec = (vec2(0.5) - texcoord) * dispersal;\n vec2 haloVec = normalize(ghostVec) * haloWidth;\n vec3 distortion = vec3(-textureOffset.x * distortion, 0.0, textureOffset.x * distortion);\n vec4 result = vec4(0.0);\n for (int i = 0; i < SAMPLE_NUMBER; i++)\n {\n vec2 offset = fract(texcoord + ghostVec * float(i));\n float weight = length(vec2(0.5) - offset) / length(vec2(0.5));\n weight = pow(1.0 - weight, 10.0);\n result += textureDistorted(offset, normalize(ghostVec), distortion) * weight;\n }\n result *= texture2D(lenscolor, vec2(length(vec2(0.5) - texcoord)) / length(vec2(0.5)));\n float weight = length(vec2(0.5) - fract(texcoord + haloVec)) / length(vec2(0.5));\n weight = pow(1.0 - weight, 10.0);\n vec2 offset = fract(texcoord + haloVec);\n result += textureDistorted(offset, normalize(ghostVec), distortion) * weight;\n gl_FragColor = result;\n}\n@end");
/***/ }),
/* 181 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_math_Matrix4__ = __webpack_require__(7);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector3__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_claygl_src_compositor_Pass__ = __webpack_require__(14);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_claygl_src_Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_claygl_src_FrameBuffer__ = __webpack_require__(10);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__halton__ = __webpack_require__(43);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__SSAO_glsl_js__ = __webpack_require__(182);
__WEBPACK_IMPORTED_MODULE_5_claygl_src_Shader__["a" /* default */].import(__WEBPACK_IMPORTED_MODULE_8__SSAO_glsl_js__["a" /* default */]);
function generateNoiseData(size) {
var data = new Uint8Array(size * size * 4);
var n = 0;
var v3 = new __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector3__["a" /* default */]();
for (var i = 0; i < size; i++) {
for (var j = 0; j < size; j++) {
v3.set(Math.random() * 2 - 1, Math.random() * 2 - 1, 0).normalize();
data[n++] = (v3.x * 0.5 + 0.5) * 255;
data[n++] = (v3.y * 0.5 + 0.5) * 255;
data[n++] = 0;
data[n++] = 255;
}
}
return data;
}
function generateNoiseTexture(size) {
return new __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__["a" /* default */]({
pixels: generateNoiseData(size),
wrapS: __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__["a" /* default */].REPEAT,
wrapT: __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__["a" /* default */].REPEAT,
width: size,
height: size
});
}
function generateKernel(size, offset, hemisphere) {
var kernel = new Float32Array(size * 3);
offset = offset || 0;
for (var i = 0; i < size; i++) {
var phi = Object(__WEBPACK_IMPORTED_MODULE_7__halton__["a" /* default */])(i + offset, 2) * (hemisphere ? 1 : 2) * Math.PI;
var theta = Object(__WEBPACK_IMPORTED_MODULE_7__halton__["a" /* default */])(i + offset, 3) * Math.PI;
var r = Math.random();
var x = Math.cos(phi) * Math.sin(theta) * r;
var y = Math.cos(theta) * r;
var z = Math.sin(phi) * Math.sin(theta) * r;
kernel[i * 3] = x;
kernel[i * 3 + 1] = y;
kernel[i * 3 + 2] = z;
}
return kernel;
// var kernel = new Float32Array(size * 3);
// var v3 = new Vector3();
// for (var i = 0; i < size; i++) {
// v3.set(Math.random() * 2 - 1, Math.random() * 2 - 1, Math.random())
// .normalize().scale(Math.random());
// kernel[i * 3] = v3.x;
// kernel[i * 3 + 1] = v3.y;
// kernel[i * 3 + 2] = v3.z;
// }
// return kernel;
}
function SSAOPass(opt) {
opt = opt || {};
this._ssaoPass = new __WEBPACK_IMPORTED_MODULE_4_claygl_src_compositor_Pass__["a" /* default */]({
fragment: __WEBPACK_IMPORTED_MODULE_5_claygl_src_Shader__["a" /* default */].source('ecgl.ssao.estimate')
});
this._blurPass = new __WEBPACK_IMPORTED_MODULE_4_claygl_src_compositor_Pass__["a" /* default */]({
fragment: __WEBPACK_IMPORTED_MODULE_5_claygl_src_Shader__["a" /* default */].source('ecgl.ssao.blur')
});
this._framebuffer = new __WEBPACK_IMPORTED_MODULE_6_claygl_src_FrameBuffer__["a" /* default */]({
depthBuffer: false
});
this._ssaoTexture = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__["a" /* default */]();
this._blurTexture = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__["a" /* default */]();
this._blurTexture2 = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__["a" /* default */]();
this._depthTex = opt.depthTexture;
this._normalTex = opt.normalTexture;
this.setNoiseSize(4);
this.setKernelSize(opt.kernelSize || 12);
if (opt.radius != null) {
this.setParameter('radius', opt.radius);
}
if (opt.power != null) {
this.setParameter('power', opt.power);
}
if (!this._normalTex) {
this._ssaoPass.material.disableTexture('normalTex');
this._blurPass.material.disableTexture('normalTex');
}
if (!this._depthTex) {
this._blurPass.material.disableTexture('depthTex');
}
this._blurPass.material.setUniform('normalTex', this._normalTex);
this._blurPass.material.setUniform('depthTex', this._depthTex);
}
SSAOPass.prototype.setDepthTexture = function (depthTex) {
this._depthTex = depthTex;
};
SSAOPass.prototype.setNormalTexture = function (normalTex) {
this._normalTex = normalTex;
this._ssaoPass.material[normalTex ? 'enableTexture' : 'disableTexture']('normalTex');
// Switch between hemisphere and shere kernel.
this.setKernelSize(this._kernelSize);
};
SSAOPass.prototype.update = function (renderer, camera, frame) {
var width = renderer.getWidth();
var height = renderer.getHeight();
var ssaoPass = this._ssaoPass;
var blurPass = this._blurPass;
ssaoPass.setUniform('kernel', this._kernels[frame % this._kernels.length]);
ssaoPass.setUniform('depthTex', this._depthTex);
if (this._normalTex != null) {
ssaoPass.setUniform('normalTex', this._normalTex);
}
ssaoPass.setUniform('depthTexSize', [this._depthTex.width, this._depthTex.height]);
var viewInverseTranspose = new __WEBPACK_IMPORTED_MODULE_0_claygl_src_math_Matrix4__["a" /* default */]();
__WEBPACK_IMPORTED_MODULE_0_claygl_src_math_Matrix4__["a" /* default */].transpose(viewInverseTranspose, camera.worldTransform);
ssaoPass.setUniform('projection', camera.projectionMatrix.array);
ssaoPass.setUniform('projectionInv', camera.invProjectionMatrix.array);
ssaoPass.setUniform('viewInverseTranspose', viewInverseTranspose.array);
var ssaoTexture = this._ssaoTexture;
var blurTexture = this._blurTexture;
var blurTexture2 = this._blurTexture2;
ssaoTexture.width = width / 2;
ssaoTexture.height = height / 2;
blurTexture.width = width;
blurTexture.height = height;
blurTexture2.width = width;
blurTexture2.height = height;
this._framebuffer.attach(ssaoTexture);
this._framebuffer.bind(renderer);
renderer.gl.clearColor(1, 1, 1, 1);
renderer.gl.clear(renderer.gl.COLOR_BUFFER_BIT);
ssaoPass.render(renderer);
blurPass.setUniform('textureSize', [width / 2, height / 2]);
blurPass.setUniform('projection', camera.projectionMatrix.array);
this._framebuffer.attach(blurTexture);
blurPass.setUniform('direction', 0);
blurPass.setUniform('ssaoTexture', ssaoTexture);
blurPass.render(renderer);
this._framebuffer.attach(blurTexture2);
blurPass.setUniform('textureSize', [width, height]);
blurPass.setUniform('direction', 1);
blurPass.setUniform('ssaoTexture', blurTexture);
blurPass.render(renderer);
this._framebuffer.unbind(renderer);
// Restore clear
var clearColor = renderer.clearColor;
renderer.gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
};
SSAOPass.prototype.getTargetTexture = function () {
return this._blurTexture2;
}
SSAOPass.prototype.setParameter = function (name, val) {
if (name === 'noiseTexSize') {
this.setNoiseSize(val);
}
else if (name === 'kernelSize') {
this.setKernelSize(val);
}
else if (name === 'intensity') {
this._ssaoPass.material.set('intensity', val);
}
else {
this._ssaoPass.setUniform(name, val);
}
};
SSAOPass.prototype.setKernelSize = function (size) {
this._kernelSize = size;
this._ssaoPass.material.define('fragment', 'KERNEL_SIZE', size);
this._kernels = this._kernels || [];
for (var i = 0; i < 30; i++) {
this._kernels[i] = generateKernel(size, i * size, !!this._normalTex);
}
};
SSAOPass.prototype.setNoiseSize = function (size) {
var texture = this._ssaoPass.getUniform('noiseTex');
if (!texture) {
texture = generateNoiseTexture(size);
this._ssaoPass.setUniform('noiseTex', generateNoiseTexture(size));
}
else {
texture.data = generateNoiseData(size);
texture.width = texture.height = size;
texture.dirty();
}
this._ssaoPass.setUniform('noiseTexSize', [size, size]);
};
SSAOPass.prototype.dispose = function (renderer) {
this._blurTexture.dispose(renderer);
this._ssaoTexture.dispose(renderer);
this._blurTexture2.dispose(renderer);
};
/* harmony default export */ __webpack_exports__["a"] = (SSAOPass);
/***/ }),
/* 182 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.ssao.estimate\n\nuniform sampler2D depthTex;\n\nuniform sampler2D normalTex;\n\nuniform sampler2D noiseTex;\n\nuniform vec2 depthTexSize;\n\nuniform vec2 noiseTexSize;\n\nuniform mat4 projection;\n\nuniform mat4 projectionInv;\n\nuniform mat4 viewInverseTranspose;\n\nuniform vec3 kernel[KERNEL_SIZE];\n\nuniform float radius : 1;\n\nuniform float power : 1;\n\nuniform float bias: 1e-2;\n\nuniform float intensity: 1.0;\n\nvarying vec2 v_Texcoord;\n\nfloat ssaoEstimator(in vec3 originPos, in mat3 kernelBasis) {\n float occlusion = 0.0;\n\n for (int i = 0; i < KERNEL_SIZE; i++) {\n vec3 samplePos = kernel[i];\n#ifdef NORMALTEX_ENABLED\n samplePos = kernelBasis * samplePos;\n#endif\n samplePos = samplePos * radius + originPos;\n\n vec4 texCoord = projection * vec4(samplePos, 1.0);\n texCoord.xy /= texCoord.w;\n\n vec4 depthTexel = texture2D(depthTex, texCoord.xy * 0.5 + 0.5);\n\n float sampleDepth = depthTexel.r * 2.0 - 1.0;\n if (projection[3][3] == 0.0) {\n sampleDepth = projection[3][2] / (sampleDepth * projection[2][3] - projection[2][2]);\n }\n else {\n sampleDepth = (sampleDepth - projection[3][2]) / projection[2][2];\n }\n \n float rangeCheck = smoothstep(0.0, 1.0, radius / abs(originPos.z - sampleDepth));\n occlusion += rangeCheck * step(samplePos.z, sampleDepth - bias);\n }\n#ifdef NORMALTEX_ENABLED\n occlusion = 1.0 - occlusion / float(KERNEL_SIZE);\n#else\n occlusion = 1.0 - clamp((occlusion / float(KERNEL_SIZE) - 0.6) * 2.5, 0.0, 1.0);\n#endif\n return pow(occlusion, power);\n}\n\nvoid main()\n{\n\n vec4 depthTexel = texture2D(depthTex, v_Texcoord);\n\n#ifdef NORMALTEX_ENABLED\n vec4 tex = texture2D(normalTex, v_Texcoord);\n if (dot(tex.rgb, tex.rgb) == 0.0) {\n gl_FragColor = vec4(1.0);\n return;\n }\n vec3 N = tex.rgb * 2.0 - 1.0;\n N = (viewInverseTranspose * vec4(N, 0.0)).xyz;\n\n vec2 noiseTexCoord = depthTexSize / vec2(noiseTexSize) * v_Texcoord;\n vec3 rvec = texture2D(noiseTex, noiseTexCoord).rgb * 2.0 - 1.0;\n vec3 T = normalize(rvec - N * dot(rvec, N));\n vec3 BT = normalize(cross(N, T));\n mat3 kernelBasis = mat3(T, BT, N);\n#else\n if (depthTexel.r > 0.99999) {\n gl_FragColor = vec4(1.0);\n return;\n }\n mat3 kernelBasis;\n#endif\n\n float z = depthTexel.r * 2.0 - 1.0;\n\n vec4 projectedPos = vec4(v_Texcoord * 2.0 - 1.0, z, 1.0);\n vec4 p4 = projectionInv * projectedPos;\n\n vec3 position = p4.xyz / p4.w;\n\n float ao = ssaoEstimator(position, kernelBasis);\n ao = clamp(1.0 - (1.0 - ao) * intensity, 0.0, 1.0);\n gl_FragColor = vec4(vec3(ao), 1.0);\n}\n\n@end\n\n\n@export ecgl.ssao.blur\n#define SHADER_NAME SSAO_BLUR\n\nuniform sampler2D ssaoTexture;\n\n#ifdef NORMALTEX_ENABLED\nuniform sampler2D normalTex;\n#endif\n\nvarying vec2 v_Texcoord;\n\nuniform vec2 textureSize;\nuniform float blurSize : 1.0;\n\nuniform int direction: 0.0;\n\n#ifdef DEPTHTEX_ENABLED\nuniform sampler2D depthTex;\nuniform mat4 projection;\nuniform float depthRange : 0.5;\n\nfloat getLinearDepth(vec2 coord)\n{\n float depth = texture2D(depthTex, coord).r * 2.0 - 1.0;\n return projection[3][2] / (depth * projection[2][3] - projection[2][2]);\n}\n#endif\n\nvoid main()\n{\n float kernel[5];\n kernel[0] = 0.122581;\n kernel[1] = 0.233062;\n kernel[2] = 0.288713;\n kernel[3] = 0.233062;\n kernel[4] = 0.122581;\n\n vec2 off = vec2(0.0);\n if (direction == 0) {\n off[0] = blurSize / textureSize.x;\n }\n else {\n off[1] = blurSize / textureSize.y;\n }\n\n vec2 coord = v_Texcoord;\n\n float sum = 0.0;\n float weightAll = 0.0;\n\n#ifdef NORMALTEX_ENABLED\n vec3 centerNormal = texture2D(normalTex, v_Texcoord).rgb * 2.0 - 1.0;\n#endif\n#if defined(DEPTHTEX_ENABLED)\n float centerDepth = getLinearDepth(v_Texcoord);\n#endif\n\n for (int i = 0; i < 5; i++) {\n vec2 coord = clamp(v_Texcoord + vec2(float(i) - 2.0) * off, vec2(0.0), vec2(1.0));\n\n float w = kernel[i];\n#ifdef NORMALTEX_ENABLED\n vec3 normal = texture2D(normalTex, coord).rgb * 2.0 - 1.0;\n w *= clamp(dot(normal, centerNormal), 0.0, 1.0);\n#endif\n#ifdef DEPTHTEX_ENABLED\n float d = getLinearDepth(coord);\n w *= (1.0 - smoothstep(abs(centerDepth - d) / depthRange, 0.0, 1.0));\n#endif\n\n weightAll += w;\n sum += texture2D(ssaoTexture, coord).r * w;\n }\n\n gl_FragColor = vec4(vec3(sum / weightAll), 1.0);\n}\n\n@end\n");
/***/ }),
/* 183 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_math_Matrix4__ = __webpack_require__(7);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector3__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_claygl_src_compositor_Pass__ = __webpack_require__(14);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_claygl_src_Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_claygl_src_FrameBuffer__ = __webpack_require__(10);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__halton__ = __webpack_require__(43);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8_claygl_src_util_cubemap__ = __webpack_require__(70);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__SSR_glsl_js__ = __webpack_require__(184);
__WEBPACK_IMPORTED_MODULE_5_claygl_src_Shader__["a" /* default */].import(__WEBPACK_IMPORTED_MODULE_9__SSR_glsl_js__["a" /* default */]);
function SSRPass(opt) {
opt = opt || {};
this._ssrPass = new __WEBPACK_IMPORTED_MODULE_4_claygl_src_compositor_Pass__["a" /* default */]({
fragment: __WEBPACK_IMPORTED_MODULE_5_claygl_src_Shader__["a" /* default */].source('ecgl.ssr.main'),
clearColor: [0, 0, 0, 0]
});
this._blurPass1 = new __WEBPACK_IMPORTED_MODULE_4_claygl_src_compositor_Pass__["a" /* default */]({
fragment: __WEBPACK_IMPORTED_MODULE_5_claygl_src_Shader__["a" /* default */].source('ecgl.ssr.blur'),
clearColor: [0, 0, 0, 0]
});
this._blurPass2 = new __WEBPACK_IMPORTED_MODULE_4_claygl_src_compositor_Pass__["a" /* default */]({
fragment: __WEBPACK_IMPORTED_MODULE_5_claygl_src_Shader__["a" /* default */].source('ecgl.ssr.blur'),
clearColor: [0, 0, 0, 0]
});
this._blendPass = new __WEBPACK_IMPORTED_MODULE_4_claygl_src_compositor_Pass__["a" /* default */]({
fragment: __WEBPACK_IMPORTED_MODULE_5_claygl_src_Shader__["a" /* default */].source('clay.compositor.blend')
});
this._blendPass.material.disableTexturesAll();
this._blendPass.material.enableTexture(['texture1', 'texture2']);
this._ssrPass.setUniform('gBufferTexture1', opt.normalTexture);
this._ssrPass.setUniform('gBufferTexture2', opt.depthTexture);
// this._ssrPass.setUniform('gBufferTexture3', opt.albedoTexture);
this._blurPass1.setUniform('gBufferTexture1', opt.normalTexture);
this._blurPass1.setUniform('gBufferTexture2', opt.depthTexture);
this._blurPass2.setUniform('gBufferTexture1', opt.normalTexture);
this._blurPass2.setUniform('gBufferTexture2', opt.depthTexture);
this._blurPass2.material.define('fragment', 'VERTICAL');
this._blurPass2.material.define('fragment', 'BLEND');
this._ssrTexture = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__["a" /* default */]({
type: __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__["a" /* default */].HALF_FLOAT
});
this._texture2 = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__["a" /* default */]({
type: __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__["a" /* default */].HALF_FLOAT
});
this._texture3 = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__["a" /* default */]({
type: __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__["a" /* default */].HALF_FLOAT
});
this._prevTexture = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__["a" /* default */]({
type: __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__["a" /* default */].HALF_FLOAT
});
this._currentTexture = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__["a" /* default */]({
type: __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__["a" /* default */].HALF_FLOAT
});
this._frameBuffer = new __WEBPACK_IMPORTED_MODULE_6_claygl_src_FrameBuffer__["a" /* default */]({
depthBuffer: false
});
this._normalDistribution = null;
this._totalSamples = 256;
this._samplePerFrame = 4;
this._ssrPass.material.define('fragment', 'SAMPLE_PER_FRAME', this._samplePerFrame);
this._ssrPass.material.define('fragment', 'TOTAL_SAMPLES', this._totalSamples);
this._downScale = 1;
}
SSRPass.prototype.setAmbientCubemap = function (specularCubemap, specularIntensity) {
this._ssrPass.material.set('specularCubemap', specularCubemap);
this._ssrPass.material.set('specularIntensity', specularIntensity);
var enableSpecularMap = specularCubemap && specularIntensity;
this._ssrPass.material[enableSpecularMap ? 'enableTexture' : 'disableTexture']('specularCubemap');
};
SSRPass.prototype.update = function (renderer, camera, sourceTexture, frame) {
var width = renderer.getWidth();
var height = renderer.getHeight();
var ssrTexture = this._ssrTexture;
var texture2 = this._texture2;
var texture3 = this._texture3;
ssrTexture.width = this._prevTexture.width = this._currentTexture.width = width / this._downScale;
ssrTexture.height = this._prevTexture.height = this._currentTexture.height = height / this._downScale;
texture2.width = texture3.width = width;
texture2.height = texture3.height = height;
var frameBuffer = this._frameBuffer;
var ssrPass = this._ssrPass;
var blurPass1 = this._blurPass1;
var blurPass2 = this._blurPass2;
var blendPass = this._blendPass;
var toViewSpace = new __WEBPACK_IMPORTED_MODULE_0_claygl_src_math_Matrix4__["a" /* default */]();
var toWorldSpace = new __WEBPACK_IMPORTED_MODULE_0_claygl_src_math_Matrix4__["a" /* default */]();
__WEBPACK_IMPORTED_MODULE_0_claygl_src_math_Matrix4__["a" /* default */].transpose(toViewSpace, camera.worldTransform);
__WEBPACK_IMPORTED_MODULE_0_claygl_src_math_Matrix4__["a" /* default */].transpose(toWorldSpace, camera.viewMatrix);
ssrPass.setUniform('sourceTexture', sourceTexture);
ssrPass.setUniform('projection', camera.projectionMatrix.array);
ssrPass.setUniform('projectionInv', camera.invProjectionMatrix.array);
ssrPass.setUniform('toViewSpace', toViewSpace.array);
ssrPass.setUniform('toWorldSpace', toWorldSpace.array);
ssrPass.setUniform('nearZ', camera.near);
var percent = frame / this._totalSamples * this._samplePerFrame;
ssrPass.setUniform('jitterOffset', percent);
ssrPass.setUniform('sampleOffset', frame * this._samplePerFrame);
blurPass1.setUniform('textureSize', [ssrTexture.width, ssrTexture.height]);
blurPass2.setUniform('textureSize', [width, height]);
blurPass2.setUniform('sourceTexture', sourceTexture);
blurPass1.setUniform('projection', camera.projectionMatrix.array);
blurPass2.setUniform('projection', camera.projectionMatrix.array);
frameBuffer.attach(ssrTexture);
frameBuffer.bind(renderer);
ssrPass.render(renderer);
if (this._physicallyCorrect) {
frameBuffer.attach(this._currentTexture);
blendPass.setUniform('texture1', this._prevTexture);
blendPass.setUniform('texture2', ssrTexture);
blendPass.material.set({
'weight1': frame >= 1 ? 0.95 : 0,
'weight2': frame >= 1 ? 0.05 : 1
// weight1: frame >= 1 ? 1 : 0,
// weight2: 1
});
blendPass.render(renderer);
}
frameBuffer.attach(texture2);
blurPass1.setUniform('texture', this._physicallyCorrect ? this._currentTexture : ssrTexture);
blurPass1.render(renderer);
frameBuffer.attach(texture3);
blurPass2.setUniform('texture', texture2);
blurPass2.render(renderer);
frameBuffer.unbind(renderer);
if (this._physicallyCorrect) {
var tmp = this._prevTexture;
this._prevTexture = this._currentTexture;
this._currentTexture = tmp;
}
};
SSRPass.prototype.getTargetTexture = function () {
return this._texture3;
};
SSRPass.prototype.setParameter = function (name, val) {
if (name === 'maxIteration') {
this._ssrPass.material.define('fragment', 'MAX_ITERATION', val);
}
else {
this._ssrPass.setUniform(name, val);
}
};
SSRPass.prototype.setPhysicallyCorrect = function (isPhysicallyCorrect) {
if (isPhysicallyCorrect) {
if (!this._normalDistribution) {
this._normalDistribution = __WEBPACK_IMPORTED_MODULE_8_claygl_src_util_cubemap__["a" /* default */].generateNormalDistribution(64, this._totalSamples);
}
this._ssrPass.material.define('fragment', 'PHYSICALLY_CORRECT');
this._ssrPass.material.set('normalDistribution', this._normalDistribution);
this._ssrPass.material.set('normalDistributionSize', [64, this._totalSamples]);
}
else {
this._ssrPass.material.undefine('fragment', 'PHYSICALLY_CORRECT');
}
this._physicallyCorrect = isPhysicallyCorrect;
};
SSRPass.prototype.setSSAOTexture = function (texture) {
var blendPass = this._blurPass2;
if (texture) {
blendPass.material.enableTexture('ssaoTex');
blendPass.material.set('ssaoTex', texture);
}
else {
blendPass.material.disableTexture('ssaoTex');
}
};
SSRPass.prototype.isFinished = function (frame) {
if (this._physicallyCorrect) {
return frame > (this._totalSamples / this._samplePerFrame);
}
else {
return true;
}
};
SSRPass.prototype.dispose = function (renderer) {
this._ssrTexture.dispose(renderer);
this._texture2.dispose(renderer);
this._texture3.dispose(renderer);
this._prevTexture.dispose(renderer);
this._currentTexture.dispose(renderer);
this._frameBuffer.dispose(renderer);
};
/* harmony default export */ __webpack_exports__["a"] = (SSRPass);
/***/ }),
/* 184 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.ssr.main\n\n#define SHADER_NAME SSR\n#define MAX_ITERATION 20;\n#define SAMPLE_PER_FRAME 5;\n#define TOTAL_SAMPLES 128;\n\nuniform sampler2D sourceTexture;\nuniform sampler2D gBufferTexture1;\nuniform sampler2D gBufferTexture2;\nuniform sampler2D gBufferTexture3;\nuniform samplerCube specularCubemap;\nuniform float specularIntensity: 1;\n\nuniform mat4 projection;\nuniform mat4 projectionInv;\nuniform mat4 toViewSpace;\nuniform mat4 toWorldSpace;\n\nuniform float maxRayDistance: 200;\n\nuniform float pixelStride: 16;\nuniform float pixelStrideZCutoff: 50; \nuniform float screenEdgeFadeStart: 0.9; \nuniform float eyeFadeStart : 0.2; uniform float eyeFadeEnd: 0.8; \nuniform float minGlossiness: 0.2; uniform float zThicknessThreshold: 1;\n\nuniform float nearZ;\nuniform vec2 viewportSize : VIEWPORT_SIZE;\n\nuniform float jitterOffset: 0;\n\nvarying vec2 v_Texcoord;\n\n#ifdef DEPTH_DECODE\n@import clay.util.decode_float\n#endif\n\n#ifdef PHYSICALLY_CORRECT\nuniform sampler2D normalDistribution;\nuniform float sampleOffset: 0;\nuniform vec2 normalDistributionSize;\n\nvec3 transformNormal(vec3 H, vec3 N) {\n vec3 upVector = N.y > 0.999 ? vec3(1.0, 0.0, 0.0) : vec3(0.0, 1.0, 0.0);\n vec3 tangentX = normalize(cross(N, upVector));\n vec3 tangentZ = cross(N, tangentX);\n return normalize(tangentX * H.x + N * H.y + tangentZ * H.z);\n}\nvec3 importanceSampleNormalGGX(float i, float roughness, vec3 N) {\n float p = fract((i + sampleOffset) / float(TOTAL_SAMPLES));\n vec3 H = texture2D(normalDistribution,vec2(roughness, p)).rgb;\n return transformNormal(H, N);\n}\nfloat G_Smith(float g, float ndv, float ndl) {\n float roughness = 1.0 - g;\n float k = roughness * roughness / 2.0;\n float G1V = ndv / (ndv * (1.0 - k) + k);\n float G1L = ndl / (ndl * (1.0 - k) + k);\n return G1L * G1V;\n}\nvec3 F_Schlick(float ndv, vec3 spec) {\n return spec + (1.0 - spec) * pow(1.0 - ndv, 5.0);\n}\n#endif\n\nfloat fetchDepth(sampler2D depthTexture, vec2 uv)\n{\n vec4 depthTexel = texture2D(depthTexture, uv);\n return depthTexel.r * 2.0 - 1.0;\n}\n\nfloat linearDepth(float depth)\n{\n if (projection[3][3] == 0.0) {\n return projection[3][2] / (depth * projection[2][3] - projection[2][2]);\n }\n else {\n return (depth - projection[3][2]) / projection[2][2];\n }\n}\n\nbool rayIntersectDepth(float rayZNear, float rayZFar, vec2 hitPixel)\n{\n if (rayZFar > rayZNear)\n {\n float t = rayZFar; rayZFar = rayZNear; rayZNear = t;\n }\n float cameraZ = linearDepth(fetchDepth(gBufferTexture2, hitPixel));\n return rayZFar <= cameraZ && rayZNear >= cameraZ - zThicknessThreshold;\n}\n\n\nbool traceScreenSpaceRay(\n vec3 rayOrigin, vec3 rayDir, float jitter,\n out vec2 hitPixel, out vec3 hitPoint, out float iterationCount\n)\n{\n float rayLength = ((rayOrigin.z + rayDir.z * maxRayDistance) > -nearZ)\n ? (-nearZ - rayOrigin.z) / rayDir.z : maxRayDistance;\n\n vec3 rayEnd = rayOrigin + rayDir * rayLength;\n\n vec4 H0 = projection * vec4(rayOrigin, 1.0);\n vec4 H1 = projection * vec4(rayEnd, 1.0);\n\n float k0 = 1.0 / H0.w, k1 = 1.0 / H1.w;\n\n vec3 Q0 = rayOrigin * k0, Q1 = rayEnd * k1;\n\n vec2 P0 = (H0.xy * k0 * 0.5 + 0.5) * viewportSize;\n vec2 P1 = (H1.xy * k1 * 0.5 + 0.5) * viewportSize;\n\n P1 += dot(P1 - P0, P1 - P0) < 0.0001 ? 0.01 : 0.0;\n vec2 delta = P1 - P0;\n\n bool permute = false;\n if (abs(delta.x) < abs(delta.y)) {\n permute = true;\n delta = delta.yx;\n P0 = P0.yx;\n P1 = P1.yx;\n }\n float stepDir = sign(delta.x);\n float invdx = stepDir / delta.x;\n\n vec3 dQ = (Q1 - Q0) * invdx;\n float dk = (k1 - k0) * invdx;\n\n vec2 dP = vec2(stepDir, delta.y * invdx);\n\n float strideScaler = 1.0 - min(1.0, -rayOrigin.z / pixelStrideZCutoff);\n float pixStride = 1.0 + strideScaler * pixelStride;\n\n dP *= pixStride; dQ *= pixStride; dk *= pixStride;\n\n vec4 pqk = vec4(P0, Q0.z, k0);\n vec4 dPQK = vec4(dP, dQ.z, dk);\n\n pqk += dPQK * jitter;\n float rayZFar = (dPQK.z * 0.5 + pqk.z) / (dPQK.w * 0.5 + pqk.w);\n float rayZNear;\n\n bool intersect = false;\n\n vec2 texelSize = 1.0 / viewportSize;\n\n iterationCount = 0.0;\n\n for (int i = 0; i < MAX_ITERATION; i++)\n {\n pqk += dPQK;\n\n rayZNear = rayZFar;\n rayZFar = (dPQK.z * 0.5 + pqk.z) / (dPQK.w * 0.5 + pqk.w);\n\n hitPixel = permute ? pqk.yx : pqk.xy;\n hitPixel *= texelSize;\n\n intersect = rayIntersectDepth(rayZNear, rayZFar, hitPixel);\n\n iterationCount += 1.0;\n\n dPQK *= 1.2;\n\n if (intersect) {\n break;\n }\n }\n\n Q0.xy += dQ.xy * iterationCount;\n Q0.z = pqk.z;\n hitPoint = Q0 / pqk.w;\n\n return intersect;\n}\n\nfloat calculateAlpha(\n float iterationCount, float reflectivity,\n vec2 hitPixel, vec3 hitPoint, float dist, vec3 rayDir\n)\n{\n float alpha = clamp(reflectivity, 0.0, 1.0);\n alpha *= 1.0 - (iterationCount / float(MAX_ITERATION));\n vec2 hitPixelNDC = hitPixel * 2.0 - 1.0;\n float maxDimension = min(1.0, max(abs(hitPixelNDC.x), abs(hitPixelNDC.y)));\n alpha *= 1.0 - max(0.0, maxDimension - screenEdgeFadeStart) / (1.0 - screenEdgeFadeStart);\n\n float _eyeFadeStart = eyeFadeStart;\n float _eyeFadeEnd = eyeFadeEnd;\n if (_eyeFadeStart > _eyeFadeEnd) {\n float tmp = _eyeFadeEnd;\n _eyeFadeEnd = _eyeFadeStart;\n _eyeFadeStart = tmp;\n }\n\n float eyeDir = clamp(rayDir.z, _eyeFadeStart, _eyeFadeEnd);\n alpha *= 1.0 - (eyeDir - _eyeFadeStart) / (_eyeFadeEnd - _eyeFadeStart);\n\n alpha *= 1.0 - clamp(dist / maxRayDistance, 0.0, 1.0);\n\n return alpha;\n}\n\n@import clay.util.rand\n\n@import clay.util.rgbm\n\nvoid main()\n{\n vec4 normalAndGloss = texture2D(gBufferTexture1, v_Texcoord);\n\n if (dot(normalAndGloss.rgb, vec3(1.0)) == 0.0) {\n discard;\n }\n\n float g = normalAndGloss.a;\n#if !defined(PHYSICALLY_CORRECT)\n if (g <= minGlossiness) {\n discard;\n }\n#endif\n\n float reflectivity = (g - minGlossiness) / (1.0 - minGlossiness);\n\n vec3 N = normalize(normalAndGloss.rgb * 2.0 - 1.0);\n N = normalize((toViewSpace * vec4(N, 0.0)).xyz);\n\n vec4 projectedPos = vec4(v_Texcoord * 2.0 - 1.0, fetchDepth(gBufferTexture2, v_Texcoord), 1.0);\n vec4 pos = projectionInv * projectedPos;\n vec3 rayOrigin = pos.xyz / pos.w;\n vec3 V = -normalize(rayOrigin);\n\n float ndv = clamp(dot(N, V), 0.0, 1.0);\n float iterationCount;\n float jitter = rand(fract(v_Texcoord + jitterOffset));\n\n#ifdef PHYSICALLY_CORRECT\n vec4 color = vec4(vec3(0.0), 1.0);\n vec4 albedoMetalness = texture2D(gBufferTexture3, v_Texcoord);\n vec3 albedo = albedoMetalness.rgb;\n float m = albedoMetalness.a;\n vec3 diffuseColor = albedo * (1.0 - m);\n vec3 spec = mix(vec3(0.04), albedo, m);\n\n float jitter2 = rand(fract(v_Texcoord)) * float(TOTAL_SAMPLES);\n\n for (int i = 0; i < SAMPLE_PER_FRAME; i++) {\n vec3 H = importanceSampleNormalGGX(float(i) + jitter2, 1.0 - g, N);\n vec3 rayDir = normalize(reflect(-V, H));\n#else\n vec3 rayDir = normalize(reflect(-V, N));\n#endif\n vec2 hitPixel;\n vec3 hitPoint;\n\n bool intersect = traceScreenSpaceRay(rayOrigin, rayDir, jitter, hitPixel, hitPoint, iterationCount);\n\n float dist = distance(rayOrigin, hitPoint);\n\n vec3 hitNormal = texture2D(gBufferTexture1, hitPixel).rgb * 2.0 - 1.0;\n hitNormal = normalize((toViewSpace * vec4(hitNormal, 0.0)).xyz);\n#ifdef PHYSICALLY_CORRECT\n float ndl = clamp(dot(N, rayDir), 0.0, 1.0);\n float vdh = clamp(dot(V, H), 0.0, 1.0);\n float ndh = clamp(dot(N, H), 0.0, 1.0);\n vec3 litTexel = vec3(0.0);\n if (dot(hitNormal, rayDir) < 0.0 && intersect) {\n litTexel = texture2D(sourceTexture, hitPixel).rgb;\n litTexel *= pow(clamp(1.0 - dist / 200.0, 0.0, 1.0), 3.0);\n\n }\n else {\n #ifdef SPECULARCUBEMAP_ENABLED\n vec3 rayDirW = normalize(toWorldSpace * vec4(rayDir, 0.0)).rgb;\n litTexel = RGBMDecode(textureCubeLodEXT(specularCubemap, rayDirW, 0.0), 8.12).rgb * specularIntensity;\n#endif\n }\n color.rgb += ndl * litTexel * (\n F_Schlick(ndl, spec) * G_Smith(g, ndv, ndl) * vdh / (ndh * ndv + 0.001)\n );\n }\n color.rgb /= float(SAMPLE_PER_FRAME);\n#else\n #if !defined(SPECULARCUBEMAP_ENABLED)\n if (dot(hitNormal, rayDir) >= 0.0) {\n discard;\n }\n if (!intersect) {\n discard;\n }\n#endif\n float alpha = clamp(calculateAlpha(iterationCount, reflectivity, hitPixel, hitPoint, dist, rayDir), 0.0, 1.0);\n vec4 color = texture2D(sourceTexture, hitPixel);\n color.rgb *= alpha;\n\n#ifdef SPECULARCUBEMAP_ENABLED\n vec3 rayDirW = normalize(toWorldSpace * vec4(rayDir, 0.0)).rgb;\n alpha = alpha * (intersect ? 1.0 : 0.0);\n float bias = (1.0 -g) * 5.0;\n color.rgb += (1.0 - alpha)\n * RGBMDecode(textureCubeLodEXT(specularCubemap, rayDirW, bias), 8.12).rgb\n * specularIntensity;\n#endif\n\n#endif\n\n gl_FragColor = encodeHDR(color);\n}\n@end\n\n@export ecgl.ssr.blur\n\nuniform sampler2D texture;\nuniform sampler2D gBufferTexture1;\nuniform sampler2D gBufferTexture2;\nuniform mat4 projection;\nuniform float depthRange : 0.05;\n\nvarying vec2 v_Texcoord;\n\nuniform vec2 textureSize;\nuniform float blurSize : 1.0;\n\n#ifdef BLEND\n #ifdef SSAOTEX_ENABLED\nuniform sampler2D ssaoTex;\n #endif\nuniform sampler2D sourceTexture;\n#endif\n\nfloat getLinearDepth(vec2 coord)\n{\n float depth = texture2D(gBufferTexture2, coord).r * 2.0 - 1.0;\n return projection[3][2] / (depth * projection[2][3] - projection[2][2]);\n}\n\n@import clay.util.rgbm\n\n\nvoid main()\n{\n @import clay.compositor.kernel.gaussian_9\n\n vec4 centerNTexel = texture2D(gBufferTexture1, v_Texcoord);\n float g = centerNTexel.a;\n float maxBlurSize = clamp(1.0 - g, 0.0, 1.0) * blurSize;\n#ifdef VERTICAL\n vec2 off = vec2(0.0, maxBlurSize / textureSize.y);\n#else\n vec2 off = vec2(maxBlurSize / textureSize.x, 0.0);\n#endif\n\n vec2 coord = v_Texcoord;\n\n vec4 sum = vec4(0.0);\n float weightAll = 0.0;\n\n vec3 cN = centerNTexel.rgb * 2.0 - 1.0;\n float cD = getLinearDepth(v_Texcoord);\n for (int i = 0; i < 9; i++) {\n vec2 coord = clamp((float(i) - 4.0) * off + v_Texcoord, vec2(0.0), vec2(1.0));\n float w = gaussianKernel[i]\n * clamp(dot(cN, texture2D(gBufferTexture1, coord).rgb * 2.0 - 1.0), 0.0, 1.0);\n float d = getLinearDepth(coord);\n w *= (1.0 - smoothstep(abs(cD - d) / depthRange, 0.0, 1.0));\n\n weightAll += w;\n sum += decodeHDR(texture2D(texture, coord)) * w;\n }\n\n#ifdef BLEND\n float aoFactor = 1.0;\n #ifdef SSAOTEX_ENABLED\n aoFactor = texture2D(ssaoTex, v_Texcoord).r;\n #endif\n gl_FragColor = encodeHDR(\n sum / weightAll * aoFactor + decodeHDR(texture2D(sourceTexture, v_Texcoord))\n );\n#else\n gl_FragColor = encodeHDR(sum / weightAll);\n#endif\n}\n\n@end");
/***/ }),
/* 185 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
// Based on https://bl.ocks.org/mbostock/19168c663618b707158
/* harmony default export */ __webpack_exports__["a"] = ([
0.0, 0.0,
-0.321585265978, -0.154972575841,
0.458126042375, 0.188473391593,
0.842080129861, 0.527766490688,
0.147304551086, -0.659453822776,
-0.331943915203, -0.940619700594,
0.0479226680259, 0.54812163202,
0.701581552186, -0.709825561388,
-0.295436780218, 0.940589268233,
-0.901489676764, 0.237713156085,
0.973570876096, -0.109899459384,
-0.866792314779, -0.451805525005,
0.330975007087, 0.800048655954,
-0.344275183665, 0.381779221166,
-0.386139432542, -0.437418421534,
-0.576478634965, -0.0148463392551,
0.385798197415, -0.262426961053,
-0.666302061145, 0.682427250835,
-0.628010632582, -0.732836215494,
0.10163141741, -0.987658134403,
0.711995289051, -0.320024291314,
0.0296005138058, 0.950296523438,
0.0130612307608, -0.351024443122,
-0.879596633704, -0.10478487883,
0.435712737232, 0.504254490347,
0.779203817497, 0.206477676721,
0.388264289969, -0.896736162545,
-0.153106280781, -0.629203242522,
-0.245517550697, 0.657969239148,
0.126830499058, 0.26862328493,
-0.634888119007, -0.302301223431,
0.617074219636, 0.779817204925
]);
/***/ }),
/* 186 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_Texture__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_FrameBuffer__ = __webpack_require__(10);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_claygl_src_Material__ = __webpack_require__(17);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_claygl_src_compositor_Pass__ = __webpack_require__(14);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_claygl_src_util_texture__ = __webpack_require__(54);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__util_shader_normal_glsl_js__ = __webpack_require__(187);
// NormalPass will generate normal and depth data.
// TODO Animation
__WEBPACK_IMPORTED_MODULE_2_claygl_src_Shader__["a" /* default */].import(__WEBPACK_IMPORTED_MODULE_7__util_shader_normal_glsl_js__["a" /* default */]);
function attachTextureToSlot(renderer, program, symbol, texture, slot) {
var gl = renderer.gl;
program.setUniform(gl, '1i', symbol, slot);
gl.activeTexture(gl.TEXTURE0 + slot);
// Maybe texture is not loaded yet;
if (texture.isRenderable()) {
texture.bind(renderer);
}
else {
// Bind texture to null
texture.unbind(renderer);
}
}
// TODO Use globalShader insteadof globalMaterial?
function getBeforeRenderHook (renderer, defaultNormalMap, defaultBumpMap, defaultRoughnessMap, normalMaterial) {
var previousNormalMap;
var previousBumpMap;
var previousRoughnessMap;
var previousRenderable;
var gl = renderer.gl;
return function (renderable, normalMaterial, prevNormalMaterial) {
// Material not change
if (previousRenderable && previousRenderable.material === renderable.material) {
return;
}
var material = renderable.material;
var program = renderable.__program;
var roughness = material.get('roughness');
if (roughness == null) {
roughness = 1;
}
var normalMap = material.get('normalMap') || defaultNormalMap;
var roughnessMap = material.get('roughnessMap');
var bumpMap = material.get('bumpMap');
var uvRepeat = material.get('uvRepeat');
var uvOffset = material.get('uvOffset');
var detailUvRepeat = material.get('detailUvRepeat');
var detailUvOffset = material.get('detailUvOffset');
var useBumpMap = !!bumpMap && material.isTextureEnabled('bumpMap');
var useRoughnessMap = !!roughnessMap && material.isTextureEnabled('roughnessMap');
var doubleSide = material.isDefined('fragment', 'DOUBLE_SIDED');
bumpMap = bumpMap || defaultBumpMap;
roughnessMap = roughnessMap || defaultRoughnessMap;
if (prevNormalMaterial !== normalMaterial) {
normalMaterial.set('normalMap', normalMap);
normalMaterial.set('bumpMap', bumpMap);
normalMaterial.set('roughnessMap', roughnessMap);
normalMaterial.set('useBumpMap', useBumpMap);
normalMaterial.set('useRoughnessMap', useRoughnessMap);
normalMaterial.set('doubleSide', doubleSide);
uvRepeat != null && normalMaterial.set('uvRepeat', uvRepeat);
uvOffset != null && normalMaterial.set('uvOffset', uvOffset);
detailUvRepeat != null && normalMaterial.set('detailUvRepeat', detailUvRepeat);
detailUvOffset != null && normalMaterial.set('detailUvOffset', detailUvOffset);
normalMaterial.set('roughness', roughness);
}
else {
program.setUniform(gl, '1f', 'roughness', roughness);
if (previousNormalMap !== normalMap) {
attachTextureToSlot(renderer, program, 'normalMap', normalMap, 0);
}
if (previousBumpMap !== bumpMap && bumpMap) {
attachTextureToSlot(renderer, program, 'bumpMap', bumpMap, 1);
}
if (previousRoughnessMap !== roughnessMap && roughnessMap) {
attachTextureToSlot(renderer, program, 'roughnessMap', roughnessMap, 2);
}
if (uvRepeat != null) {
program.setUniform(gl, '2f', 'uvRepeat', uvRepeat);
}
if (uvOffset != null) {
program.setUniform(gl, '2f', 'uvOffset', uvOffset);
}
if (detailUvRepeat != null) {
program.setUniform(gl, '2f', 'detailUvRepeat', detailUvRepeat);
}
if (detailUvOffset != null) {
program.setUniform(gl, '2f', 'detailUvOffset', detailUvOffset);
}
program.setUniform(gl, '1i', 'useBumpMap', +useBumpMap);
program.setUniform(gl, '1i', 'useRoughnessMap', +useRoughnessMap);
program.setUniform(gl, '1i', 'doubleSide', +doubleSide);
}
previousNormalMap = normalMap;
previousBumpMap = bumpMap;
previousRoughnessMap = roughnessMap;
previousRenderable = renderable;
};
}
function NormalPass(opt) {
opt = opt || {};
this._depthTex = new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Texture2D__["a" /* default */]({
format: __WEBPACK_IMPORTED_MODULE_1_claygl_src_Texture__["a" /* default */].DEPTH_COMPONENT,
type: __WEBPACK_IMPORTED_MODULE_1_claygl_src_Texture__["a" /* default */].UNSIGNED_INT
});
this._normalTex = new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Texture2D__["a" /* default */]({
type: __WEBPACK_IMPORTED_MODULE_1_claygl_src_Texture__["a" /* default */].HALF_FLOAT
});
this._framebuffer = new __WEBPACK_IMPORTED_MODULE_3_claygl_src_FrameBuffer__["a" /* default */]();
this._framebuffer.attach(this._normalTex);
this._framebuffer.attach(this._depthTex, __WEBPACK_IMPORTED_MODULE_3_claygl_src_FrameBuffer__["a" /* default */].DEPTH_ATTACHMENT);
this._normalMaterial = new __WEBPACK_IMPORTED_MODULE_4_claygl_src_Material__["a" /* default */]({
shader: new __WEBPACK_IMPORTED_MODULE_2_claygl_src_Shader__["a" /* default */](
__WEBPACK_IMPORTED_MODULE_2_claygl_src_Shader__["a" /* default */].source('ecgl.normal.vertex'),
__WEBPACK_IMPORTED_MODULE_2_claygl_src_Shader__["a" /* default */].source('ecgl.normal.fragment')
)
});
this._normalMaterial.enableTexture(['normalMap', 'bumpMap', 'roughnessMap']);
this._defaultNormalMap = __WEBPACK_IMPORTED_MODULE_6_claygl_src_util_texture__["a" /* default */].createBlank('#000');
this._defaultBumpMap = __WEBPACK_IMPORTED_MODULE_6_claygl_src_util_texture__["a" /* default */].createBlank('#000');
this._defaultRoughessMap = __WEBPACK_IMPORTED_MODULE_6_claygl_src_util_texture__["a" /* default */].createBlank('#000');
this._debugPass = new __WEBPACK_IMPORTED_MODULE_5_claygl_src_compositor_Pass__["a" /* default */]({
fragment: __WEBPACK_IMPORTED_MODULE_2_claygl_src_Shader__["a" /* default */].source('clay.compositor.output')
});
this._debugPass.setUniform('texture', this._normalTex);
this._debugPass.material.undefine('fragment', 'OUTPUT_ALPHA');
}
NormalPass.prototype.getDepthTexture = function () {
return this._depthTex;
};
NormalPass.prototype.getNormalTexture = function () {
return this._normalTex;
};
NormalPass.prototype.update = function (renderer, scene, camera) {
var width = renderer.getWidth();
var height = renderer.getHeight();
var depthTexture = this._depthTex;
var normalTexture = this._normalTex;
var normalMaterial = this._normalMaterial;
depthTexture.width = width;
depthTexture.height = height;
normalTexture.width = width;
normalTexture.height = height;
var opaqueList = scene.getRenderList(camera).opaque;
this._framebuffer.bind(renderer);
renderer.gl.clearColor(0, 0, 0, 0);
renderer.gl.clear(renderer.gl.COLOR_BUFFER_BIT | renderer.gl.DEPTH_BUFFER_BIT);
renderer.gl.disable(renderer.gl.BLEND);
renderer.renderPass(opaqueList, camera, {
getMaterial: function () {
return normalMaterial;
},
ifRender: function (object) {
return object.renderNormal;
},
beforeRender: getBeforeRenderHook(
renderer, this._defaultNormalMap, this._defaultBumpMap, this._defaultRoughessMap, this._normalMaterial
),
sort: renderer.opaqueSortCompare
});
this._framebuffer.unbind(renderer);
};
NormalPass.prototype.renderDebug = function (renderer) {
this._debugPass.render(renderer);
};
NormalPass.prototype.dispose = function (renderer) {
this._depthTex.dispose(renderer);
this._normalTex.dispose(renderer);
}
/* harmony default export */ __webpack_exports__["a"] = (NormalPass);
/***/ }),
/* 187 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.normal.vertex\n\n@import ecgl.common.transformUniforms\n\n@import ecgl.common.uv.header\n\n@import ecgl.common.attributes\n\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\n\n@import ecgl.common.normalMap.vertexHeader\n\n@import ecgl.common.vertexAnimation.header\n\nvoid main()\n{\n\n @import ecgl.common.vertexAnimation.main\n\n @import ecgl.common.uv.main\n\n v_Normal = normalize((worldInverseTranspose * vec4(normal, 0.0)).xyz);\n v_WorldPosition = (world * vec4(pos, 1.0)).xyz;\n\n @import ecgl.common.normalMap.vertexMain\n\n gl_Position = worldViewProjection * vec4(pos, 1.0);\n\n}\n\n\n@end\n\n\n@export ecgl.normal.fragment\n\n#define ROUGHNESS_CHANEL 0\n\nuniform bool useBumpMap;\nuniform bool useRoughnessMap;\nuniform bool doubleSide;\nuniform float roughness;\n\n@import ecgl.common.uv.fragmentHeader\n\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\n\nuniform mat4 viewInverse : VIEWINVERSE;\n\n@import ecgl.common.normalMap.fragmentHeader\n@import ecgl.common.bumpMap.header\n\nuniform sampler2D roughnessMap;\n\nvoid main()\n{\n vec3 N = v_Normal;\n \n bool flipNormal = false;\n if (doubleSide) {\n vec3 eyePos = viewInverse[3].xyz;\n vec3 V = normalize(eyePos - v_WorldPosition);\n\n if (dot(N, V) < 0.0) {\n flipNormal = true;\n }\n }\n\n @import ecgl.common.normalMap.fragmentMain\n\n if (useBumpMap) {\n N = bumpNormal(v_WorldPosition, v_Normal, N);\n }\n\n float g = 1.0 - roughness;\n\n if (useRoughnessMap) {\n float g2 = 1.0 - texture2D(roughnessMap, v_DetailTexcoord)[ROUGHNESS_CHANEL];\n g = clamp(g2 + (g - 0.5) * 2.0, 0.0, 1.0);\n }\n\n if (flipNormal) {\n N = -N;\n }\n\n gl_FragColor.rgb = (N.xyz + 1.0) * 0.5;\n gl_FragColor.a = g;\n}\n@end");
/***/ }),
/* 188 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_math_Matrix4__ = __webpack_require__(7);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector3__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_claygl_src_compositor_Pass__ = __webpack_require__(14);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_claygl_src_Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_claygl_src_FrameBuffer__ = __webpack_require__(10);
function EdgePass(opt) {
opt = opt || {};
this._edgePass = new __WEBPACK_IMPORTED_MODULE_4_claygl_src_compositor_Pass__["a" /* default */]({
fragment: __WEBPACK_IMPORTED_MODULE_5_claygl_src_Shader__["a" /* default */].source('ecgl.edge')
});
this._edgePass.setUniform('normalTexture', opt.normalTexture);
this._edgePass.setUniform('depthTexture', opt.depthTexture);
this._targetTexture = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_Texture2D__["a" /* default */]({
type: __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture__["a" /* default */].HALF_FLOAT
});
this._frameBuffer = new __WEBPACK_IMPORTED_MODULE_6_claygl_src_FrameBuffer__["a" /* default */]();
this._frameBuffer.attach(this._targetTexture);
}
EdgePass.prototype.update = function (renderer, camera, sourceTexture, frame) {
var width = renderer.getWidth();
var height = renderer.getHeight();
var texture = this._targetTexture;
texture.width = width;
texture.height = height;
var frameBuffer = this._frameBuffer;
frameBuffer.bind(renderer);
this._edgePass.setUniform('projectionInv', camera.invProjectionMatrix.array);
this._edgePass.setUniform('textureSize', [width, height]);
this._edgePass.setUniform('texture', sourceTexture);
this._edgePass.render(renderer);
frameBuffer.unbind(renderer);
};
EdgePass.prototype.getTargetTexture = function () {
return this._targetTexture;
};
EdgePass.prototype.setParameter = function (name, val) {
this._edgePass.setUniform(name, val);
};
EdgePass.prototype.dispose = function (renderer) {
this._targetTexture.dispose(renderer);
this._frameBuffer.dispose(renderer);
};
/* harmony default export */ __webpack_exports__["a"] = (EdgePass);
/***/ }),
/* 189 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ({
'type' : 'compositor',
'nodes' : [
{
'name': 'source',
'type': 'texture',
'outputs': {
'color': {}
}
},
{
'name': 'source_half',
'shader': '#source(clay.compositor.downsample)',
'inputs': {
'texture': 'source'
},
'outputs': {
'color': {
'parameters': {
'width': 'expr(width * 1.0 / 2)',
'height': 'expr(height * 1.0 / 2)',
'type': 'HALF_FLOAT'
}
}
},
'parameters' : {
'textureSize': 'expr( [width * 1.0, height * 1.0] )'
}
},
{
'name' : 'bright',
'shader' : '#source(clay.compositor.bright)',
'inputs' : {
'texture' : 'source_half'
},
'outputs' : {
'color' : {
'parameters' : {
'width' : 'expr(width * 1.0 / 2)',
'height' : 'expr(height * 1.0 / 2)',
'type': 'HALF_FLOAT'
}
}
},
'parameters' : {
'threshold' : 2,
'scale': 4,
'textureSize': 'expr([width * 1.0 / 2, height / 2])'
}
},
{
'name': 'bright_downsample_4',
'shader' : '#source(clay.compositor.downsample)',
'inputs' : {
'texture' : 'bright'
},
'outputs' : {
'color' : {
'parameters' : {
'width' : 'expr(width * 1.0 / 4)',
'height' : 'expr(height * 1.0 / 4)',
'type': 'HALF_FLOAT'
}
}
},
'parameters' : {
'textureSize': 'expr( [width * 1.0 / 2, height / 2] )'
}
},
{
'name': 'bright_downsample_8',
'shader' : '#source(clay.compositor.downsample)',
'inputs' : {
'texture' : 'bright_downsample_4'
},
'outputs' : {
'color' : {
'parameters' : {
'width' : 'expr(width * 1.0 / 8)',
'height' : 'expr(height * 1.0 / 8)',
'type': 'HALF_FLOAT'
}
}
},
'parameters' : {
'textureSize': 'expr( [width * 1.0 / 4, height / 4] )'
}
},
{
'name': 'bright_downsample_16',
'shader' : '#source(clay.compositor.downsample)',
'inputs' : {
'texture' : 'bright_downsample_8'
},
'outputs' : {
'color' : {
'parameters' : {
'width' : 'expr(width * 1.0 / 16)',
'height' : 'expr(height * 1.0 / 16)',
'type': 'HALF_FLOAT'
}
}
},
'parameters' : {
'textureSize': 'expr( [width * 1.0 / 8, height / 8] )'
}
},
{
'name': 'bright_downsample_32',
'shader' : '#source(clay.compositor.downsample)',
'inputs' : {
'texture' : 'bright_downsample_16'
},
'outputs' : {
'color' : {
'parameters' : {
'width' : 'expr(width * 1.0 / 32)',
'height' : 'expr(height * 1.0 / 32)',
'type': 'HALF_FLOAT'
}
}
},
'parameters' : {
'textureSize': 'expr( [width * 1.0 / 16, height / 16] )'
}
},
{
'name' : 'bright_upsample_16_blur_h',
'shader' : '#source(clay.compositor.gaussian_blur)',
'inputs' : {
'texture' : 'bright_downsample_32'
},
'outputs' : {
'color' : {
'parameters' : {
'width' : 'expr(width * 1.0 / 16)',
'height' : 'expr(height * 1.0 / 16)',
'type': 'HALF_FLOAT'
}
}
},
'parameters' : {
'blurSize' : 1,
'blurDir': 0.0,
'textureSize': 'expr( [width * 1.0 / 32, height / 32] )'
}
},
{
'name' : 'bright_upsample_16_blur_v',
'shader' : '#source(clay.compositor.gaussian_blur)',
'inputs' : {
'texture' : 'bright_upsample_16_blur_h'
},
'outputs' : {
'color' : {
'parameters' : {
'width' : 'expr(width * 1.0 / 16)',
'height' : 'expr(height * 1.0 / 16)',
'type': 'HALF_FLOAT'
}
}
},
'parameters' : {
'blurSize' : 1,
'blurDir': 1.0,
'textureSize': 'expr( [width * 1.0 / 16, height * 1.0 / 16] )'
}
},
{
'name' : 'bright_upsample_8_blur_h',
'shader' : '#source(clay.compositor.gaussian_blur)',
'inputs' : {
'texture' : 'bright_downsample_16'
},
'outputs' : {
'color' : {
'parameters' : {
'width' : 'expr(width * 1.0 / 8)',
'height' : 'expr(height * 1.0 / 8)',
'type': 'HALF_FLOAT'
}
}
},
'parameters' : {
'blurSize' : 1,
'blurDir': 0.0,
'textureSize': 'expr( [width * 1.0 / 16, height * 1.0 / 16] )'
}
},
{
'name' : 'bright_upsample_8_blur_v',
'shader' : '#source(clay.compositor.gaussian_blur)',
'inputs' : {
'texture' : 'bright_upsample_8_blur_h'
},
'outputs' : {
'color' : {
'parameters' : {
'width' : 'expr(width * 1.0 / 8)',
'height' : 'expr(height * 1.0 / 8)',
'type': 'HALF_FLOAT'
}
}
},
'parameters' : {
'blurSize' : 1,
'blurDir': 1.0,
'textureSize': 'expr( [width * 1.0 / 8, height * 1.0 / 8] )'
}
},
{
'name' : 'bright_upsample_8_blend',
'shader' : '#source(clay.compositor.blend)',
'inputs' : {
'texture1' : 'bright_upsample_8_blur_v',
'texture2' : 'bright_upsample_16_blur_v'
},
'outputs' : {
'color' : {
'parameters' : {
'width' : 'expr(width * 1.0 / 8)',
'height' : 'expr(height * 1.0 / 8)',
'type': 'HALF_FLOAT'
}
}
},
'parameters' : {
'weight1' : 0.3,
'weight2' : 0.7
}
},
{
'name' : 'bright_upsample_4_blur_h',
'shader' : '#source(clay.compositor.gaussian_blur)',
'inputs' : {
'texture' : 'bright_downsample_8'
},
'outputs' : {
'color' : {
'parameters' : {
'width' : 'expr(width * 1.0 / 4)',
'height' : 'expr(height * 1.0 / 4)',
'type': 'HALF_FLOAT'
}
}
},
'parameters' : {
'blurSize' : 1,
'blurDir': 0.0,
'textureSize': 'expr( [width * 1.0 / 8, height * 1.0 / 8] )'
}
},
{
'name' : 'bright_upsample_4_blur_v',
'shader' : '#source(clay.compositor.gaussian_blur)',
'inputs' : {
'texture' : 'bright_upsample_4_blur_h'
},
'outputs' : {
'color' : {
'parameters' : {
'width' : 'expr(width * 1.0 / 4)',
'height' : 'expr(height * 1.0 / 4)',
'type': 'HALF_FLOAT'
}
}
},
'parameters' : {
'blurSize' : 1,
'blurDir': 1.0,
'textureSize': 'expr( [width * 1.0 / 4, height * 1.0 / 4] )'
}
},
{
'name' : 'bright_upsample_4_blend',
'shader' : '#source(clay.compositor.blend)',
'inputs' : {
'texture1' : 'bright_upsample_4_blur_v',
'texture2' : 'bright_upsample_8_blend'
},
'outputs' : {
'color' : {
'parameters' : {
'width' : 'expr(width * 1.0 / 4)',
'height' : 'expr(height * 1.0 / 4)',
'type': 'HALF_FLOAT'
}
}
},
'parameters' : {
'weight1' : 0.3,
'weight2' : 0.7
}
},
{
'name' : 'bright_upsample_2_blur_h',
'shader' : '#source(clay.compositor.gaussian_blur)',
'inputs' : {
'texture' : 'bright_downsample_4'
},
'outputs' : {
'color' : {
'parameters' : {
'width' : 'expr(width * 1.0 / 2)',
'height' : 'expr(height * 1.0 / 2)',
'type': 'HALF_FLOAT'
}
}
},
'parameters' : {
'blurSize' : 1,
'blurDir': 0.0,
'textureSize': 'expr( [width * 1.0 / 4, height * 1.0 / 4] )'
}
},
{
'name' : 'bright_upsample_2_blur_v',
'shader' : '#source(clay.compositor.gaussian_blur)',
'inputs' : {
'texture' : 'bright_upsample_2_blur_h'
},
'outputs' : {
'color' : {
'parameters' : {
'width' : 'expr(width * 1.0 / 2)',
'height' : 'expr(height * 1.0 / 2)',
'type': 'HALF_FLOAT'
}
}
},
'parameters' : {
'blurSize' : 1,
'blurDir': 1.0,
'textureSize': 'expr( [width * 1.0 / 2, height * 1.0 / 2] )'
}
},
{
'name' : 'bright_upsample_2_blend',
'shader' : '#source(clay.compositor.blend)',
'inputs' : {
'texture1' : 'bright_upsample_2_blur_v',
'texture2' : 'bright_upsample_4_blend'
},
'outputs' : {
'color' : {
'parameters' : {
'width' : 'expr(width * 1.0 / 2)',
'height' : 'expr(height * 1.0 / 2)',
'type': 'HALF_FLOAT'
}
}
},
'parameters' : {
'weight1' : 0.3,
'weight2' : 0.7
}
},
{
'name' : 'bright_upsample_full_blur_h',
'shader' : '#source(clay.compositor.gaussian_blur)',
'inputs' : {
'texture' : 'bright'
},
'outputs' : {
'color' : {
'parameters' : {
'width' : 'expr(width * 1.0)',
'height' : 'expr(height * 1.0)',
'type': 'HALF_FLOAT'
}
}
},
'parameters' : {
'blurSize' : 1,
'blurDir': 0.0,
'textureSize': 'expr( [width * 1.0 / 2, height * 1.0 / 2] )'
}
},
{
'name' : 'bright_upsample_full_blur_v',
'shader' : '#source(clay.compositor.gaussian_blur)',
'inputs' : {
'texture' : 'bright_upsample_full_blur_h'
},
'outputs' : {
'color' : {
'parameters' : {
'width' : 'expr(width * 1.0)',
'height' : 'expr(height * 1.0)',
'type': 'HALF_FLOAT'
}
}
},
'parameters' : {
'blurSize' : 1,
'blurDir': 1.0,
'textureSize': 'expr( [width * 1.0, height * 1.0] )'
}
},
{
'name' : 'bloom_composite',
'shader' : '#source(clay.compositor.blend)',
'inputs' : {
'texture1' : 'bright_upsample_full_blur_v',
'texture2' : 'bright_upsample_2_blend'
},
'outputs' : {
'color' : {
'parameters' : {
'width' : 'expr(width * 1.0)',
'height' : 'expr(height * 1.0)',
'type': 'HALF_FLOAT'
}
}
},
'parameters' : {
'weight1' : 0.3,
'weight2' : 0.7
}
},
{
'name': 'coc',
'shader': '#source(ecgl.dof.coc)',
'outputs': {
'color': {
'parameters': {
'minFilter': 'NEAREST',
'magFilter': 'NEAREST',
'width': 'expr(width * 1.0)',
'height': 'expr(height * 1.0)'
}
}
},
'parameters': {
'focalDist': 50,
'focalRange': 30
}
},
{
'name': 'dof_far_blur',
'shader': '#source(ecgl.dof.diskBlur)',
'inputs': {
'texture': 'source',
'coc': 'coc'
},
'outputs': {
'color': {
'parameters': {
'width': 'expr(width * 1.0)',
'height': 'expr(height * 1.0)',
'type': 'HALF_FLOAT'
}
}
},
'parameters': {
'textureSize': 'expr( [width * 1.0, height * 1.0] )'
}
},
{
'name': 'dof_near_blur',
'shader': '#source(ecgl.dof.diskBlur)',
'inputs': {
'texture': 'source',
'coc': 'coc'
},
'outputs': {
'color': {
'parameters': {
'width': 'expr(width * 1.0)',
'height': 'expr(height * 1.0)',
'type': 'HALF_FLOAT'
}
}
},
'parameters': {
'textureSize': 'expr( [width * 1.0, height * 1.0] )'
},
'defines': {
'BLUR_NEARFIELD': null
}
},
{
'name': 'dof_coc_blur',
'shader': '#source(ecgl.dof.diskBlur)',
'inputs': {
'texture': 'coc'
},
'outputs': {
'color': {
'parameters': {
'minFilter': 'NEAREST',
'magFilter': 'NEAREST',
'width': 'expr(width * 1.0)',
'height': 'expr(height * 1.0)'
}
}
},
'parameters': {
'textureSize': 'expr( [width * 1.0, height * 1.0] )'
},
'defines': {
'BLUR_COC': null
}
},
{
'name': 'dof_composite',
'shader': '#source(ecgl.dof.composite)',
'inputs': {
'original': 'source',
'blurred': 'dof_far_blur',
'nearfield': 'dof_near_blur',
'coc': 'coc',
'nearcoc': 'dof_coc_blur'
},
'outputs': {
'color': {
'parameters': {
'width': 'expr(width * 1.0)',
'height': 'expr(height * 1.0)',
'type': 'HALF_FLOAT'
}
}
}
},
{
'name' : 'composite',
'shader' : '#source(clay.compositor.hdr.composite)',
'inputs' : {
'texture': 'source',
'bloom' : 'bloom_composite'
},
'defines': {
// Images are all premultiplied alpha before composite because of blending.
// 'PREMULTIPLY_ALPHA': null,
// 'DEBUG': 2
}
},
{
'name' : 'FXAA',
'shader' : '#source(clay.compositor.fxaa)',
'inputs' : {
'texture' : 'composite'
}
}
]
});
/***/ }),
/* 190 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.dof.coc\n\nuniform sampler2D depth;\n\nuniform float zNear: 0.1;\nuniform float zFar: 2000;\n\nuniform float focalDistance: 3;\nuniform float focalRange: 1;\nuniform float focalLength: 30;\nuniform float fstop: 2.8;\n\nvarying vec2 v_Texcoord;\n\n@import clay.util.encode_float\n\nvoid main()\n{\n float z = texture2D(depth, v_Texcoord).r * 2.0 - 1.0;\n\n float dist = 2.0 * zNear * zFar / (zFar + zNear - z * (zFar - zNear));\n\n float aperture = focalLength / fstop;\n\n float coc;\n\n float uppper = focalDistance + focalRange;\n float lower = focalDistance - focalRange;\n if (dist <= uppper && dist >= lower) {\n coc = 0.5;\n }\n else {\n float focalAdjusted = dist > uppper ? uppper : lower;\n\n coc = abs(aperture * (focalLength * (dist - focalAdjusted)) / (dist * (focalAdjusted - focalLength)));\n coc = clamp(coc, 0.0, 2.0) / 2.00001;\n\n if (dist < lower) {\n coc = -coc;\n }\n coc = coc * 0.5 + 0.5;\n }\n\n gl_FragColor = encodeFloat(coc);\n}\n@end\n\n\n@export ecgl.dof.composite\n\n#define DEBUG 0\n\nuniform sampler2D original;\nuniform sampler2D blurred;\nuniform sampler2D nearfield;\nuniform sampler2D coc;\nuniform sampler2D nearcoc;\nvarying vec2 v_Texcoord;\n\n@import clay.util.rgbm\n@import clay.util.float\n\nvoid main()\n{\n vec4 blurredColor = texture2D(blurred, v_Texcoord);\n vec4 originalColor = texture2D(original, v_Texcoord);\n\n float fCoc = decodeFloat(texture2D(coc, v_Texcoord));\n\n fCoc = abs(fCoc * 2.0 - 1.0);\n\n float weight = smoothstep(0.0, 1.0, fCoc);\n \n#ifdef NEARFIELD_ENABLED\n vec4 nearfieldColor = texture2D(nearfield, v_Texcoord);\n float fNearCoc = decodeFloat(texture2D(nearcoc, v_Texcoord));\n fNearCoc = abs(fNearCoc * 2.0 - 1.0);\n\n gl_FragColor = encodeHDR(\n mix(\n nearfieldColor, mix(originalColor, blurredColor, weight),\n pow(1.0 - fNearCoc, 4.0)\n )\n );\n#else\n gl_FragColor = encodeHDR(mix(originalColor, blurredColor, weight));\n#endif\n\n}\n\n@end\n\n\n\n@export ecgl.dof.diskBlur\n\n#define POISSON_KERNEL_SIZE 16;\n\nuniform sampler2D texture;\nuniform sampler2D coc;\nvarying vec2 v_Texcoord;\n\nuniform float blurRadius : 10.0;\nuniform vec2 textureSize : [512.0, 512.0];\n\nuniform vec2 poissonKernel[POISSON_KERNEL_SIZE];\n\nuniform float percent;\n\nfloat nrand(const in vec2 n) {\n return fract(sin(dot(n.xy ,vec2(12.9898,78.233))) * 43758.5453);\n}\n\n@import clay.util.rgbm\n@import clay.util.float\n\n\nvoid main()\n{\n vec2 offset = blurRadius / textureSize;\n\n float rnd = 6.28318 * nrand(v_Texcoord + 0.07 * percent );\n float cosa = cos(rnd);\n float sina = sin(rnd);\n vec4 basis = vec4(cosa, -sina, sina, cosa);\n\n#if !defined(BLUR_NEARFIELD) && !defined(BLUR_COC)\n offset *= abs(decodeFloat(texture2D(coc, v_Texcoord)) * 2.0 - 1.0);\n#endif\n\n#ifdef BLUR_COC\n float cocSum = 0.0;\n#else\n vec4 color = vec4(0.0);\n#endif\n\n\n float weightSum = 0.0;\n\n for (int i = 0; i < POISSON_KERNEL_SIZE; i++) {\n vec2 ofs = poissonKernel[i];\n\n ofs = vec2(dot(ofs, basis.xy), dot(ofs, basis.zw));\n\n vec2 uv = v_Texcoord + ofs * offset;\n vec4 texel = texture2D(texture, uv);\n\n float w = 1.0;\n#ifdef BLUR_COC\n float fCoc = decodeFloat(texel) * 2.0 - 1.0;\n cocSum += clamp(fCoc, -1.0, 0.0) * w;\n#else\n texel = texel;\n #if !defined(BLUR_NEARFIELD)\n float fCoc = decodeFloat(texture2D(coc, uv)) * 2.0 - 1.0;\n w *= abs(fCoc);\n #endif\n texel.rgb *= texel.a;\n color += texel * w;\n#endif\n\n weightSum += w;\n }\n\n#ifdef BLUR_COC\n gl_FragColor = encodeFloat(clamp(cocSum / weightSum, -1.0, 0.0) * 0.5 + 0.5);\n#else\n color /= weightSum;\n color.rgb /= (color.a + 0.0001);\n gl_FragColor = color;\n#endif\n}\n\n@end");
/***/ }),
/* 191 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.edge\n\nuniform sampler2D texture;\n\nuniform sampler2D normalTexture;\nuniform sampler2D depthTexture;\n\nuniform mat4 projectionInv;\n\nuniform vec2 textureSize;\n\nuniform vec4 edgeColor: [0,0,0,0.8];\n\nvarying vec2 v_Texcoord;\n\nvec3 packColor(vec2 coord) {\n float z = texture2D(depthTexture, coord).r * 2.0 - 1.0;\n vec4 p = vec4(v_Texcoord * 2.0 - 1.0, z, 1.0);\n vec4 p4 = projectionInv * p;\n\n return vec3(\n texture2D(normalTexture, coord).rg,\n -p4.z / p4.w / 5.0\n );\n}\n\nvoid main() {\n vec2 cc = v_Texcoord;\n vec3 center = packColor(cc);\n\n float size = clamp(1.0 - (center.z - 10.0) / 100.0, 0.0, 1.0) * 0.5;\n float dx = size / textureSize.x;\n float dy = size / textureSize.y;\n\n vec2 coord;\n vec3 topLeft = packColor(cc+vec2(-dx, -dy));\n vec3 top = packColor(cc+vec2(0.0, -dy));\n vec3 topRight = packColor(cc+vec2(dx, -dy));\n vec3 left = packColor(cc+vec2(-dx, 0.0));\n vec3 right = packColor(cc+vec2(dx, 0.0));\n vec3 bottomLeft = packColor(cc+vec2(-dx, dy));\n vec3 bottom = packColor(cc+vec2(0.0, dy));\n vec3 bottomRight = packColor(cc+vec2(dx, dy));\n\n vec3 v = -topLeft-2.0*top-topRight+bottomLeft+2.0*bottom+bottomRight;\n vec3 h = -bottomLeft-2.0*left-topLeft+bottomRight+2.0*right+topRight;\n\n float edge = sqrt(dot(h, h) + dot(v, v));\n\n edge = smoothstep(0.8, 1.0, edge);\n\n gl_FragColor = mix(texture2D(texture, v_Texcoord), vec4(edgeColor.rgb, 1.0), edgeColor.a * edge);\n}\n@end");
/***/ }),
/* 192 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__halton__ = __webpack_require__(43);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_compositor_Pass__ = __webpack_require__(14);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_FrameBuffer__ = __webpack_require__(10);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_claygl_src_math_Matrix4__ = __webpack_require__(7);
// Temporal Super Sample for static Scene
function TemporalSuperSampling (frames) {
var haltonSequence = [];
for (var i = 0; i < 30; i++) {
haltonSequence.push([Object(__WEBPACK_IMPORTED_MODULE_0__halton__["a" /* default */])(i, 2), Object(__WEBPACK_IMPORTED_MODULE_0__halton__["a" /* default */])(i, 3)]);
}
this._haltonSequence = haltonSequence;
this._frame = 0;
this._sourceTex = new __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture2D__["a" /* default */]();
this._sourceFb = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_FrameBuffer__["a" /* default */]();
this._sourceFb.attach(this._sourceTex);
// Frame texture before temporal supersampling
this._prevFrameTex = new __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture2D__["a" /* default */]();
this._outputTex = new __WEBPACK_IMPORTED_MODULE_3_claygl_src_Texture2D__["a" /* default */]();
var blendPass = this._blendPass = new __WEBPACK_IMPORTED_MODULE_1_claygl_src_compositor_Pass__["a" /* default */]({
fragment: __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].source('clay.compositor.blend')
});
blendPass.material.disableTexturesAll();
blendPass.material.enableTexture(['texture1', 'texture2']);
this._blendFb = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_FrameBuffer__["a" /* default */]({
depthBuffer: false
});
this._outputPass = new __WEBPACK_IMPORTED_MODULE_1_claygl_src_compositor_Pass__["a" /* default */]({
fragment: __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].source('clay.compositor.output'),
// TODO, alpha is premultiplied?
blendWithPrevious: true
});
this._outputPass.material.define('fragment', 'OUTPUT_ALPHA');
this._outputPass.material.blend = function (_gl) {
// FIXME.
// Output is premultiplied alpha when BLEND is enabled ?
// http://stackoverflow.com/questions/2171085/opengl-blending-with-previous-contents-of-framebuffer
_gl.blendEquationSeparate(_gl.FUNC_ADD, _gl.FUNC_ADD);
_gl.blendFuncSeparate(_gl.ONE, _gl.ONE_MINUS_SRC_ALPHA, _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA);
};
}
TemporalSuperSampling.prototype = {
constructor: TemporalSuperSampling,
/**
* Jitter camera projectionMatrix
* @parma {clay.Renderer} renderer
* @param {clay.Camera} camera
*/
jitterProjection: function (renderer, camera) {
var viewport = renderer.viewport;
var dpr = viewport.devicePixelRatio || renderer.getDevicePixelRatio();
var width = viewport.width * dpr;
var height = viewport.height * dpr;
var offset = this._haltonSequence[this._frame % this._haltonSequence.length];
var translationMat = new __WEBPACK_IMPORTED_MODULE_5_claygl_src_math_Matrix4__["a" /* default */]();
translationMat.array[12] = (offset[0] * 2.0 - 1.0) / width;
translationMat.array[13] = (offset[1] * 2.0 - 1.0) / height;
__WEBPACK_IMPORTED_MODULE_5_claygl_src_math_Matrix4__["a" /* default */].mul(camera.projectionMatrix, translationMat, camera.projectionMatrix);
__WEBPACK_IMPORTED_MODULE_5_claygl_src_math_Matrix4__["a" /* default */].invert(camera.invProjectionMatrix, camera.projectionMatrix);
},
/**
* Reset accumulating frame
*/
resetFrame: function () {
this._frame = 0;
},
/**
* Return current frame
*/
getFrame: function () {
return this._frame;
},
/**
* Get source framebuffer for usage
*/
getSourceFrameBuffer: function () {
return this._sourceFb;
},
getOutputTexture: function () {
return this._outputTex;
},
resize: function (width, height) {
this._prevFrameTex.width = width;
this._prevFrameTex.height = height;
this._outputTex.width = width;
this._outputTex.height = height;
this._sourceTex.width = width;
this._sourceTex.height = height;
this._prevFrameTex.dirty();
this._outputTex.dirty();
this._sourceTex.dirty();
},
isFinished: function () {
return this._frame >= this._haltonSequence.length;
},
render: function (renderer, sourceTex, notOutput) {
var blendPass = this._blendPass;
if (this._frame === 0) {
// Direct output
blendPass.setUniform('weight1', 0);
blendPass.setUniform('weight2', 1);
}
else {
blendPass.setUniform('weight1', 0.9);
blendPass.setUniform('weight2', 0.1);
}
blendPass.setUniform('texture1', this._prevFrameTex);
blendPass.setUniform('texture2', sourceTex || this._sourceTex);
this._blendFb.attach(this._outputTex);
this._blendFb.bind(renderer);
blendPass.render(renderer);
this._blendFb.unbind(renderer);
if (!notOutput) {
this._outputPass.setUniform('texture', this._outputTex);
this._outputPass.render(renderer);
}
// Swap texture
var tmp = this._prevFrameTex;
this._prevFrameTex = this._outputTex;
this._outputTex = tmp;
this._frame++;
},
dispose: function (renderer) {
this._sourceFb.dispose(renderer);
this._blendFb.dispose(renderer);
this._prevFrameTex.dispose(renderer);
this._outputTex.dispose(renderer);
this._sourceTex.dispose(renderer);
this._outputPass.dispose(renderer);
this._blendPass.dispose(renderer);
}
};
/* harmony default export */ __webpack_exports__["a"] = (TemporalSuperSampling);
/***/ }),
/* 193 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__geo3D_Geo3DModel__ = __webpack_require__(194);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__geo3D_Geo3DView__ = __webpack_require__(195);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__coord_geo3DCreator__ = __webpack_require__(91);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerAction({
type: 'geo3DChangeCamera',
event: 'geo3dcamerachanged',
update: 'series:updateCamera'
}, function (payload, ecModel) {
ecModel.eachComponent({
mainType: 'geo3D', query: payload
}, function (componentModel) {
componentModel.setView(payload);
});
});
/***/ }),
/* 194 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__common_componentViewControlMixin__ = __webpack_require__(38);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__common_componentPostEffectMixin__ = __webpack_require__(25);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__common_componentLightMixin__ = __webpack_require__(26);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_componentShadingMixin__ = __webpack_require__(28);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__coord_geo3D_geo3DModelMixin__ = __webpack_require__(89);
var Geo3DModel = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendComponentModel({
type: 'geo3D',
layoutMode: 'box',
coordinateSystem: null,
optionUpdated: function () {
var option = this.option;
option.regions = this.getFilledRegions(option.regions, option.map);
var dimensions = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.helper.completeDimensions(['value'], option.data, {
encodeDef: this.get('encode'),
dimsDef: this.get('dimensions')
});
var list = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.List(dimensions, this);
list.initData(option.regions);
var regionModelMap = {};
list.each(function (idx) {
var name = list.getName(idx);
var itemModel = list.getItemModel(idx);
regionModelMap[name] = itemModel;
});
this._regionModelMap = regionModelMap;
this._data = list;
},
getData: function () {
return this._data;
},
getRegionModel: function (idx) {
var name = this.getData().getName(idx);
return this._regionModelMap[name] || new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.Model(null, this);
},
getRegionPolygonCoords: function (idx) {
var name = this.getData().getName(idx);
var region = this.coordinateSystem.getRegion(name);
return region ? region.geometries : [];
},
/**
* Format label
* @param {string} name Region name
* @param {string} [status='normal'] 'normal' or 'emphasis'
* @return {string}
*/
getFormattedLabel: function (dataIndex, status) {
var name = this._data.getName(dataIndex);
var regionModel = this.getRegionModel(name);
var formatter = regionModel.get(status === 'normal' ? ['label', 'formatter'] : ['emphasis', 'label', 'formatter']);
if (formatter == null) {
formatter = regionModel.get(['label', 'formatter']);
}
var params = {
name: name
};
if (typeof formatter === 'function') {
params.status = status;
return formatter(params);
}
else if (typeof formatter === 'string') {
var serName = params.seriesName;
return formatter.replace('{a}', serName != null ? serName : '');
}
else {
return name;
}
},
defaultOption: {
// itemStyle: {},
// height,
// label: {}
// realisticMaterial
regions: []
}
});
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Geo3DModel.prototype, __WEBPACK_IMPORTED_MODULE_5__coord_geo3D_geo3DModelMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Geo3DModel.prototype, __WEBPACK_IMPORTED_MODULE_1__common_componentViewControlMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Geo3DModel.prototype, __WEBPACK_IMPORTED_MODULE_2__common_componentPostEffectMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Geo3DModel.prototype, __WEBPACK_IMPORTED_MODULE_3__common_componentLightMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Geo3DModel.prototype, __WEBPACK_IMPORTED_MODULE_4__common_componentShadingMixin__["a" /* default */]);
/* unused harmony default export */ var _unused_webpack_default_export = (Geo3DModel);
/***/ }),
/* 195 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__common_Geo3DBuilder__ = __webpack_require__(59);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_OrbitControl__ = __webpack_require__(39);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_SceneHelper__ = __webpack_require__(27);
/* unused harmony default export */ var _unused_webpack_default_export = (__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default.a.extendComponentView({
type: 'geo3D',
__ecgl__: true,
init: function (ecModel, api) {
this._geo3DBuilder = new __WEBPACK_IMPORTED_MODULE_0__common_Geo3DBuilder__["a" /* default */](api);
this.groupGL = new __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].Node();
this._lightRoot = new __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].Node();
this._sceneHelper = new __WEBPACK_IMPORTED_MODULE_4__common_SceneHelper__["a" /* default */](this._lightRoot);
this._sceneHelper.initLight(this._lightRoot);
this._control = new __WEBPACK_IMPORTED_MODULE_3__util_OrbitControl__["a" /* default */]({
zr: api.getZr()
});
this._control.init();
},
render: function (geo3DModel, ecModel, api) {
this.groupGL.add(this._geo3DBuilder.rootNode);
var geo3D = geo3DModel.coordinateSystem;
if (!geo3D || !geo3D.viewGL) {
return;
}
// Always have light.
geo3D.viewGL.add(this._lightRoot);
if (geo3DModel.get('show')) {
geo3D.viewGL.add(this.groupGL);
}
else {
geo3D.viewGL.remove(this.groupGL);
}
var control = this._control;
control.setViewGL(geo3D.viewGL);
var viewControlModel = geo3DModel.getModel('viewControl');
control.setFromViewControlModel(viewControlModel, 0);
this._sceneHelper.setScene(geo3D.viewGL.scene);
this._sceneHelper.updateLight(geo3DModel);
// Set post effect
geo3D.viewGL.setPostEffect(geo3DModel.getModel('postEffect'), api);
geo3D.viewGL.setTemporalSuperSampling(geo3DModel.getModel('temporalSuperSampling'));
// Must update after geo3D.viewGL.setPostEffect
this._geo3DBuilder.update(geo3DModel, ecModel, api, 0, geo3DModel.getData().count());
var srgbDefineMethod = geo3D.viewGL.isLinearSpace() ? 'define' : 'undefine';
this._geo3DBuilder.rootNode.traverse(function (mesh) {
if (mesh.material) {
mesh.material[srgbDefineMethod]('fragment', 'SRGB_DECODE');
}
});
control.off('update');
control.on('update', function () {
api.dispatchAction({
type: 'geo3DChangeCamera',
alpha: control.getAlpha(),
beta: control.getBeta(),
distance: control.getDistance(),
center: control.getCenter(),
from: this.uid,
geo3DId: geo3DModel.id
});
});
control.update();
},
afterRender: function (geo3DModel, ecModel, api, layerGL) {
var renderer = layerGL.renderer;
this._sceneHelper.updateAmbientCubemap(renderer, geo3DModel, api);
this._sceneHelper.updateSkybox(renderer, geo3DModel, api);
},
dispose: function () {
this._control.dispose();
}
}));
/***/ }),
/* 196 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
// https://github.com/mapbox/earcut/blob/master/src/earcut.js
/* harmony default export */ __webpack_exports__["a"] = (earcut);
function earcut(data, holeIndices, dim) {
dim = dim || 2;
var hasHoles = holeIndices && holeIndices.length,
outerLen = hasHoles ? holeIndices[0] * dim : data.length,
outerNode = linkedList(data, 0, outerLen, dim, true),
triangles = [];
if (!outerNode) return triangles;
var minX, minY, maxX, maxY, x, y, size;
if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);
// if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox
if (data.length > 80 * dim) {
minX = maxX = data[0];
minY = maxY = data[1];
for (var i = dim; i < outerLen; i += dim) {
x = data[i];
y = data[i + 1];
if (x < minX) minX = x;
if (y < minY) minY = y;
if (x > maxX) maxX = x;
if (y > maxY) maxY = y;
}
// minX, minY and size are later used to transform coords into integers for z-order calculation
size = Math.max(maxX - minX, maxY - minY);
}
earcutLinked(outerNode, triangles, dim, minX, minY, size);
return triangles;
}
// create a circular doubly linked list from polygon points in the specified winding order
function linkedList(data, start, end, dim, clockwise) {
var i, last;
if (clockwise === (signedArea(data, start, end, dim) > 0)) {
for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last);
} else {
for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last);
}
if (last && equals(last, last.next)) {
removeNode(last);
last = last.next;
}
return last;
}
// eliminate colinear or duplicate points
function filterPoints(start, end) {
if (!start) return start;
if (!end) end = start;
var p = start,
again;
do {
again = false;
if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {
removeNode(p);
p = end = p.prev;
if (p === p.next) return null;
again = true;
} else {
p = p.next;
}
} while (again || p !== end);
return end;
}
// main ear slicing loop which triangulates a polygon (given as a linked list)
function earcutLinked(ear, triangles, dim, minX, minY, size, pass) {
if (!ear) return;
// interlink polygon nodes in z-order
if (!pass && size) indexCurve(ear, minX, minY, size);
var stop = ear,
prev, next;
// iterate through ears, slicing them one by one
while (ear.prev !== ear.next) {
prev = ear.prev;
next = ear.next;
if (size ? isEarHashed(ear, minX, minY, size) : isEar(ear)) {
// cut off the triangle
triangles.push(prev.i / dim);
triangles.push(ear.i / dim);
triangles.push(next.i / dim);
removeNode(ear);
// skipping the next vertice leads to less sliver triangles
ear = next.next;
stop = next.next;
continue;
}
ear = next;
// if we looped through the whole remaining polygon and can't find any more ears
if (ear === stop) {
// try filtering points and slicing again
if (!pass) {
earcutLinked(filterPoints(ear), triangles, dim, minX, minY, size, 1);
// if this didn't work, try curing all small self-intersections locally
} else if (pass === 1) {
ear = cureLocalIntersections(ear, triangles, dim);
earcutLinked(ear, triangles, dim, minX, minY, size, 2);
// as a last resort, try splitting the remaining polygon into two
} else if (pass === 2) {
splitEarcut(ear, triangles, dim, minX, minY, size);
}
break;
}
}
}
// check whether a polygon node forms a valid ear with adjacent nodes
function isEar(ear) {
var a = ear.prev,
b = ear,
c = ear.next;
if (area(a, b, c) >= 0) return false; // reflex, can't be an ear
// now make sure we don't have other points inside the potential ear
var p = ear.next.next;
while (p !== ear.prev) {
if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&
area(p.prev, p, p.next) >= 0) return false;
p = p.next;
}
return true;
}
function isEarHashed(ear, minX, minY, size) {
var a = ear.prev,
b = ear,
c = ear.next;
if (area(a, b, c) >= 0) return false; // reflex, can't be an ear
// triangle bbox; min & max are calculated like this for speed
var minTX = a.x < b.x ? (a.x < c.x ? a.x : c.x) : (b.x < c.x ? b.x : c.x),
minTY = a.y < b.y ? (a.y < c.y ? a.y : c.y) : (b.y < c.y ? b.y : c.y),
maxTX = a.x > b.x ? (a.x > c.x ? a.x : c.x) : (b.x > c.x ? b.x : c.x),
maxTY = a.y > b.y ? (a.y > c.y ? a.y : c.y) : (b.y > c.y ? b.y : c.y);
// z-order range for the current triangle bbox;
var minZ = zOrder(minTX, minTY, minX, minY, size),
maxZ = zOrder(maxTX, maxTY, minX, minY, size);
// first look for points inside the triangle in increasing z-order
var p = ear.nextZ;
while (p && p.z <= maxZ) {
if (p !== ear.prev && p !== ear.next &&
pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&
area(p.prev, p, p.next) >= 0) return false;
p = p.nextZ;
}
// then look for points in decreasing z-order
p = ear.prevZ;
while (p && p.z >= minZ) {
if (p !== ear.prev && p !== ear.next &&
pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&
area(p.prev, p, p.next) >= 0) return false;
p = p.prevZ;
}
return true;
}
// go through all polygon nodes and cure small local self-intersections
function cureLocalIntersections(start, triangles, dim) {
var p = start;
do {
var a = p.prev,
b = p.next.next;
if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {
triangles.push(a.i / dim);
triangles.push(p.i / dim);
triangles.push(b.i / dim);
// remove two nodes involved
removeNode(p);
removeNode(p.next);
p = start = b;
}
p = p.next;
} while (p !== start);
return p;
}
// try splitting polygon into two and triangulate them independently
function splitEarcut(start, triangles, dim, minX, minY, size) {
// look for a valid diagonal that divides the polygon into two
var a = start;
do {
var b = a.next.next;
while (b !== a.prev) {
if (a.i !== b.i && isValidDiagonal(a, b)) {
// split the polygon in two by the diagonal
var c = splitPolygon(a, b);
// filter colinear points around the cuts
a = filterPoints(a, a.next);
c = filterPoints(c, c.next);
// run earcut on each half
earcutLinked(a, triangles, dim, minX, minY, size);
earcutLinked(c, triangles, dim, minX, minY, size);
return;
}
b = b.next;
}
a = a.next;
} while (a !== start);
}
// link every hole into the outer loop, producing a single-ring polygon without holes
function eliminateHoles(data, holeIndices, outerNode, dim) {
var queue = [],
i, len, start, end, list;
for (i = 0, len = holeIndices.length; i < len; i++) {
start = holeIndices[i] * dim;
end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
list = linkedList(data, start, end, dim, false);
if (list === list.next) list.steiner = true;
queue.push(getLeftmost(list));
}
queue.sort(compareX);
// process holes from left to right
for (i = 0; i < queue.length; i++) {
eliminateHole(queue[i], outerNode);
outerNode = filterPoints(outerNode, outerNode.next);
}
return outerNode;
}
function compareX(a, b) {
return a.x - b.x;
}
// find a bridge between vertices that connects hole with an outer ring and and link it
function eliminateHole(hole, outerNode) {
outerNode = findHoleBridge(hole, outerNode);
if (outerNode) {
var b = splitPolygon(outerNode, hole);
filterPoints(b, b.next);
}
}
// David Eberly's algorithm for finding a bridge between hole and outer polygon
function findHoleBridge(hole, outerNode) {
var p = outerNode,
hx = hole.x,
hy = hole.y,
qx = -Infinity,
m;
// find a segment intersected by a ray from the hole's leftmost point to the left;
// segment's endpoint with lesser x will be potential connection point
do {
if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) {
var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);
if (x <= hx && x > qx) {
qx = x;
if (x === hx) {
if (hy === p.y) return p;
if (hy === p.next.y) return p.next;
}
m = p.x < p.next.x ? p : p.next;
}
}
p = p.next;
} while (p !== outerNode);
if (!m) return null;
if (hx === qx) return m.prev; // hole touches outer segment; pick lower endpoint
// look for points inside the triangle of hole point, segment intersection and endpoint;
// if there are no points found, we have a valid connection;
// otherwise choose the point of the minimum angle with the ray as connection point
var stop = m,
mx = m.x,
my = m.y,
tanMin = Infinity,
tan;
p = m.next;
while (p !== stop) {
if (hx >= p.x && p.x >= mx && hx !== p.x &&
pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {
tan = Math.abs(hy - p.y) / (hx - p.x); // tangential
if ((tan < tanMin || (tan === tanMin && p.x > m.x)) && locallyInside(p, hole)) {
m = p;
tanMin = tan;
}
}
p = p.next;
}
return m;
}
// interlink polygon nodes in z-order
function indexCurve(start, minX, minY, size) {
var p = start;
do {
if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, size);
p.prevZ = p.prev;
p.nextZ = p.next;
p = p.next;
} while (p !== start);
p.prevZ.nextZ = null;
p.prevZ = null;
sortLinked(p);
}
// Simon Tatham's linked list merge sort algorithm
// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
function sortLinked(list) {
var i, p, q, e, tail, numMerges, pSize, qSize,
inSize = 1;
do {
p = list;
list = null;
tail = null;
numMerges = 0;
while (p) {
numMerges++;
q = p;
pSize = 0;
for (i = 0; i < inSize; i++) {
pSize++;
q = q.nextZ;
if (!q) break;
}
qSize = inSize;
while (pSize > 0 || (qSize > 0 && q)) {
if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) {
e = p;
p = p.nextZ;
pSize--;
} else {
e = q;
q = q.nextZ;
qSize--;
}
if (tail) tail.nextZ = e;
else list = e;
e.prevZ = tail;
tail = e;
}
p = q;
}
tail.nextZ = null;
inSize *= 2;
} while (numMerges > 1);
return list;
}
// z-order of a point given coords and size of the data bounding box
function zOrder(x, y, minX, minY, size) {
// coords are transformed into non-negative 15-bit integer range
x = 32767 * (x - minX) / size;
y = 32767 * (y - minY) / size;
x = (x | (x << 8)) & 0x00FF00FF;
x = (x | (x << 4)) & 0x0F0F0F0F;
x = (x | (x << 2)) & 0x33333333;
x = (x | (x << 1)) & 0x55555555;
y = (y | (y << 8)) & 0x00FF00FF;
y = (y | (y << 4)) & 0x0F0F0F0F;
y = (y | (y << 2)) & 0x33333333;
y = (y | (y << 1)) & 0x55555555;
return x | (y << 1);
}
// find the leftmost node of a polygon ring
function getLeftmost(start) {
var p = start,
leftmost = start;
do {
if (p.x < leftmost.x) leftmost = p;
p = p.next;
} while (p !== start);
return leftmost;
}
// check if a point lies within a convex triangle
function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {
return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 &&
(ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 &&
(bx - px) * (cy - py) - (cx - px) * (by - py) >= 0;
}
// check if a diagonal between two polygon nodes is valid (lies in polygon interior)
function isValidDiagonal(a, b) {
return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) &&
locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b);
}
// signed area of a triangle
function area(p, q, r) {
return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
}
// check if two points are equal
function equals(p1, p2) {
return p1.x === p2.x && p1.y === p2.y;
}
// check if two segments intersect
function intersects(p1, q1, p2, q2) {
if ((equals(p1, q1) && equals(p2, q2)) ||
(equals(p1, q2) && equals(p2, q1))) return true;
return area(p1, q1, p2) > 0 !== area(p1, q1, q2) > 0 &&
area(p2, q2, p1) > 0 !== area(p2, q2, q1) > 0;
}
// check if a polygon diagonal intersects any polygon segments
function intersectsPolygon(a, b) {
var p = a;
do {
if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i &&
intersects(p, p.next, a, b)) return true;
p = p.next;
} while (p !== a);
return false;
}
// check if a polygon diagonal is locally inside the polygon
function locallyInside(a, b) {
return area(a.prev, a, a.next) < 0 ?
area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 :
area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;
}
// check if the middle point of a polygon diagonal is inside the polygon
function middleInside(a, b) {
var p = a,
inside = false,
px = (a.x + b.x) / 2,
py = (a.y + b.y) / 2;
do {
if (((p.y > py) !== (p.next.y > py)) && p.next.y !== p.y &&
(px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x))
inside = !inside;
p = p.next;
} while (p !== a);
return inside;
}
// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;
// if one belongs to the outer ring and another to a hole, it merges it into a single ring
function splitPolygon(a, b) {
var a2 = new Node(a.i, a.x, a.y),
b2 = new Node(b.i, b.x, b.y),
an = a.next,
bp = b.prev;
a.next = b;
b.prev = a;
a2.next = an;
an.prev = a2;
b2.next = a2;
a2.prev = b2;
bp.next = b2;
b2.prev = bp;
return b2;
}
// create a node and optionally link it with previous one (in a circular doubly linked list)
function insertNode(i, x, y, last) {
var p = new Node(i, x, y);
if (!last) {
p.prev = p;
p.next = p;
} else {
p.next = last.next;
p.prev = last;
last.next.prev = p;
last.next = p;
}
return p;
}
function removeNode(p) {
p.next.prev = p.prev;
p.prev.next = p.next;
if (p.prevZ) p.prevZ.nextZ = p.nextZ;
if (p.nextZ) p.nextZ.prevZ = p.prevZ;
}
function Node(i, x, y) {
// vertice index in coordinates array
this.i = i;
// vertex coordinates
this.x = x;
this.y = y;
// previous and next vertice nodes in a polygon ring
this.prev = null;
this.next = null;
// z-order curve value
this.z = null;
// previous and next nodes in z-order
this.prevZ = null;
this.nextZ = null;
// indicates whether this is a steiner point
this.steiner = false;
}
// return a percentage difference between the polygon area and its triangulation area;
// used to verify correctness of triangulation
earcut.deviation = function (data, holeIndices, dim, triangles) {
var hasHoles = holeIndices && holeIndices.length;
var outerLen = hasHoles ? holeIndices[0] * dim : data.length;
var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim));
if (hasHoles) {
for (var i = 0, len = holeIndices.length; i < len; i++) {
var start = holeIndices[i] * dim;
var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
polygonArea -= Math.abs(signedArea(data, start, end, dim));
}
}
var trianglesArea = 0;
for (i = 0; i < triangles.length; i += 3) {
var a = triangles[i] * dim;
var b = triangles[i + 1] * dim;
var c = triangles[i + 2] * dim;
trianglesArea += Math.abs(
(data[a] - data[c]) * (data[b + 1] - data[a + 1]) -
(data[a] - data[b]) * (data[c + 1] - data[a + 1]));
}
return polygonArea === 0 && trianglesArea === 0 ? 0 :
Math.abs((trianglesArea - polygonArea) / polygonArea);
};
function signedArea(data, start, end, dim) {
var sum = 0;
for (var i = start, j = end - dim; i < end; i += dim) {
sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);
j = i;
}
return sum;
}
/***/ }),
/* 197 */
/***/ (function(module, exports, __webpack_require__) {
var zrUtil = __webpack_require__(12);
var coordsOffsetMap = {
'南海诸岛': [32, 80],
// 全国
'广东': [0, -10],
'香港': [10, 5],
'澳门': [-10, 10],
//'北京': [-10, 0],
'天津': [5, 5]
};
function _default(geo) {
zrUtil.each(geo.regions, function (region) {
var coordFix = coordsOffsetMap[region.name];
if (coordFix) {
var cp = region.center;
cp[0] += coordFix[0] / 10.5;
cp[1] += -coordFix[1] / (10.5 / 0.75);
}
});
}
module.exports = _default;
/***/ }),
/* 198 */
/***/ (function(module, exports, __webpack_require__) {
var zrUtil = __webpack_require__(12);
var geoCoordMap = {
'Russia': [100, 60],
'United States': [-99, 38],
'United States of America': [-99, 38]
};
function _default(geo) {
zrUtil.each(geo.regions, function (region) {
var geoCoord = geoCoordMap[region.name];
if (geoCoord) {
var cp = region.center;
cp[0] = geoCoord[0];
cp[1] = geoCoord[1];
}
});
}
module.exports = _default;
/***/ }),
/* 199 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__globe_GlobeModel__ = __webpack_require__(200);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__globe_GlobeView__ = __webpack_require__(201);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__coord_globeCreator__ = __webpack_require__(203);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerAction({
type: 'globeChangeCamera',
event: 'globecamerachanged',
update: 'series:updateCamera'
}, function (payload, ecModel) {
ecModel.eachComponent({
mainType: 'globe', query: payload
}, function (componentModel) {
componentModel.setView(payload);
});
});
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerAction({
type: 'globeUpdateDisplacment',
event: 'globedisplacementupdated',
update: 'update'
}, function (payload, ecModel) {
// Noop
});
/***/ }),
/* 200 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__common_componentViewControlMixin__ = __webpack_require__(38);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__common_componentPostEffectMixin__ = __webpack_require__(25);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__common_componentLightMixin__ = __webpack_require__(26);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_componentShadingMixin__ = __webpack_require__(28);
function defaultId(option, idx) {
option.id = option.id || option.name || (idx + '');
}
var GlobeModel = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendComponentModel({
type: 'globe',
layoutMode: 'box',
coordinateSystem: null,
init: function () {
GlobeModel.superApply(this, 'init', arguments);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.each(this.option.layers, function (layerOption, idx) {
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(layerOption, this.defaultLayerOption);
defaultId(layerOption, idx);
}, this);
},
mergeOption: function (option) {
// TODO test
var oldLayers = this.option.layers;
this.option.layers = null;
GlobeModel.superApply(this, 'mergeOption', arguments);
function createLayerMap(layers) {
return __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.reduce(layers, function (obj, layerOption, idx) {
defaultId(layerOption, idx);
obj[layerOption.id] = layerOption;
return obj;
}, {});
}
if (oldLayers && oldLayers.length) {
var newLayerMap = createLayerMap(option.layers);
var oldLayerMap = createLayerMap(oldLayers);
for (var id in newLayerMap) {
if (oldLayerMap[id]) {
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(oldLayerMap[id], newLayerMap[id], true);
}
else {
oldLayers.push(option.layers[id]);
}
}
// Copy back
this.option.layers = oldLayers;
}
// else overwrite
// Set default
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.each(this.option.layers, function (layerOption) {
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(layerOption, this.defaultLayerOption);
}, this);
},
optionUpdated: function () {
this.updateDisplacementHash();
},
defaultLayerOption: {
show: true,
type: 'overlay'
},
defaultOption: {
show: true,
zlevel: -10,
// Layout used for viewport
left: 0,
top: 0,
width: '100%',
height: '100%',
environment: 'auto',
baseColor: '#fff',
// Base albedo texture
baseTexture: '',
// Height texture for bump mapping and vertex displacement
heightTexture: '',
// Texture for vertex displacement, default use heightTexture
displacementTexture: '',
// Scale of vertex displacement, available only if displacementTexture is set.
displacementScale: 0,
// Detail of displacement. 'low', 'medium', 'high', 'ultra'
displacementQuality: 'medium',
// Globe radius
globeRadius: 100,
// Globe outer radius. Which is max of altitude.
globeOuterRadius: 150,
// Shading of globe
shading: 'lambert',
// Extend light
light: {
// Main sun light
main: {
// Time, default it will use system time
time: ''
}
},
// light
// postEffect
// temporalSuperSampling
viewControl: {
autoRotate: true,
panSensitivity: 0,
targetCoord: null
},
// {
// show: true,
// name: 'cloud',
// type: 'overlay',
// shading: 'lambert',
// distance: 10,
// texture: ''
// }
// {
// type: 'blend',
// blendTo: 'albedo'
// blendType: 'source-over'
// }
layers: []
},
setDisplacementData: function (data, width, height) {
this.displacementData = data;
this.displacementWidth = width;
this.displacementHeight = height;
},
getDisplacementTexture: function () {
return this.get('displacementTexture') || this.get('heightTexture');
},
getDisplacemenScale: function () {
var displacementTexture = this.getDisplacementTexture();
var displacementScale = this.get('displacementScale');
if (!displacementTexture || displacementTexture === 'none') {
displacementScale = 0;
}
return displacementScale;
},
hasDisplacement: function () {
return this.getDisplacemenScale() > 0;
},
_displacementChanged: true,
_displacementScale: 0,
updateDisplacementHash: function () {
var displacementTexture = this.getDisplacementTexture();
var displacementScale = this.getDisplacemenScale();
this._displacementChanged =
this._displacementTexture !== displacementTexture
|| this._displacementScale !== displacementScale;
this._displacementTexture = displacementTexture;
this._displacementScale = displacementScale;
},
isDisplacementChanged: function () {
return this._displacementChanged;
}
});
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(GlobeModel.prototype, __WEBPACK_IMPORTED_MODULE_1__common_componentViewControlMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(GlobeModel.prototype, __WEBPACK_IMPORTED_MODULE_2__common_componentPostEffectMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(GlobeModel.prototype, __WEBPACK_IMPORTED_MODULE_3__common_componentLightMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(GlobeModel.prototype, __WEBPACK_IMPORTED_MODULE_4__common_componentShadingMixin__["a" /* default */]);
/* unused harmony default export */ var _unused_webpack_default_export = (GlobeModel);
/***/ }),
/* 201 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_OrbitControl__ = __webpack_require__(39);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__common_SceneHelper__ = __webpack_require__(27);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_sunCalc__ = __webpack_require__(202);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__util_retrieve__ = __webpack_require__(3);
/* unused harmony default export */ var _unused_webpack_default_export = (__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendComponentView({
type: 'globe',
__ecgl__: true,
_displacementScale: 0,
init: function (ecModel, api) {
this.groupGL = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();
/**
* @type {clay.geometry.Sphere}
* @private
*/
this._sphereGeometry = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].SphereGeometry({
widthSegments: 200,
heightSegments: 100,
dynamic: true
});
this._overlayGeometry = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].SphereGeometry({
widthSegments: 80,
heightSegments: 40
});
/**
* @type {clay.geometry.Plane}
*/
this._planeGeometry = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].PlaneGeometry();
/**
* @type {clay.geometry.Mesh}
*/
this._earthMesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
renderNormal: true
});
this._lightRoot = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();
this._sceneHelper = new __WEBPACK_IMPORTED_MODULE_3__common_SceneHelper__["a" /* default */]();
this._sceneHelper.initLight(this._lightRoot);
this.groupGL.add(this._earthMesh);
this._control = new __WEBPACK_IMPORTED_MODULE_2__util_OrbitControl__["a" /* default */]({
zr: api.getZr()
});
this._control.init();
this._layerMeshes = {};
},
render: function (globeModel, ecModel, api) {
var coordSys = globeModel.coordinateSystem;
var shading = globeModel.get('shading');
// Always have light.
coordSys.viewGL.add(this._lightRoot);
if (globeModel.get('show')) {
// Add self to scene;
coordSys.viewGL.add(this.groupGL);
}
else {
coordSys.viewGL.remove(this.groupGL);
}
this._sceneHelper.setScene(coordSys.viewGL.scene);
// Set post effect
coordSys.viewGL.setPostEffect(globeModel.getModel('postEffect'), api);
coordSys.viewGL.setTemporalSuperSampling(globeModel.getModel('temporalSuperSampling'));
var earthMesh = this._earthMesh;
earthMesh.geometry = this._sphereGeometry;
var shadingPrefix = 'ecgl.' + shading;
if (!earthMesh.material || earthMesh.material.shader.name !== shadingPrefix) {
earthMesh.material = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createMaterial(shadingPrefix);
}
__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].setMaterialFromModel(
shading, earthMesh.material, globeModel, api
);
['roughnessMap', 'metalnessMap', 'detailMap', 'normalMap'].forEach(function (texName) {
var texture = earthMesh.material.get(texName);
if (texture) {
texture.flipY = false;
}
})
earthMesh.material.set('color', __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(
globeModel.get('baseColor')
));
// shrink a little
var scale = coordSys.radius * 0.99;
earthMesh.scale.set(scale, scale, scale);
var diffuseTexture = earthMesh.material.setTextureImage('diffuseMap', globeModel.get('baseTexture'), api, {
flipY: false,
anisotropic: 8
});
if (diffuseTexture && diffuseTexture.surface) {
diffuseTexture.surface.attachToMesh(earthMesh);
}
// Update bump map
var bumpTexture = earthMesh.material.setTextureImage('bumpMap', globeModel.get('heightTexture'), api, {
flipY: false,
anisotropic: 8
});
if (bumpTexture && bumpTexture.surface) {
bumpTexture.surface.attachToMesh(earthMesh);
}
earthMesh.material[globeModel.get('postEffect.enable') ? 'define' : 'undefine']('fragment', 'SRGB_DECODE');
this._updateLight(globeModel, api);
this._displaceVertices(globeModel, api);
this._updateViewControl(globeModel, api);
this._updateLayers(globeModel, api);
},
afterRender: function (globeModel, ecModel, api, layerGL) {
// Create ambient cubemap after render because we need to know the renderer.
// TODO
var renderer = layerGL.renderer;
this._sceneHelper.updateAmbientCubemap(renderer, globeModel, api);
this._sceneHelper.updateSkybox(renderer, globeModel, api);
},
_updateLayers: function (globeModel, api) {
var coordSys = globeModel.coordinateSystem;
var layers = globeModel.get('layers');
var lastDistance = coordSys.radius;
var layerDiffuseTextures = [];
var layerDiffuseIntensity = [];
var layerEmissiveTextures = [];
var layerEmissionIntensity = [];
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.each(layers, function (layerOption) {
var layerModel = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.Model(layerOption);
var layerType = layerModel.get('type');
var texture = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].loadTexture(layerModel.get('texture'), api, {
flipY: false,
anisotropic: 8
});
if (texture.surface) {
texture.surface.attachToMesh(this._earthMesh);
}
if (layerType === 'blend') {
var blendTo = layerModel.get('blendTo');
var intensity = __WEBPACK_IMPORTED_MODULE_5__util_retrieve__["a" /* default */].firstNotNull(layerModel.get('intensity'), 1.0);
if (blendTo === 'emission') {
layerEmissiveTextures.push(texture);
layerEmissionIntensity.push(intensity);
}
else { // Default is albedo
layerDiffuseTextures.push(texture);
layerDiffuseIntensity.push(intensity);
}
}
else { // Default use overlay
var id = layerModel.get('id');
var overlayMesh = this._layerMeshes[id];
if (!overlayMesh) {
overlayMesh = this._layerMeshes[id] = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
geometry: this._overlayGeometry,
castShadow: false,
ignorePicking: true
});
}
var shading = layerModel.get('shading');
if (shading === 'lambert') {
overlayMesh.material = overlayMesh.__lambertMaterial || new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
autoUpdateTextureStatus: false,
shader: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createShader('ecgl.lambert'),
transparent: true,
depthMask: false
});
overlayMesh.__lambertMaterial = overlayMesh.material;
}
else { // color
overlayMesh.material = overlayMesh.__colorMaterial || new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
autoUpdateTextureStatus: false,
shader: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createShader('ecgl.color'),
transparent: true,
depthMask: false
});
overlayMesh.__colorMaterial = overlayMesh.material;
}
// overlay should be transparent if texture is not loaded yet.
overlayMesh.material.enableTexture('diffuseMap');
var distance = layerModel.get('distance');
// Based on distance of last layer
var radius = lastDistance + (distance == null ? coordSys.radius / 100 : distance);
overlayMesh.scale.set(radius, radius, radius);
lastDistance = radius;
// FIXME Exists blink.
var blankTexture = this._blankTexture || (this._blankTexture = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createBlankTexture('rgba(255, 255, 255, 0)'));
overlayMesh.material.set('diffuseMap', blankTexture);
__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].loadTexture(layerModel.get('texture'), api, {
flipY: false,
anisotropic: 8
}, function (texture) {
if (texture.surface) {
texture.surface.attachToMesh(overlayMesh);
}
overlayMesh.material.set('diffuseMap', texture);
api.getZr().refresh();
});
layerModel.get('show') ? this.groupGL.add(overlayMesh) : this.groupGL.remove(overlayMesh);
}
}, this);
var earthMaterial = this._earthMesh.material;
earthMaterial.define('fragment', 'LAYER_DIFFUSEMAP_COUNT', layerDiffuseTextures.length);
earthMaterial.define('fragment', 'LAYER_EMISSIVEMAP_COUNT', layerEmissiveTextures.length);
earthMaterial.set('layerDiffuseMap', layerDiffuseTextures);
earthMaterial.set('layerDiffuseIntensity', layerDiffuseIntensity);
earthMaterial.set('layerEmissiveMap', layerEmissiveTextures);
earthMaterial.set('layerEmissionIntensity', layerEmissionIntensity);
var debugWireframeModel = globeModel.getModel('debug.wireframe');
if (debugWireframeModel.get('show')) {
earthMaterial.define('both', 'WIREFRAME_TRIANGLE');
var color = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(
debugWireframeModel.get('lineStyle.color') || 'rgba(0,0,0,0.5)'
);
var width = __WEBPACK_IMPORTED_MODULE_5__util_retrieve__["a" /* default */].firstNotNull(
debugWireframeModel.get('lineStyle.width'), 1
);
earthMaterial.set('wireframeLineWidth', width);
earthMaterial.set('wireframeLineColor', color);
}
else {
earthMaterial.undefine('both', 'WIREFRAME_TRIANGLE');
}
},
_updateViewControl: function (globeModel, api) {
var coordSys = globeModel.coordinateSystem;
// Update camera
var viewControlModel = globeModel.getModel('viewControl');
var camera = coordSys.viewGL.camera;
var self = this;
function makeAction() {
return {
type: 'globeChangeCamera',
alpha: control.getAlpha(),
beta: control.getBeta(),
distance: control.getDistance() - coordSys.radius,
center: control.getCenter(),
from: self.uid,
globeId: globeModel.id
};
}
// Update control
var control = this._control;
control.setViewGL(coordSys.viewGL);
var coord = viewControlModel.get('targetCoord');
var alpha, beta;
if (coord != null) {
beta = coord[0] + 90;
alpha = coord[1];
}
control.setFromViewControlModel(viewControlModel, {
baseDistance: coordSys.radius,
alpha: alpha,
beta: beta
});
control.off('update');
control.on('update', function () {
api.dispatchAction(makeAction());
});
},
_displaceVertices: function (globeModel, api) {
var displacementQuality = globeModel.get('displacementQuality');
var showDebugWireframe = globeModel.get('debug.wireframe.show');
var globe = globeModel.coordinateSystem;
if (!globeModel.isDisplacementChanged()
&& displacementQuality === this._displacementQuality
&& showDebugWireframe === this._showDebugWireframe
) {
return;
}
this._displacementQuality = displacementQuality;
this._showDebugWireframe = showDebugWireframe;
var geometry = this._sphereGeometry;
var widthSegments = ({
low: 100,
medium: 200,
high: 400,
ultra: 800
})[displacementQuality] || 200;
var heightSegments = widthSegments / 2;
if (geometry.widthSegments !== widthSegments || showDebugWireframe) {
geometry.widthSegments = widthSegments;
geometry.heightSegments = heightSegments;
geometry.build();
}
this._doDisplaceVertices(geometry, globe);
if (showDebugWireframe) {
geometry.generateBarycentric();
}
},
_doDisplaceVertices: function (geometry, globe) {
var positionArr = geometry.attributes.position.value;
var uvArr = geometry.attributes.texcoord0.value;
var originalPositionArr = geometry.__originalPosition;
if (!originalPositionArr || originalPositionArr.length !== positionArr.length) {
originalPositionArr = new Float32Array(positionArr.length);
originalPositionArr.set(positionArr);
geometry.__originalPosition = originalPositionArr;
}
var width = globe.displacementWidth;
var height = globe.displacementHeight;
var data = globe.displacementData;
for (var i = 0; i < geometry.vertexCount; i++) {
var i3 = i * 3;
var i2 = i * 2;
var x = originalPositionArr[i3 + 1];
var y = originalPositionArr[i3 + 2];
var z = originalPositionArr[i3 + 3];
var u = uvArr[i2++];
var v = uvArr[i2++];
var j = Math.round(u * (width - 1));
var k = Math.round(v * (height - 1));
var idx = k * width + j;
var scale = data ? data[idx] : 0;
positionArr[i3 + 1] = x + x * scale;
positionArr[i3 + 2] = y + y * scale;
positionArr[i3 + 3] = z + z * scale;
}
geometry.generateVertexNormals();
geometry.dirty();
geometry.updateBoundingBox();
},
_updateLight: function (globeModel, api) {
var earthMesh = this._earthMesh;
this._sceneHelper.updateLight(globeModel);
var mainLight = this._sceneHelper.mainLight;
// Put sun in the right position
var time = globeModel.get('light.main.time') || new Date();
// http://en.wikipedia.org/wiki/Azimuth
var pos = __WEBPACK_IMPORTED_MODULE_4__util_sunCalc__["a" /* default */].getPosition(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.number.parseDate(time), 0, 0);
var r0 = Math.cos(pos.altitude);
// FIXME How to calculate the y ?
mainLight.position.y = -r0 * Math.cos(pos.azimuth);
mainLight.position.x = Math.sin(pos.altitude);
mainLight.position.z = r0 * Math.sin(pos.azimuth);
mainLight.lookAt(earthMesh.getWorldPosition());
},
dispose: function (ecModel, api) {
this.groupGL.removeAll();
this._control.dispose();
}
}));
/***/ }),
/* 202 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/*
(c) 2011-2014, Vladimir Agafonkin
SunCalc is a JavaScript library for calculating sun/mooon position and light phases.
https://github.com/mourner/suncalc
*/
// shortcuts for easier to read formulas
var PI = Math.PI,
sin = Math.sin,
cos = Math.cos,
tan = Math.tan,
asin = Math.asin,
atan = Math.atan2,
rad = PI / 180;
// sun calculations are based on http://aa.quae.nl/en/reken/zonpositie.html formulas
// date/time constants and conversions
var dayMs = 1000 * 60 * 60 * 24,
J1970 = 2440588,
J2000 = 2451545;
function toJulian (date) { return date.valueOf() / dayMs - 0.5 + J1970; }
function toDays (date) { return toJulian(date) - J2000; }
// general calculations for position
var e = rad * 23.4397; // obliquity of the Earth
function rightAscension(l, b) { return atan(sin(l) * cos(e) - tan(b) * sin(e), cos(l)); }
function declination(l, b) { return asin(sin(b) * cos(e) + cos(b) * sin(e) * sin(l)); }
function azimuth(H, phi, dec) { return atan(sin(H), cos(H) * sin(phi) - tan(dec) * cos(phi)); }
function altitude(H, phi, dec) { return asin(sin(phi) * sin(dec) + cos(phi) * cos(dec) * cos(H)); }
function siderealTime(d, lw) { return rad * (280.16 + 360.9856235 * d) - lw; }
// general sun calculations
function solarMeanAnomaly(d) { return rad * (357.5291 + 0.98560028 * d); }
function eclipticLongitude(M) {
var C = rad * (1.9148 * sin(M) + 0.02 * sin(2 * M) + 0.0003 * sin(3 * M)), // equation of center
P = rad * 102.9372; // perihelion of the Earth
return M + C + P + PI;
}
function sunCoords(d) {
var M = solarMeanAnomaly(d),
L = eclipticLongitude(M);
return {
dec: declination(L, 0),
ra: rightAscension(L, 0)
};
}
var SunCalc = {};
// calculates sun position for a given date and latitude/longitude
SunCalc.getPosition = function (date, lat, lng) {
var lw = rad * -lng,
phi = rad * lat,
d = toDays(date),
c = sunCoords(d),
H = siderealTime(d, lw) - c.ra;
return {
azimuth: azimuth(H, phi, c.dec),
altitude: altitude(H, phi, c.dec)
};
};
/* harmony default export */ __webpack_exports__["a"] = (SunCalc);
/***/ }),
/* 203 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__globe_Globe__ = __webpack_require__(204);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_util_layout__ = __webpack_require__(41);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_util_layout___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_echarts_lib_util_layout__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__core_ViewGL__ = __webpack_require__(19);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_retrieve__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__util_graphicGL__ = __webpack_require__(2);
function getDisplacementData(img, displacementScale) {
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
var width = img.width;
var height = img.height;
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
var rgbaArr = ctx.getImageData(0, 0, width, height).data;
var displacementArr = new Float32Array(rgbaArr.length / 4);
for (var i = 0; i < rgbaArr.length / 4; i++) {
var x = rgbaArr[i * 4];
displacementArr[i] = x / 255 * displacementScale;
}
return {
data: displacementArr,
width: width,
height: height
};
}
function resizeGlobe(globeModel, api) {
// Use left/top/width/height
var boxLayoutOption = globeModel.getBoxLayoutParams();
var viewport = __WEBPACK_IMPORTED_MODULE_2_echarts_lib_util_layout___default.a.getLayoutRect(boxLayoutOption, {
width: api.getWidth(),
height: api.getHeight()
});
// Flip Y
viewport.y = api.getHeight() - viewport.y - viewport.height;
this.viewGL.setViewport(viewport.x, viewport.y, viewport.width, viewport.height, api.getDevicePixelRatio());
this.radius = globeModel.get('globeRadius');
var outerRadius = globeModel.get('globeOuterRadius');
if (this.altitudeAxis) {
this.altitudeAxis.setExtent(0, outerRadius - this.radius);
}
}
function updateGlobe(ecModel, api) {
var altitudeDataExtent = [Infinity, -Infinity]
ecModel.eachSeries(function (seriesModel) {
if (seriesModel.coordinateSystem !== this) {
return;
}
// Get altitude data extent.
var data = seriesModel.getData();
var altDims = seriesModel.coordDimToDataDim('alt');
var altDim = altDims && altDims[0];
if (altDim) {
// TODO altitiude is in coords of lines.
var dataExtent = data.getDataExtent(altDim, true);
altitudeDataExtent[0] = Math.min(
altitudeDataExtent[0], dataExtent[0]
);
altitudeDataExtent[1] = Math.max(
altitudeDataExtent[1], dataExtent[1]
);
}
}, this);
// Create altitude axis
if (altitudeDataExtent && isFinite(altitudeDataExtent[1] - altitudeDataExtent[0])) {
var scale = __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default.a.helper.createScale(
altitudeDataExtent, {
type: 'value',
// PENDING
min: 'dataMin',
max: 'dataMax'
}
);
this.altitudeAxis = new __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default.a.Axis('altitude', scale);
// Resize again
this.resize(this.model, api);
}
}
var globeCreator = {
dimensions: __WEBPACK_IMPORTED_MODULE_0__globe_Globe__["a" /* default */].prototype.dimensions,
create: function (ecModel, api) {
var globeList = [];
ecModel.eachComponent('globe', function (globeModel) {
// FIXME
globeModel.__viewGL = globeModel.__viewGL || new __WEBPACK_IMPORTED_MODULE_3__core_ViewGL__["a" /* default */]();
var globe = new __WEBPACK_IMPORTED_MODULE_0__globe_Globe__["a" /* default */]();
globe.viewGL = globeModel.__viewGL;
globeModel.coordinateSystem = globe;
globe.model = globeModel;
globeList.push(globe);
// Inject resize
globe.resize = resizeGlobe;
globe.resize(globeModel, api);
globe.update = updateGlobe;
});
ecModel.eachSeries(function (seriesModel) {
if (seriesModel.get('coordinateSystem') === 'globe') {
var globeModel = seriesModel.getReferringComponents('globe')[0];
if (!globeModel) {
globeModel = ecModel.getComponent('globe');
}
if (!globeModel) {
throw new Error('globe "' + __WEBPACK_IMPORTED_MODULE_4__util_retrieve__["a" /* default */].firstNotNull(
seriesModel.get('globe3DIndex'),
seriesModel.get('globe3DId'),
0
) + '" not found');
}
var coordSys = globeModel.coordinateSystem;
seriesModel.coordinateSystem = coordSys;
}
});
ecModel.eachComponent('globe', function (globeModel, idx) {
var globe = globeModel.coordinateSystem;
// Update displacement data
var displacementTextureValue = globeModel.getDisplacementTexture();
var displacementScale = globeModel.getDisplacemenScale();
if (globeModel.isDisplacementChanged()) {
if (globeModel.hasDisplacement()) {
var immediateLoaded = true;
__WEBPACK_IMPORTED_MODULE_5__util_graphicGL__["a" /* default */].loadTexture(displacementTextureValue, api, function (texture) {
var img = texture.image;
var displacementData = getDisplacementData(img, displacementScale);
globeModel.setDisplacementData(displacementData.data, displacementData.width, displacementData.height);
if (!immediateLoaded) {
// Update layouts
api.dispatchAction({
type: 'globeUpdateDisplacment'
});
}
});
immediateLoaded = false;
}
else {
globe.setDisplacementData(null, 0, 0);
}
globe.setDisplacementData(
globeModel.displacementData, globeModel.displacementWidth, globeModel.displacementHeight
);
}
});
return globeList;
}
};
__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default.a.registerCoordinateSystem('globe', globeCreator);
/* unused harmony default export */ var _unused_webpack_default_export = (globeCreator);
/***/ }),
/* 204 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_claygl_src_dep_glmatrix__);
var vec3 = __WEBPACK_IMPORTED_MODULE_0_claygl_src_dep_glmatrix___default.a.vec3;
function Globe(radius) {
this.radius = radius;
this.viewGL = null;
this.altitudeAxis;
// Displacement data provided by texture.
this.displacementData = null;
this.displacementWidth;
this.displacementHeight;
}
Globe.prototype = {
constructor: Globe,
dimensions: ['lng', 'lat', 'alt'],
type: 'globe',
containPoint: function () {},
setDisplacementData: function (data, width, height) {
this.displacementData = data;
this.displacementWidth = width;
this.displacementHeight = height;
},
_getDisplacementScale: function (lng, lat) {
var i = (lng + 180) / 360 * (this.displacementWidth - 1);
var j = (90 - lat) / 180 * (this.displacementHeight - 1);
// NEAREST SAMPLING
// TODO Better bilinear sampling
var idx = Math.round(i) + Math.round(j) * this.displacementWidth;
return this.displacementData[idx];
},
dataToPoint: function (data, out) {
var lng = data[0];
var lat = data[1];
// Default have 0 altitude
var altVal = data[2] || 0;
var r = this.radius;
if (this.displacementData) {
r *= 1 + this._getDisplacementScale(lng, lat);
}
if (this.altitudeAxis) {
r += this.altitudeAxis.dataToCoord(altVal);
}
lng = lng * Math.PI / 180;
lat = lat * Math.PI / 180;
var r0 = Math.cos(lat) * r;
out = out || [];
// PENDING
out[0] = -r0 * Math.cos(lng + Math.PI);
out[1] = Math.sin(lat) * r;
out[2] = r0 * Math.sin(lng + Math.PI);
return out;
},
pointToData: function (point, out) {
var x = point[0];
var y = point[1];
var z = point[2];
var len = vec3.len(point);
x /= len;
y /= len;
z /= len;
var theta = Math.asin(y);
var phi = Math.atan2(z, -x);
if (phi < 0) {
phi = Math.PI * 2 + phi;
}
var lat = theta * 180 / Math.PI;
var lng = phi * 180 / Math.PI - 180;
out = out || [];
out[0] = lng;
out[1] = lat;
out[2] = len - this.radius;
if (this.altitudeAxis) {
out[2] = this.altitudeAxis.coordToData(out[2]);
}
return out;
}
};
/* harmony default export */ __webpack_exports__["a"] = (Globe);
/***/ }),
/* 205 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__coord_mapbox3DCreator__ = __webpack_require__(206);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__mapbox3D_Mapbox3DModel__ = __webpack_require__(208);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__mapbox3D_Mapbox3DView__ = __webpack_require__(209);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerAction({
type: 'mapbox3DChangeCamera',
event: 'mapbox3dcamerachanged',
update: 'mapbox3D:updateCamera'
}, function (payload, ecModel) {
ecModel.eachComponent({
mainType: 'mapbox3D', query: payload
}, function (componentModel) {
componentModel.setMapboxCameraOption(payload);
});
});
/***/ }),
/* 206 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__mapbox3D_Mapbox3D__ = __webpack_require__(207);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__mapServiceCommon_createMapService3DCreator__ = __webpack_require__(94);
var mapbox3DCreator = Object(__WEBPACK_IMPORTED_MODULE_2__mapServiceCommon_createMapService3DCreator__["a" /* default */])('mapbox3D', __WEBPACK_IMPORTED_MODULE_0__mapbox3D_Mapbox3D__["a" /* default */], function (mapbox3DList) {
mapbox3DList.forEach(function (mapbox3D) {
mapbox3D.setCameraOption(mapbox3D.model.getMapboxCameraOption());
});
});
__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default.a.registerCoordinateSystem('mapbox3D', mapbox3DCreator);
/* unused harmony default export */ var _unused_webpack_default_export = (mapbox3DCreator);
/***/ }),
/* 207 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__mapServiceCommon_MapService3D__ = __webpack_require__(93);
function Mapbox3D() {
__WEBPACK_IMPORTED_MODULE_0__mapServiceCommon_MapService3D__["a" /* default */].apply(this, arguments);
}
Mapbox3D.prototype = new __WEBPACK_IMPORTED_MODULE_0__mapServiceCommon_MapService3D__["a" /* default */]();
Mapbox3D.prototype.constructor = Mapbox3D;
Mapbox3D.prototype.type = 'mapbox3D';
/* harmony default export */ __webpack_exports__["a"] = (Mapbox3D);
/***/ }),
/* 208 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__common_componentPostEffectMixin__ = __webpack_require__(25);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__common_componentLightMixin__ = __webpack_require__(26);
var MAPBOX_CAMERA_OPTION = ['zoom', 'center', 'pitch', 'bearing'];
var Mapbox3DModel = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendComponentModel({
type: 'mapbox3D',
layoutMode: 'box',
coordinateSystem: null,
defaultOption: {
zlevel: -10,
style: 'mapbox://styles/mapbox/light-v9',
center: [0, 0],
zoom: 0,
pitch: 0,
bearing: 0,
light: {
main: {
alpha: 20,
beta: 30
}
},
altitudeScale: 1,
// Default depend on altitudeScale
boxHeight: 'auto'
},
getMapboxCameraOption: function () {
var self = this;
return MAPBOX_CAMERA_OPTION.reduce(function (obj, key) {
obj[key] = self.get(key);
return obj;
}, {});
},
setMapboxCameraOption: function (option) {
if (option != null) {
MAPBOX_CAMERA_OPTION.forEach(function (key) {
if (option[key] != null) {
this.option[key] = option[key];
}
}, this);
}
},
/**
* Get mapbox instance
*/
getMapbox: function () {
return this._mapbox;
},
setMapbox: function (mapbox) {
this._mapbox = mapbox;
}
});
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Mapbox3DModel.prototype, __WEBPACK_IMPORTED_MODULE_1__common_componentPostEffectMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Mapbox3DModel.prototype, __WEBPACK_IMPORTED_MODULE_2__common_componentLightMixin__["a" /* default */]);
/* unused harmony default export */ var _unused_webpack_default_export = (Mapbox3DModel);
/***/ }),
/* 209 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Mapbox3DLayer__ = __webpack_require__(210);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__common_SceneHelper__ = __webpack_require__(27);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_shader_displayShadow_glsl_js__ = __webpack_require__(95);
__WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Shader.import(__WEBPACK_IMPORTED_MODULE_4__util_shader_displayShadow_glsl_js__["a" /* default */]);
var TILE_SIZE = 512;
/* unused harmony default export */ var _unused_webpack_default_export = (__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendComponentView({
type: 'mapbox3D',
__ecgl__: true,
init: function (ecModel, api) {
var zr = api.getZr();
this._zrLayer = new __WEBPACK_IMPORTED_MODULE_1__Mapbox3DLayer__["a" /* default */]('mapbox3D', zr);
zr.painter.insertLayer(-1000, this._zrLayer);
this._lightRoot = new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Node();
this._sceneHelper = new __WEBPACK_IMPORTED_MODULE_2__common_SceneHelper__["a" /* default */](this._lightRoot);
this._sceneHelper.initLight(this._lightRoot);
var mapbox = this._zrLayer.getMapbox();
var dispatchInteractAction = this._dispatchInteractAction.bind(this, api, mapbox);
// PENDING
['zoom', 'rotate', 'drag', 'pitch', 'rotate', 'move'].forEach(function (eName) {
mapbox.on(eName, dispatchInteractAction);
});
this._groundMesh = new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Mesh({
geometry: new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].PlaneGeometry(),
material: new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Material({
shader: new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Shader({
vertex: __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Shader.source('ecgl.displayShadow.vertex'),
fragment: __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Shader.source('ecgl.displayShadow.fragment')
}),
depthMask: false
}),
// Render first
renderOrder: -100,
culling: false,
castShadow: false,
$ignorePicking: true,
renderNormal: true
});
},
render: function (mapbox3DModel, ecModel, api) {
var mapbox = this._zrLayer.getMapbox();
var styleDesc = mapbox3DModel.get('style');
var styleStr = JSON.stringify(styleDesc);
if (styleStr !== this._oldStyleStr) {
if (styleDesc) {
mapbox.setStyle(styleDesc);
}
}
this._oldStyleStr = styleStr;
mapbox.setCenter(mapbox3DModel.get('center'));
mapbox.setZoom(mapbox3DModel.get('zoom'));
mapbox.setPitch(mapbox3DModel.get('pitch'));
mapbox.setBearing(mapbox3DModel.get('bearing'));
mapbox3DModel.setMapbox(mapbox);
var coordSys = mapbox3DModel.coordinateSystem;
// Not add to rootNode. Or light direction will be stretched by rootNode scale
coordSys.viewGL.scene.add(this._lightRoot);
coordSys.viewGL.add(this._groundMesh);
this._updateGroundMesh();
// Update lights
this._sceneHelper.setScene(coordSys.viewGL.scene);
this._sceneHelper.updateLight(mapbox3DModel);
// Update post effects
coordSys.viewGL.setPostEffect(mapbox3DModel.getModel('postEffect'), api);
coordSys.viewGL.setTemporalSuperSampling(mapbox3DModel.getModel('temporalSuperSampling'));
this._mapbox3DModel = mapbox3DModel;
},
afterRender: function (mapbox3DModel, ecModel, api, layerGL) {
var renderer = layerGL.renderer;
this._sceneHelper.updateAmbientCubemap(renderer, mapbox3DModel, api);
this._sceneHelper.updateSkybox(renderer, mapbox3DModel, api);
// FIXME If other series changes coordinate system.
// FIXME When doing progressive rendering.
mapbox3DModel.coordinateSystem.viewGL.scene.traverse(function (mesh) {
if (mesh.material) {
mesh.material.define('fragment', 'NORMAL_UP_AXIS', 2);
mesh.material.define('fragment', 'NORMAL_FRONT_AXIS', 1);
}
});
},
updateCamera: function (mapbox3DModel, ecModel, api, payload) {
mapbox3DModel.coordinateSystem.setCameraOption(payload);
this._updateGroundMesh();
api.getZr().refresh();
},
_dispatchInteractAction: function (api, mapbox, mapbox3DModel) {
api.dispatchAction({
type: 'mapbox3DChangeCamera',
pitch: mapbox.getPitch(),
zoom: mapbox.getZoom(),
center: mapbox.getCenter().toArray(),
bearing: mapbox.getBearing(),
mapbox3DId: this._mapbox3DModel && this._mapbox3DModel.id
});
},
_updateGroundMesh: function () {
if (this._mapbox3DModel) {
var coordSys = this._mapbox3DModel.coordinateSystem;
var pt = coordSys.dataToPoint(coordSys.center);
this._groundMesh.position.set(pt[0], pt[1], -0.001);
var plane = new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Plane(new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Vector3(0, 0, 1), 0);
var ray1 = coordSys.viewGL.camera.castRay(new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Vector2(-1, -1));
var ray2 = coordSys.viewGL.camera.castRay(new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Vector2(1, 1));
var pos0 = ray1.intersectPlane(plane);
var pos1 = ray2.intersectPlane(plane);
var scale = pos0.dist(pos1) / coordSys.viewGL.rootNode.scale.x;
this._groundMesh.scale.set(scale, scale, 1);
}
},
dispose: function (ecModel, api) {
if (this._zrLayer) {
this._zrLayer.dispose();
}
api.getZr().painter.delLayer(-1000);
}
}));
/***/ }),
/* 210 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/**
* @constructor
* @alias module:echarts-gl/component/mapbox3D/Mapbox3DLayer
* @param {string} id Layer ID
* @param {module:zrender/ZRender} zr
*/
function Mapbox3DLayer (id, zr) {
this.id = id;
this.zr = zr;
this.dom = document.createElement('div');
this.dom.style.cssText = 'position:absolute;left:0;right:0;top:0;bottom:0;';
// FIXME If in module environment.
if (!mapboxgl) {
throw new Error('Mapbox GL library must be included. See https://www.mapbox.com/mapbox-gl-js/api/');
}
this._mapbox = new mapboxgl.Map({
container: this.dom
});
// Proxy events
this._initEvents();
}
Mapbox3DLayer.prototype.resize = function () {
this._mapbox.resize();
};
Mapbox3DLayer.prototype.getMapbox = function () {
return this._mapbox;
};
Mapbox3DLayer.prototype.clear = function () {};
Mapbox3DLayer.prototype.refresh = function () {
this._mapbox.resize();
};
var EVENTS = ['mousedown', 'mouseup', 'click', 'dblclick', 'mousemove',
'mousewheel', 'wheel',
'touchstart', 'touchend', 'touchmove', 'touchcancel'
];
Mapbox3DLayer.prototype._initEvents = function () {
// Event is bound on canvas container.
var mapboxRoot = this._mapbox.getCanvasContainer();
this._handlers = this._handlers || {
contextmenu: function (e) {
e.preventDefault();
return false;
}
};
EVENTS.forEach(function (eName) {
this._handlers[eName] = function (e) {
var obj = {};
for (var name in e) {
obj[name] = e[name];
}
obj.bubbles = false;
var newE = new e.constructor(e.type, obj);
mapboxRoot.dispatchEvent(newE);
};
this.zr.dom.addEventListener(eName, this._handlers[eName]);
}, this);
// PENDING
this.zr.dom.addEventListener('contextmenu', this._handlers.contextmenu);
};
Mapbox3DLayer.prototype.dispose = function () {
EVENTS.forEach(function (eName) {
this.zr.dom.removeEventListener(eName, this._handlers[eName]);
}, this);
};
/* harmony default export */ __webpack_exports__["a"] = (Mapbox3DLayer);
/***/ }),
/* 211 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__coord_maptalks3DCreator__ = __webpack_require__(212);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__maptalks3D_Maptalks3DModel__ = __webpack_require__(214);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__maptalks3D_Maptalks3DView__ = __webpack_require__(215);
// Thanks to https://gitee.com/iverson_hu/maptalks-echarts-gl
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerAction({
type: 'maptalks3DChangeCamera',
event: 'maptalks3dcamerachanged',
update: 'maptalks3D:updateCamera'
}, function (payload, ecModel) {
ecModel.eachComponent({
mainType: 'maptalks3D', query: payload
}, function (componentModel) {
componentModel.setMaptalksCameraOption(payload);
});
});
/***/ }),
/* 212 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__maptalks3D_Maptalks3D__ = __webpack_require__(213);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__mapServiceCommon_createMapService3DCreator__ = __webpack_require__(94);
var maptalks3DCreator = Object(__WEBPACK_IMPORTED_MODULE_2__mapServiceCommon_createMapService3DCreator__["a" /* default */])('maptalks3D', __WEBPACK_IMPORTED_MODULE_0__maptalks3D_Maptalks3D__["a" /* default */], function (maptalks3DList) {
maptalks3DList.forEach(function (maptalks3D) {
maptalks3D.setCameraOption(maptalks3D.model.getMaptalksCameraOption());
});
});
__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default.a.registerCoordinateSystem('maptalks3D', maptalks3DCreator);
/* unused harmony default export */ var _unused_webpack_default_export = (maptalks3DCreator);
/***/ }),
/* 213 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__mapServiceCommon_MapService3D__ = __webpack_require__(93);
function Maptalks3D() {
__WEBPACK_IMPORTED_MODULE_0__mapServiceCommon_MapService3D__["a" /* default */].apply(this, arguments);
this.maxPitch = 85;
this.zoomOffset = 1;
}
Maptalks3D.prototype = new __WEBPACK_IMPORTED_MODULE_0__mapServiceCommon_MapService3D__["a" /* default */]();
Maptalks3D.prototype.constructor = Maptalks3D;
Maptalks3D.prototype.type = 'maptalks3D';
/* harmony default export */ __webpack_exports__["a"] = (Maptalks3D);
/***/ }),
/* 214 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__common_componentPostEffectMixin__ = __webpack_require__(25);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__common_componentLightMixin__ = __webpack_require__(26);
var MAPTALKS_CAMERA_OPTION = ['zoom', 'center', 'pitch', 'bearing'];
var Maptalks3DModel = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendComponentModel({
type: 'maptalks3D',
layoutMode: 'box',
coordinateSystem: null,
defaultOption: {
zlevel: -10,
urlTemplate: 'http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png',
attribution: '© OpenStreetMap contributors, © CARTO ',
center: [0, 0],
zoom: 0,
pitch: 0,
bearing: 0,
light: {
main: {
alpha: 20,
beta: 30
}
},
altitudeScale: 1,
// Default depend on altitudeScale
boxHeight: 'auto'
},
getMaptalksCameraOption: function () {
var self = this;
return MAPTALKS_CAMERA_OPTION.reduce(function (obj, key) {
obj[key] = self.get(key);
return obj;
}, {});
},
setMaptalksCameraOption: function (option) {
if (option != null) {
MAPTALKS_CAMERA_OPTION.forEach(function (key) {
if (option[key] != null) {
this.option[key] = option[key];
}
}, this);
}
},
/**
* Get maptalks instance
*/
getMaptalks: function () {
return this._maptalks;
},
setMaptalks: function (maptalks) {
this._maptalks = maptalks;
}
});
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Maptalks3DModel.prototype, __WEBPACK_IMPORTED_MODULE_1__common_componentPostEffectMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Maptalks3DModel.prototype, __WEBPACK_IMPORTED_MODULE_2__common_componentLightMixin__["a" /* default */]);
/* unused harmony default export */ var _unused_webpack_default_export = (Maptalks3DModel);
/***/ }),
/* 215 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Maptalks3DLayer__ = __webpack_require__(216);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__common_SceneHelper__ = __webpack_require__(27);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_shader_displayShadow_glsl_js__ = __webpack_require__(95);
__WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Shader.import(__WEBPACK_IMPORTED_MODULE_4__util_shader_displayShadow_glsl_js__["a" /* default */]);
/* unused harmony default export */ var _unused_webpack_default_export = (__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendComponentView({
type: 'maptalks3D',
__ecgl__: true,
init: function (ecModel, api) {
this._groundMesh = new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Mesh({
geometry: new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].PlaneGeometry(),
material: new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Material({
shader: new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Shader({
vertex: __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Shader.source('ecgl.displayShadow.vertex'),
fragment: __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Shader.source('ecgl.displayShadow.fragment')
}),
depthMask: false
}),
// Render first
renderOrder: -100,
culling: false,
castShadow: false,
$ignorePicking: true,
renderNormal: true
});
},
_initMaptalksLayer: function (mapbox3DModel, api) {
var zr = api.getZr();
this._zrLayer = new __WEBPACK_IMPORTED_MODULE_1__Maptalks3DLayer__["a" /* default */]('maptalks3D', zr, mapbox3DModel.get('center'), mapbox3DModel.get('zoom'));
zr.painter.insertLayer(-1000, this._zrLayer);
this._lightRoot = new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Node();
this._sceneHelper = new __WEBPACK_IMPORTED_MODULE_2__common_SceneHelper__["a" /* default */](this._lightRoot);
this._sceneHelper.initLight(this._lightRoot);
var maptalks = this._zrLayer.getMaptalks();
var dispatchInteractAction = this._dispatchInteractAction.bind(this, api, maptalks);
// PENDING
['zoomend', 'zooming', 'zoomstart', 'dragrotating', 'pitch', 'pitchend', 'movestart',
'moving', 'moveend', 'resize', 'touchstart', 'touchmove', 'touchend'].forEach(function (eName) {
maptalks.on(eName, dispatchInteractAction);
});
},
render: function (maptalks3DModel, ecModel, api) {
if (!this._zrLayer) {
this._initMaptalksLayer(maptalks3DModel, api);
}
var mtks = this._zrLayer.getMaptalks();
var urlTemplate = maptalks3DModel.get('urlTemplate');
var baseLayer = mtks.getBaseLayer();
if (urlTemplate !== this._oldUrlTemplate) {
if (!baseLayer) {
baseLayer = new maptalks.TileLayer('maptalks-echarts-gl-baselayer', {
urlTemplate: urlTemplate,
// used sequentially to help with browser parallel requests per domain limitation
subdomains: ['a', 'b', 'c'],
attribution: maptalks3DModel.get('attribution')
});
mtks.setBaseLayer(baseLayer);
}
else {
// PENDING setOptions may not work?
baseLayer.setOptions({
urlTemplate: urlTemplate,
attribution: maptalks3DModel.get('attribution')
});
}
}
this._oldUrlTemplate = urlTemplate;
mtks.setCenter(maptalks3DModel.get('center'));
mtks.setZoom(maptalks3DModel.get('zoom'),{ animation: false });
mtks.setPitch(maptalks3DModel.get('pitch'));
mtks.setBearing(maptalks3DModel.get('bearing'));
maptalks3DModel.setMaptalks(mtks);
var coordSys = maptalks3DModel.coordinateSystem;
// Not add to rootNode. Or light direction will be stretched by rootNode scale
coordSys.viewGL.scene.add(this._lightRoot);
coordSys.viewGL.add(this._groundMesh);
this._updateGroundMesh();
// Update lights
this._sceneHelper.setScene(coordSys.viewGL.scene);
this._sceneHelper.updateLight(maptalks3DModel);
// Update post effects
coordSys.viewGL.setPostEffect(maptalks3DModel.getModel('postEffect'), api);
coordSys.viewGL.setTemporalSuperSampling(maptalks3DModel.getModel('temporalSuperSampling'));
this._maptalks3DModel = maptalks3DModel;
},
afterRender: function (maptalks3DModel, ecModel, api, layerGL) {
var renderer = layerGL.renderer;
this._sceneHelper.updateAmbientCubemap(renderer, maptalks3DModel, api);
this._sceneHelper.updateSkybox(renderer, maptalks3DModel, api);
// FIXME If other series changes coordinate system.
// FIXME When doing progressive rendering.
maptalks3DModel.coordinateSystem.viewGL.scene.traverse(function (mesh) {
if (mesh.material) {
mesh.material.define('fragment', 'NORMAL_UP_AXIS', 2);
mesh.material.define('fragment', 'NORMAL_FRONT_AXIS', 1);
}
});
},
updateCamera: function (maptalks3DModel, ecModel, api, payload) {
maptalks3DModel.coordinateSystem.setCameraOption(payload);
this._updateGroundMesh();
api.getZr().refresh();
},
_dispatchInteractAction: function (api, maptalks, maptalks3DModel) {
api.dispatchAction({
type: 'maptalks3DChangeCamera',
pitch: maptalks.getPitch(),
zoom: maptalks.getZoom(),
center: maptalks.getCenter().toArray(),
bearing: maptalks.getBearing(),
maptalks3DId: this._maptalks3DModel && this._maptalks3DModel.id
});
},
_updateGroundMesh: function () {
if (this._maptalks3DModel) {
var coordSys = this._maptalks3DModel.coordinateSystem;
var pt = coordSys.dataToPoint(coordSys.center);
this._groundMesh.position.set(pt[0], pt[1], -0.001);
var plane = new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Plane(new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Vector3(0, 0, 1), 0);
var ray1 = coordSys.viewGL.camera.castRay(new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Vector2(-1, -1));
var ray2 = coordSys.viewGL.camera.castRay(new __WEBPACK_IMPORTED_MODULE_3__util_graphicGL__["a" /* default */].Vector2(1, 1));
var pos0 = ray1.intersectPlane(plane);
var pos1 = ray2.intersectPlane(plane);
var scale = pos0.dist(pos1) / coordSys.viewGL.rootNode.scale.x;
this._groundMesh.scale.set(scale, scale, 1);
}
},
dispose: function (ecModel, api) {
if (this._zrLayer) {
this._zrLayer.dispose();
}
api.getZr().painter.delLayer(-1000);
}
}));
/***/ }),
/* 216 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/**
* @constructor
* @alias module:echarts-gl/component/maptalks/Maptalks3DLayer
* @param {string} id Layer ID
* @param {module:zrender/ZRender} zr
*/
function Maptalks3DLayer (id, zr, defaultCenter, defaultZoom) {
this.id = id;
this.zr = zr;
this.dom = document.createElement('div');
this.dom.style.cssText = 'position:absolute;left:0;right:0;top:0;bottom:0;';
// FIXME If in module environment.
if (!maptalks) {
throw new Error('Maptalks library must be included. See https://maptalks.org');
}
this._maptalks = new maptalks.Map(this.dom, {
center: defaultCenter,
zoom: defaultZoom,
fog: false
// fogColor: [0, 0, 0]
});
// Proxy events
this._initEvents();
}
Maptalks3DLayer.prototype.resize = function () {
this._maptalks.checkSize();
};
Maptalks3DLayer.prototype.getMaptalks = function () {
return this._maptalks;
};
Maptalks3DLayer.prototype.clear = function () {};
Maptalks3DLayer.prototype.refresh = function () {
this._maptalks.checkSize();
};
var EVENTS = ['mousedown', 'mouseup', 'click', 'dblclick', 'mousemove',
'mousewheel', 'DOMMouseScroll',
'touchstart', 'touchend', 'touchmove', 'touchcancel'
];
Maptalks3DLayer.prototype._initEvents = function () {
// Event is bound on canvas container.
var maptalksRoot = this.dom;
this._handlers = this._handlers || {
contextmenu: function (e) {
e.preventDefault();
return false;
}
};
EVENTS.forEach(function (eName) {
this._handlers[eName] = function (e) {
var obj = {};
for (var name in e) {
obj[name] = e[name];
}
obj.bubbles = false;
var newE = new e.constructor(e.type, obj);
if (eName === 'mousewheel' || eName === 'DOMMouseScroll') {
// maptalks listens events to different elements?
maptalksRoot.dispatchEvent(newE);
}
else {
maptalksRoot.firstElementChild.dispatchEvent(newE);
}
};
this.zr.dom.addEventListener(eName, this._handlers[eName]);
}, this);
// PENDING
this.zr.dom.addEventListener('contextmenu', this._handlers.contextmenu);
};
Maptalks3DLayer.prototype.dispose = function () {
EVENTS.forEach(function (eName) {
this.zr.dom.removeEventListener(eName, this._handlers[eName]);
}, this);
this._maptalks.remove();
};
/* harmony default export */ __webpack_exports__["a"] = (Maptalks3DLayer);
/***/ }),
/* 217 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__bar3D_bar3DLayout__ = __webpack_require__(218);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__bar3D_Bar3DView__ = __webpack_require__(221);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__bar3D_Bar3DSeries__ = __webpack_require__(223);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__ = __webpack_require__(16);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(Object(__WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__["a" /* default */])('bar3D'));
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerProcessor(function (ecModel, api) {
ecModel.eachSeriesByType('bar3d', function (seriesModel) {
var data = seriesModel.getData();
data.filterSelf(function (idx) {
return data.hasValue(idx);
});
});
});
/***/ }),
/* 218 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector3__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_claygl_src_dep_glmatrix__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__cartesian3DLayout__ = __webpack_require__(219);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__evaluateBarSparseness__ = __webpack_require__(220);
var vec3 = __WEBPACK_IMPORTED_MODULE_2_claygl_src_dep_glmatrix___default.a.vec3;
var isDimensionStacked = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.helper.dataStack.isDimensionStacked;
function globeLayout(seriesModel, coordSys) {
var data = seriesModel.getData();
var barMinHeight = seriesModel.get('minHeight') || 0;
var barSize = seriesModel.get('barSize');
var dims = ['lng', 'lat', 'alt'].map(function (coordDimName) {
return seriesModel.coordDimToDataDim(coordDimName)[0];
});
if (barSize == null) {
var perimeter = coordSys.radius * Math.PI;
var fillRatio = Object(__WEBPACK_IMPORTED_MODULE_4__evaluateBarSparseness__["a" /* default */])(data, dims[0], dims[1]);
barSize = [
perimeter / Math.sqrt(data.count() / fillRatio),
perimeter / Math.sqrt(data.count() / fillRatio)
];
}
else if (!__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.isArray(barSize)) {
barSize = [barSize, barSize];
}
var valueDim = getValueDimension(data, dims);
data.each(dims, function (lng, lat, val, idx) {
var stackedValue = data.get(valueDim.dimension, idx);
var baseValue = valueDim.isStacked ? (stackedValue - val) : coordSys.altitudeAxis.scale.getExtent()[0];
// TODO Stacked with minHeight.
var height = Math.max(coordSys.altitudeAxis.dataToCoord(val), barMinHeight);
var start = coordSys.dataToPoint([lng, lat, baseValue]);
var end = coordSys.dataToPoint([lng, lat, stackedValue]);
var dir = vec3.sub([], end, start);
vec3.normalize(dir, dir);
var size = [barSize[0], height, barSize[1]];
data.setItemLayout(idx, [start, dir, size]);
});
data.setLayout('orient', __WEBPACK_IMPORTED_MODULE_1_claygl_src_math_Vector3__["a" /* default */].UP.array);
}
function geo3DLayout(seriesModel, coordSys) {
var data = seriesModel.getData();
var barSize = seriesModel.get('barSize');
var barMinHeight = seriesModel.get('minHeight') || 0;
var dims = ['lng', 'lat', 'alt'].map(function (coordDimName) {
return seriesModel.coordDimToDataDim(coordDimName)[0];
});
if (barSize == null) {
var size = Math.min(coordSys.size[0], coordSys.size[2]);
var fillRatio = Object(__WEBPACK_IMPORTED_MODULE_4__evaluateBarSparseness__["a" /* default */])(data, dims[0], dims[1]);
barSize = [
size / Math.sqrt(data.count() / fillRatio),
size / Math.sqrt(data.count() / fillRatio)
];
}
else if (!__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.isArray(barSize)) {
barSize = [barSize, barSize];
}
var dir = [0, 1, 0];
var valueDim = getValueDimension(data, dims);
data.each(dims, function (lng, lat, val, idx) {
var stackedValue = data.get(valueDim.dimension, idx);
var baseValue = valueDim.isStacked ? (stackedValue - val) : coordSys.altitudeAxis.scale.getExtent()[0];
var height = Math.max(coordSys.altitudeAxis.dataToCoord(val), barMinHeight);
var start = coordSys.dataToPoint([lng, lat, baseValue]);
var size = [barSize[0], height, barSize[1]];
data.setItemLayout(idx, [start, dir, size]);
});
data.setLayout('orient', [1, 0, 0]);
}
function mapService3DLayout(seriesModel, coordSys) {
var data = seriesModel.getData();
var dimLng = seriesModel.coordDimToDataDim('lng')[0];
var dimLat = seriesModel.coordDimToDataDim('lat')[0];
var dimAlt = seriesModel.coordDimToDataDim('alt')[0];
var barSize = seriesModel.get('barSize');
var barMinHeight = seriesModel.get('minHeight') || 0;
if (barSize == null) {
var xExtent = data.getDataExtent(dimLng);
var yExtent = data.getDataExtent(dimLat);
var corner0 = coordSys.dataToPoint([xExtent[0], yExtent[0]]);
var corner1 = coordSys.dataToPoint([xExtent[1], yExtent[1]]);
var size = Math.min(
Math.abs(corner0[0] - corner1[0]),
Math.abs(corner0[1] - corner1[1])
) || 1;
var fillRatio = Object(__WEBPACK_IMPORTED_MODULE_4__evaluateBarSparseness__["a" /* default */])(data, dimLng, dimLat);
// PENDING, data density
barSize = [
size / Math.sqrt(data.count() / fillRatio),
size / Math.sqrt(data.count() / fillRatio)
];
}
else {
if (!__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.isArray(barSize)) {
barSize = [barSize, barSize];
}
barSize[0] /= coordSys.getScale() / 16;
barSize[1] /= coordSys.getScale() / 16;
}
var dir = [0, 0, 1];
var dims = [dimLng, dimLat, dimAlt];
var valueDim = getValueDimension(data, dims);
data.each(dims, function (lng, lat, val, idx) {
var stackedValue = data.get(valueDim.dimension, idx);
var baseValue = valueDim.isStacked ? (stackedValue - val) : 0;
var start = coordSys.dataToPoint([lng, lat, baseValue]);
var end = coordSys.dataToPoint([lng, lat, stackedValue]);
var height = Math.max(end[2] - start[2], barMinHeight);
var size = [barSize[0], height, barSize[1]];
data.setItemLayout(idx, [start, dir, size]);
});
data.setLayout('orient', [1, 0, 0]);
}
function getValueDimension(data, dataDims) {
var isStacked = isDimensionStacked(data, dataDims[2]);
return {
dimension: isStacked
? data.getCalculationInfo('stackResultDimension')
: dataDims[2],
isStacked: isStacked
};
}
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerLayout(function (ecModel, api) {
ecModel.eachSeriesByType('bar3D', function (seriesModel) {
var coordSys = seriesModel.coordinateSystem;
var coordSysType = coordSys && coordSys.type;
if (coordSysType === 'globe') {
globeLayout(seriesModel, coordSys);
}
else if (coordSysType === 'cartesian3D') {
Object(__WEBPACK_IMPORTED_MODULE_3__cartesian3DLayout__["a" /* default */])(seriesModel, coordSys);
}
else if (coordSysType === 'geo3D') {
geo3DLayout(seriesModel, coordSys);
}
else if (coordSysType === 'mapbox3D' || coordSysType === 'maptalks3D') {
mapService3DLayout(seriesModel, coordSys);
}
else {
if (true) {
if (!coordSys) {
throw new Error('bar3D doesn\'t have coordinate system.');
}
else {
throw new Error('bar3D doesn\'t support coordinate system ' + coordSys.type);
}
}
}
});
});
/***/ }),
/* 219 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix__);
var vec3 = __WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix___default.a.vec3;
var isDimensionStacked = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.helper.dataStack.isDimensionStacked;
function ifCrossZero(extent) {
var min = extent[0];
var max = extent[1];
return !((min > 0 && max > 0) || (min < 0 && max < 0));
};
function cartesian3DLayout(seriesModel, coordSys) {
var data = seriesModel.getData();
// var barOnPlane = seriesModel.get('onGridPlane');
var barSize = seriesModel.get('barSize');
if (barSize == null) {
var size = coordSys.size;
var barWidth;
var barDepth;
var xAxis = coordSys.getAxis('x');
var yAxis = coordSys.getAxis('y');
if (xAxis.type === 'category') {
barWidth = xAxis.getBandWidth() * 0.7;
}
else {
// PENDING
barWidth = Math.round(size[0] / Math.sqrt(data.count())) * 0.6;
}
if (yAxis.type === 'category') {
barDepth = yAxis.getBandWidth() * 0.7;
}
else {
barDepth = Math.round(size[1] / Math.sqrt(data.count())) * 0.6;
}
barSize = [barWidth, barDepth];
}
else if (!__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.isArray(barSize)) {
barSize = [barSize, barSize];
}
var zAxisExtent = coordSys.getAxis('z').scale.getExtent();
var ifZAxisCrossZero = ifCrossZero(zAxisExtent);
var dims = ['x', 'y', 'z'].map(function (coordDimName) {
return seriesModel.coordDimToDataDim(coordDimName)[0];
});
var isStacked = isDimensionStacked(data, dims[2]);
var valueDim = isStacked
? data.getCalculationInfo('stackResultDimension')
: dims[2];
data.each(dims, function (x, y, z, idx) {
// TODO zAxis is inversed
// TODO On different plane.
var stackedValue = data.get(valueDim, idx);
var baseValue = isStacked ? (stackedValue - z)
: (ifZAxisCrossZero ? 0 : zAxisExtent[0]);
var start = coordSys.dataToPoint([x, y, baseValue]);
var end = coordSys.dataToPoint([x, y, stackedValue]);
var height = vec3.dist(start, end);
// PENDING When zAxis is not cross zero.
var dir = [0, end[1] < start[1] ? -1 : 1, 0];
if (Math.abs(height) === 0) {
// TODO
height = 0.1;
}
var size = [barSize[0], height, barSize[1]];
data.setItemLayout(idx, [start, dir, size]);
});
data.setLayout('orient', [1, 0, 0]);
}
/* harmony default export */ __webpack_exports__["a"] = (cartesian3DLayout);
/***/ }),
/* 220 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = (function (data, dimX, dimY) {
var xExtent = data.getDataExtent(dimX);
var yExtent = data.getDataExtent(dimY);
// TODO Handle one data situation
var xSpan = (xExtent[1] - xExtent[0]) || xExtent[0];
var ySpan = (yExtent[1] - yExtent[0]) || yExtent[0];
var dimSize = 50;
var tmp = new Uint8Array(dimSize * dimSize);
for (var i = 0; i < data.count(); i++) {
var x = data.get(dimX, i);
var y = data.get(dimY, i);
var xIdx = Math.floor((x - xExtent[0]) / xSpan * (dimSize - 1));
var yIdx = Math.floor((y - yExtent[0]) / ySpan * (dimSize - 1));
var idx = yIdx * dimSize + xIdx;
tmp[idx] = tmp[idx] || 1;
}
var filledCount = 0;
for (var i = 0; i < tmp.length; i++) {
if (tmp[i]) {
filledCount++;
}
}
return filledCount / tmp.length;
});;
/***/ }),
/* 221 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_retrieve__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_format__ = __webpack_require__(29);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_geometry_Bars3DGeometry__ = __webpack_require__(222);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__component_common_LabelsBuilder__ = __webpack_require__(61);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_claygl_src_dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_claygl_src_dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_claygl_src_dep_glmatrix__);
var vec3 = __WEBPACK_IMPORTED_MODULE_6_claygl_src_dep_glmatrix___default.a.vec3;
/* unused harmony default export */ var _unused_webpack_default_export = (__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendChartView({
type: 'bar3D',
__ecgl__: true,
init: function (ecModel, api) {
this.groupGL = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();
this._api = api;
this._labelsBuilder = new __WEBPACK_IMPORTED_MODULE_5__component_common_LabelsBuilder__["a" /* default */](256, 256, api);
var self = this;
this._labelsBuilder.getLabelPosition = function (dataIndex, position, distance) {
if (self._data) {
var layout = self._data.getItemLayout(dataIndex);
var start = layout[0];
var dir = layout[1];
var height = layout[2][1];
return vec3.scaleAndAdd([], start, dir, distance + height);
}
else {
return [0, 0];
}
};
// Give a large render order.
this._labelsBuilder.getMesh().renderOrder = 100;
},
render: function (seriesModel, ecModel, api) {
// Swap barMesh
var tmp = this._prevBarMesh;
this._prevBarMesh = this._barMesh;
this._barMesh = tmp;
if (!this._barMesh) {
this._barMesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
geometry: new __WEBPACK_IMPORTED_MODULE_4__util_geometry_Bars3DGeometry__["a" /* default */](),
shadowDepthMaterial: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
shader: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader(
__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.source('ecgl.sm.depth.vertex'),
__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.source('ecgl.sm.depth.fragment')
)
}),
// Only cartesian3D enable culling
// FIXME Performance
culling: seriesModel.coordinateSystem.type === 'cartesian3D',
// Render after axes
renderOrder: 10,
// Render normal in normal pass
renderNormal: true
});
}
this.groupGL.remove(this._prevBarMesh);
this.groupGL.add(this._barMesh);
this.groupGL.add(this._labelsBuilder.getMesh());
var coordSys = seriesModel.coordinateSystem;
this._doRender(seriesModel, api);
if (coordSys && coordSys.viewGL) {
coordSys.viewGL.add(this.groupGL);
var methodName = coordSys.viewGL.isLinearSpace() ? 'define' : 'undefine';
this._barMesh.material[methodName]('fragment', 'SRGB_DECODE');
}
this._data = seriesModel.getData();
this._labelsBuilder.updateData(this._data);
this._labelsBuilder.updateLabels();
this._updateAnimation(seriesModel);
},
_updateAnimation: function (seriesModel) {
__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].updateVertexAnimation(
[['prevPosition', 'position'],
['prevNormal', 'normal']],
this._prevBarMesh,
this._barMesh,
seriesModel
);
},
_doRender: function (seriesModel, api) {
var data = seriesModel.getData();
var shading = seriesModel.get('shading');
var enableNormal = shading !== 'color';
var self = this;
var barMesh = this._barMesh;
var shadingPrefix = 'ecgl.' + shading;
if (!barMesh.material || barMesh.material.shader.name !== shadingPrefix) {
barMesh.material = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createMaterial(shadingPrefix, ['VERTEX_COLOR']);
}
__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].setMaterialFromModel(
shading, barMesh.material, seriesModel, api
);
barMesh.geometry.enableNormal = enableNormal;
barMesh.geometry.resetOffset();
// Bevel settings
var bevelSize = seriesModel.get('bevelSize');
var bevelSegments = seriesModel.get('bevelSmoothness');
barMesh.geometry.bevelSegments = bevelSegments;
barMesh.geometry.bevelSize = bevelSize;
var colorArr = [];
var vertexColors = new Float32Array(data.count() * 4);
var colorOffset = 0;
var barCount = 0;
var hasTransparent = false;
data.each(function (idx) {
if (!data.hasValue(idx)) {
return;
}
var color = data.getItemVisual(idx, 'color');
var opacity = data.getItemVisual(idx, 'opacity');
if (opacity == null) {
opacity = 1;
}
__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(color, colorArr);
colorArr[3] *= opacity;
vertexColors[colorOffset++] = colorArr[0];
vertexColors[colorOffset++] = colorArr[1];
vertexColors[colorOffset++] = colorArr[2];
vertexColors[colorOffset++] = colorArr[3];
if (colorArr[3] > 0) {
barCount++;
if (colorArr[3] < 0.99) {
hasTransparent = true;
}
}
});
barMesh.geometry.setBarCount(barCount);
var orient = data.getLayout('orient');
// Map of dataIndex and barIndex.
var barIndexOfData = this._barIndexOfData = new Int32Array(data.count());
var barCount = 0;
data.each(function (idx) {
if (!data.hasValue(idx)) {
barIndexOfData[idx] = -1;
return;
}
var layout = data.getItemLayout(idx);
var start = layout[0];
var dir = layout[1];
var size = layout[2];
var idx4 = idx * 4;
colorArr[0] = vertexColors[idx4++];
colorArr[1] = vertexColors[idx4++];
colorArr[2] = vertexColors[idx4++];
colorArr[3] = vertexColors[idx4++];
if (colorArr[3] > 0) {
self._barMesh.geometry.addBar(start, dir, orient, size, colorArr, idx);
barIndexOfData[idx] = barCount++;
}
});
barMesh.geometry.dirty();
barMesh.geometry.updateBoundingBox();
var material = barMesh.material;
material.transparent = hasTransparent;
material.depthMask = !hasTransparent;
barMesh.geometry.sortTriangles = hasTransparent;
this._initHandler(seriesModel, api);
},
_initHandler: function (seriesModel, api) {
var data = seriesModel.getData();
var barMesh = this._barMesh;
var isCartesian3D = seriesModel.coordinateSystem.type === 'cartesian3D';
barMesh.seriesIndex = seriesModel.seriesIndex;
var lastDataIndex = -1;
barMesh.off('mousemove');
barMesh.off('mouseout');
barMesh.on('mousemove', function (e) {
var dataIndex = barMesh.geometry.getDataIndexOfVertex(e.triangle[0]);
if (dataIndex !== lastDataIndex) {
this._downplay(lastDataIndex);
this._highlight(dataIndex);
this._labelsBuilder.updateLabels([dataIndex]);
if (isCartesian3D) {
api.dispatchAction({
type: 'grid3DShowAxisPointer',
value: [data.get('x', dataIndex), data.get('y', dataIndex), data.get('z', dataIndex, true)]
});
}
}
lastDataIndex = dataIndex;
barMesh.dataIndex = dataIndex;
}, this);
barMesh.on('mouseout', function (e) {
this._downplay(lastDataIndex);
this._labelsBuilder.updateLabels();
lastDataIndex = -1;
barMesh.dataIndex = -1;
if (isCartesian3D) {
api.dispatchAction({
type: 'grid3DHideAxisPointer'
});
}
}, this);
},
_highlight: function (dataIndex) {
var data = this._data;
if (!data) {
return;
}
var barIndex = this._barIndexOfData[dataIndex];
if (barIndex < 0) {
return;
}
var itemModel = data.getItemModel(dataIndex);
var emphasisItemStyleModel = itemModel.getModel('emphasis.itemStyle');
var emphasisColor = emphasisItemStyleModel.get('color');
var emphasisOpacity = emphasisItemStyleModel.get('opacity');
if (emphasisColor == null) {
var color = data.getItemVisual(dataIndex, 'color');
emphasisColor = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.color.lift(color, -0.4);
}
if (emphasisOpacity == null) {
emphasisOpacity = data.getItemVisual(dataIndex, 'opacity');
}
var colorArr = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(emphasisColor);
colorArr[3] *= emphasisOpacity;
this._barMesh.geometry.setColor(barIndex, colorArr);
this._api.getZr().refresh();
},
_downplay: function (dataIndex) {
var data = this._data;
if (!data) {
return;
}
var barIndex = this._barIndexOfData[dataIndex];
if (barIndex < 0) {
return;
}
var color = data.getItemVisual(dataIndex, 'color');
var opacity = data.getItemVisual(dataIndex, 'opacity');
var colorArr = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(color);
colorArr[3] *= opacity;
this._barMesh.geometry.setColor(barIndex, colorArr);
this._api.getZr().refresh();
},
highlight: function (seriesModel, ecModel, api, payload) {
this._toggleStatus('highlight', seriesModel, ecModel, api, payload);
},
downplay: function (seriesModel, ecModel, api, payload) {
this._toggleStatus('downplay', seriesModel, ecModel, api, payload);
},
_toggleStatus: function (status, seriesModel, ecModel, api, payload) {
var data = seriesModel.getData();
var dataIndex = __WEBPACK_IMPORTED_MODULE_2__util_retrieve__["a" /* default */].queryDataIndex(data, payload);
var self = this;
if (dataIndex != null) {
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.each(__WEBPACK_IMPORTED_MODULE_3__util_format__["a" /* default */].normalizeToArray(dataIndex), function (dataIdx) {
status === 'highlight' ? this._highlight(dataIdx) : this._downplay(dataIdx);
}, this);
}
else {
data.each(function (dataIdx) {
status === 'highlight' ? self._highlight(dataIdx) : self._downplay(dataIdx);
});
}
},
remove: function () {
this.groupGL.removeAll();
},
dispose: function () {
this.groupGL.removeAll();
}
}));
/***/ }),
/* 222 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__dynamicConvertMixin__ = __webpack_require__(34);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__trianglesSortMixin__ = __webpack_require__(60);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_Geometry__ = __webpack_require__(13);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_claygl_src_dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_claygl_src_dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_claygl_src_dep_glmatrix__);
/**
* Geometry collecting bars data
*
* @module echarts-gl/chart/bars/BarsGeometry
* @author Yi Shen(http://github.com/pissang)
*/
var vec3 = __WEBPACK_IMPORTED_MODULE_4_claygl_src_dep_glmatrix___default.a.vec3;
var mat3 = __WEBPACK_IMPORTED_MODULE_4_claygl_src_dep_glmatrix___default.a.mat3;
/**
* @constructor
* @alias module:echarts-gl/chart/bars/BarsGeometry
* @extends clay.Geometry
*/
var BarsGeometry = __WEBPACK_IMPORTED_MODULE_3_claygl_src_Geometry__["a" /* default */].extend(function () {
return {
attributes: {
position: new __WEBPACK_IMPORTED_MODULE_3_claygl_src_Geometry__["a" /* default */].Attribute('position', 'float', 3, 'POSITION'),
normal: new __WEBPACK_IMPORTED_MODULE_3_claygl_src_Geometry__["a" /* default */].Attribute('normal', 'float', 3, 'NORMAL'),
color: new __WEBPACK_IMPORTED_MODULE_3_claygl_src_Geometry__["a" /* default */].Attribute('color', 'float', 4, 'COLOR'),
prevPosition: new __WEBPACK_IMPORTED_MODULE_3_claygl_src_Geometry__["a" /* default */].Attribute('prevPosition', 'float', 3),
prevNormal: new __WEBPACK_IMPORTED_MODULE_3_claygl_src_Geometry__["a" /* default */].Attribute('prevNormal', 'float', 3)
},
dynamic: true,
enableNormal: false,
bevelSize: 1,
bevelSegments: 0,
// Map from vertexIndex to dataIndex.
_dataIndices: null,
_vertexOffset: 0,
_triangleOffset: 0
};
},
/** @lends module:echarts-gl/chart/bars/BarsGeometry.prototype */
{
resetOffset: function () {
this._vertexOffset = 0;
this._triangleOffset = 0;
},
setBarCount: function (barCount) {
var enableNormal = this.enableNormal;
var vertexCount = this.getBarVertexCount() * barCount;
var triangleCount = this.getBarTriangleCount() * barCount;
if (this.vertexCount !== vertexCount) {
this.attributes.position.init(vertexCount);
if (enableNormal) {
this.attributes.normal.init(vertexCount);
}
else {
this.attributes.normal.value = null;
}
this.attributes.color.init(vertexCount);
}
if (this.triangleCount !== triangleCount) {
this.indices = vertexCount > 0xffff ? new Uint32Array(triangleCount * 3) : new Uint16Array(triangleCount * 3);
this._dataIndices = new Uint32Array(vertexCount);
}
},
getBarVertexCount: function () {
var bevelSegments = this.bevelSize > 0 ? this.bevelSegments : 0;
return bevelSegments > 0 ? this._getBevelBarVertexCount(bevelSegments)
: (this.enableNormal ? 24 : 8);
},
getBarTriangleCount: function () {
var bevelSegments = this.bevelSize > 0 ? this.bevelSegments : 0;
return bevelSegments > 0 ? this._getBevelBarTriangleCount(bevelSegments)
: 12;
},
_getBevelBarVertexCount: function (bevelSegments) {
return (bevelSegments + 1) * 4 * (bevelSegments + 1) * 2;
},
_getBevelBarTriangleCount: function (bevelSegments) {
var widthSegments = bevelSegments * 4 + 3;
var heightSegments = bevelSegments * 2 + 1;
return (widthSegments + 1) * heightSegments * 2 + 4;
},
setColor: function (idx, color) {
var vertexCount = this.getBarVertexCount();
var start = vertexCount * idx;
var end = vertexCount * (idx + 1);
for (var i = start; i < end; i++) {
this.attributes.color.set(i, color);
}
this.dirtyAttribute('color');
},
/**
* Get dataIndex of vertex.
* @param {number} vertexIndex
*/
getDataIndexOfVertex: function (vertexIndex) {
return this._dataIndices ? this._dataIndices[vertexIndex] : null;
},
/**
* Add a bar
* @param {Array.} start
* @param {Array.} end
* @param {Array.} orient right direction
* @param {Array.} size size on x and z
* @param {Array.} color
*/
addBar: (function () {
var v3Create = vec3.create;
var v3ScaleAndAdd = vec3.scaleAndAdd;
var end = v3Create();
var px = v3Create();
var py = v3Create();
var pz = v3Create();
var nx = v3Create();
var ny = v3Create();
var nz = v3Create();
var pts = [];
var normals = [];
for (var i = 0; i < 8; i++) {
pts[i] = v3Create();
}
var cubeFaces4 = [
// PX
[0, 1, 5, 4],
// NX
[2, 3, 7, 6],
// PY
[4, 5, 6, 7],
// NY
[3, 2, 1, 0],
// PZ
[0, 4, 7, 3],
// NZ
[1, 2, 6, 5]
];
var face4To3 = [
0, 1, 2, 0, 2, 3
];
var cubeFaces3 = [];
for (var i = 0; i < cubeFaces4.length; i++) {
var face4 = cubeFaces4[i];
for (var j = 0; j < 2; j++) {
var face = [];
for (var k = 0; k < 3; k++) {
face.push(face4[face4To3[j * 3 + k]]);
}
cubeFaces3.push(face);
}
}
return function (start, dir, leftDir, size, color, dataIndex) {
// Use vertex, triangle maybe sorted.
var startVertex = this._vertexOffset;
if (this.bevelSize > 0 && this.bevelSegments > 0) {
this._addBevelBar(start, dir, leftDir, size, this.bevelSize, this.bevelSegments, color);
}
else {
vec3.copy(py, dir);
vec3.normalize(py, py);
// x * y => z
vec3.cross(pz, leftDir, py);
vec3.normalize(pz, pz);
// y * z => x
vec3.cross(px, py, pz);
vec3.normalize(pz, pz);
vec3.negate(nx, px);
vec3.negate(ny, py);
vec3.negate(nz, pz);
v3ScaleAndAdd(pts[0], start, px, size[0] / 2);
v3ScaleAndAdd(pts[0], pts[0], pz, size[2] / 2);
v3ScaleAndAdd(pts[1], start, px, size[0] / 2);
v3ScaleAndAdd(pts[1], pts[1], nz, size[2] / 2);
v3ScaleAndAdd(pts[2], start, nx, size[0] / 2);
v3ScaleAndAdd(pts[2], pts[2], nz, size[2] / 2);
v3ScaleAndAdd(pts[3], start, nx, size[0] / 2);
v3ScaleAndAdd(pts[3], pts[3], pz, size[2] / 2);
v3ScaleAndAdd(end, start, py, size[1]);
v3ScaleAndAdd(pts[4], end, px, size[0] / 2);
v3ScaleAndAdd(pts[4], pts[4], pz, size[2] / 2);
v3ScaleAndAdd(pts[5], end, px, size[0] / 2);
v3ScaleAndAdd(pts[5], pts[5], nz, size[2] / 2);
v3ScaleAndAdd(pts[6], end, nx, size[0] / 2);
v3ScaleAndAdd(pts[6], pts[6], nz, size[2] / 2);
v3ScaleAndAdd(pts[7], end, nx, size[0] / 2);
v3ScaleAndAdd(pts[7], pts[7], pz, size[2] / 2);
var attributes = this.attributes;
if (this.enableNormal) {
normals[0] = px;
normals[1] = nx;
normals[2] = py;
normals[3] = ny;
normals[4] = pz;
normals[5] = nz;
var vertexOffset = this._vertexOffset;
for (var i = 0; i < cubeFaces4.length; i++) {
var idx3 = this._triangleOffset * 3;
for (var k = 0; k < 6; k++) {
this.indices[idx3++] = vertexOffset + face4To3[k];
}
vertexOffset += 4;
this._triangleOffset += 2;
}
for (var i = 0; i < cubeFaces4.length; i++) {
var normal = normals[i];
for (var k = 0; k < 4; k++) {
var idx = cubeFaces4[i][k];
attributes.position.set(this._vertexOffset, pts[idx]);
attributes.normal.set(this._vertexOffset, normal);
attributes.color.set(this._vertexOffset++, color);
}
}
}
else {
for (var i = 0; i < cubeFaces3.length; i++) {
var idx3 = this._triangleOffset * 3;
for (var k = 0; k < 3; k++) {
this.indices[idx3 + k] = cubeFaces3[i][k] + this._vertexOffset;
}
this._triangleOffset++;
}
for (var i = 0; i < pts.length; i++) {
attributes.position.set(this._vertexOffset, pts[i]);
attributes.color.set(this._vertexOffset++, color);
}
}
}
var endVerex = this._vertexOffset;
for (var i = startVertex; i < endVerex; i++) {
this._dataIndices[i] = dataIndex;
}
};
})(),
/**
* Add a bar with bevel
* @param {Array.} start
* @param {Array.} end
* @param {Array.} orient right direction
* @param {Array.} size size on x and z
* @param {number} bevelSize
* @param {number} bevelSegments
* @param {Array.} color
*/
_addBevelBar: (function () {
var px = vec3.create();
var py = vec3.create();
var pz = vec3.create();
var rotateMat = mat3.create();
var bevelStartSize = [];
var xOffsets = [1, -1, -1, 1];
var zOffsets = [1, 1, -1, -1];
var yOffsets = [2, 0];
return function (start, dir, leftDir, size, bevelSize, bevelSegments, color) {
vec3.copy(py, dir);
vec3.normalize(py, py);
// x * y => z
vec3.cross(pz, leftDir, py);
vec3.normalize(pz, pz);
// y * z => x
vec3.cross(px, py, pz);
vec3.normalize(pz, pz);
rotateMat[0] = px[0]; rotateMat[1] = px[1]; rotateMat[2] = px[2];
rotateMat[3] = py[0]; rotateMat[4] = py[1]; rotateMat[5] = py[2];
rotateMat[6] = pz[0]; rotateMat[7] = pz[1]; rotateMat[8] = pz[2];
bevelSize = Math.min(size[0], size[2]) / 2 * bevelSize;
for (var i = 0; i < 3; i++) {
bevelStartSize[i] = Math.max(size[i] - bevelSize * 2, 0);
}
var rx = (size[0] - bevelStartSize[0]) / 2;
var ry = (size[1] - bevelStartSize[1]) / 2;
var rz = (size[2] - bevelStartSize[2]) / 2;
var pos = [];
var normal = [];
var vertexOffset = this._vertexOffset;
var endIndices = [];
for (var i = 0; i < 2; i++) {
endIndices[i] = endIndices[i] = [];
for (var m = 0; m <= bevelSegments; m++) {
for (var j = 0; j < 4; j++) {
if ((m === 0 && i === 0) || (i === 1 && m === bevelSegments)) {
endIndices[i].push(vertexOffset);
}
for (var n = 0; n <= bevelSegments; n++) {
var phi = n / bevelSegments * Math.PI / 2 + Math.PI / 2 * j;
var theta = m / bevelSegments * Math.PI / 2 + Math.PI / 2 * i;
// var r = rx < ry ? (rz < rx ? rz : rx) : (rz < ry ? rz : ry);
normal[0] = rx * Math.cos(phi) * Math.sin(theta);
normal[1] = ry * Math.cos(theta);
normal[2] = rz * Math.sin(phi) * Math.sin(theta);
pos[0] = normal[0] + xOffsets[j] * bevelStartSize[0] / 2;
pos[1] = (normal[1] + ry) + yOffsets[i] * bevelStartSize[1] / 2;
pos[2] = normal[2] + zOffsets[j] * bevelStartSize[2] / 2;
// Normal is not right if rx, ry, rz not equal.
if (!(Math.abs(rx - ry) < 1e-6 && Math.abs(ry - rz) < 1e-6)) {
normal[0] /= rx * rx;
normal[1] /= ry * ry;
normal[2] /= rz * rz;
}
vec3.normalize(normal, normal);
vec3.transformMat3(pos, pos, rotateMat);
vec3.transformMat3(normal, normal, rotateMat);
vec3.add(pos, pos, start);
this.attributes.position.set(vertexOffset, pos);
if (this.enableNormal) {
this.attributes.normal.set(vertexOffset, normal);
}
this.attributes.color.set(vertexOffset, color);
vertexOffset++;
}
}
}
}
var widthSegments = bevelSegments * 4 + 3;
var heightSegments = bevelSegments * 2 + 1;
var len = widthSegments + 1;
for (var j = 0; j < heightSegments; j ++) {
for (var i = 0; i <= widthSegments; i ++) {
var i2 = j * len + i + this._vertexOffset;
var i1 = (j * len + (i + 1) % len) + this._vertexOffset;
var i4 = (j + 1) * len + (i + 1) % len + this._vertexOffset;
var i3 = (j + 1) * len + i + this._vertexOffset;
this.setTriangleIndices(this._triangleOffset++, [i4, i2, i1]);
this.setTriangleIndices(this._triangleOffset++, [i4, i3, i2]);
}
}
// Close top and bottom
this.setTriangleIndices(this._triangleOffset++, [endIndices[0][0], endIndices[0][2], endIndices[0][1]]);
this.setTriangleIndices(this._triangleOffset++, [endIndices[0][0], endIndices[0][3], endIndices[0][2]]);
this.setTriangleIndices(this._triangleOffset++, [endIndices[1][0], endIndices[1][1], endIndices[1][2]]);
this.setTriangleIndices(this._triangleOffset++, [endIndices[1][0], endIndices[1][2], endIndices[1][3]]);
this._vertexOffset = vertexOffset;
};
})()
});
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.defaults(BarsGeometry.prototype, __WEBPACK_IMPORTED_MODULE_1__dynamicConvertMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.defaults(BarsGeometry.prototype, __WEBPACK_IMPORTED_MODULE_2__trianglesSortMixin__["a" /* default */]);
/* harmony default export */ __webpack_exports__["a"] = (BarsGeometry);
/***/ }),
/* 223 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__component_common_componentShadingMixin__ = __webpack_require__(28);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_format__ = __webpack_require__(29);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__common_formatTooltip__ = __webpack_require__(35);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_createList__ = __webpack_require__(44);
var Bar3DSeries = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendSeriesModel({
type: 'series.bar3D',
dependencies: ['globe'],
visualColorAccessPath: 'itemStyle.color',
getInitialData: function (option, ecModel) {
return Object(__WEBPACK_IMPORTED_MODULE_4__common_createList__["a" /* default */])(this);
},
getFormattedLabel: function (dataIndex, status, dataType, dimIndex) {
var text = __WEBPACK_IMPORTED_MODULE_2__util_format__["a" /* default */].getFormattedLabel(this, dataIndex, status, dataType, dimIndex);
if (text == null) {
text = this.getData().get('z', dataIndex);
}
return text;
},
formatTooltip: function (dataIndex) {
return Object(__WEBPACK_IMPORTED_MODULE_3__common_formatTooltip__["a" /* default */])(this, dataIndex);
},
defaultOption: {
coordinateSystem: 'cartesian3D',
globeIndex: 0,
grid3DIndex: 0,
zlevel: -10,
// bevelSize, 0 has no bevel
bevelSize: 0,
// higher is smoother
bevelSmoothness: 2,
// Bar width and depth
// barSize: [1, 1],
// On grid plane when coordinateSystem is cartesian3D
onGridPlane: 'xy',
// Shading of globe
shading: 'color',
minHeight: 0,
itemStyle: {
opacity: 1
},
label: {
show: false,
distance: 2,
textStyle: {
fontSize: 14,
color: '#000',
backgroundColor: 'rgba(255,255,255,0.7)',
padding: 3,
borderRadius: 3
}
},
emphasis: {
label: {
show: true
}
},
animationDurationUpdate: 500
}
});
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Bar3DSeries.prototype, __WEBPACK_IMPORTED_MODULE_1__component_common_componentShadingMixin__["a" /* default */]);
/* unused harmony default export */ var _unused_webpack_default_export = (Bar3DSeries);
/***/ }),
/* 224 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__line3D_Line3DSeries__ = __webpack_require__(225);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__line3D_Line3DView__ = __webpack_require__(226);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol__ = __webpack_require__(45);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__ = __webpack_require__(16);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(__WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol___default()('line3D', 'circle', null));
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(Object(__WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__["a" /* default */])('line3D'));
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerLayout(function (ecModel, api) {
ecModel.eachSeriesByType('line3D', function (seriesModel) {
var data = seriesModel.getData();
var coordSys = seriesModel.coordinateSystem;
if (coordSys) {
if (coordSys.type !== 'cartesian3D') {
if (true) {
console.error('line3D needs cartesian3D coordinateSystem');
}
return;
}
var points = new Float32Array(data.count() * 3);
var item = [];
var out = [];
var coordDims = coordSys.dimensions;
var dims = coordDims.map(function (coordDim) {
return seriesModel.coordDimToDataDim(coordDim)[0];
});
if (coordSys) {
data.each(dims, function (x, y, z, idx) {
item[0] = x;
item[1] = y;
item[2] = z;
coordSys.dataToPoint(item, out);
points[idx * 3] = out[0];
points[idx * 3 + 1] = out[1];
points[idx * 3 + 2] = out[2];
});
}
data.setLayout('points', points);
}
});
});
/***/ }),
/* 225 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__common_formatTooltip__ = __webpack_require__(35);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__common_createList__ = __webpack_require__(44);
var Line3DSeries = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendSeriesModel({
type: 'series.line3D',
dependencies: ['grid3D'],
visualColorAccessPath: 'lineStyle.color',
getInitialData: function (option, ecModel) {
return Object(__WEBPACK_IMPORTED_MODULE_2__common_createList__["a" /* default */])(this);
},
formatTooltip: function (dataIndex) {
return Object(__WEBPACK_IMPORTED_MODULE_1__common_formatTooltip__["a" /* default */])(this, dataIndex);
},
defaultOption: {
coordinateSystem: 'cartesian3D',
zlevel: -10,
// Cartesian coordinate system
grid3DIndex: 0,
lineStyle: {
width: 2
},
animationDurationUpdate: 500
}
});
/* unused harmony default export */ var _unused_webpack_default_export = (Line3DSeries);
/***/ }),
/* 226 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_retrieve__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_geometry_Lines3D__ = __webpack_require__(22);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_claygl_src_math_Matrix4__ = __webpack_require__(7);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_claygl_src_math_Vector3__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_zrender_lib_contain_line__ = __webpack_require__(227);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_zrender_lib_contain_line___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_zrender_lib_contain_line__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_claygl_src_dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_claygl_src_dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_7_claygl_src_dep_glmatrix__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__util_shader_lines3D_glsl_js__ = __webpack_require__(40);
var vec3 = __WEBPACK_IMPORTED_MODULE_7_claygl_src_dep_glmatrix___default.a.vec3;
__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.import(__WEBPACK_IMPORTED_MODULE_8__util_shader_lines3D_glsl_js__["a" /* default */]);
/* unused harmony default export */ var _unused_webpack_default_export = (__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendChartView({
type: 'line3D',
__ecgl__: true,
init: function (ecModel, api) {
this.groupGL = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();
this._api = api;
},
render: function (seriesModel, ecModel, api) {
var tmp = this._prevLine3DMesh;
this._prevLine3DMesh = this._line3DMesh;
this._line3DMesh = tmp;
if (!this._line3DMesh) {
this._line3DMesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
geometry: new __WEBPACK_IMPORTED_MODULE_3__util_geometry_Lines3D__["a" /* default */]({
useNativeLine: false,
sortTriangles: true
}),
material: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
shader: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createShader('ecgl.meshLines3D')
}),
// Render after axes
renderOrder: 10
});
this._line3DMesh.geometry.pick = this._pick.bind(this);
}
this.groupGL.remove(this._prevLine3DMesh);
this.groupGL.add(this._line3DMesh);
var coordSys = seriesModel.coordinateSystem;
if (coordSys && coordSys.viewGL) {
coordSys.viewGL.add(this.groupGL);
// TODO
var methodName = coordSys.viewGL.isLinearSpace() ? 'define' : 'undefine';
this._line3DMesh.material[methodName]('fragment', 'SRGB_DECODE');
}
this._doRender(seriesModel, api);
this._data = seriesModel.getData();
this._camera = coordSys.viewGL.camera;
this.updateCamera();
this._updateAnimation(seriesModel);
},
updateCamera: function () {
this._updateNDCPosition();
},
_doRender: function (seriesModel, api) {
var data = seriesModel.getData();
var lineMesh = this._line3DMesh;
lineMesh.geometry.resetOffset();
var points = data.getLayout('points');
var colorArr = [];
var vertexColors = new Float32Array(points.length / 3 * 4);
var colorOffset = 0;
var hasTransparent = false;
data.each(function (idx) {
var color = data.getItemVisual(idx, 'color');
var opacity = data.getItemVisual(idx, 'opacity');
if (opacity == null) {
opacity = 1;
}
__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(color, colorArr);
colorArr[3] *= opacity;
vertexColors[colorOffset++] = colorArr[0];
vertexColors[colorOffset++] = colorArr[1];
vertexColors[colorOffset++] = colorArr[2];
vertexColors[colorOffset++] = colorArr[3];
if (colorArr[3] < 0.99) {
hasTransparent = true;
}
});
lineMesh.geometry.setVertexCount(
lineMesh.geometry.getPolylineVertexCount(points)
);
lineMesh.geometry.setTriangleCount(
lineMesh.geometry.getPolylineTriangleCount(points)
);
lineMesh.geometry.addPolyline(
points, vertexColors,
__WEBPACK_IMPORTED_MODULE_2__util_retrieve__["a" /* default */].firstNotNull(seriesModel.get('lineStyle.width'), 1)
);
lineMesh.geometry.dirty();
lineMesh.geometry.updateBoundingBox();
var material = lineMesh.material;
material.transparent = hasTransparent;
material.depthMask = !hasTransparent;
var debugWireframeModel = seriesModel.getModel('debug.wireframe');
if (debugWireframeModel.get('show')) {
lineMesh.geometry.createAttribute('barycentric', 'float', 3);
lineMesh.geometry.generateBarycentric();
lineMesh.material.set('both', 'WIREFRAME_TRIANGLE');
lineMesh.material.set(
'wireframeLineColor', __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(
debugWireframeModel.get('lineStyle.color') || 'rgba(0,0,0,0.5)'
)
);
lineMesh.material.set(
'wireframeLineWidth', __WEBPACK_IMPORTED_MODULE_2__util_retrieve__["a" /* default */].firstNotNull(
debugWireframeModel.get('lineStyle.width'), 1
)
);
}
else {
lineMesh.material.set('both', 'WIREFRAME_TRIANGLE');
}
this._points = points;
this._initHandler(seriesModel, api);
},
_updateAnimation: function (seriesModel) {
__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].updateVertexAnimation(
[['prevPosition', 'position'],
['prevPositionPrev', 'positionPrev'],
['prevPositionNext', 'positionNext']],
this._prevLine3DMesh,
this._line3DMesh,
seriesModel
);
},
_initHandler: function (seriesModel, api) {
var data = seriesModel.getData();
var coordSys = seriesModel.coordinateSystem;
var lineMesh = this._line3DMesh;
var lastDataIndex = -1;
lineMesh.seriesIndex = seriesModel.seriesIndex;
lineMesh.off('mousemove');
lineMesh.off('mouseout');
lineMesh.on('mousemove', function (e) {
var value = coordSys.pointToData(e.point.array);
var dataIndex = data.indicesOfNearest('x', value[0])[0];
if (dataIndex !== lastDataIndex) {
// this._downplay(lastDataIndex);
// this._highlight(dataIndex);
api.dispatchAction({
type: 'grid3DShowAxisPointer',
value: [data.get('x', dataIndex), data.get('y', dataIndex), data.get('z', dataIndex)]
});
lineMesh.dataIndex = dataIndex;
}
lastDataIndex = dataIndex;
}, this);
lineMesh.on('mouseout', function (e) {
// this._downplay(lastDataIndex);
lastDataIndex = -1;
lineMesh.dataIndex = -1;
api.dispatchAction({
type: 'grid3DHideAxisPointer'
});
}, this);
},
// _highlight: function (dataIndex) {
// var data = this._data;
// if (!data) {
// return;
// }
// },
// _downplay: function (dataIndex) {
// var data = this._data;
// if (!data) {
// return;
// }
// },
_updateNDCPosition: function () {
var worldViewProjection = new __WEBPACK_IMPORTED_MODULE_4_claygl_src_math_Matrix4__["a" /* default */]();
var camera = this._camera;
__WEBPACK_IMPORTED_MODULE_4_claygl_src_math_Matrix4__["a" /* default */].multiply(worldViewProjection, camera.projectionMatrix, camera.viewMatrix);
var positionNDC = this._positionNDC;
var points = this._points;
var nPoints = points.length / 3;
if (!positionNDC || positionNDC.length / 2 !== nPoints) {
positionNDC = this._positionNDC = new Float32Array(nPoints * 2);
}
var pos = [];
for (var i = 0; i < nPoints; i++) {
var i3 = i * 3;
var i2 = i * 2;
pos[0] = points[i3];
pos[1] = points[i3 + 1];
pos[2] = points[i3 + 2];
pos[3] = 1;
vec3.transformMat4(pos, pos, worldViewProjection.array);
positionNDC[i2] = pos[0] / pos[3];
positionNDC[i2 + 1] = pos[1] / pos[3];
}
},
_pick: function (x, y, renderer, camera, renderable, out) {
var positionNDC = this._positionNDC;
var seriesModel = this._data.hostModel;
var lineWidth = seriesModel.get('lineStyle.width');
var dataIndex = -1;
var width = renderer.viewport.width;
var height = renderer.viewport.height;
var halfWidth = width * 0.5;
var halfHeight = height * 0.5;
x = (x + 1) * halfWidth;
y = (y + 1) * halfHeight;
for (var i = 1; i < positionNDC.length / 2; i++) {
var x0 = (positionNDC[(i - 1) * 2] + 1) * halfWidth;
var y0 = (positionNDC[(i - 1) * 2 + 1] + 1) * halfHeight;
var x1 = (positionNDC[i * 2] + 1) * halfWidth;
var y1 = (positionNDC[i * 2 + 1] + 1) * halfHeight;
if (__WEBPACK_IMPORTED_MODULE_6_zrender_lib_contain_line___default.a.containStroke(x0, y0, x1, y1, lineWidth, x, y)) {
var dist0 = (x0 - x) * (x0 - x) + (y0 - y) * (y0 - y);
var dist1 = (x1 - x) * (x1 - x) + (y1 - y) * (y1 - y);
// Nearest point.
dataIndex = dist0 < dist1 ? (i - 1) : i;
}
}
if (dataIndex >= 0) {
var i3 = dataIndex * 3;
var point = new __WEBPACK_IMPORTED_MODULE_5_claygl_src_math_Vector3__["a" /* default */](
this._points[i3],
this._points[i3 + 1],
this._points[i3 + 2]
);
out.push({
dataIndex: dataIndex,
point: point,
pointWorld: point.clone(),
target: this._line3DMesh,
distance: this._camera.getWorldPosition().dist(point)
});
}
},
remove: function () {
this.groupGL.removeAll();
},
dispose: function () {
this.groupGL.removeAll();
}
}));
/***/ }),
/* 227 */
/***/ (function(module, exports) {
/**
* 线段包含判断
* @param {number} x0
* @param {number} y0
* @param {number} x1
* @param {number} y1
* @param {number} lineWidth
* @param {number} x
* @param {number} y
* @return {boolean}
*/
function containStroke(x0, y0, x1, y1, lineWidth, x, y) {
if (lineWidth === 0) {
return false;
}
var _l = lineWidth;
var _a = 0;
var _b = x0; // Quick reject
if (y > y0 + _l && y > y1 + _l || y < y0 - _l && y < y1 - _l || x > x0 + _l && x > x1 + _l || x < x0 - _l && x < x1 - _l) {
return false;
}
if (x0 !== x1) {
_a = (y0 - y1) / (x0 - x1);
_b = (x0 * y1 - x1 * y0) / (x0 - x1);
} else {
return Math.abs(x - x0) <= _l / 2;
}
var tmp = _a * x - y + _b;
var _s = tmp * tmp / (_a * _a + 1);
return _s <= _l / 2 * _l / 2;
}
exports.containStroke = containStroke;
/***/ }),
/* 228 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__scatter3D_Scatter3DSeries__ = __webpack_require__(229);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__scatter3D_Scatter3DView__ = __webpack_require__(230);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol__ = __webpack_require__(45);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__ = __webpack_require__(16);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(__WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol___default()('scatter3D', 'circle', null));
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(Object(__WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__["a" /* default */])('scatter3D'));
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerLayout({
seriesType: 'scatter3D',
reset: function (seriesModel) {
var coordSys = seriesModel.coordinateSystem;
if (coordSys) {
var coordDims = coordSys.dimensions;
if (coordDims.length < 3) {
if (true) {
console.error('scatter3D needs 3D coordinateSystem');
}
return;
}
var dims = coordDims.map(function (coordDim) {
return seriesModel.coordDimToDataDim(coordDim)[0];
});
var item = [];
var out = [];
return {
progress: function (params, data) {
var points = new Float32Array((params.end - params.start) * 3);
for (var idx = params.start; idx < params.end; idx++) {
var idx3 = (idx - params.start) * 3;
item[0] = data.get(dims[0], idx);
item[1] = data.get(dims[1], idx);
item[2] = data.get(dims[2], idx);
coordSys.dataToPoint(item, out);
points[idx3] = out[0];
points[idx3 + 1] = out[1];
points[idx3 + 2] = out[2];
}
data.setLayout('points', points);
}
};
}
}
});
/***/ }),
/* 229 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_format__ = __webpack_require__(29);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__common_formatTooltip__ = __webpack_require__(35);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__common_createList__ = __webpack_require__(44);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendSeriesModel({
type: 'series.scatter3D',
dependencies: ['globe', 'grid3D', 'geo3D'],
visualColorAccessPath: 'itemStyle.color',
getInitialData: function (option, ecModel) {
return Object(__WEBPACK_IMPORTED_MODULE_3__common_createList__["a" /* default */])(this);
},
getFormattedLabel: function (dataIndex, status, dataType, dimIndex) {
var text = __WEBPACK_IMPORTED_MODULE_1__util_format__["a" /* default */].getFormattedLabel(this, dataIndex, status, dataType, dimIndex);
if (text == null) {
var data = this.getData();
var lastDim = data.dimensions[data.dimensions.length - 1];
text = data.get(lastDim, dataIndex);
}
return text;
},
formatTooltip: function (dataIndex) {
return Object(__WEBPACK_IMPORTED_MODULE_2__common_formatTooltip__["a" /* default */])(this, dataIndex);
},
defaultOption: {
coordinateSystem: 'cartesian3D',
zlevel: -10,
progressive: 1e5,
progressiveThreshold: 1e5,
// Cartesian coordinate system
grid3DIndex: 0,
globeIndex: 0,
symbol: 'circle',
symbolSize: 10,
// Support source-over, lighter
blendMode: 'source-over',
label: {
show: false,
position: 'right',
// Screen space distance
distance: 5,
textStyle: {
fontSize: 14,
color: '#000',
backgroundColor: 'rgba(255,255,255,0.7)',
padding: 3,
borderRadius: 3
}
},
itemStyle: {
opacity: 0.8
},
emphasis: {
label: {
show: true
}
},
animationDurationUpdate: 500
}
});
/***/ }),
/* 230 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_retrieve__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_format__ = __webpack_require__(29);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_PointsBuilder__ = __webpack_require__(62);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendChartView({
type: 'scatter3D',
__ecgl__: true,
init: function (ecModel, api) {
this.groupGL = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();
this._pointsBuilderList = [];
this._currentStep = 0;
},
render: function (seriesModel, ecModel, api) {
this.groupGL.removeAll();
if (!seriesModel.getData().count()) {
return;
}
var coordSys = seriesModel.coordinateSystem;
if (coordSys && coordSys.viewGL) {
coordSys.viewGL.add(this.groupGL);
this._camera = coordSys.viewGL.camera;
var pointsBuilder = this._pointsBuilderList[0];
if (!pointsBuilder) {
pointsBuilder = this._pointsBuilderList[0] = new __WEBPACK_IMPORTED_MODULE_4__common_PointsBuilder__["a" /* default */](false, api);
}
this._pointsBuilderList.length = 1;
this.groupGL.add(pointsBuilder.rootNode);
pointsBuilder.update(seriesModel, ecModel, api);
pointsBuilder.updateView(coordSys.viewGL.camera);
}
else {
if (true) {
throw new Error('Invalid coordinate system');
}
}
},
incrementalPrepareRender: function (seriesModel, ecModel, api) {
var coordSys = seriesModel.coordinateSystem;
if (coordSys && coordSys.viewGL) {
coordSys.viewGL.add(this.groupGL);
this._camera = coordSys.viewGL.camera;
}
else {
if (true) {
throw new Error('Invalid coordinate system');
}
}
this.groupGL.removeAll();
this._currentStep = 0;
},
incrementalRender: function (params, seriesModel, ecModel, api) {
// TODO Sort transparency.
if (params.end <= params.start) {
return;
}
var pointsBuilder = this._pointsBuilderList[this._currentStep];
if (!pointsBuilder) {
pointsBuilder = new __WEBPACK_IMPORTED_MODULE_4__common_PointsBuilder__["a" /* default */](false, api);
this._pointsBuilderList[this._currentStep] = pointsBuilder;
}
this.groupGL.add(pointsBuilder.rootNode);
pointsBuilder.update(seriesModel, ecModel, api, params.start, params.end);
pointsBuilder.updateView(seriesModel.coordinateSystem.viewGL.camera);
this._currentStep++;
},
updateCamera: function () {
this._pointsBuilderList.forEach(function (pointsBuilder) {
pointsBuilder.updateView(this._camera);
}, this);
},
highlight: function (seriesModel, ecModel, api, payload) {
this._toggleStatus('highlight', seriesModel, ecModel, api, payload);
},
downplay: function (seriesModel, ecModel, api, payload) {
this._toggleStatus('downplay', seriesModel, ecModel, api, payload);
},
_toggleStatus: function (status, seriesModel, ecModel, api, payload) {
var data = seriesModel.getData();
var dataIndex = __WEBPACK_IMPORTED_MODULE_2__util_retrieve__["a" /* default */].queryDataIndex(data, payload);
var isHighlight = status === 'highlight';
if (dataIndex != null) {
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.each(__WEBPACK_IMPORTED_MODULE_3__util_format__["a" /* default */].normalizeToArray(dataIndex), function (dataIdx) {
for (var i = 0; i < this._pointsBuilderList.length; i++) {
var pointsBuilder = this._pointsBuilderList[i];
isHighlight ? pointsBuilder.highlight(data, dataIdx) : pointsBuilder.downplay(data, dataIdx);
}
}, this);
}
else {
// PENDING, OPTIMIZE
data.each(function (dataIdx) {
for (var i = 0; i < this._pointsBuilderList.length; i++) {
var pointsBuilder = this._pointsBuilderList[i];
isHighlight ? pointsBuilder.highlight(data, dataIdx) : pointsBuilder.downplay(data, dataIdx);
}
});
}
},
dispose: function () {
this.groupGL.removeAll();
},
remove: function () {
this.groupGL.removeAll();
}
});
/***/ }),
/* 231 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
function makeSprite(size, canvas, draw) {
// http://simonsarris.com/blog/346-how-you-clear-your-canvas-matters
// http://jsperf.com/canvasclear
// Set width and height is fast
// And use the exist canvas if possible
// http://jsperf.com/create-canvas-vs-set-width-height/2
var canvas = canvas || document.createElement('canvas');
canvas.width = size;
canvas.height = size;
var ctx = canvas.getContext('2d');
draw && draw(ctx);
return canvas;
}
function makePath(symbol, symbolSize, style, marginBias) {
if (!__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.isArray(symbolSize)) {
symbolSize = [symbolSize, symbolSize];
}
var margin = spriteUtil.getMarginByStyle(style, marginBias);
var width = symbolSize[0] + margin.left + margin.right;
var height = symbolSize[1] + margin.top + margin.bottom;
var path = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.helper.createSymbol(symbol, 0, 0, symbolSize[0], symbolSize[1]);
var size = Math.max(width, height);
path.position = [margin.left, margin.top];
if (width > height) {
path.position[1] += (size - height) / 2;
}
else {
path.position[0] += (size - width) / 2;
}
var rect = path.getBoundingRect();
path.position[0] -= rect.x;
path.position[1] -= rect.y;
path.setStyle(style);
path.update();
path.__size = size;
return path;
}
// http://www.valvesoftware.com/publications/2007/SIGGRAPH2007_AlphaTestedMagnification.pdf
function generateSDF(ctx, sourceImageData, range) {
var sourceWidth = sourceImageData.width;
var sourceHeight = sourceImageData.height;
var width = ctx.canvas.width;
var height = ctx.canvas.height;
var scaleX = sourceWidth / width;
var scaleY = sourceHeight / height;
function sign(r) {
return r < 128 ? 1 : -1;
}
function searchMinDistance(x, y) {
var minDistSqr = Infinity;
x = Math.floor(x * scaleX);
y = Math.floor(y * scaleY);
var i = y * sourceWidth + x;
var r = sourceImageData.data[i * 4];
var a = sign(r);
// Search for min distance
for (var y2 = Math.max(y - range, 0); y2 < Math.min(y + range, sourceHeight); y2++) {
for (var x2 = Math.max(x - range, 0); x2 < Math.min(x + range, sourceWidth); x2++) {
var i = y2 * sourceWidth + x2;
var r2 = sourceImageData.data[i * 4];
var b = sign(r2);
var dx = x2 - x;
var dy = y2 - y;
if (a !== b) {
var distSqr = dx * dx + dy * dy;
if (distSqr < minDistSqr) {
minDistSqr = distSqr;
}
}
}
}
return a * Math.sqrt(minDistSqr);
}
var sdfImageData = ctx.createImageData(width, height);
for (var y = 0; y < height; y++) {
for (var x = 0; x < width; x++) {
var dist = searchMinDistance(x, y);
var normalized = dist / range * 0.5 + 0.5;
var i = (y * width + x) * 4;
sdfImageData.data[i++] = (1.0 - normalized) * 255;
sdfImageData.data[i++] = (1.0 - normalized) * 255;
sdfImageData.data[i++] = (1.0 - normalized) * 255;
sdfImageData.data[i++] = 255;
}
}
return sdfImageData;
}
var spriteUtil = {
getMarginByStyle: function (style) {
var minMargin = style.minMargin || 0;
var lineWidth = 0;
if (style.stroke && style.stroke !== 'none') {
lineWidth = style.lineWidth == null ? 1 : style.lineWidth;
}
var shadowBlurSize = style.shadowBlur || 0;
var shadowOffsetX = style.shadowOffsetX || 0;
var shadowOffsetY = style.shadowOffsetY || 0;
var margin = {};
margin.left = Math.max(lineWidth / 2, -shadowOffsetX + shadowBlurSize, minMargin);
margin.right = Math.max(lineWidth / 2, shadowOffsetX + shadowBlurSize, minMargin);
margin.top = Math.max(lineWidth / 2, -shadowOffsetY + shadowBlurSize, minMargin);
margin.bottom = Math.max(lineWidth / 2, shadowOffsetY + shadowBlurSize, minMargin);
return margin;
},
// TODO Not consider shadowOffsetX, shadowOffsetY.
/**
* @param {string} symbol
* @param {number | Array.} symbolSize
* @param {Object} style
*/
createSymbolSprite: function (symbol, symbolSize, style, canvas) {
var path = makePath(symbol, symbolSize, style);
var margin = spriteUtil.getMarginByStyle(style);
return {
image: makeSprite(path.__size, canvas, function (ctx) {
path.brush(ctx);
}),
margin: margin
};
},
createSDFFromCanvas: function (canvas, size, range, outCanvas) {
// TODO Create a low resolution SDF from high resolution image.
return makeSprite(size, outCanvas, function (outCtx) {
var ctx = canvas.getContext('2d');
var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
outCtx.putImageData(generateSDF(outCtx, imgData, range), 0, 0);
});
},
createSimpleSprite: function (size, canvas) {
return makeSprite(size, canvas, function (ctx) {
var halfSize = size / 2;
ctx.beginPath();
ctx.arc(halfSize, halfSize, 60, 0, Math.PI * 2, false) ;
ctx.closePath();
var gradient = ctx.createRadialGradient(
halfSize, halfSize, 0, halfSize, halfSize, halfSize
);
gradient.addColorStop(0, 'rgba(255, 255, 255, 1)');
gradient.addColorStop(0.5, 'rgba(255, 255, 255, 0.5)');
gradient.addColorStop(1, 'rgba(255, 255, 255, 0)');
ctx.fillStyle = gradient;
ctx.fill();
});
}
};
/* harmony default export */ __webpack_exports__["a"] = (spriteUtil);
/***/ }),
/* 232 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_geometry_verticesSortMixin__ = __webpack_require__(233);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__sdfSprite_glsl_js__ = __webpack_require__(234);
var vec4 = __WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix___default.a.vec4;
__WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Shader.import(__WEBPACK_IMPORTED_MODULE_4__sdfSprite_glsl_js__["a" /* default */]);
var PointsMesh = __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Mesh.extend(function () {
var geometry = new __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Geometry({
dynamic: true,
attributes: {
color: new __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Geometry.Attribute('color', 'float', 4, 'COLOR'),
position: new __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Geometry.Attribute('position', 'float', 3, 'POSITION'),
size: new __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Geometry.Attribute('size', 'float', 1),
prevPosition: new __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Geometry.Attribute('prevPosition', 'float', 3),
prevSize: new __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Geometry.Attribute('prevSize', 'float', 1)
}
});
__WEBPACK_IMPORTED_MODULE_2_echarts_lib_echarts___default.a.util.extend(geometry, __WEBPACK_IMPORTED_MODULE_1__util_geometry_verticesSortMixin__["a" /* default */]);
var material = new __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Material({
shader: __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].createShader('ecgl.sdfSprite'),
transparent: true,
depthMask: false
});
material.enableTexture('sprite');
material.define('both', 'VERTEX_COLOR');
material.define('both', 'VERTEX_SIZE');
var sdfTexture = new __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Texture2D({
image: document.createElement('canvas'),
flipY: false
});
material.set('sprite', sdfTexture);
// Custom pick methods.
geometry.pick = this._pick.bind(this);
return {
geometry: geometry,
material: material,
mode: __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Mesh.POINTS,
sizeScale: 1
};
}, {
_pick: function (x, y, renderer, camera, renderable, out) {
var positionNDC = this._positionNDC;
if (!positionNDC) {
return;
}
var viewport = renderer.viewport;
var ndcScaleX = 2 / viewport.width;
var ndcScaleY = 2 / viewport.height;
// From near to far. indices have been sorted.
for (var i = this.geometry.vertexCount - 1; i >= 0; i--) {
var idx;
if (!this.geometry.indices) {
idx = i;
}
else {
idx = this.geometry.indices[i];
}
var cx = positionNDC[idx * 2];
var cy = positionNDC[idx * 2 + 1];
var size = this.geometry.attributes.size.get(idx) / this.sizeScale;
var halfSize = size / 2;
if (
x > (cx - halfSize * ndcScaleX) && x < (cx + halfSize * ndcScaleX)
&& y > (cy - halfSize * ndcScaleY) && y < (cy + halfSize * ndcScaleY)
) {
var point = new __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Vector3();
var pointWorld = new __WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Vector3();
this.geometry.attributes.position.get(idx, point.array);
__WEBPACK_IMPORTED_MODULE_0__util_graphicGL__["a" /* default */].Vector3.transformMat4(pointWorld, point, this.worldTransform);
out.push({
vertexIndex: idx,
point: point,
pointWorld: pointWorld,
target: this,
distance: pointWorld.distance(camera.getWorldPosition())
});
}
}
},
updateNDCPosition: function (worldViewProjection, is2D, api) {
var positionNDC = this._positionNDC;
var geometry = this.geometry;
if (!positionNDC || positionNDC.length / 2 !== geometry.vertexCount) {
positionNDC = this._positionNDC = new Float32Array(geometry.vertexCount * 2);
}
var pos = vec4.create();
for (var i = 0; i < geometry.vertexCount; i++) {
geometry.attributes.position.get(i, pos);
pos[3] = 1;
vec4.transformMat4(pos, pos, worldViewProjection.array);
vec4.scale(pos, pos, 1 / pos[3]);
positionNDC[i * 2] = pos[0];
positionNDC[i * 2 + 1] = pos[1];
}
}
});
/* harmony default export */ __webpack_exports__["a"] = (PointsMesh);
/***/ }),
/* 233 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__ProgressiveQuickSort__ = __webpack_require__(90);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix__);
var vec3 = __WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix___default.a.vec3;
/* harmony default export */ __webpack_exports__["a"] = ({
needsSortVertices: function () {
return this.sortVertices;
},
needsSortVerticesProgressively: function () {
return this.needsSortVertices() && this.vertexCount >= 2e4;
},
doSortVertices: function (cameraPos, frame) {
var indices = this.indices;
var p = vec3.create();
if (!indices) {
indices = this.indices = this.vertexCount > 0xffff ? new Uint32Array(this.vertexCount) : new Uint16Array(this.vertexCount);
for (var i = 0; i < indices.length; i++) {
indices[i] = i;
}
}
// Do progressive quick sort.
if (frame === 0) {
var posAttr = this.attributes.position;
var cameraPos = cameraPos.array;
var noneCount = 0;
if (!this._zList || this._zList.length !== this.vertexCount) {
this._zList = new Float32Array(this.vertexCount);
}
var firstZ;
for (var i = 0; i < this.vertexCount; i++) {
posAttr.get(i, p);
// Camera position is in object space
var z = vec3.sqrDist(p, cameraPos);
if (isNaN(z)) {
// Put far away, NaN value may cause sort slow
z = 1e7;
noneCount++;
}
if (i === 0) {
firstZ = z;
z = 0;
}
else {
// Only store the difference to avoid the precision issue.
z = z - firstZ;
}
this._zList[i] = z;
}
this._noneCount = noneCount;
}
if (this.vertexCount < 2e4) {
// Use simple native sort for simple geometries.
if (frame === 0) {
this._simpleSort(this._noneCount / this.vertexCount > 0.05);
}
}
else {
for (var i = 0; i < 3; i++) {
this._progressiveQuickSort(frame * 3 + i);
}
}
this.dirtyIndices();
},
_simpleSort: function (useNativeQuickSort) {
var zList = this._zList;
var indices = this.indices;
function compare(a, b) {
// Sort from far to near. which is descending order
return zList[b] - zList[a];
}
// When too much value are equal, using native quick sort with three partition..
// or the simple quick sort will be nearly O(n*n)
// http://stackoverflow.com/questions/5126586/quicksort-complexity-when-all-the-elements-are-same
// Otherwise simple quicksort is more effecient than v8 native quick sort when data all different.
if (useNativeQuickSort) {
Array.prototype.sort.call(indices, compare);
}
else {
__WEBPACK_IMPORTED_MODULE_0__ProgressiveQuickSort__["a" /* default */].sort(indices, compare, 0, indices.length - 1);
}
},
_progressiveQuickSort: function (frame) {
var zList = this._zList;
var indices = this.indices;
this._quickSort = this._quickSort || new __WEBPACK_IMPORTED_MODULE_0__ProgressiveQuickSort__["a" /* default */]();
this._quickSort.step(indices, function (a, b) {
return zList[b] - zList[a];
}, frame);
}
});
/***/ }),
/* 234 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.sdfSprite.vertex\n\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform float elapsedTime : 0;\n\nattribute vec3 position : POSITION;\n\n#ifdef VERTEX_SIZE\nattribute float size;\n#else\nuniform float u_Size;\n#endif\n\n#ifdef VERTEX_COLOR\nattribute vec4 a_FillColor: COLOR;\nvarying vec4 v_Color;\n#endif\n\n#ifdef VERTEX_ANIMATION\nattribute vec3 prevPosition;\nattribute float prevSize;\nuniform float percent : 1.0;\n#endif\n\n\n#ifdef POSITIONTEXTURE_ENABLED\nuniform sampler2D positionTexture;\n#endif\n\nvarying float v_Size;\n\nvoid main()\n{\n\n#ifdef POSITIONTEXTURE_ENABLED\n gl_Position = worldViewProjection * vec4(texture2D(positionTexture, position.xy).xy, -10.0, 1.0);\n#else\n\n #ifdef VERTEX_ANIMATION\n vec3 pos = mix(prevPosition, position, percent);\n #else\n vec3 pos = position;\n #endif\n gl_Position = worldViewProjection * vec4(pos, 1.0);\n#endif\n\n#ifdef VERTEX_SIZE\n#ifdef VERTEX_ANIMATION\n v_Size = mix(prevSize, size, percent);\n#else\n v_Size = size;\n#endif\n#else\n v_Size = u_Size;\n#endif\n\n#ifdef VERTEX_COLOR\n v_Color = a_FillColor;\n #endif\n\n gl_PointSize = v_Size;\n}\n\n@end\n\n@export ecgl.sdfSprite.fragment\n\nuniform vec4 color: [1, 1, 1, 1];\nuniform vec4 strokeColor: [1, 1, 1, 1];\nuniform float smoothing: 0.07;\n\nuniform float lineWidth: 0.0;\n\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\n\nvarying float v_Size;\n\nuniform sampler2D sprite;\n\n@import clay.util.srgb\n\nvoid main()\n{\n gl_FragColor = color;\n\n vec4 _strokeColor = strokeColor;\n\n#ifdef VERTEX_COLOR\n gl_FragColor *= v_Color;\n #endif\n\n#ifdef SPRITE_ENABLED\n float d = texture2D(sprite, gl_PointCoord).r;\n gl_FragColor.a *= smoothstep(0.5 - smoothing, 0.5 + smoothing, d);\n\n if (lineWidth > 0.0) {\n float sLineWidth = lineWidth / 2.0;\n\n float outlineMaxValue0 = 0.5 + sLineWidth;\n float outlineMaxValue1 = 0.5 + sLineWidth + smoothing;\n float outlineMinValue0 = 0.5 - sLineWidth - smoothing;\n float outlineMinValue1 = 0.5 - sLineWidth;\n\n if (d <= outlineMaxValue1 && d >= outlineMinValue0) {\n float a = _strokeColor.a;\n if (d <= outlineMinValue1) {\n a = a * smoothstep(outlineMinValue0, outlineMinValue1, d);\n }\n else {\n a = a * smoothstep(outlineMaxValue1, outlineMaxValue0, d);\n }\n gl_FragColor.rgb = mix(gl_FragColor.rgb * gl_FragColor.a, _strokeColor.rgb, a);\n gl_FragColor.a = gl_FragColor.a * (1.0 - a) + a;\n }\n }\n#endif\n\n#ifdef SRGB_DECODE\n gl_FragColor = sRGBToLinear(gl_FragColor);\n#endif\n}\n@end");
/***/ }),
/* 235 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__lines3D_lines3DLayout__ = __webpack_require__(236);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__lines3D_Lines3DView__ = __webpack_require__(237);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__lines3D_Lines3DSeries__ = __webpack_require__(240);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__ = __webpack_require__(16);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(Object(__WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__["a" /* default */])('lines3D'));
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerAction({
type: 'lines3DPauseEffect',
event: 'lines3deffectpaused',
update: 'series.lines3D:pauseEffect'
}, function () {});
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerAction({
type: 'lines3DResumeEffect',
event: 'lines3deffectresumed',
update: 'series.lines3D:resumeEffect'
}, function () {});
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerAction({
type: 'lines3DToggleEffect',
event: 'lines3deffectchanged',
update: 'series.lines3D:toggleEffect'
}, function () {});
/***/ }),
/* 236 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix__);
var vec3 = __WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix___default.a.vec3;
var vec2 = __WEBPACK_IMPORTED_MODULE_1_claygl_src_dep_glmatrix___default.a.vec2;
var normalize = vec3.normalize;
var cross = vec3.cross;
var sub = vec3.sub;
var add = vec3.add;
var create = vec3.create;
var normal = create();
var tangent = create();
var bitangent = create();
var halfVector = create();
var coord0 = [];
var coord1 = [];
function getCubicPointsOnGlobe(coords, coordSys) {
vec2.copy(coord0, coords[0]);
vec2.copy(coord1, coords[1]);
var pts = [];
var p0 = pts[0] = create();
var p1 = pts[1] = create();
var p2 = pts[2] = create();
var p3 = pts[3] = create();
coordSys.dataToPoint(coord0, p0);
coordSys.dataToPoint(coord1, p3);
// Get p1
normalize(normal, p0);
// TODO p0-p3 is parallel with normal
sub(tangent, p3, p0);
normalize(tangent, tangent);
cross(bitangent, tangent, normal);
normalize(bitangent, bitangent);
cross(tangent, normal, bitangent);
// p1 is half vector of p0 and tangent on p0
add(p1, normal, tangent);
normalize(p1, p1);
// Get p2
normalize(normal, p3);
sub(tangent, p0, p3);
normalize(tangent, tangent);
cross(bitangent, tangent, normal);
normalize(bitangent, bitangent);
cross(tangent, normal, bitangent);
// p2 is half vector of p3 and tangent on p3
add(p2, normal, tangent);
normalize(p2, p2);
// Project distance of p0 on halfVector
add(halfVector, p0, p3);
normalize(halfVector, halfVector);
var projDist = vec3.dot(p0, halfVector);
// Angle of halfVector and p1
var cosTheta = vec3.dot(halfVector, p1);
var len = (Math.max(vec3.len(p0), vec3.len(p3)) - projDist) / cosTheta * 2;
vec3.scaleAndAdd(p1, p0, p1, len);
vec3.scaleAndAdd(p2, p3, p2, len);
return pts;
}
function getCubicPointsOnPlane(coords, coordSys, up) {
var pts = [];
var p0 = pts[0] = vec3.create();
var p1 = pts[1] = vec3.create();
var p2 = pts[2] = vec3.create();
var p3 = pts[3] = vec3.create();
coordSys.dataToPoint(coords[0], p0);
coordSys.dataToPoint(coords[1], p3);
var len = vec3.dist(p0, p3);
vec3.lerp(p1, p0, p3, 0.3);
vec3.lerp(p2, p0, p3, 0.3);
vec3.scaleAndAdd(p1, p1, up, Math.min(len * 0.1, 10));
vec3.scaleAndAdd(p2, p2, up, Math.min(len * 0.1, 10));
return pts;
}
function getPolylinePoints(coords, coordSys) {
var pts = new Float32Array(coords.length * 3);
var off = 0;
var pt = [];
for (var i = 0; i < coords.length; i++) {
coordSys.dataToPoint(coords[i], pt);
pts[off++] = pt[0];
pts[off++] = pt[1];
pts[off++] = pt[2];
}
return pts;
}
function prepareCoords(data) {
var coordsList = [];
data.each(function (idx) {
var itemModel = data.getItemModel(idx);
var coords = (itemModel.option instanceof Array) ?
itemModel.option : itemModel.getShallow('coords', true);
if (true) {
if (!(coords instanceof Array && coords.length > 0 && coords[0] instanceof Array)) {
throw new Error('Invalid coords ' + JSON.stringify(coords) + '. Lines must have 2d coords array in data item.');
}
}
coordsList.push(coords);
});
return {
coordsList: coordsList
};
}
function layoutGlobe(seriesModel, coordSys) {
var data = seriesModel.getData();
var isPolyline = seriesModel.get('polyline');
data.setLayout('lineType', isPolyline ? 'polyline' : 'cubicBezier');
var res = prepareCoords(data);
data.each(function (idx) {
var coords = res.coordsList[idx];
var getPointsMethod = isPolyline ? getPolylinePoints : getCubicPointsOnGlobe;
data.setItemLayout(idx, getPointsMethod(coords, coordSys));
});
}
function layoutOnPlane(seriesModel, coordSys, normal) {
var data = seriesModel.getData();
var isPolyline = seriesModel.get('polyline');
var res = prepareCoords(data);
data.setLayout('lineType', isPolyline ? 'polyline' : 'cubicBezier');
data.each(function (idx) {
var coords = res.coordsList[idx];
var pts = isPolyline ? getPolylinePoints(coords, coordSys)
: getCubicPointsOnPlane(coords, coordSys, normal);
data.setItemLayout(idx, pts);
});
}
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerLayout(function (ecModel, api) {
ecModel.eachSeriesByType('lines3D', function (seriesModel) {
var coordSys = seriesModel.coordinateSystem;
if (coordSys.type === 'globe') {
layoutGlobe(seriesModel, coordSys);
}
else if (coordSys.type === 'geo3D') {
layoutOnPlane(seriesModel, coordSys, [0, 1, 0]);
}
else if (coordSys.type === 'mapbox3D' || coordSys.type === 'maptalks3D') {
layoutOnPlane(seriesModel, coordSys, [0, 0, 1]);
}
});
});
/***/ }),
/* 237 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_geometry_Lines3D__ = __webpack_require__(22);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__TrailMesh2__ = __webpack_require__(238);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_shader_lines3D_glsl_js__ = __webpack_require__(40);
// import TrailMesh from './TrailMesh';
__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.import(__WEBPACK_IMPORTED_MODULE_4__util_shader_lines3D_glsl_js__["a" /* default */]);
function getCoordSysSize(coordSys) {
if (coordSys.radius != null) {
return coordSys.radius;
}
if (coordSys.size != null) {
return Math.max(coordSys.size[0], coordSys.size[1], coordSys.size[2]);
}
else {
return 100;
}
}
/* unused harmony default export */ var _unused_webpack_default_export = (__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendChartView({
type: 'lines3D',
__ecgl__: true,
init: function (ecModel, api) {
this.groupGL = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();
this._meshLinesMaterial = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
shader: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createShader('ecgl.meshLines3D'),
transparent: true,
depthMask: false
});
this._linesMesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
geometry: new __WEBPACK_IMPORTED_MODULE_2__util_geometry_Lines3D__["a" /* default */](),
material: this._meshLinesMaterial,
$ignorePicking: true
});
// this._trailMesh = new TrailMesh();
this._trailMesh = new __WEBPACK_IMPORTED_MODULE_3__TrailMesh2__["a" /* default */]();
},
render: function (seriesModel, ecModel, api) {
this.groupGL.add(this._linesMesh);
var coordSys = seriesModel.coordinateSystem;
var data = seriesModel.getData();
if (coordSys && coordSys.viewGL) {
var viewGL = coordSys.viewGL;
viewGL.add(this.groupGL);
this._updateLines(seriesModel, ecModel, api);
var methodName = coordSys.viewGL.isLinearSpace() ? 'define' : 'undefine';
this._linesMesh.material[methodName]('fragment', 'SRGB_DECODE');
this._trailMesh.material[methodName]('fragment', 'SRGB_DECODE');
}
var trailMesh = this._trailMesh;
trailMesh.stopAnimation();
if (seriesModel.get('effect.show')) {
this.groupGL.add(trailMesh);
trailMesh.updateData(data, api, this._linesMesh.geometry);
trailMesh.__time = trailMesh.__time || 0;
var time = 3600 * 1000; // 1hour
this._curveEffectsAnimator = trailMesh.animate('', { loop: true })
.when(time, {
__time: time
})
.during(function () {
trailMesh.setAnimationTime(trailMesh.__time);
})
.start();
}
else {
this.groupGL.remove(trailMesh);
this._curveEffectsAnimator = null;
}
this._linesMesh.material.blend = this._trailMesh.material.blend
= seriesModel.get('blendMode') === 'lighter'
? __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].additiveBlend : null;
},
pauseEffect: function () {
if (this._curveEffectsAnimator) {
this._curveEffectsAnimator.pause();
}
},
resumeEffect: function () {
if (this._curveEffectsAnimator) {
this._curveEffectsAnimator.resume();
}
},
toggleEffect: function () {
var animator = this._curveEffectsAnimator;
if (animator) {
animator.isPaused() ? animator.resume() : animator.pause();
}
},
_updateLines: function (seriesModel, ecModel, api) {
var data = seriesModel.getData();
var coordSys = seriesModel.coordinateSystem;
var geometry = this._linesMesh.geometry;
var isPolyline = seriesModel.get('polyline');
geometry.expandLine = true;
var size = getCoordSysSize(coordSys);
geometry.segmentScale = size / 20;
var lineWidthQueryPath = 'lineStyle.width'.split('.');
var dpr = api.getDevicePixelRatio();
var maxLineWidth = 0;
data.each(function (idx) {
var itemModel = data.getItemModel(idx);
var lineWidth = itemModel.get(lineWidthQueryPath);
if (lineWidth == null) {
lineWidth = 1;
}
data.setItemVisual(idx, 'lineWidth', lineWidth);
maxLineWidth = Math.max(lineWidth, maxLineWidth);
});
// Must set useNativeLine before calling any other methods
geometry.useNativeLine = false;
var nVertex = 0;
var nTriangle = 0;
data.each(function (idx) {
var pts = data.getItemLayout(idx);
if (isPolyline) {
nVertex += geometry.getPolylineVertexCount(pts);
nTriangle += geometry.getPolylineTriangleCount(pts);
}
else {
nVertex += geometry.getCubicCurveVertexCount(pts[0], pts[1], pts[2], pts[3]);
nTriangle += geometry.getCubicCurveTriangleCount(pts[0], pts[1], pts[2], pts[3]);
}
});
geometry.setVertexCount(nVertex);
geometry.setTriangleCount(nTriangle);
geometry.resetOffset();
var colorArr = [];
data.each(function (idx) {
var pts = data.getItemLayout(idx);
var color = data.getItemVisual(idx, 'color');
var opacity = data.getItemVisual(idx, 'opacity');
var lineWidth = data.getItemVisual(idx, 'lineWidth') * dpr;
if (opacity == null) {
opacity = 1;
}
colorArr = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(color, colorArr);
colorArr[3] *= opacity;
if (isPolyline) {
geometry.addPolyline(pts, colorArr, lineWidth);
}
else {
geometry.addCubicCurve(pts[0], pts[1], pts[2], pts[3], colorArr, lineWidth);
}
});
geometry.dirty();
},
remove: function () {
this.groupGL.removeAll();
},
dispose: function () {
this.groupGL.removeAll();
}
}));
/***/ }),
/* 238 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_claygl_src_dep_glmatrix__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_geometry_Lines3D__ = __webpack_require__(22);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__shader_trail2_glsl_js__ = __webpack_require__(239);
var vec3 = __WEBPACK_IMPORTED_MODULE_2_claygl_src_dep_glmatrix___default.a.vec3;
function sign(a) {
return a > 0 ? 1 : -1;
}
__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.import(__WEBPACK_IMPORTED_MODULE_4__shader_trail2_glsl_js__["a" /* default */]);
/* harmony default export */ __webpack_exports__["a"] = (__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh.extend(function () {
var material = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
shader: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader(
__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.source('ecgl.trail2.vertex'),
__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.source('ecgl.trail2.fragment')
),
transparent: true,
depthMask: false
});
var geometry = new __WEBPACK_IMPORTED_MODULE_3__util_geometry_Lines3D__["a" /* default */]({
dynamic: true
});
geometry.createAttribute('dist', 'float', 1);
geometry.createAttribute('distAll', 'float', 1);
geometry.createAttribute('start', 'float', 1);
return {
geometry: geometry,
material: material,
culling: false,
$ignorePicking: true
};
}, {
updateData: function (data, api, lines3DGeometry) {
var seriesModel = data.hostModel;
var geometry = this.geometry;
var effectModel = seriesModel.getModel('effect');
var size = effectModel.get('trailWidth') * api.getDevicePixelRatio();
var trailLength = effectModel.get('trailLength');
var speed = seriesModel.get('effect.constantSpeed');
var period = seriesModel.get('effect.period') * 1000;
var useConstantSpeed = speed != null;
if (true) {
if (!this.getScene()) {
console.error('TrailMesh must been add to scene before updateData');
}
}
useConstantSpeed
? this.material.set('speed', speed / 1000)
: this.material.set('period', period);
this.material[useConstantSpeed ? 'define' : 'undefine']('vertex', 'CONSTANT_SPEED');
var isPolyline = seriesModel.get('polyline');
geometry.trailLength = trailLength;
this.material.set('trailLength', trailLength);
geometry.resetOffset();
['position', 'positionPrev', 'positionNext'].forEach(function (attrName) {
geometry.attributes[attrName].value = lines3DGeometry.attributes[attrName].value;
});
var extraAttrs = ['dist', 'distAll', 'start', 'offset', 'color'];
extraAttrs.forEach(function (attrName) {
geometry.attributes[attrName].init(geometry.vertexCount);
});
geometry.indices = lines3DGeometry.indices;
var colorArr = [];
var effectColor = effectModel.get('trailColor');
var effectOpacity = effectModel.get('trailOpacity');
var hasEffectColor = effectColor != null;
var hasEffectOpacity = effectOpacity != null;
this.updateWorldTransform();
var xScale = this.worldTransform.x.len();
var yScale = this.worldTransform.y.len();
var zScale = this.worldTransform.z.len();
var vertexOffset = 0;
var maxDistance = 0;
data.each(function (idx) {
var pts = data.getItemLayout(idx);
var opacity = hasEffectOpacity ? effectOpacity : data.getItemVisual(idx, 'opacity');
var color = data.getItemVisual(idx, 'color');
if (opacity == null) {
opacity = 1;
}
colorArr = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(hasEffectColor ? effectColor : color, colorArr);
colorArr[3] *= opacity;
var vertexCount = isPolyline
? lines3DGeometry.getPolylineVertexCount(pts)
: lines3DGeometry.getCubicCurveVertexCount(pts[0], pts[1], pts[2], pts[3])
var dist = 0;
var pos = [];
var posPrev = [];
for (var i = vertexOffset; i < vertexOffset + vertexCount; i++) {
geometry.attributes.position.get(i, pos);
pos[0] *= xScale;
pos[1] *= yScale;
pos[2] *= zScale;
if (i > vertexOffset) {
dist += vec3.dist(pos, posPrev);
}
geometry.attributes.dist.set(i, dist);
vec3.copy(posPrev, pos);
}
maxDistance = Math.max(maxDistance, dist);
var randomStart = Math.random() * (useConstantSpeed ? dist : period);
for (var i = vertexOffset; i < vertexOffset + vertexCount; i++) {
geometry.attributes.distAll.set(i, dist);
geometry.attributes.start.set(i, randomStart);
geometry.attributes.offset.set(
i, sign(lines3DGeometry.attributes.offset.get(i)) * size / 2
);
geometry.attributes.color.set(i, colorArr);
}
vertexOffset += vertexCount;
});
this.material.set('spotSize', maxDistance * 0.1 * trailLength);
this.material.set('spotIntensity', effectModel.get('spotIntensity'));
geometry.dirty();
},
setAnimationTime: function (time) {
this.material.set('time', time);
}
}));
/***/ }),
/* 239 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.trail2.vertex\nattribute vec3 position: POSITION;\nattribute vec3 positionPrev;\nattribute vec3 positionNext;\nattribute float offset;\nattribute float dist;\nattribute float distAll;\nattribute float start;\n\nattribute vec4 a_Color : COLOR;\n\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform vec4 viewport : VIEWPORT;\nuniform float near : NEAR;\n\nuniform float speed : 0;\nuniform float trailLength: 0.3;\nuniform float time;\nuniform float period: 1000;\n\nuniform float spotSize: 1;\n\nvarying vec4 v_Color;\nvarying float v_Percent;\nvarying float v_SpotPercent;\n\n@import ecgl.common.wireframe.vertexHeader\n\n@import ecgl.lines3D.clipNear\n\nvoid main()\n{\n @import ecgl.lines3D.expandLine\n\n gl_Position = currProj;\n\n v_Color = a_Color;\n\n @import ecgl.common.wireframe.vertexMain\n\n#ifdef CONSTANT_SPEED\n float t = mod((speed * time + start) / distAll, 1. + trailLength) - trailLength;\n#else\n float t = mod((time + start) / period, 1. + trailLength) - trailLength;\n#endif\n\n float trailLen = distAll * trailLength;\n\n v_Percent = (dist - t * distAll) / trailLen;\n\n v_SpotPercent = spotSize / distAll;\n\n }\n@end\n\n\n@export ecgl.trail2.fragment\n\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\nuniform float spotIntensity: 5;\n\nvarying vec4 v_Color;\nvarying float v_Percent;\nvarying float v_SpotPercent;\n\n@import ecgl.common.wireframe.fragmentHeader\n\n@import clay.util.srgb\n\nvoid main()\n{\n if (v_Percent > 1.0 || v_Percent < 0.0) {\n discard;\n }\n\n float fade = v_Percent;\n\n#ifdef SRGB_DECODE\n gl_FragColor = sRGBToLinear(color * v_Color);\n#else\n gl_FragColor = color * v_Color;\n#endif\n\n @import ecgl.common.wireframe.fragmentMain\n\n if (v_Percent > (1.0 - v_SpotPercent)) {\n gl_FragColor.rgb *= spotIntensity;\n }\n\n gl_FragColor.a *= fade;\n}\n\n@end");
/***/ }),
/* 240 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendSeriesModel({
type: 'series.lines3D',
dependencies: ['globe'],
visualColorAccessPath: 'lineStyle.color',
getInitialData: function (option, ecModel) {
var lineData = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.List(['value'], this);
lineData.hasItemOption = false;
lineData.initData(option.data, [], function (dataItem, dimName, dataIndex, dimIndex) {
// dataItem is simply coords
if (dataItem instanceof Array) {
return NaN;
}
else {
lineData.hasItemOption = true;
var value = dataItem.value;
if (value != null) {
return value instanceof Array ? value[dimIndex] : value;
}
}
});
return lineData;
},
defaultOption: {
coordinateSystem: 'globe',
globeIndex: 0,
geo3DIndex: 0,
zlevel: -10,
polyline: false,
effect: {
show: false,
period: 4,
// Trail width
trailWidth: 4,
trailLength: 0.2,
spotIntensity: 6
},
silent: true,
// Support source-over, lighter
blendMode: 'source-over',
lineStyle: {
width: 1,
opacity: 0.5
// color
}
}
});
/***/ }),
/* 241 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__polygons3D_Polygons3DSeries__ = __webpack_require__(242);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__polygons3D_Polygons3DView__ = __webpack_require__(243);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__common_opacityVisual__ = __webpack_require__(16);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(Object(__WEBPACK_IMPORTED_MODULE_3__common_opacityVisual__["a" /* default */])('polygons3D'));
/***/ }),
/* 242 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__component_common_componentShadingMixin__ = __webpack_require__(28);
function transformPolygon(coordSys, poly) {
var ret = [];
for (var i = 0; i < poly.length; i++) {
ret.push(coordSys.dataToPoint(poly[i]));
}
return ret;
}
var Polygons3DSeries = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendSeriesModel({
type: 'series.polygons3D',
getRegionModel: function (idx) {
return this.getData().getItemModel(idx);
},
getRegionPolygonCoords: function (idx) {
var coordSys = this.coordinateSystem;
var itemModel = this.getData().getItemModel(idx);
var coords = itemModel.option instanceof Array
? itemModel.option : itemModel.getShallow('coords');
if (!itemModel.get('multiPolygon')) {
coords = [coords];
}
// TODO Validate
var out = [];
for (var i = 0; i < coords.length; i++) {
// TODO Convert here ?
var interiors = [];
for (var k = 1; k < coords[i].length; k++) {
interiors.push(transformPolygon(coordSys, coords[i][k]));
}
out.push({
exterior: transformPolygon(coordSys, coords[i][0]),
interiors: interiors
});
}
return out;
},
getInitialData: function (option) {
var polygonsData = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.List(['value'], this);
polygonsData.hasItemOption = false;
polygonsData.initData(option.data, [], function (dataItem, dimName, dataIndex, dimIndex) {
// dataItem is simply coords
if (dataItem instanceof Array) {
return NaN;
}
else {
polygonsData.hasItemOption = true;
var value = dataItem.value;
if (value != null) {
return value instanceof Array ? value[dimIndex] : value;
}
}
});
return polygonsData;
},
defaultOption: {
show: true,
data: null,
multiPolygon: false,
progressiveThreshold: 1e3,
progressive: 1e3,
zlevel: -10,
label: {
show: false,
// Distance in 3d space.
distance: 2,
textStyle: {
fontSize: 20,
color: '#000',
backgroundColor: 'rgba(255,255,255,0.7)',
padding: 3,
borderRadius: 4
}
},
itemStyle: {
color: '#fff',
borderWidth: 0,
borderColor: '#333'
},
emphasis: {
itemStyle: {
color: '#639fc0'
},
label: {
show: true
}
}
}
});
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Polygons3DSeries.prototype, __WEBPACK_IMPORTED_MODULE_1__component_common_componentShadingMixin__["a" /* default */]);
/* unused harmony default export */ var _unused_webpack_default_export = (Polygons3DSeries);
/***/ }),
/* 243 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__component_common_Geo3DBuilder__ = __webpack_require__(59);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__ = __webpack_require__(2);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendChartView({
type: 'polygons3D',
__ecgl__: true,
init: function (ecModel, api) {
this.groupGL = new __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].Node();
this._geo3DBuilderList = [];
this._currentStep = 0;
},
render: function (seriesModel, ecModel, api) {
this.groupGL.removeAll();
var coordSys = seriesModel.coordinateSystem;
if (coordSys && coordSys.viewGL) {
coordSys.viewGL.add(this.groupGL);
}
var geo3DBuilder = this._geo3DBuilderList[0];
if (!geo3DBuilder) {
geo3DBuilder = new __WEBPACK_IMPORTED_MODULE_1__component_common_Geo3DBuilder__["a" /* default */](api);
geo3DBuilder.extrudeY = coordSys.type !== 'mapbox3D'
&& coordSys.type !== 'maptalks3D';
this._geo3DBuilderList[0] = geo3DBuilder;
}
this._updateShaderDefines(coordSys, geo3DBuilder);
geo3DBuilder.update(seriesModel, ecModel, api);
this._geo3DBuilderList.length = 1;
this.groupGL.add(geo3DBuilder.rootNode);
},
incrementalPrepareRender: function (seriesModel, ecModel, api) {
this.groupGL.removeAll();
var coordSys = seriesModel.coordinateSystem;
if (coordSys && coordSys.viewGL) {
coordSys.viewGL.add(this.groupGL);
}
this._currentStep = 0;
},
incrementalRender: function (params, seriesModel, ecModel, api) {
var geo3DBuilder = this._geo3DBuilderList[this._currentStep];
var coordSys = seriesModel.coordinateSystem;
if (!geo3DBuilder) {
geo3DBuilder = new __WEBPACK_IMPORTED_MODULE_1__component_common_Geo3DBuilder__["a" /* default */](api);
geo3DBuilder.extrudeY = coordSys.type !== 'mapbox3D'
&& coordSys.type !== 'maptalks3D';
this._geo3DBuilderList[this._currentStep] = geo3DBuilder;
}
geo3DBuilder.update(seriesModel, ecModel, api, params.start, params.end);
this.groupGL.add(geo3DBuilder.rootNode);
this._updateShaderDefines(coordSys, geo3DBuilder);
this._currentStep++;
},
_updateShaderDefines: function (coordSys, geo3DBuilder) {
var methodName = coordSys.viewGL.isLinearSpace() ? 'define' : 'undefine';
geo3DBuilder.rootNode.traverse(function (mesh) {
if (mesh.material) {
mesh.material[methodName]('fragment', 'SRGB_DECODE');
// FIXME
if (coordSys.type === 'mapbox3D' || coordSys.type === 'maptalks3D') {
mesh.material.define('fragment', 'NORMAL_UP_AXIS', 2);
mesh.material.define('fragment', 'NORMAL_FRONT_AXIS', 1);
}
}
});
},
remove: function () {
this.groupGL.removeAll();
},
dispose: function () {
this.groupGL.removeAll();
}
});
/***/ }),
/* 244 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__surface_SurfaceSeries__ = __webpack_require__(245);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__surface_SurfaceView__ = __webpack_require__(246);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__surface_surfaceLayout__ = __webpack_require__(247);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__ = __webpack_require__(16);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(Object(__WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__["a" /* default */])('surface'));
/***/ }),
/* 245 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__component_common_componentShadingMixin__ = __webpack_require__(28);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__common_formatTooltip__ = __webpack_require__(35);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__common_createList__ = __webpack_require__(44);
var SurfaceSeries = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendSeriesModel({
type: 'series.surface',
dependencies: ['globe', 'grid3D', 'geo3D'],
visualColorAccessPath: 'itemStyle.color',
formatTooltip: function (dataIndex) {
return Object(__WEBPACK_IMPORTED_MODULE_2__common_formatTooltip__["a" /* default */])(this, dataIndex);
},
getInitialData: function (option, ecModel) {
var data = option.data;
function validateDimension(dimOpts) {
return !(isNaN(dimOpts.min) || isNaN(dimOpts.max) || isNaN(dimOpts.step));
}
function getPrecision(dimOpts) {
var getPrecision = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.number.getPrecisionSafe;
return Math.max(
getPrecision(dimOpts.min), getPrecision(dimOpts.max), getPrecision(dimOpts.step)
) + 1;
}
if (!data) {
if (!option.parametric) {
// From surface equation
var equation = option.equation || {};
var xOpts = equation.x || {};
var yOpts = equation.y || {};
['x', 'y'].forEach(function (dim) {
if (!validateDimension(equation[dim])) {
if (true) {
console.error('Invalid equation.%s', dim);
}
return;
}
});
if (typeof equation.z !== 'function') {
if (true) {
console.error('equation.z needs to be function');
}
return;
}
var xCount = Math.floor((xOpts.max + xOpts.step - xOpts.min) / xOpts.step);
var yCount = Math.floor((yOpts.max + yOpts.step - yOpts.min) / yOpts.step);
data = new Float32Array(xCount * yCount * 3);
var xPrecision = getPrecision(xOpts);
var yPrecision = getPrecision(yOpts);
var off = 0;
for (var j = 0; j < yCount; j++) {
for (var i = 0; i < xCount; i++) {
var x = i * xOpts.step + xOpts.min;
var y = j * yOpts.step + yOpts.min;
var x2 = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.number.round(Math.min(x, xOpts.max), xPrecision);
var y2 = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.number.round(Math.min(y, yOpts.max), yPrecision);
var z = equation.z(x2, y2);
data[off++] = x2;
data[off++] = y2;
data[off++] = z;
}
}
}
else {
var parametricEquation = option.parametricEquation || {};
var uOpts = parametricEquation.u || {};
var vOpts = parametricEquation.v || {};
['u', 'v'].forEach(function (dim) {
if (!validateDimension(parametricEquation[dim])) {
if (true) {
console.error('Invalid parametricEquation.%s', dim);
}
return;
}
});
['x', 'y', 'z'].forEach(function (dim) {
if (typeof parametricEquation[dim] !== 'function') {
if (true) {
console.error('parametricEquation.%s needs to be function', dim);
}
return;
}
});
var uCount = Math.floor((uOpts.max + uOpts.step - uOpts.min) / uOpts.step);
var vCount = Math.floor((vOpts.max + vOpts.step - vOpts.min) / vOpts.step);
data = new Float32Array(uCount * vCount * 5);
var uPrecision = getPrecision(uOpts);
var vPrecision = getPrecision(vOpts);
var off = 0;
for (var j = 0; j < vCount; j++) {
for (var i = 0; i < uCount; i++) {
var u = i * uOpts.step + uOpts.min;
var v = j * vOpts.step + vOpts.min;
var u2 = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.number.round(Math.min(u, uOpts.max), uPrecision);
var v2 = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.number.round(Math.min(v, vOpts.max), vPrecision);
var x = parametricEquation.x(u2, v2);
var y = parametricEquation.y(u2, v2);
var z = parametricEquation.z(u2, v2);
data[off++] = x;
data[off++] = y;
data[off++] = z;
data[off++] = u2;
data[off++] = v2;
}
}
}
}
var dims = ['x', 'y', 'z'];
if (option.parametric) {
dims.push('u', 'v');
}
// PENDING getSource?
var list = Object(__WEBPACK_IMPORTED_MODULE_3__common_createList__["a" /* default */])(this, dims, data);
return list;
},
defaultOption: {
coordinateSystem: 'cartesian3D',
zlevel: -10,
// Cartesian coordinate system
grid3DIndex: 0,
// Surface needs lambert shading to show the difference
shading: 'lambert',
// If parametric surface
parametric: false,
wireframe: {
show: true,
lineStyle: {
color: 'rgba(0,0,0,0.5)',
width: 1
}
},
/**
* Generate surface data from z = f(x, y) equation
*/
equation: {
// [min, max, step]
x: {
min: -1,
max: 1,
step: 0.1
},
y: {
min: -1,
max: 1,
step: 0.1
},
z: null
},
parametricEquation: {
// [min, max, step]
u: {
min: -1,
max: 1,
step: 0.1
},
v: {
min: -1,
max: 1,
step: 0.1
},
// [x, y, z] = f(x, y)
x: null,
y: null,
z: null
},
itemStyle: {
// Color
},
animationDurationUpdate: 500
}
});
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(SurfaceSeries.prototype, __WEBPACK_IMPORTED_MODULE_1__component_common_componentShadingMixin__["a" /* default */]);
/* unused harmony default export */ var _unused_webpack_default_export = (SurfaceSeries);
/***/ }),
/* 246 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_retrieve__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_geometry_trianglesSortMixin__ = __webpack_require__(60);
var vec3 = __WEBPACK_IMPORTED_MODULE_3_claygl_src_dep_glmatrix___default.a.vec3;
function isPointsNaN(pt) {
return isNaN(pt[0]) || isNaN(pt[1]) || isNaN(pt[2]);
}
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendChartView({
type: 'surface',
__ecgl__: true,
init: function (ecModel, api) {
this.groupGL = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();
},
render: function (seriesModel, ecModel, api) {
// Swap surfaceMesh
var tmp = this._prevSurfaceMesh;
this._prevSurfaceMesh = this._surfaceMesh;
this._surfaceMesh = tmp;
if (!this._surfaceMesh) {
this._surfaceMesh = this._createSurfaceMesh();
}
this.groupGL.remove(this._prevSurfaceMesh);
this.groupGL.add(this._surfaceMesh);
var coordSys = seriesModel.coordinateSystem;
var shading = seriesModel.get('shading');
var data = seriesModel.getData();
var shadingPrefix = 'ecgl.' + shading;
if (!this._surfaceMesh.material || this._surfaceMesh.material.shader.name !== shadingPrefix) {
this._surfaceMesh.material = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createMaterial(shadingPrefix, ['VERTEX_COLOR', 'DOUBLE_SIDED']);
}
__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].setMaterialFromModel(
shading, this._surfaceMesh.material, seriesModel, api
);
if (coordSys && coordSys.viewGL) {
coordSys.viewGL.add(this.groupGL);
var methodName = coordSys.viewGL.isLinearSpace() ? 'define' : 'undefine';
this._surfaceMesh.material[methodName]('fragment', 'SRGB_DECODE');
}
var isParametric = seriesModel.get('parametric');
var dataShape = this._getDataShape(data, isParametric);
var wireframeModel = seriesModel.getModel('wireframe');
var wireframeLineWidth = wireframeModel.get('lineStyle.width');
var showWireframe = wireframeModel.get('show') && wireframeLineWidth > 0;
this._updateSurfaceMesh(this._surfaceMesh, seriesModel, dataShape, showWireframe);
var material = this._surfaceMesh.material;
if (showWireframe) {
material.define('WIREFRAME_QUAD');
material.set('wireframeLineWidth', wireframeLineWidth);
material.set('wireframeLineColor', __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(wireframeModel.get('lineStyle.color')));
}
else {
material.undefine('WIREFRAME_QUAD');
}
this._initHandler(seriesModel, api);
this._updateAnimation(seriesModel);
},
_updateAnimation: function (seriesModel) {
__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].updateVertexAnimation(
[['prevPosition', 'position'],
['prevNormal', 'normal']],
this._prevSurfaceMesh,
this._surfaceMesh,
seriesModel
);
},
_createSurfaceMesh: function () {
var mesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
geometry: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Geometry({
dynamic: true,
sortTriangles: true
}),
shadowDepthMaterial: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
shader: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader(__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.source('ecgl.sm.depth.vertex'), __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.source('ecgl.sm.depth.fragment'))
}),
culling: false,
// Render after axes
renderOrder: 10,
// Render normal in normal pass
renderNormal: true
});
mesh.geometry.createAttribute('barycentric', 'float', 4);
mesh.geometry.createAttribute('prevPosition', 'float', 3);
mesh.geometry.createAttribute('prevNormal', 'float', 3);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.extend(mesh.geometry, __WEBPACK_IMPORTED_MODULE_4__util_geometry_trianglesSortMixin__["a" /* default */]);
return mesh;
},
_initHandler: function (seriesModel, api) {
var data = seriesModel.getData();
var surfaceMesh = this._surfaceMesh;
var coordSys = seriesModel.coordinateSystem;
function getNearestPointIdx(triangle, point) {
var nearestDist = Infinity;
var nearestIdx = -1;
var pos = [];
for (var i = 0; i < triangle.length; i++) {
surfaceMesh.geometry.attributes.position.get(triangle[i], pos);
var dist = vec3.dist(point.array, pos);
if (dist < nearestDist) {
nearestDist = dist;
nearestIdx = triangle[i];
}
}
return nearestIdx;
}
surfaceMesh.seriesIndex = seriesModel.seriesIndex;
var lastDataIndex = -1;
surfaceMesh.off('mousemove');
surfaceMesh.off('mouseout');
surfaceMesh.on('mousemove', function (e) {
var idx = getNearestPointIdx(e.triangle, e.point);
if (idx >= 0) {
var point = [];
surfaceMesh.geometry.attributes.position.get(idx, point);
var value = coordSys.pointToData(point);
var minDist = Infinity;
var dataIndex = -1;
var item = [];
for (var i = 0; i < data.count(); i++) {
item[0] = data.get('x', i);
item[1] = data.get('y', i);
item[2] = data.get('z', i);
var dist = vec3.squaredDistance(item, value);
if (dist < minDist) {
dataIndex = i;
minDist = dist;
}
}
if (dataIndex !== lastDataIndex) {
api.dispatchAction({
type: 'grid3DShowAxisPointer',
value: value
});
}
lastDataIndex = dataIndex;
surfaceMesh.dataIndex = dataIndex;
}
else {
surfaceMesh.dataIndex = -1;
}
}, this);
surfaceMesh.on('mouseout', function (e) {
lastDataIndex = -1;
surfaceMesh.dataIndex = -1;
api.dispatchAction({
type: 'grid3DHideAxisPointer'
});
}, this);
},
_updateSurfaceMesh: function (surfaceMesh, seriesModel, dataShape, showWireframe) {
var geometry = surfaceMesh.geometry;
var data = seriesModel.getData();
var pointsArr = data.getLayout('points');
var invalidDataCount = 0;
data.each(function (idx) {
if (!data.hasValue(idx)) {
invalidDataCount++;
}
});
var needsSplitQuad = invalidDataCount || showWireframe;
var positionAttr = geometry.attributes.position;
var normalAttr = geometry.attributes.normal;
var texcoordAttr = geometry.attributes.texcoord0;
var barycentricAttr = geometry.attributes.barycentric;
var colorAttr = geometry.attributes.color;
var row = dataShape.row;
var column = dataShape.column;
var shading = seriesModel.get('shading');
var needsNormal = shading !== 'color';
if (needsSplitQuad) {
// TODO, If needs remove the invalid points, or set color transparent.
var vertexCount = (row - 1) * (column - 1) * 4;
positionAttr.init(vertexCount);
if (showWireframe) {
barycentricAttr.init(vertexCount);
}
}
else {
positionAttr.value = new Float32Array(pointsArr);
}
colorAttr.init(geometry.vertexCount);
texcoordAttr.init(geometry.vertexCount);
var quadToTriangle = [0, 3, 1, 1, 3, 2];
// 3----2
// 0----1
// Make sure pixels on 1---3 edge will not have channel 0.
// And pixels on four edges have at least one channel 0.
var quadBarycentric = [
[1, 1, 0, 0],
[0, 1, 0, 1],
[1, 0, 0, 1],
[1, 0, 1, 0]
];
var indices = geometry.indices = new (geometry.vertexCount > 0xffff ? Uint32Array : Uint16Array)((row - 1) * (column - 1) * 6);
var getQuadIndices = function (i, j, out) {
out[1] = i * column + j;
out[0] = i * column + j + 1;
out[3] = (i + 1) * column + j + 1;
out[2] = (i + 1) * column + j;
};
var isTransparent = false;
if (needsSplitQuad) {
var quadIndices = [];
var pos = [];
var faceOffset = 0;
if (needsNormal) {
normalAttr.init(geometry.vertexCount);
}
else {
normalAttr.value = null;
}
var pts = [[], [], []];
var v21 = [], v32 = [];
var normal = vec3.create();
var getFromArray = function (arr, idx, out) {
var idx3 = idx * 3;
out[0] = arr[idx3];
out[1] = arr[idx3 + 1];
out[2] = arr[idx3 + 2];
return out;
};
var vertexNormals = new Float32Array(pointsArr.length);
var vertexColors = new Float32Array(pointsArr.length / 3 * 4);
for (var i = 0; i < data.count(); i++) {
if (data.hasValue(i)) {
var rgbaArr = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(data.getItemVisual(i, 'color'));
var opacity = data.getItemVisual(i, 'opacity');
rgbaArr[3] *= opacity;
if (rgbaArr[3] < 0.99) {
isTransparent = true;
}
for (var k = 0; k < 4; k++) {
vertexColors[i * 4 + k] = rgbaArr[k];
}
}
}
var farPoints = [1e7, 1e7, 1e7];
for (var i = 0; i < row - 1; i++) {
for (var j = 0; j < column - 1; j++) {
var dataIndex = i * (column - 1) + j;
var vertexOffset = dataIndex * 4;
getQuadIndices(i, j, quadIndices);
var invisibleQuad = false;
for (var k = 0; k < 4; k++) {
getFromArray(pointsArr, quadIndices[k], pos);
if (isPointsNaN(pos)) {
// Quad is invisible if any point is NaN
invisibleQuad = true;
}
}
for (var k = 0; k < 4; k++) {
if (invisibleQuad) {
// Move point far away
positionAttr.set(vertexOffset + k, farPoints);
}
else {
getFromArray(pointsArr, quadIndices[k], pos);
positionAttr.set(vertexOffset + k, pos);
}
if (showWireframe) {
barycentricAttr.set(vertexOffset + k, quadBarycentric[k]);
}
}
for (var k = 0; k < 6; k++) {
indices[faceOffset++] = quadToTriangle[k] + vertexOffset;
}
// Vertex normals
if (needsNormal && !invisibleQuad) {
for (var k = 0; k < 2; k++) {
var k3 = k * 3;
for (var m = 0; m < 3; m++) {
var idx = quadIndices[quadToTriangle[k3] + m];
getFromArray(pointsArr, idx, pts[m]);
}
vec3.sub(v21, pts[0], pts[1]);
vec3.sub(v32, pts[1], pts[2]);
vec3.cross(normal, v21, v32);
// Weighted by the triangle area
for (var m = 0; m < 3; m++) {
var idx3 = quadIndices[quadToTriangle[k3] + m] * 3;
vertexNormals[idx3] = vertexNormals[idx3] + normal[0];
vertexNormals[idx3 + 1] = vertexNormals[idx3 + 1] + normal[1];
vertexNormals[idx3 + 2] = vertexNormals[idx3 + 2] + normal[2];
}
}
}
}
}
if (needsNormal) {
for (var i = 0; i < vertexNormals.length / 3; i++) {
getFromArray(vertexNormals, i, normal);
vec3.normalize(normal, normal);
vertexNormals[i * 3] = normal[0];
vertexNormals[i * 3 + 1] = normal[1];
vertexNormals[i * 3 + 2] = normal[2];
}
}
// Split normal and colors, write to the attributes.
var rgbaArr = [];
var uvArr = [];
for (var i = 0; i < row - 1; i++) {
for (var j = 0; j < column - 1; j++) {
var dataIndex = i * (column - 1) + j;
var vertexOffset = dataIndex * 4;
getQuadIndices(i, j, quadIndices);
for (var k = 0; k < 4; k++) {
for (var m = 0; m < 4; m++) {
rgbaArr[m] = vertexColors[quadIndices[k] * 4 + m];
}
colorAttr.set(vertexOffset + k, rgbaArr);
if (needsNormal) {
getFromArray(vertexNormals, quadIndices[k], normal);
normalAttr.set(vertexOffset + k, normal);
}
var idx = quadIndices[k];
uvArr[0] = (idx % column) / (column - 1);
uvArr[1] = Math.floor(idx / column) / (row - 1);
texcoordAttr.set(vertexOffset + k, uvArr);
}
dataIndex++;
}
}
}
else {
var uvArr = [];
for (var i = 0; i < data.count(); i++) {
uvArr[0] = (i % column) / (column - 1);
uvArr[1] = Math.floor(i / column) / (row - 1);
var rgbaArr = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(data.getItemVisual(i, 'color'));
var opacity = data.getItemVisual(i, 'opacity');
rgbaArr[3] *= opacity;
if (rgbaArr[3] < 0.99) {
isTransparent = true;
}
colorAttr.set(i, rgbaArr);
texcoordAttr.set(i, uvArr);
}
var quadIndices = [];
// Triangles
var cursor = 0;
for (var i = 0; i < row - 1; i++) {
for (var j = 0; j < column - 1; j++) {
getQuadIndices(i, j, quadIndices);
for (var k = 0; k < 6; k++) {
indices[cursor++] = quadIndices[quadToTriangle[k]];
}
}
}
if (needsNormal) {
geometry.generateVertexNormals();
}
else {
normalAttr.value = null;
}
}
if (surfaceMesh.material.get('normalMap')) {
geometry.generateTangents();
}
geometry.updateBoundingBox();
geometry.dirty();
surfaceMesh.material.transparent = isTransparent;
surfaceMesh.material.depthMask = !isTransparent;
},
_getDataShape: function (data, isParametric) {
var prevX = -Infinity;
var rowCount = 0;
var columnCount = 0;
var prevColumnCount = 0;
var rowDim = isParametric ? 'u' : 'x';
// Check data format
for (var i = 0; i < data.count(); i++) {
var x = data.get(rowDim, i);
if (x < prevX) {
if (prevColumnCount && prevColumnCount !== columnCount) {
if (true) {
throw new Error('Invalid data. data should be a row major 2d array.')
}
}
// A new row.
prevColumnCount = columnCount;
columnCount = 0;
rowCount++;
}
prevX = x;
columnCount++;
}
return {
row: rowCount + 1,
column: columnCount
};
},
dispose: function () {
this.groupGL.removeAll();
},
remove: function () {
this.groupGL.removeAll();
}
});
/***/ }),
/* 247 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerLayout(function (ecModel, api) {
ecModel.eachSeriesByType('surface', function (surfaceModel) {
var cartesian = surfaceModel.coordinateSystem;
if (!cartesian || cartesian.type !== 'cartesian3D') {
if (true) {
console.error('Surface chart only support cartesian3D coordinateSystem');
}
}
var data = surfaceModel.getData();
var points = new Float32Array(3 * data.count());
var nanPoint = [NaN, NaN, NaN];
if (cartesian && cartesian.type === 'cartesian3D') {
var coordDims = cartesian.dimensions;
var dims = coordDims.map(function (coordDim) {
return surfaceModel.coordDimToDataDim(coordDim)[0];
});
data.each(dims, function (x, y, z, idx) {
var pt;
if (!data.hasValue(idx)) {
pt = nanPoint;
}
else {
pt = cartesian.dataToPoint([x, y, z]);
}
points[idx * 3] = pt[0];
points[idx * 3 + 1] = pt[1];
points[idx * 3 + 2] = pt[2];
});
}
data.setLayout('points', points);
});
});
/***/ }),
/* 248 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__coord_geo3D_Geo3D__ = __webpack_require__(92);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__map3D_Map3DSeries__ = __webpack_require__(249);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__map3D_Map3DView__ = __webpack_require__(250);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__ = __webpack_require__(16);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(Object(__WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__["a" /* default */])('map3D'));
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerAction({
type: 'map3DChangeCamera',
event: 'map3dcamerachanged',
update: 'series:updateCamera'
}, function (payload, ecModel) {
ecModel.eachComponent({
mainType: 'series', subType: 'map3D', query: payload
}, function (componentModel) {
componentModel.setView(payload);
});
});
/***/ }),
/* 249 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__component_common_componentViewControlMixin__ = __webpack_require__(38);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__component_common_componentPostEffectMixin__ = __webpack_require__(25);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__component_common_componentLightMixin__ = __webpack_require__(26);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__component_common_componentShadingMixin__ = __webpack_require__(28);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__coord_geo3D_geo3DModelMixin__ = __webpack_require__(89);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__util_format__ = __webpack_require__(29);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__common_formatTooltip__ = __webpack_require__(35);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__coord_geo3DCreator__ = __webpack_require__(91);
function transformPolygon(mapbox3DCoordSys, poly) {
var newPoly = [];
for (var k = 0; k < poly.length; k++) {
newPoly.push(mapbox3DCoordSys.dataToPoint(poly[k]));
}
return newPoly;
}
var Map3DSeries = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendSeriesModel({
type: 'series.map3D',
layoutMode: 'box',
coordinateSystem: null,
visualColorAccessPath: 'itemStyle.color',
optionUpdated: function (newOpt) {
newOpt = newOpt || {};
var coordSysType = this.get('coordinateSystem');
if (coordSysType == null || coordSysType === 'geo3D') {
return;
}
if (true) {
var propsNeedToCheck = [
'left', 'top', 'width', 'height',
'boxWidth', 'boxDepth', 'boxHeight',
'light', 'viewControl', 'postEffect', 'temporalSuperSampling',
'environment', 'groundPlane'
];
var ignoredProperties = [];
propsNeedToCheck.forEach(function (propName) {
if (newOpt[propName] != null) {
ignoredProperties.push(propName);
}
});
if (ignoredProperties.length) {
console.warn(
'Property %s in map3D series will be ignored if coordinate system is %s',
ignoredProperties.join(', '), coordSysType
);
}
}
if (this.get('groundPlane.show')) {
// Force disable groundPlane if map3D has other coordinate systems.
this.option.groundPlane.show = false;
}
// Reset geo.
this._geo = null;
},
getInitialData: function (option) {
option.data = this.getFilledRegions(option.data, option.map);
var dimensions = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.helper.completeDimensions(['value'], option.data);
var list = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.List(dimensions, this);
list.initData(option.data);
var regionModelMap = {};
list.each(function (idx) {
var name = list.getName(idx);
var itemModel = list.getItemModel(idx);
regionModelMap[name] = itemModel;
});
this._regionModelMap = regionModelMap;
return list;
},
formatTooltip: function (dataIndex) {
return Object(__WEBPACK_IMPORTED_MODULE_7__common_formatTooltip__["a" /* default */])(this, dataIndex);
},
getRegionModel: function (idx) {
var name = this.getData().getName(idx);
return this._regionModelMap[name] || new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.Model(null, this);
},
getRegionPolygonCoords: function (idx) {
var coordSys = this.coordinateSystem;
var name = this.getData().getName(idx);
if (coordSys.transform) {
var region = coordSys.getRegion(name);
return region ? region.geometries : [];
}
else {
if (!this._geo) {
this._geo = __WEBPACK_IMPORTED_MODULE_8__coord_geo3DCreator__["a" /* default */].createGeo3D(this);
}
var region = this._geo.getRegion(name);
var ret = [];
for (var k = 0; k < region.geometries.length; k++) {
var geo = region.geometries[k];
var interiors = [];
var exterior = transformPolygon(coordSys, geo.exterior);
if (interiors && interiors.length) {
for (var m = 0; m < geo.interiors.length; m++) {
interiors.push(transformPolygon(coordSys, interiors[m]));
}
}
ret.push({
interiors: interiors,
exterior: exterior
});
}
return ret;
}
},
/**
* Format label
* @param {string} name Region name
* @param {string} [status='normal'] 'normal' or 'emphasis'
* @return {string}
*/
getFormattedLabel: function (dataIndex, status) {
var text = __WEBPACK_IMPORTED_MODULE_6__util_format__["a" /* default */].getFormattedLabel(this, dataIndex, status);
if (text == null) {
text = this.getData().getName(dataIndex);
}
return text;
},
defaultOption: {
// Support geo3D, mapbox, maptalks3D
coordinateSystem: 'geo3D',
// itemStyle: {},
// height,
// label: {}
data: null
}
});
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Map3DSeries.prototype, __WEBPACK_IMPORTED_MODULE_5__coord_geo3D_geo3DModelMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Map3DSeries.prototype, __WEBPACK_IMPORTED_MODULE_1__component_common_componentViewControlMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Map3DSeries.prototype, __WEBPACK_IMPORTED_MODULE_2__component_common_componentPostEffectMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Map3DSeries.prototype, __WEBPACK_IMPORTED_MODULE_3__component_common_componentLightMixin__["a" /* default */]);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.merge(Map3DSeries.prototype, __WEBPACK_IMPORTED_MODULE_4__component_common_componentShadingMixin__["a" /* default */]);
/* unused harmony default export */ var _unused_webpack_default_export = (Map3DSeries);
/***/ }),
/* 250 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_OrbitControl__ = __webpack_require__(39);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__component_common_SceneHelper__ = __webpack_require__(27);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__component_common_Geo3DBuilder__ = __webpack_require__(59);
/* unused harmony default export */ var _unused_webpack_default_export = (__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendChartView({
type: 'map3D',
__ecgl__: true,
init: function (ecModel, api) {
this._geo3DBuilder = new __WEBPACK_IMPORTED_MODULE_4__component_common_Geo3DBuilder__["a" /* default */](api);
this.groupGL = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();
},
render: function (map3DModel, ecModel, api) {
var coordSys = map3DModel.coordinateSystem;
if (!coordSys || !coordSys.viewGL) {
return;
}
this.groupGL.add(this._geo3DBuilder.rootNode);
coordSys.viewGL.add(this.groupGL);
var geo3D;
if (coordSys.type === 'geo3D') {
geo3D = coordSys;
if (!this._sceneHelper) {
this._sceneHelper = new __WEBPACK_IMPORTED_MODULE_3__component_common_SceneHelper__["a" /* default */]();
this._sceneHelper.initLight(this.groupGL);
}
this._sceneHelper.setScene(coordSys.viewGL.scene);
this._sceneHelper.updateLight(map3DModel);
// Set post effect
coordSys.viewGL.setPostEffect(map3DModel.getModel('postEffect'), api);
coordSys.viewGL.setTemporalSuperSampling(map3DModel.getModel('temporalSuperSampling'));
var control = this._control;
if (!control) {
control = this._control = new __WEBPACK_IMPORTED_MODULE_2__util_OrbitControl__["a" /* default */]({
zr: api.getZr()
});
this._control.init();
}
var viewControlModel = map3DModel.getModel('viewControl');
control.setViewGL(coordSys.viewGL);
control.setFromViewControlModel(viewControlModel, 0);
control.off('update');
control.on('update', function () {
api.dispatchAction({
type: 'map3DChangeCamera',
alpha: control.getAlpha(),
beta: control.getBeta(),
distance: control.getDistance(),
from: this.uid,
map3DId: map3DModel.id
});
});
this._geo3DBuilder.extrudeY = true;
}
else {
if (this._control) {
this._control.dispose();
this._control = null;
}
if (this._sceneHelper) {
this._sceneHelper.dispose();
this._sceneHelper = null;
}
geo3D = map3DModel.getData().getLayout('geo3D');
this._geo3DBuilder.extrudeY = false;
}
this._geo3DBuilder.update(map3DModel, ecModel, api, 0, map3DModel.getData().count());
// Must update after geo3D.viewGL.setPostEffect to determine linear space
var srgbDefineMethod = coordSys.viewGL.isLinearSpace() ? 'define' : 'undefine';
this._geo3DBuilder.rootNode.traverse(function (mesh) {
if (mesh.material) {
mesh.material[srgbDefineMethod]('fragment', 'SRGB_DECODE');
}
});
},
afterRender: function (map3DModel, ecModel, api, layerGL) {
var renderer = layerGL.renderer;
var coordSys = map3DModel.coordinateSystem;
if (coordSys && coordSys.type === 'geo3D') {
this._sceneHelper.updateAmbientCubemap(renderer, map3DModel, api);
this._sceneHelper.updateSkybox(renderer, map3DModel, api);
}
},
dispose: function () {
this.groupGL.removeAll();
this._control.dispose();
}
}));
/***/ }),
/* 251 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__scatterGL_ScatterGLSeries__ = __webpack_require__(252);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__scatterGL_ScatterGLView__ = __webpack_require__(253);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol__ = __webpack_require__(45);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__ = __webpack_require__(16);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(__WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol___default()('scatterGL', 'circle', null));
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(Object(__WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__["a" /* default */])('scatterGL'));
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerLayout({
seriesType: 'scatterGL',
reset: function (seriesModel) {
var coordSys = seriesModel.coordinateSystem;
var progress;
if (coordSys) {
var dims = coordSys.dimensions;
var pt = [];
if (dims.length === 1) {
progress = function (params, data) {
var points = new Float32Array((params.end - params.start) * 2);
for (var idx = params.start; idx < params.end; idx++) {
var offset = (idx - params.start) * 2;
var x = data.get(dims[0], idx);
var pt = coordSys.dataToPoint(x);
points[offset] = pt[0];
points[offset + 1] = pt[1];
}
data.setLayout('points', points);
};
}
else if (dims.length === 2) {
progress = function (params, data) {
var points = new Float32Array((params.end - params.start) * 2);
for (var idx = params.start; idx < params.end; idx++) {
var offset = (idx - params.start) * 2;
var x = data.get(dims[0], idx);
var y = data.get(dims[1], idx);
pt[0] = x;
pt[1] = y;
pt = coordSys.dataToPoint(pt);
points[offset] = pt[0];
points[offset + 1] = pt[1];
}
data.setLayout('points', points);
};
}
}
return { progress: progress };
}
});
/***/ }),
/* 252 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendSeriesModel({
type: 'series.scatterGL',
dependencies: ['grid', 'polar', 'geo', 'singleAxis'],
visualColorAccessPath: 'itemStyle.color',
getInitialData: function () {
return __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.helper.createList(this);
},
defaultOption: {
coordinateSystem: 'cartesian2d',
zlevel: 10,
progressive: 1e5,
progressiveThreshold: 1e5,
// Cartesian coordinate system
// xAxisIndex: 0,
// yAxisIndex: 0,
// Polar coordinate system
// polarIndex: 0,
// Geo coordinate system
// geoIndex: 0,
large: false,
symbol: 'circle',
symbolSize: 10,
// symbolSize scale when zooming.
zoomScale: 0,
// Support source-over, lighter
blendMode: 'source-over',
itemStyle: {
opacity: 0.8
},
postEffect: {
enable: false,
colorCorrection: {
exposure: 0,
brightness: 0,
contrast: 1,
saturation: 1,
enable: true
}
}
}
});
/***/ }),
/* 253 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__core_ViewGL__ = __webpack_require__(19);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__common_PointsBuilder__ = __webpack_require__(62);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_GLViewHelper__ = __webpack_require__(96);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__util_retrieve__ = __webpack_require__(3);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendChartView({
type: 'scatterGL',
__ecgl__: true,
init: function (ecModel, api) {
this.groupGL = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();
this.viewGL = new __WEBPACK_IMPORTED_MODULE_2__core_ViewGL__["a" /* default */]('orthographic');
this.viewGL.add(this.groupGL);
this._pointsBuilderList = [];
this._currentStep = 0;
this._sizeScale = 1;
this._glViewHelper = new __WEBPACK_IMPORTED_MODULE_4__common_GLViewHelper__["a" /* default */](this.viewGL);
},
render: function (seriesModel, ecModel, api) {
this.groupGL.removeAll();
this._glViewHelper.reset(seriesModel, api);
if (!seriesModel.getData().count()) {
return;
}
var pointsBuilder = this._pointsBuilderList[0];
if (!pointsBuilder) {
pointsBuilder = this._pointsBuilderList[0] = new __WEBPACK_IMPORTED_MODULE_3__common_PointsBuilder__["a" /* default */](true, api);
}
this._pointsBuilderList.length = 1;
this.groupGL.add(pointsBuilder.rootNode);
this._removeTransformInPoints(seriesModel.getData().getLayout('points'));
pointsBuilder.update(seriesModel, ecModel, api);
this.viewGL.setPostEffect(seriesModel.getModel('postEffect'), api);
},
incrementalPrepareRender: function (seriesModel, ecModel, api) {
this.groupGL.removeAll();
this._glViewHelper.reset(seriesModel, api);
this._currentStep = 0;
this.viewGL.setPostEffect(seriesModel.getModel('postEffect'), api);
},
incrementalRender: function (params, seriesModel, ecModel, api) {
if (params.end <= params.start) {
return;
}
var pointsBuilder = this._pointsBuilderList[this._currentStep];
if (!pointsBuilder) {
pointsBuilder = new __WEBPACK_IMPORTED_MODULE_3__common_PointsBuilder__["a" /* default */](true, api);
this._pointsBuilderList[this._currentStep] = pointsBuilder;
}
this.groupGL.add(pointsBuilder.rootNode);
this._removeTransformInPoints(seriesModel.getData().getLayout('points'));
pointsBuilder.setSizeScale(this._sizeScale);
pointsBuilder.update(seriesModel, ecModel, api, params.start, params.end);
api.getZr().refresh();
this._currentStep++;
},
updateTransform: function (seriesModel, ecModel, api) {
if (seriesModel.coordinateSystem.getRoamTransform) {
this._glViewHelper.updateTransform(seriesModel, api);
var zoom = this._glViewHelper.getZoom();
var sizeScale = Math.max((seriesModel.get('zoomScale') || 0) * (zoom - 1) + 1, 0);
this._sizeScale = sizeScale;
this._pointsBuilderList.forEach(function (pointsBuilder) {
pointsBuilder.setSizeScale(sizeScale);
});
}
},
_removeTransformInPoints: function (points) {
if (!points) {
return;
}
var pt = [];
for (var i = 0; i < points.length; i += 2) {
pt[0] = points[i];
pt[1] = points[i + 1];
this._glViewHelper.removeTransformInPoint(pt);
points[i] = pt[0];
points[i + 1] = pt[1];
}
},
dispose: function () {
this.groupGL.removeAll();
},
remove: function () {
this.groupGL.removeAll();
}
});
/***/ }),
/* 254 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__graphGL_GraphGLSeries__ = __webpack_require__(255);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__graphGL_GraphGLView__ = __webpack_require__(260);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol__ = __webpack_require__(45);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__ = __webpack_require__(16);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(__WEBPACK_IMPORTED_MODULE_3_echarts_lib_visual_symbol___default()('graphGL', 'circle', null));
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(Object(__WEBPACK_IMPORTED_MODULE_4__common_opacityVisual__["a" /* default */])('graphGL'));
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(function (ecModel) {
var paletteScope = {};
ecModel.eachSeriesByType('graphGL', function (seriesModel) {
var categoriesData = seriesModel.getCategoriesData();
var data = seriesModel.getData();
var categoryNameIdxMap = {};
categoriesData.each(function (idx) {
var name = categoriesData.getName(idx);
categoryNameIdxMap[name] = idx;
var itemModel = categoriesData.getItemModel(idx);
var color = itemModel.get('itemStyle.color')
|| seriesModel.getColorFromPalette(name, paletteScope);
categoriesData.setItemVisual(idx, 'color', color);
});
// Assign category color to visual
if (categoriesData.count()) {
data.each(function (idx) {
var model = data.getItemModel(idx);
var category = model.getShallow('category');
if (category != null) {
if (typeof category === 'string') {
category = categoryNameIdxMap[category];
}
if (!data.getItemVisual(idx, 'color', true)) {
data.setItemVisual(
idx, 'color',
categoriesData.getItemVisual(category, 'color')
);
}
}
});
}
});
});
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(function (ecModel) {
ecModel.eachSeriesByType('graphGL', function (seriesModel) {
var graph = seriesModel.getGraph();
var edgeData = seriesModel.getEdgeData();
var colorQuery = 'lineStyle.color'.split('.');
var opacityQuery = 'lineStyle.opacity'.split('.');
edgeData.setVisual('color', seriesModel.get(colorQuery));
edgeData.setVisual('opacity', seriesModel.get(opacityQuery));
edgeData.each(function (idx) {
var itemModel = edgeData.getItemModel(idx);
var edge = graph.getEdgeByIndex(idx);
// Edge visual must after node visual
var color = itemModel.get(colorQuery);
var opacity = itemModel.get(opacityQuery);
switch (color) {
case 'source':
color = edge.node1.getVisual('color');
break;
case 'target':
color = edge.node2.getVisual('color');
break;
}
edge.setVisual('color', color);
edge.setVisual('opacity', opacity);
});
});
});
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerAction({
type: 'graphGLRoam',
event: 'graphglroam',
update: 'series.graphGL:roam'
}, function (payload, ecModel) {
ecModel.eachComponent({
mainType: 'series', query: payload
}, function (componentModel) {
componentModel.setView(payload);
});
});
function noop() {}
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerAction({
type: 'graphGLStartLayout',
event: 'graphgllayoutstarted',
update: 'series.graphGL:startLayout'
}, noop);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerAction({
type: 'graphGLStopLayout',
event: 'graphgllayoutstopped',
update: 'series.graphGL:stopLayout'
}, noop);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerAction({
type: 'graphGLFocusNodeAdjacency',
event: 'graphGLFocusNodeAdjacency',
update: 'series.graphGL:focusNodeAdjacency'
}, noop);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerAction({
type: 'graphGLUnfocusNodeAdjacency',
event: 'graphGLUnfocusNodeAdjacency',
update: 'series.graphGL:unfocusNodeAdjacency'
}, noop);
/***/ }),
/* 255 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__createGraphFromNodeEdge__ = __webpack_require__(256);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_format__ = __webpack_require__(29);
var GraphSeries = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendSeriesModel({
type: 'series.graphGL',
visualColorAccessPath: 'itemStyle.color',
init: function (option) {
GraphSeries.superApply(this, 'init', arguments);
// Provide data for legend select
this.legendDataProvider = function () {
return this._categoriesData;
};
this._updateCategoriesData();
},
mergeOption: function (option) {
GraphSeries.superApply(this, 'mergeOption', arguments);
this._updateCategoriesData();
},
getFormattedLabel: function (dataIndex, status, dataType, dimIndex) {
var text = __WEBPACK_IMPORTED_MODULE_2__util_format__["a" /* default */].getFormattedLabel(this, dataIndex, status, dataType, dimIndex);
if (text == null) {
var data = this.getData();
var lastDim = data.dimensions[data.dimensions.length - 1];
text = data.get(lastDim, dataIndex);
}
return text;
},
getInitialData: function (option, ecModel) {
var edges = option.edges || option.links || [];
var nodes = option.data || option.nodes || [];
var self = this;
if (nodes && edges) {
return Object(__WEBPACK_IMPORTED_MODULE_1__createGraphFromNodeEdge__["a" /* default */])(nodes, edges, this, true, beforeLink).data;
}
function beforeLink(nodeData, edgeData) {
// Overwrite nodeData.getItemModel to
nodeData.wrapMethod('getItemModel', function (model) {
var categoriesModels = self._categoriesModels;
var categoryIdx = model.getShallow('category');
var categoryModel = categoriesModels[categoryIdx];
if (categoryModel) {
categoryModel.parentModel = model.parentModel;
model.parentModel = categoryModel;
}
return model;
});
var edgeLabelModel = self.getModel('edgeLabel');
// For option `edgeLabel` can be found by label.xxx.xxx on item mode.
var fakeSeriesModel = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.Model(
{ label: edgeLabelModel.option },
edgeLabelModel.parentModel,
ecModel
);
edgeData.wrapMethod('getItemModel', function (model) {
model.customizeGetParent(edgeGetParent);
return model;
});
function edgeGetParent(path) {
path = this.parsePath(path);
return (path && path[0] === 'label')
? fakeSeriesModel
: this.parentModel;
}
}
},
/**
* @return {module:echarts/data/Graph}
*/
getGraph: function () {
return this.getData().graph;
},
/**
* @return {module:echarts/data/List}
*/
getEdgeData: function () {
return this.getGraph().edgeData;
},
/**
* @return {module:echarts/data/List}
*/
getCategoriesData: function () {
return this._categoriesData;
},
/**
* @override
*/
formatTooltip: function (dataIndex, multipleSeries, dataType) {
if (dataType === 'edge') {
var nodeData = this.getData();
var params = this.getDataParams(dataIndex, dataType);
var edge = nodeData.graph.getEdgeByIndex(dataIndex);
var sourceName = nodeData.getName(edge.node1.dataIndex);
var targetName = nodeData.getName(edge.node2.dataIndex);
var html = [];
sourceName != null && html.push(sourceName);
targetName != null && html.push(targetName);
html = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.format.encodeHTML(html.join(' > '));
if (params.value) {
html += ' : ' + __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.format.encodeHTML(params.value);
}
return html;
}
else { // dataType === 'node' or empty
return GraphSeries.superApply(this, 'formatTooltip', arguments);
}
},
_updateCategoriesData: function () {
var categories = (this.option.categories || []).map(function (category) {
// Data must has value
return category.value != null ? category : __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.util.extend({
value: 0
}, category);
});
var categoriesData = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.List(['value'], this);
categoriesData.initData(categories);
this._categoriesData = categoriesData;
this._categoriesModels = categoriesData.mapArray(function (idx) {
return categoriesData.getItemModel(idx, true);
});
},
setView: function (payload) {
if (payload.zoom != null) {
this.option.zoom = payload.zoom;
}
if (payload.offset != null) {
this.option.offset = payload.offset;
}
},
setNodePosition: function (points) {
for (var i = 0; i < points.length / 2; i++) {
var x = points[i * 2];
var y = points[i * 2 + 1];
var opt = this.getData().getRawDataItem(i);
opt.x = x;
opt.y = y;
}
},
isAnimationEnabled: function () {
return GraphSeries.superCall(this, 'isAnimationEnabled')
// Not enable animation when do force layout
&& !(this.get('layout') === 'force' && this.get('force.layoutAnimation'));
},
defaultOption: {
zlevel: 10,
z: 2,
legendHoverLink: true,
// Only support forceAtlas2
layout: 'forceAtlas2',
// Configuration of force directed layout
forceAtlas2: {
initLayout: null,
GPU: true,
steps: 1,
// barnesHutOptimize
// Maxp layout steps.
maxSteps: 1000,
repulsionByDegree: true,
linLogMode: false,
strongGravityMode: false,
gravity: 1.0,
// scaling: 1.0,
edgeWeightInfluence: 1.0,
// Edge weight range.
edgeWeight: [1, 4],
// Node weight range.
nodeWeight: [1, 4],
// jitterTolerence: 0.1,
preventOverlap: false,
gravityCenter: null
},
focusNodeAdjacency: true,
focusNodeAdjacencyOn: 'mouseover',
left: 'center',
top: 'center',
// right: null,
// bottom: null,
// width: '80%',
// height: '80%',
symbol: 'circle',
symbolSize: 5,
roam: false,
// Default on center of graph
center: null,
zoom: 1,
// categories: [],
// data: []
// Or
// nodes: []
//
// links: []
// Or
// edges: []
label: {
show: false,
formatter: '{b}',
position: 'right',
distance: 5,
textStyle: {
fontSize: 14
}
},
itemStyle: {},
lineStyle: {
color: '#aaa',
width: 1,
opacity: 0.5
},
emphasis: {
label: {
show: true
}
},
animation: false
}
});
/* unused harmony default export */ var _unused_webpack_default_export = (GraphSeries);
/***/ }),
/* 256 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_data_Graph__ = __webpack_require__(257);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_data_Graph___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_echarts_lib_data_Graph__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_data_helper_linkList__ = __webpack_require__(259);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_echarts_lib_data_helper_linkList___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_echarts_lib_data_helper_linkList__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_retrieve__ = __webpack_require__(3);
/* harmony default export */ __webpack_exports__["a"] = (function (nodes, edges, hostModel, directed, beforeLink) {
var graph = new __WEBPACK_IMPORTED_MODULE_1_echarts_lib_data_Graph___default.a(directed);
for (var i = 0; i < nodes.length; i++) {
graph.addNode(__WEBPACK_IMPORTED_MODULE_3__util_retrieve__["a" /* default */].firstNotNull(
// Id, name, dataIndex
nodes[i].id, nodes[i].name, i
), i);
}
var linkNameList = [];
var validEdges = [];
var linkCount = 0;
for (var i = 0; i < edges.length; i++) {
var link = edges[i];
var source = link.source;
var target = link.target;
// addEdge may fail when source or target not exists
if (graph.addEdge(source, target, linkCount)) {
validEdges.push(link);
linkNameList.push(__WEBPACK_IMPORTED_MODULE_3__util_retrieve__["a" /* default */].firstNotNull(link.id, source + ' > ' + target));
linkCount++;
}
}
var nodeData;
// FIXME, support more coordinate systems.
var dimensionNames = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.helper.completeDimensions(
['value'], nodes
);
nodeData = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.List(dimensionNames, hostModel);
nodeData.initData(nodes);
var edgeData = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.List(['value'], hostModel);
edgeData.initData(validEdges, linkNameList);
beforeLink && beforeLink(nodeData, edgeData);
__WEBPACK_IMPORTED_MODULE_2_echarts_lib_data_helper_linkList___default()({
mainData: nodeData,
struct: graph,
structAttr: 'graph',
datas: {node: nodeData, edge: edgeData},
datasAttr: {node: 'data', edge: 'edgeData'}
});
// Update dataIndex of nodes and edges because invalid edge may be removed
graph.update();
return graph;
});;
/***/ }),
/* 257 */
/***/ (function(module, exports, __webpack_require__) {
var _config = __webpack_require__(97);
var __DEV__ = _config.__DEV__;
var zrUtil = __webpack_require__(12);
var _clazz = __webpack_require__(258);
var enableClassCheck = _clazz.enableClassCheck;
/**
* Graph data structure
*
* @module echarts/data/Graph
* @author Yi Shen(https://www.github.com/pissang)
*/
// id may be function name of Object, add a prefix to avoid this problem.
function generateNodeKey(id) {
return '_EC_' + id;
}
/**
* @alias module:echarts/data/Graph
* @constructor
* @param {boolean} directed
*/
var Graph = function (directed) {
/**
* 是否是有向图
* @type {boolean}
* @private
*/
this._directed = directed || false;
/**
* @type {Array.}
* @readOnly
*/
this.nodes = [];
/**
* @type {Array.}
* @readOnly
*/
this.edges = [];
/**
* @type {Object.}
* @private
*/
this._nodesMap = {};
/**
* @type {Object.}
* @private
*/
this._edgesMap = {};
/**
* @type {module:echarts/data/List}
* @readOnly
*/
this.data;
/**
* @type {module:echarts/data/List}
* @readOnly
*/
this.edgeData;
};
var graphProto = Graph.prototype;
/**
* @type {string}
*/
graphProto.type = 'graph';
/**
* If is directed graph
* @return {boolean}
*/
graphProto.isDirected = function () {
return this._directed;
};
/**
* Add a new node
* @param {string} id
* @param {number} [dataIndex]
*/
graphProto.addNode = function (id, dataIndex) {
id = id || '' + dataIndex;
var nodesMap = this._nodesMap;
if (nodesMap[generateNodeKey(id)]) {
return;
}
var node = new Node(id, dataIndex);
node.hostGraph = this;
this.nodes.push(node);
nodesMap[generateNodeKey(id)] = node;
return node;
};
/**
* Get node by data index
* @param {number} dataIndex
* @return {module:echarts/data/Graph~Node}
*/
graphProto.getNodeByIndex = function (dataIndex) {
var rawIdx = this.data.getRawIndex(dataIndex);
return this.nodes[rawIdx];
};
/**
* Get node by id
* @param {string} id
* @return {module:echarts/data/Graph.Node}
*/
graphProto.getNodeById = function (id) {
return this._nodesMap[generateNodeKey(id)];
};
/**
* Add a new edge
* @param {number|string|module:echarts/data/Graph.Node} n1
* @param {number|string|module:echarts/data/Graph.Node} n2
* @param {number} [dataIndex=-1]
* @return {module:echarts/data/Graph.Edge}
*/
graphProto.addEdge = function (n1, n2, dataIndex) {
var nodesMap = this._nodesMap;
var edgesMap = this._edgesMap; // PNEDING
if (typeof n1 === 'number') {
n1 = this.nodes[n1];
}
if (typeof n2 === 'number') {
n2 = this.nodes[n2];
}
if (!Node.isInstance(n1)) {
n1 = nodesMap[generateNodeKey(n1)];
}
if (!Node.isInstance(n2)) {
n2 = nodesMap[generateNodeKey(n2)];
}
if (!n1 || !n2) {
return;
}
var key = n1.id + '-' + n2.id; // PENDING
if (edgesMap[key]) {
return;
}
var edge = new Edge(n1, n2, dataIndex);
edge.hostGraph = this;
if (this._directed) {
n1.outEdges.push(edge);
n2.inEdges.push(edge);
}
n1.edges.push(edge);
if (n1 !== n2) {
n2.edges.push(edge);
}
this.edges.push(edge);
edgesMap[key] = edge;
return edge;
};
/**
* Get edge by data index
* @param {number} dataIndex
* @return {module:echarts/data/Graph~Node}
*/
graphProto.getEdgeByIndex = function (dataIndex) {
var rawIdx = this.edgeData.getRawIndex(dataIndex);
return this.edges[rawIdx];
};
/**
* Get edge by two linked nodes
* @param {module:echarts/data/Graph.Node|string} n1
* @param {module:echarts/data/Graph.Node|string} n2
* @return {module:echarts/data/Graph.Edge}
*/
graphProto.getEdge = function (n1, n2) {
if (Node.isInstance(n1)) {
n1 = n1.id;
}
if (Node.isInstance(n2)) {
n2 = n2.id;
}
var edgesMap = this._edgesMap;
if (this._directed) {
return edgesMap[n1 + '-' + n2];
} else {
return edgesMap[n1 + '-' + n2] || edgesMap[n2 + '-' + n1];
}
};
/**
* Iterate all nodes
* @param {Function} cb
* @param {*} [context]
*/
graphProto.eachNode = function (cb, context) {
var nodes = this.nodes;
var len = nodes.length;
for (var i = 0; i < len; i++) {
if (nodes[i].dataIndex >= 0) {
cb.call(context, nodes[i], i);
}
}
};
/**
* Iterate all edges
* @param {Function} cb
* @param {*} [context]
*/
graphProto.eachEdge = function (cb, context) {
var edges = this.edges;
var len = edges.length;
for (var i = 0; i < len; i++) {
if (edges[i].dataIndex >= 0 && edges[i].node1.dataIndex >= 0 && edges[i].node2.dataIndex >= 0) {
cb.call(context, edges[i], i);
}
}
};
/**
* Breadth first traverse
* @param {Function} cb
* @param {module:echarts/data/Graph.Node} startNode
* @param {string} [direction='none'] 'none'|'in'|'out'
* @param {*} [context]
*/
graphProto.breadthFirstTraverse = function (cb, startNode, direction, context) {
if (!Node.isInstance(startNode)) {
startNode = this._nodesMap[generateNodeKey(startNode)];
}
if (!startNode) {
return;
}
var edgeType = direction === 'out' ? 'outEdges' : direction === 'in' ? 'inEdges' : 'edges';
for (var i = 0; i < this.nodes.length; i++) {
this.nodes[i].__visited = false;
}
if (cb.call(context, startNode, null)) {
return;
}
var queue = [startNode];
while (queue.length) {
var currentNode = queue.shift();
var edges = currentNode[edgeType];
for (var i = 0; i < edges.length; i++) {
var e = edges[i];
var otherNode = e.node1 === currentNode ? e.node2 : e.node1;
if (!otherNode.__visited) {
if (cb.call(context, otherNode, currentNode)) {
// Stop traversing
return;
}
queue.push(otherNode);
otherNode.__visited = true;
}
}
}
}; // TODO
// graphProto.depthFirstTraverse = function (
// cb, startNode, direction, context
// ) {
// };
// Filter update
graphProto.update = function () {
var data = this.data;
var edgeData = this.edgeData;
var nodes = this.nodes;
var edges = this.edges;
for (var i = 0, len = nodes.length; i < len; i++) {
nodes[i].dataIndex = -1;
}
for (var i = 0, len = data.count(); i < len; i++) {
nodes[data.getRawIndex(i)].dataIndex = i;
}
edgeData.filterSelf(function (idx) {
var edge = edges[edgeData.getRawIndex(idx)];
return edge.node1.dataIndex >= 0 && edge.node2.dataIndex >= 0;
}); // Update edge
for (var i = 0, len = edges.length; i < len; i++) {
edges[i].dataIndex = -1;
}
for (var i = 0, len = edgeData.count(); i < len; i++) {
edges[edgeData.getRawIndex(i)].dataIndex = i;
}
};
/**
* @return {module:echarts/data/Graph}
*/
graphProto.clone = function () {
var graph = new Graph(this._directed);
var nodes = this.nodes;
var edges = this.edges;
for (var i = 0; i < nodes.length; i++) {
graph.addNode(nodes[i].id, nodes[i].dataIndex);
}
for (var i = 0; i < edges.length; i++) {
var e = edges[i];
graph.addEdge(e.node1.id, e.node2.id, e.dataIndex);
}
return graph;
};
/**
* @alias module:echarts/data/Graph.Node
*/
function Node(id, dataIndex) {
/**
* @type {string}
*/
this.id = id == null ? '' : id;
/**
* @type {Array.}
*/
this.inEdges = [];
/**
* @type {Array.}
*/
this.outEdges = [];
/**
* @type {Array.}
*/
this.edges = [];
/**
* @type {module:echarts/data/Graph}
*/
this.hostGraph;
/**
* @type {number}
*/
this.dataIndex = dataIndex == null ? -1 : dataIndex;
}
Node.prototype = {
constructor: Node,
/**
* @return {number}
*/
degree: function () {
return this.edges.length;
},
/**
* @return {number}
*/
inDegree: function () {
return this.inEdges.length;
},
/**
* @return {number}
*/
outDegree: function () {
return this.outEdges.length;
},
/**
* @param {string} [path]
* @return {module:echarts/model/Model}
*/
getModel: function (path) {
if (this.dataIndex < 0) {
return;
}
var graph = this.hostGraph;
var itemModel = graph.data.getItemModel(this.dataIndex);
return itemModel.getModel(path);
}
};
/**
* 图边
* @alias module:echarts/data/Graph.Edge
* @param {module:echarts/data/Graph.Node} n1
* @param {module:echarts/data/Graph.Node} n2
* @param {number} [dataIndex=-1]
*/
function Edge(n1, n2, dataIndex) {
/**
* 节点1,如果是有向图则为源节点
* @type {module:echarts/data/Graph.Node}
*/
this.node1 = n1;
/**
* 节点2,如果是有向图则为目标节点
* @type {module:echarts/data/Graph.Node}
*/
this.node2 = n2;
this.dataIndex = dataIndex == null ? -1 : dataIndex;
}
/**
* @param {string} [path]
* @return {module:echarts/model/Model}
*/
Edge.prototype.getModel = function (path) {
if (this.dataIndex < 0) {
return;
}
var graph = this.hostGraph;
var itemModel = graph.edgeData.getItemModel(this.dataIndex);
return itemModel.getModel(path);
};
var createGraphDataProxyMixin = function (hostName, dataName) {
return {
/**
* @param {string=} [dimension='value'] Default 'value'. can be 'a', 'b', 'c', 'd', 'e'.
* @return {number}
*/
getValue: function (dimension) {
var data = this[hostName][dataName];
return data.get(data.getDimension(dimension || 'value'), this.dataIndex);
},
/**
* @param {Object|string} key
* @param {*} [value]
*/
setVisual: function (key, value) {
this.dataIndex >= 0 && this[hostName][dataName].setItemVisual(this.dataIndex, key, value);
},
/**
* @param {string} key
* @return {boolean}
*/
getVisual: function (key, ignoreParent) {
return this[hostName][dataName].getItemVisual(this.dataIndex, key, ignoreParent);
},
/**
* @param {Object} layout
* @return {boolean} [merge=false]
*/
setLayout: function (layout, merge) {
this.dataIndex >= 0 && this[hostName][dataName].setItemLayout(this.dataIndex, layout, merge);
},
/**
* @return {Object}
*/
getLayout: function () {
return this[hostName][dataName].getItemLayout(this.dataIndex);
},
/**
* @return {module:zrender/Element}
*/
getGraphicEl: function () {
return this[hostName][dataName].getItemGraphicEl(this.dataIndex);
},
/**
* @return {number}
*/
getRawIndex: function () {
return this[hostName][dataName].getRawIndex(this.dataIndex);
}
};
};
zrUtil.mixin(Node, createGraphDataProxyMixin('hostGraph', 'data'));
zrUtil.mixin(Edge, createGraphDataProxyMixin('hostGraph', 'edgeData'));
Graph.Node = Node;
Graph.Edge = Edge;
enableClassCheck(Node);
enableClassCheck(Edge);
var _default = Graph;
module.exports = _default;
/***/ }),
/* 258 */
/***/ (function(module, exports, __webpack_require__) {
var _config = __webpack_require__(97);
var __DEV__ = _config.__DEV__;
var zrUtil = __webpack_require__(12);
var TYPE_DELIMITER = '.';
var IS_CONTAINER = '___EC__COMPONENT__CONTAINER___';
/**
* Notice, parseClassType('') should returns {main: '', sub: ''}
* @public
*/
function parseClassType(componentType) {
var ret = {
main: '',
sub: ''
};
if (componentType) {
componentType = componentType.split(TYPE_DELIMITER);
ret.main = componentType[0] || '';
ret.sub = componentType[1] || '';
}
return ret;
}
/**
* @public
*/
function checkClassType(componentType) {
zrUtil.assert(/^[a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)?$/.test(componentType), 'componentType "' + componentType + '" illegal');
}
/**
* @public
*/
function enableClassExtend(RootClass, mandatoryMethods) {
RootClass.$constructor = RootClass;
RootClass.extend = function (proto) {
var superClass = this;
var ExtendedClass = function () {
if (!proto.$constructor) {
superClass.apply(this, arguments);
} else {
proto.$constructor.apply(this, arguments);
}
};
zrUtil.extend(ExtendedClass.prototype, proto);
ExtendedClass.extend = this.extend;
ExtendedClass.superCall = superCall;
ExtendedClass.superApply = superApply;
zrUtil.inherits(ExtendedClass, this);
ExtendedClass.superClass = superClass;
return ExtendedClass;
};
}
var classBase = 0;
/**
* Can not use instanceof, consider different scope by
* cross domain or es module import in ec extensions.
* Mount a method "isInstance()" to Clz.
*/
function enableClassCheck(Clz) {
var classAttr = ['__\0is_clz', classBase++, Math.random().toFixed(3)].join('_');
Clz.prototype[classAttr] = true;
Clz.isInstance = function (obj) {
return !!(obj && obj[classAttr]);
};
} // superCall should have class info, which can not be fetch from 'this'.
// Consider this case:
// class A has method f,
// class B inherits class A, overrides method f, f call superApply('f'),
// class C inherits class B, do not overrides method f,
// then when method of class C is called, dead loop occured.
function superCall(context, methodName) {
var args = zrUtil.slice(arguments, 2);
return this.superClass.prototype[methodName].apply(context, args);
}
function superApply(context, methodName, args) {
return this.superClass.prototype[methodName].apply(context, args);
}
/**
* @param {Object} entity
* @param {Object} options
* @param {boolean} [options.registerWhenExtend]
* @public
*/
function enableClassManagement(entity, options) {
options = options || {};
/**
* Component model classes
* key: componentType,
* value:
* componentClass, when componentType is 'xxx'
* or Object., when componentType is 'xxx.yy'
* @type {Object}
*/
var storage = {};
entity.registerClass = function (Clazz, componentType) {
if (componentType) {
checkClassType(componentType);
componentType = parseClassType(componentType);
if (!componentType.sub) {
storage[componentType.main] = Clazz;
} else if (componentType.sub !== IS_CONTAINER) {
var container = makeContainer(componentType);
container[componentType.sub] = Clazz;
}
}
return Clazz;
};
entity.getClass = function (componentMainType, subType, throwWhenNotFound) {
var Clazz = storage[componentMainType];
if (Clazz && Clazz[IS_CONTAINER]) {
Clazz = subType ? Clazz[subType] : null;
}
if (throwWhenNotFound && !Clazz) {
throw new Error(!subType ? componentMainType + '.' + 'type should be specified.' : 'Component ' + componentMainType + '.' + (subType || '') + ' not exists. Load it first.');
}
return Clazz;
};
entity.getClassesByMainType = function (componentType) {
componentType = parseClassType(componentType);
var result = [];
var obj = storage[componentType.main];
if (obj && obj[IS_CONTAINER]) {
zrUtil.each(obj, function (o, type) {
type !== IS_CONTAINER && result.push(o);
});
} else {
result.push(obj);
}
return result;
};
entity.hasClass = function (componentType) {
// Just consider componentType.main.
componentType = parseClassType(componentType);
return !!storage[componentType.main];
};
/**
* @return {Array.} Like ['aa', 'bb'], but can not be ['aa.xx']
*/
entity.getAllClassMainTypes = function () {
var types = [];
zrUtil.each(storage, function (obj, type) {
types.push(type);
});
return types;
};
/**
* If a main type is container and has sub types
* @param {string} mainType
* @return {boolean}
*/
entity.hasSubTypes = function (componentType) {
componentType = parseClassType(componentType);
var obj = storage[componentType.main];
return obj && obj[IS_CONTAINER];
};
entity.parseClassType = parseClassType;
function makeContainer(componentType) {
var container = storage[componentType.main];
if (!container || !container[IS_CONTAINER]) {
container = storage[componentType.main] = {};
container[IS_CONTAINER] = true;
}
return container;
}
if (options.registerWhenExtend) {
var originalExtend = entity.extend;
if (originalExtend) {
entity.extend = function (proto) {
var ExtendedClass = originalExtend.call(this, proto);
return entity.registerClass(ExtendedClass, proto.type);
};
}
}
return entity;
}
/**
* @param {string|Array.} properties
*/
function setReadOnly(obj, properties) {// FIXME It seems broken in IE8 simulation of IE11
// if (!zrUtil.isArray(properties)) {
// properties = properties != null ? [properties] : [];
// }
// zrUtil.each(properties, function (prop) {
// var value = obj[prop];
// Object.defineProperty
// && Object.defineProperty(obj, prop, {
// value: value, writable: false
// });
// zrUtil.isArray(obj[prop])
// && Object.freeze
// && Object.freeze(obj[prop]);
// });
}
exports.parseClassType = parseClassType;
exports.enableClassExtend = enableClassExtend;
exports.enableClassCheck = enableClassCheck;
exports.enableClassManagement = enableClassManagement;
exports.setReadOnly = setReadOnly;
/***/ }),
/* 259 */
/***/ (function(module, exports, __webpack_require__) {
var zrUtil = __webpack_require__(12);
/**
* Link lists and struct (graph or tree)
*/
var each = zrUtil.each;
var DATAS = '\0__link_datas';
var MAIN_DATA = '\0__link_mainData'; // Caution:
// In most case, either list or its shallow clones (see list.cloneShallow)
// is active in echarts process. So considering heap memory consumption,
// we do not clone tree or graph, but share them among list and its shallow clones.
// But in some rare case, we have to keep old list (like do animation in chart). So
// please take care that both the old list and the new list share the same tree/graph.
/**
* @param {Object} opt
* @param {module:echarts/data/List} opt.mainData
* @param {Object} [opt.struct] For example, instance of Graph or Tree.
* @param {string} [opt.structAttr] designation: list[structAttr] = struct;
* @param {Object} [opt.datas] {dataType: data},
* like: {node: nodeList, edge: edgeList}.
* Should contain mainData.
* @param {Object} [opt.datasAttr] {dataType: attr},
* designation: struct[datasAttr[dataType]] = list;
*/
function linkList(opt) {
var mainData = opt.mainData;
var datas = opt.datas;
if (!datas) {
datas = {
main: mainData
};
opt.datasAttr = {
main: 'data'
};
}
opt.datas = opt.mainData = null;
linkAll(mainData, datas, opt); // Porxy data original methods.
each(datas, function (data) {
each(mainData.TRANSFERABLE_METHODS, function (methodName) {
data.wrapMethod(methodName, zrUtil.curry(transferInjection, opt));
});
}); // Beyond transfer, additional features should be added to `cloneShallow`.
mainData.wrapMethod('cloneShallow', zrUtil.curry(cloneShallowInjection, opt)); // Only mainData trigger change, because struct.update may trigger
// another changable methods, which may bring about dead lock.
each(mainData.CHANGABLE_METHODS, function (methodName) {
mainData.wrapMethod(methodName, zrUtil.curry(changeInjection, opt));
}); // Make sure datas contains mainData.
zrUtil.assert(datas[mainData.dataType] === mainData);
}
function transferInjection(opt, res) {
if (isMainData(this)) {
// Transfer datas to new main data.
var datas = zrUtil.extend({}, this[DATAS]);
datas[this.dataType] = res;
linkAll(res, datas, opt);
} else {
// Modify the reference in main data to point newData.
linkSingle(res, this.dataType, this[MAIN_DATA], opt);
}
return res;
}
function changeInjection(opt, res) {
opt.struct && opt.struct.update(this);
return res;
}
function cloneShallowInjection(opt, res) {
// cloneShallow, which brings about some fragilities, may be inappropriate
// to be exposed as an API. So for implementation simplicity we can make
// the restriction that cloneShallow of not-mainData should not be invoked
// outside, but only be invoked here.
each(res[DATAS], function (data, dataType) {
data !== res && linkSingle(data.cloneShallow(), dataType, res, opt);
});
return res;
}
/**
* Supplement method to List.
*
* @public
* @param {string} [dataType] If not specified, return mainData.
* @return {module:echarts/data/List}
*/
function getLinkedData(dataType) {
var mainData = this[MAIN_DATA];
return dataType == null || mainData == null ? mainData : mainData[DATAS][dataType];
}
function isMainData(data) {
return data[MAIN_DATA] === data;
}
function linkAll(mainData, datas, opt) {
mainData[DATAS] = {};
each(datas, function (data, dataType) {
linkSingle(data, dataType, mainData, opt);
});
}
function linkSingle(data, dataType, mainData, opt) {
mainData[DATAS][dataType] = data;
data[MAIN_DATA] = mainData;
data.dataType = dataType;
if (opt.struct) {
data[opt.structAttr] = opt.struct;
opt.struct[opt.datasAttr[dataType]] = data;
} // Supplement method.
data.getLinkedData = getLinkedData;
}
var _default = linkList;
module.exports = _default;
/***/ }),
/* 260 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_util_layout__ = __webpack_require__(41);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_util_layout___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_echarts_lib_util_layout__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__core_ViewGL__ = __webpack_require__(19);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_geometry_Lines2D__ = __webpack_require__(98);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__util_retrieve__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__ForceAtlas2GPU__ = __webpack_require__(261);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__ForceAtlas2__ = __webpack_require__(263);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8_zrender_lib_animation_requestAnimationFrame__ = __webpack_require__(72);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8_zrender_lib_animation_requestAnimationFrame___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_8_zrender_lib_animation_requestAnimationFrame__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9_claygl_src_dep_glmatrix__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9_claygl_src_dep_glmatrix___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_9_claygl_src_dep_glmatrix__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__util_Roam2DControl__ = __webpack_require__(265);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__common_PointsBuilder__ = __webpack_require__(62);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__util_shader_lines2D_glsl_js__ = __webpack_require__(266);
var vec2 = __WEBPACK_IMPORTED_MODULE_9_claygl_src_dep_glmatrix___default.a.vec2;
__WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].Shader.import(__WEBPACK_IMPORTED_MODULE_12__util_shader_lines2D_glsl_js__["a" /* default */]);
var globalLayoutId = 1;
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendChartView({
type: 'graphGL',
__ecgl__: true,
init: function (ecModel, api) {
this.groupGL = new __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].Node();
this.viewGL = new __WEBPACK_IMPORTED_MODULE_3__core_ViewGL__["a" /* default */]('orthographic');
this.viewGL.camera.left = this.viewGL.camera.right = 0;
this.viewGL.add(this.groupGL);
this._pointsBuilder = new __WEBPACK_IMPORTED_MODULE_11__common_PointsBuilder__["a" /* default */](true, api);
// Mesh used during force directed layout.
this._forceEdgesMesh = new __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].Mesh({
material: new __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].Material({
shader: __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].createShader('ecgl.forceAtlas2.edges'),
transparent: true,
depthMask: false,
depthTest: false
}),
$ignorePicking: true,
geometry: new __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].Geometry({
attributes: {
node: new __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].Geometry.Attribute('node', 'float', 2),
color: new __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].Geometry.Attribute('color', 'float', 4, 'COLOR')
},
dynamic: true,
mainAttribute: 'node'
}),
renderOrder: -1,
mode: __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].Mesh.LINES
});
// Mesh used after force directed layout.
this._edgesMesh = new __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].Mesh({
material: new __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].Material({
shader: __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].createShader('ecgl.meshLines2D'),
transparent: true,
depthMask: false,
depthTest: false
}),
$ignorePicking: true,
geometry: new __WEBPACK_IMPORTED_MODULE_4__util_geometry_Lines2D__["a" /* default */]({
useNativeLine: false,
dynamic: true
}),
renderOrder: -1,
culling: false
});
this._layoutId = 0;
this._control = new __WEBPACK_IMPORTED_MODULE_10__util_Roam2DControl__["a" /* default */]({
zr: api.getZr(),
viewGL: this.viewGL
});
this._control.setTarget(this.groupGL);
this._control.init();
this._clickHandler = this._clickHandler.bind(this);
},
render: function (seriesModel, ecModel, api) {
this.groupGL.add(this._pointsBuilder.rootNode);
this._model = seriesModel;
this._api = api;
this._initLayout(seriesModel, ecModel, api);
this._pointsBuilder.update(seriesModel, ecModel, api);
if (!(this._forceLayoutInstance instanceof __WEBPACK_IMPORTED_MODULE_6__ForceAtlas2GPU__["a" /* default */])) {
this.groupGL.remove(this._forceEdgesMesh);
}
this._updateCamera(seriesModel, api);
this._control.off('update');
this._control.on('update', function () {
api.dispatchAction({
type: 'graphGLRoam',
seriesId: seriesModel.id,
zoom: this._control.getZoom(),
offset: this._control.getOffset()
});
this._pointsBuilder.updateView(this.viewGL.camera);
}, this);
this._control.setZoom(__WEBPACK_IMPORTED_MODULE_5__util_retrieve__["a" /* default */].firstNotNull(seriesModel.get('zoom'), 1));
this._control.setOffset(seriesModel.get('offset') || [0, 0]);
var mesh = this._pointsBuilder.getPointsMesh();
mesh.off('mousemove', this._mousemoveHandler);
mesh.off('mouseout', this._mouseOutHandler, this);
api.getZr().off('click', this._clickHandler);
this._pointsBuilder.highlightOnMouseover = true;
if (seriesModel.get('focusNodeAdjacency')) {
var focusNodeAdjacencyOn = seriesModel.get('focusNodeAdjacencyOn');
if (focusNodeAdjacencyOn === 'click') {
// Remove default emphasis effect
api.getZr().on('click', this._clickHandler);
}
else if (focusNodeAdjacencyOn === 'mouseover') {
mesh.on('mousemove', this._mousemoveHandler, this);
mesh.on('mouseout', this._mouseOutHandler, this);
this._pointsBuilder.highlightOnMouseover = false;
}
else {
if (true) {
console.warn('Unkown focusNodeAdjacencyOn value \s' + focusNodeAdjacencyOn);
}
}
}
// Reset
this._lastMouseOverDataIndex = -1;
},
_clickHandler: function (e) {
if (this._layouting) {
return;
}
var dataIndex = this._pointsBuilder.getPointsMesh().dataIndex;
if (dataIndex >= 0) {
this._api.dispatchAction({
type: 'graphGLFocusNodeAdjacency',
seriesId: this._model.id,
dataIndex: dataIndex
});
}
else {
this._api.dispatchAction({
type: 'graphGLUnfocusNodeAdjacency',
seriesId: this._model.id
});
}
},
_mousemoveHandler: function (e) {
if (this._layouting) {
return;
}
var dataIndex = this._pointsBuilder.getPointsMesh().dataIndex;
if (dataIndex >= 0) {
if (dataIndex !== this._lastMouseOverDataIndex) {
this._api.dispatchAction({
type: 'graphGLFocusNodeAdjacency',
seriesId: this._model.id,
dataIndex: dataIndex
});
}
}
else {
this._mouseOutHandler(e);
}
this._lastMouseOverDataIndex = dataIndex;
},
_mouseOutHandler: function (e) {
if (this._layouting) {
return;
}
this._api.dispatchAction({
type: 'graphGLUnfocusNodeAdjacency',
seriesId: this._model.id
});
this._lastMouseOverDataIndex = -1;
},
_updateForceEdgesGeometry: function (edges, seriesModel) {
var geometry = this._forceEdgesMesh.geometry;
var edgeData = seriesModel.getEdgeData();
var offset = 0;
var layoutInstance = this._forceLayoutInstance;
var vertexCount = edgeData.count() * 2;
geometry.attributes.node.init(vertexCount);
geometry.attributes.color.init(vertexCount);
edgeData.each(function (idx) {
var edge = edges[idx];
geometry.attributes.node.set(offset, layoutInstance.getNodeUV(edge.node1));
geometry.attributes.node.set(offset + 1, layoutInstance.getNodeUV(edge.node2));
var color = edgeData.getItemVisual(edge.dataIndex, 'color');
var colorArr = __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].parseColor(color);
colorArr[3] *= __WEBPACK_IMPORTED_MODULE_5__util_retrieve__["a" /* default */].firstNotNull(
edgeData.getItemVisual(edge.dataIndex, 'opacity'), 1
);
geometry.attributes.color.set(offset, colorArr);
geometry.attributes.color.set(offset + 1, colorArr);
offset += 2;
});
geometry.dirty();
},
_updateMeshLinesGeometry: function () {
var edgeData = this._model.getEdgeData();
var geometry = this._edgesMesh.geometry;
var edgeData = this._model.getEdgeData();
var points = this._model.getData().getLayout('points');
geometry.resetOffset();
geometry.setVertexCount(edgeData.count() * geometry.getLineVertexCount());
geometry.setTriangleCount(edgeData.count() * geometry.getLineTriangleCount());
var p0 = [];
var p1 = [];
var lineWidthQuery = ['lineStyle', 'width'];
this._originalEdgeColors = new Float32Array(edgeData.count() * 4);
this._edgeIndicesMap = new Float32Array(edgeData.count());
edgeData.each(function (idx) {
var edge = edgeData.graph.getEdgeByIndex(idx);
var idx1 = edge.node1.dataIndex * 2;
var idx2 = edge.node2.dataIndex * 2;
p0[0] = points[idx1];
p0[1] = points[idx1 + 1];
p1[0] = points[idx2];
p1[1] = points[idx2 + 1];
var color = edgeData.getItemVisual(edge.dataIndex, 'color');
var colorArr = __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].parseColor(color);
colorArr[3] *= __WEBPACK_IMPORTED_MODULE_5__util_retrieve__["a" /* default */].firstNotNull(edgeData.getItemVisual(edge.dataIndex, 'opacity'), 1);
var itemModel = edgeData.getItemModel(edge.dataIndex);
var lineWidth = __WEBPACK_IMPORTED_MODULE_5__util_retrieve__["a" /* default */].firstNotNull(itemModel.get(lineWidthQuery), 1) * this._api.getDevicePixelRatio();
geometry.addLine(p0, p1, colorArr, lineWidth);
for (var k = 0; k < 4; k++) {
this._originalEdgeColors[edge.dataIndex * 4 + k] = colorArr[k];
}
this._edgeIndicesMap[edge.dataIndex] = idx;
}, this);
geometry.dirty();
},
_updateForceNodesGeometry: function (nodeData) {
var pointsMesh = this._pointsBuilder.getPointsMesh();
var pos = [];
for (var i = 0; i < nodeData.count(); i++) {
this._forceLayoutInstance.getNodeUV(i, pos);
pointsMesh.geometry.attributes.position.set(i, pos);
}
pointsMesh.geometry.dirty('position');
},
_initLayout: function (seriesModel, ecModel, api) {
var layout = seriesModel.get('layout');
var graph = seriesModel.getGraph();
var boxLayoutOption = seriesModel.getBoxLayoutParams();
var viewport = __WEBPACK_IMPORTED_MODULE_1_echarts_lib_util_layout___default.a.getLayoutRect(boxLayoutOption, {
width: api.getWidth(),
height: api.getHeight()
});
if (layout === 'force') {
if (true) {
console.warn('Currently only forceAtlas2 layout supported.');
}
layout = 'forceAtlas2';
}
// Stop previous layout
this.stopLayout(seriesModel, ecModel, api, {
beforeLayout: true
});
var nodeData = seriesModel.getData();
var edgeData = seriesModel.getData();
if (layout === 'forceAtlas2') {
var layoutModel = seriesModel.getModel('forceAtlas2');
var layoutInstance = this._forceLayoutInstance;
var nodes = [];
var edges = [];
var nodeDataExtent = nodeData.getDataExtent('value');
var edgeDataExtent = edgeData.getDataExtent('value');
var edgeWeightRange = __WEBPACK_IMPORTED_MODULE_5__util_retrieve__["a" /* default */].firstNotNull(layoutModel.get('edgeWeight'), 1.0);
var nodeWeightRange = __WEBPACK_IMPORTED_MODULE_5__util_retrieve__["a" /* default */].firstNotNull(layoutModel.get('nodeWeight'), 1.0);
if (typeof edgeWeightRange === 'number') {
edgeWeightRange = [edgeWeightRange, edgeWeightRange];
}
if (typeof nodeWeightRange === 'number') {
nodeWeightRange = [nodeWeightRange, nodeWeightRange];
}
var offset = 0;
var nodesIndicesMap = {};
var layoutPoints = new Float32Array(nodeData.count() * 2);
graph.eachNode(function (node) {
var dataIndex = node.dataIndex;
var value = nodeData.get('value', dataIndex);
var x;
var y;
if (nodeData.hasItemOption) {
var itemModel = nodeData.getItemModel(dataIndex);
x = itemModel.get('x');
y = itemModel.get('y');
}
if (x == null) {
// Random in rectangle
x = viewport.x + Math.random() * viewport.width;
y = viewport.y + Math.random() * viewport.height;
}
layoutPoints[offset * 2] = x;
layoutPoints[offset * 2 + 1] = y;
nodesIndicesMap[node.id] = offset++;
var mass = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.number.linearMap(value, nodeDataExtent, nodeWeightRange);
if (isNaN(mass)) {
if (!isNaN(nodeWeightRange[0])) {
mass = nodeWeightRange[0];
}
else {
mass = 1;
}
}
nodes.push({
x: x, y: y, mass: mass, size: nodeData.getItemVisual(dataIndex, 'symbolSize')
});
});
nodeData.setLayout('points', layoutPoints);
graph.eachEdge(function (edge) {
var dataIndex = edge.dataIndex;
var value = nodeData.get('value', dataIndex);
var weight = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.number.linearMap(value, edgeDataExtent, edgeWeightRange);
if (isNaN(weight)) {
if (!isNaN(edgeWeightRange[0])) {
weight = edgeWeightRange[0];
}
else {
weight = 1;
}
}
edges.push({
node1: nodesIndicesMap[edge.node1.id],
node2: nodesIndicesMap[edge.node2.id],
weight: weight,
dataIndex: dataIndex
});
});
if (!layoutInstance) {
var isGPU = layoutModel.get('GPU');
if (this._forceLayoutInstance) {
if ((isGPU && !(this._forceLayoutInstance instanceof __WEBPACK_IMPORTED_MODULE_6__ForceAtlas2GPU__["a" /* default */]))
|| (!isGPU && !(this._forceLayoutInstance instanceof __WEBPACK_IMPORTED_MODULE_7__ForceAtlas2__["a" /* default */]))
) {
// Mark to dispose
this._forceLayoutInstanceToDispose = this._forceLayoutInstance;
}
}
layoutInstance = this._forceLayoutInstance = isGPU
? new __WEBPACK_IMPORTED_MODULE_6__ForceAtlas2GPU__["a" /* default */]()
: new __WEBPACK_IMPORTED_MODULE_7__ForceAtlas2__["a" /* default */]();
}
layoutInstance.initData(nodes, edges);
layoutInstance.updateOption(layoutModel.option);
// Update lines geometry after first layout;
this._updateForceEdgesGeometry(layoutInstance.getEdges(), seriesModel);
this._updatePositionTexture();
api.dispatchAction({
type: 'graphGLStartLayout',
from: this.uid
});
}
else {
var layoutPoints = new Float32Array(nodeData.count() * 2);
var offset = 0;
graph.eachNode(function (node) {
var dataIndex = node.dataIndex;
var x;
var y;
if (nodeData.hasItemOption) {
var itemModel = nodeData.getItemModel(dataIndex);
x = itemModel.get('x');
y = itemModel.get('y');
}
layoutPoints[offset++] = x;
layoutPoints[offset++] = y;
});
nodeData.setLayout('points', layoutPoints);
this._updateAfterLayout(seriesModel, ecModel, api);
}
},
_updatePositionTexture: function () {
var positionTex = this._forceLayoutInstance.getNodePositionTexture();
this._pointsBuilder.setPositionTexture(positionTex);
this._forceEdgesMesh.material.set('positionTex', positionTex);
},
startLayout: function (seriesModel, ecModel, api, payload) {
if (payload && payload.from != null && payload.from !== this.uid) {
return;
}
var viewGL = this.viewGL;
var api = this._api;
var layoutInstance = this._forceLayoutInstance;
var data = this._model.getData();
var layoutModel = this._model.getModel('forceAtlas2');
if (!layoutInstance) {
if (true) {
console.error('None layout don\'t have startLayout action');
}
return;
}
this.groupGL.remove(this._edgesMesh);
this.groupGL.add(this._forceEdgesMesh);
if (!this._forceLayoutInstance) {
return;
}
this._updateForceNodesGeometry(seriesModel.getData());
this._pointsBuilder.hideLabels();
var self = this;
var layoutId = this._layoutId = globalLayoutId++;
var maxSteps = layoutModel.getShallow('maxSteps');
var steps = layoutModel.getShallow('steps');
var stepsCount = 0;
var syncStepCount = Math.max(steps * 2, 20);
var doLayout = function (layoutId) {
if (layoutId !== self._layoutId) {
return;
}
if (layoutInstance.isFinished(maxSteps)) {
api.dispatchAction({
type: 'graphGLStopLayout',
from: self.uid
});
api.dispatchAction({
type: 'graphGLFinishLayout',
points: data.getLayout('points'),
from: self.uid
});
return;
}
layoutInstance.update(viewGL.layer.renderer, steps, function () {
self._updatePositionTexture();
// PENDING Performance.
stepsCount += steps;
// Sync posiiton every 20 steps.
if (stepsCount >= syncStepCount) {
self._syncNodePosition(seriesModel);
stepsCount = 0;
}
// Position texture will been swapped. set every time.
api.getZr().refresh();
__WEBPACK_IMPORTED_MODULE_8_zrender_lib_animation_requestAnimationFrame___default()(function () {
doLayout(layoutId);
});
});
};
__WEBPACK_IMPORTED_MODULE_8_zrender_lib_animation_requestAnimationFrame___default()(function () {
if (self._forceLayoutInstanceToDispose) {
self._forceLayoutInstanceToDispose.dispose(viewGL.layer.renderer);
self._forceLayoutInstanceToDispose = null;
}
doLayout(layoutId);
});
this._layouting = true;
},
stopLayout: function (seriesModel, ecModel, api, payload) {
if (payload && payload.from != null && payload.from !== this.uid) {
return;
}
this._layoutId = 0;
this.groupGL.remove(this._forceEdgesMesh);
this.groupGL.add(this._edgesMesh);
if (!this._forceLayoutInstance) {
return;
}
if (!this.viewGL.layer) {
return;
}
if (!(payload && payload.beforeLayout)) {
this._syncNodePosition(seriesModel);
this._updateAfterLayout(seriesModel, ecModel, api);
}
this._api.getZr().refresh();
this._layouting = false;
},
_syncNodePosition: function (seriesModel) {
var points = this._forceLayoutInstance.getNodePosition(this.viewGL.layer.renderer);
seriesModel.getData().setLayout('points', points);
seriesModel.setNodePosition(points);
},
_updateAfterLayout: function (seriesModel, ecModel, api) {
this._updateMeshLinesGeometry();
this._pointsBuilder.removePositionTexture();
this._pointsBuilder.updateLayout(seriesModel, ecModel, api);
this._pointsBuilder.updateView(this.viewGL.camera);
this._pointsBuilder.updateLabels();
this._pointsBuilder.showLabels();
},
focusNodeAdjacency: function (seriesModel, ecModel, api, payload) {
var data = this._model.getData();
this._downplayAll();
var dataIndex = payload.dataIndex;
var graph = data.graph;
var focusNodes = [];
var node = graph.getNodeByIndex(dataIndex);
focusNodes.push(node);
node.edges.forEach(function (edge) {
if (edge.dataIndex < 0) {
return;
}
edge.node1 !== node && focusNodes.push(edge.node1);
edge.node2 !== node && focusNodes.push(edge.node2);
}, this);
this._pointsBuilder.fadeOutAll(0.05);
this._fadeOutEdgesAll(0.05);
focusNodes.forEach(function (node) {
this._pointsBuilder.highlight(data, node.dataIndex);
}, this);
this._pointsBuilder.updateLabels(focusNodes.map(function (node) {
return node.dataIndex;
}));
var focusEdges = [];
node.edges.forEach(function (edge) {
if (edge.dataIndex >= 0) {
this._highlightEdge(edge.dataIndex);
focusEdges.push(edge);
}
}, this);
this._focusNodes = focusNodes;
this._focusEdges = focusEdges;
},
unfocusNodeAdjacency: function (seriesModel, ecModel, api, payload) {
this._downplayAll();
this._pointsBuilder.fadeInAll();
this._fadeInEdgesAll();
this._pointsBuilder.updateLabels();
},
_highlightEdge: function (dataIndex) {
var itemModel = this._model.getEdgeData().getItemModel(dataIndex);
var emphasisColor = __WEBPACK_IMPORTED_MODULE_2__util_graphicGL__["a" /* default */].parseColor(itemModel.get('emphasis.lineStyle.color') || itemModel.get('lineStyle.color'));
var emphasisOpacity = __WEBPACK_IMPORTED_MODULE_5__util_retrieve__["a" /* default */].firstNotNull(itemModel.get('emphasis.lineStyle.opacity'), itemModel.get('lineStyle.opacity'), 1);
emphasisColor[3] *= emphasisOpacity;
this._edgesMesh.geometry.setItemColor(this._edgeIndicesMap[dataIndex], emphasisColor);
},
_downplayAll: function () {
if (this._focusNodes) {
this._focusNodes.forEach(function (node) {
this._pointsBuilder.downplay(this._model.getData(), node.dataIndex);
}, this);
}
if (this._focusEdges) {
this._focusEdges.forEach(function (edge) {
this._downplayEdge(edge.dataIndex);
}, this);
}
},
_downplayEdge: function (dataIndex) {
var color = this._getColor(dataIndex, []);
this._edgesMesh.geometry.setItemColor(this._edgeIndicesMap[dataIndex], color);
},
_setEdgeFade: (function () {
var color = [];
return function (dataIndex, percent) {
this._getColor(dataIndex, color);
color[3] *= percent;
this._edgesMesh.geometry.setItemColor(this._edgeIndicesMap[dataIndex], color);
};
})(),
_getColor: function (dataIndex, out) {
for (var i = 0; i < 4; i++) {
out[i] = this._originalEdgeColors[dataIndex * 4 + i];
}
return out;
},
_fadeOutEdgesAll: function (percent) {
var graph = this._model.getData().graph;
graph.eachEdge(function (edge) {
this._setEdgeFade(edge.dataIndex, percent);
}, this);
},
_fadeInEdgesAll: function () {
this._fadeOutEdgesAll(1);
},
_updateCamera: function (seriesModel, api) {
this.viewGL.setViewport(0, 0, api.getWidth(), api.getHeight(), api.getDevicePixelRatio());
var camera = this.viewGL.camera;
var nodeData = seriesModel.getData();
var points = nodeData.getLayout('points');
var min = vec2.create(Infinity, Infinity);
var max = vec2.create(-Infinity, -Infinity);
var pt = [];
for (var i = 0; i < points.length;) {
pt[0] = points[i++];
pt[1] = points[i++];
vec2.min(min, min, pt);
vec2.max(max, max, pt);
}
var cy = (max[1] + min[1]) / 2;
var cx = (max[0] + min[0]) / 2;
// Only fit the camera when graph is not in the center.
// PENDING
if (cx > camera.left && cx < camera.right
&& cy < camera.bottom && cy > camera.top
) {
return;
}
// Scale a bit
var width = Math.max(max[0] - min[0], 10);
// Keep aspect
var height = width / api.getWidth() * api.getHeight();
width *= 1.4;
height *= 1.4;
min[0] -= width * 0.2;
camera.left = min[0];
camera.top = cy - height / 2;
camera.bottom = cy + height / 2;
camera.right = width + min[0];
camera.near = 0;
camera.far = 100;
},
dispose: function () {
var renderer = this.viewGL.layer.renderer;
if (this._forceLayoutInstance) {
this._forceLayoutInstance.dispose(renderer);
}
this.groupGL.removeAll();
// Stop layout.
this._layoutId = -1;
},
remove: function () {
this.groupGL.removeAll();
this._control.dispose();
}
});
/***/ }),
/* 261 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_compositor_Pass__ = __webpack_require__(14);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_FrameBuffer__ = __webpack_require__(10);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__forceAtlas2_glsl_js__ = __webpack_require__(262);
__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.import(__WEBPACK_IMPORTED_MODULE_4__forceAtlas2_glsl_js__["a" /* default */]);
var defaultConfigs = {
repulsionByDegree: true,
linLogMode: false,
strongGravityMode: false,
gravity: 1.0,
scaling: 1.0,
edgeWeightInfluence: 1.0,
jitterTolerence: 0.1,
preventOverlap: false,
dissuadeHubs: false,
gravityCenter: null
};
function ForceAtlas2GPU(options) {
var textureOpt = {
type: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Texture.FLOAT,
minFilter: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Texture.NEAREST,
magFilter: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Texture.NEAREST
};
this._positionSourceTex = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Texture2D(textureOpt);
this._positionSourceTex.flipY = false;
this._positionTex = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Texture2D(textureOpt);
this._positionPrevTex = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Texture2D(textureOpt);
this._forceTex = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Texture2D(textureOpt);
this._forcePrevTex = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Texture2D(textureOpt);
this._weightedSumTex = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Texture2D(textureOpt);
this._weightedSumTex.width = this._weightedSumTex.height = 1;
this._globalSpeedTex = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Texture2D(textureOpt);
this._globalSpeedPrevTex = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Texture2D(textureOpt);
this._globalSpeedTex.width = this._globalSpeedTex.height = 1;
this._globalSpeedPrevTex.width = this._globalSpeedPrevTex.height = 1;
this._nodeRepulsionPass = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_compositor_Pass__["a" /* default */]({
fragment: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.source('ecgl.forceAtlas2.updateNodeRepulsion')
});
this._positionPass = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_compositor_Pass__["a" /* default */]({
fragment: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.source('ecgl.forceAtlas2.updatePosition')
});
this._globalSpeedPass = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_compositor_Pass__["a" /* default */]({
fragment: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.source('ecgl.forceAtlas2.calcGlobalSpeed')
});
this._copyPass = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_compositor_Pass__["a" /* default */]({
fragment: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.source('clay.compositor.output')
});
var additiveBlend = function (gl) {
gl.blendEquation(gl.FUNC_ADD);
gl.blendFunc(gl.ONE, gl.ONE);
};
this._edgeForceMesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
geometry: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Geometry({
attributes: {
node1: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Geometry.Attribute('node1', 'float', 2),
node2: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Geometry.Attribute('node2', 'float', 2),
weight: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Geometry.Attribute('weight', 'float', 1)
},
dynamic: true,
mainAttribute: 'node1'
}),
material: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
transparent: true,
shader: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createShader('ecgl.forceAtlas2.updateEdgeAttraction'),
blend: additiveBlend,
depthMask: false,
depthText: false
}),
mode: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh.POINTS
});
this._weightedSumMesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
geometry: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Geometry({
attributes: {
node: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Geometry.Attribute('node', 'float', 2)
},
dynamic: true,
mainAttribute: 'node'
}),
material: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
transparent: true,
shader: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createShader('ecgl.forceAtlas2.calcWeightedSum'),
blend: additiveBlend,
depthMask: false,
depthText: false
}),
mode: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh.POINTS
});
this._framebuffer = new __WEBPACK_IMPORTED_MODULE_3_claygl_src_FrameBuffer__["a" /* default */]({
depthBuffer: false
});
this._dummyCamera = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].OrthographicCamera({
left: -1, right: 1,
top: 1, bottom: -1,
near: 0, far: 100
});
this._globalSpeed = 0;
}
ForceAtlas2GPU.prototype.updateOption = function (options) {
// Default config
for (var name in defaultConfigs) {
this[name] = defaultConfigs[name];
}
// Config according to data scale
var nNodes = this._nodes.length;
if (nNodes > 50000) {
this.jitterTolerence = 10;
}
else if (nNodes > 5000) {
this.jitterTolerence = 1;
}
else {
this.jitterTolerence = 0.1;
}
if (nNodes > 100) {
this.scaling = 2.0;
}
else {
this.scaling = 10.0;
}
// this.edgeWeightInfluence = 1;
// this.gravity = 1;
// this.strongGravityMode = false;
if (options) {
for (var name in defaultConfigs) {
if (options[name] != null) {
this[name] = options[name];
}
}
}
if (this.repulsionByDegree) {
var positionBuffer = this._positionSourceTex.pixels;
for (var i = 0; i < this._nodes.length; i++) {
positionBuffer[i * 4 + 2] = (this._nodes[i].degree || 0) + 1;
}
}
};
ForceAtlas2GPU.prototype._updateGravityCenter = function (options) {
var nodes = this._nodes;
var edges = this._edges;
if (!this.gravityCenter) {
var min = [Infinity, Infinity];
var max = [-Infinity, -Infinity];
for (var i = 0; i < nodes.length; i++) {
min[0] = Math.min(nodes[i].x, min[0]);
min[1] = Math.min(nodes[i].y, min[1]);
max[0] = Math.max(nodes[i].x, max[0]);
max[1] = Math.max(nodes[i].y, max[1]);
}
this._gravityCenter = [(min[0] + max[0]) * 0.5, (min[1] + max[1]) * 0.5];
}
else {
this._gravityCenter = this.gravityCenter;
}
// Update inDegree, outDegree
for (var i = 0; i < edges.length; i++) {
var node1 = edges[i].node1;
var node2 = edges[i].node2;
nodes[node1].degree = (nodes[node1].degree || 0) + 1;
nodes[node2].degree = (nodes[node2].degree || 0) + 1;
}
};
/**
* @param {Array.} [{ x, y, mass }] nodes
* @param {Array.} [{ node1, node2, weight }] edges
*/
ForceAtlas2GPU.prototype.initData = function (nodes, edges) {
this._nodes = nodes;
this._edges = edges;
this._updateGravityCenter();
var textureWidth = Math.ceil(Math.sqrt(nodes.length));
var textureHeight = textureWidth;
var positionBuffer = new Float32Array(textureWidth * textureHeight * 4);
this._resize(textureWidth, textureHeight);
var offset = 0;
for (var i = 0; i < nodes.length; i++) {
var node = nodes[i];
positionBuffer[offset++] = node.x || 0;
positionBuffer[offset++] = node.y || 0;
positionBuffer[offset++] = node.mass || 1;
positionBuffer[offset++] = node.size || 1;
}
this._positionSourceTex.pixels = positionBuffer;
var edgeGeometry = this._edgeForceMesh.geometry;
var edgeLen = edges.length;
edgeGeometry.attributes.node1.init(edgeLen * 2);
edgeGeometry.attributes.node2.init(edgeLen * 2);
edgeGeometry.attributes.weight.init(edgeLen * 2);
var uv = [];
for (var i = 0; i < edges.length; i++) {
var attributes = edgeGeometry.attributes;
var weight = edges[i].weight;
if (weight == null) {
weight = 1;
}
// Two way.
attributes.node1.set(i, this.getNodeUV(edges[i].node1, uv));
attributes.node2.set(i, this.getNodeUV(edges[i].node2, uv));
attributes.weight.set(i, weight);
attributes.node1.set(i + edgeLen, this.getNodeUV(edges[i].node2, uv));
attributes.node2.set(i + edgeLen, this.getNodeUV(edges[i].node1, uv));
attributes.weight.set(i + edgeLen, weight);
}
var weigtedSumGeo = this._weightedSumMesh.geometry;
weigtedSumGeo.attributes.node.init(nodes.length);
for (var i = 0; i < nodes.length; i++) {
weigtedSumGeo.attributes.node.set(i, this.getNodeUV(i, uv));
}
edgeGeometry.dirty();
weigtedSumGeo.dirty();
this._nodeRepulsionPass.material.define('fragment', 'NODE_COUNT', nodes.length);
this._nodeRepulsionPass.material.setUniform('textureSize', [textureWidth, textureHeight]);
this._inited = false;
this._frame = 0;
};
ForceAtlas2GPU.prototype.getNodes = function () {
return this._nodes;
};
ForceAtlas2GPU.prototype.getEdges = function () {
return this._edges;
};
ForceAtlas2GPU.prototype.step = function (renderer) {
if (!this._inited) {
this._initFromSource(renderer);
this._inited = true;
}
this._frame++;
this._framebuffer.attach(this._forceTex);
this._framebuffer.bind(renderer);
var nodeRepulsionPass = this._nodeRepulsionPass;
// Calc node repulsion, gravity
nodeRepulsionPass.setUniform('strongGravityMode', this.strongGravityMode);
nodeRepulsionPass.setUniform('gravity', this.gravity);
nodeRepulsionPass.setUniform('gravityCenter', this._gravityCenter);
nodeRepulsionPass.setUniform('scaling', this.scaling);
nodeRepulsionPass.setUniform('preventOverlap', this.preventOverlap);
nodeRepulsionPass.setUniform('positionTex', this._positionPrevTex);
nodeRepulsionPass.render(renderer);
// Calc edge attraction force
var edgeForceMesh = this._edgeForceMesh;
edgeForceMesh.material.set('linLogMode', this.linLogMode);
edgeForceMesh.material.set('edgeWeightInfluence', this.edgeWeightInfluence);
edgeForceMesh.material.set('preventOverlap', this.preventOverlap);
edgeForceMesh.material.set('positionTex', this._positionPrevTex);
renderer.gl.enable(renderer.gl.BLEND);
renderer.renderPass([edgeForceMesh], this._dummyCamera);
// Calc weighted sum.
this._framebuffer.attach(this._weightedSumTex);
renderer.gl.clearColor(0, 0, 0, 0);
renderer.gl.clear(renderer.gl.COLOR_BUFFER_BIT);
renderer.gl.enable(renderer.gl.BLEND);
var weightedSumMesh = this._weightedSumMesh;
weightedSumMesh.material.set('positionTex', this._positionPrevTex);
weightedSumMesh.material.set('forceTex', this._forceTex);
weightedSumMesh.material.set('forcePrevTex', this._forcePrevTex);
renderer.renderPass([weightedSumMesh], this._dummyCamera);
// Calc global speed.
this._framebuffer.attach(this._globalSpeedTex);
var globalSpeedPass = this._globalSpeedPass;
globalSpeedPass.setUniform('globalSpeedPrevTex', this._globalSpeedPrevTex);
globalSpeedPass.setUniform('weightedSumTex', this._weightedSumTex);
globalSpeedPass.setUniform('jitterTolerence', this.jitterTolerence);
renderer.gl.disable(renderer.gl.BLEND);
globalSpeedPass.render(renderer);
// Update position.
var positionPass = this._positionPass;
this._framebuffer.attach(this._positionTex);
positionPass.setUniform('globalSpeedTex', this._globalSpeedTex);
positionPass.setUniform('positionTex', this._positionPrevTex);
positionPass.setUniform('forceTex', this._forceTex);
positionPass.setUniform('forcePrevTex', this._forcePrevTex);
positionPass.render(renderer);
this._framebuffer.unbind(renderer);
this._swapTexture();
};
ForceAtlas2GPU.prototype.update = function (renderer, steps, cb) {
if (steps == null) {
steps = 1;
}
steps = Math.max(steps, 1);
for (var i = 0; i < steps; i++) {
this.step(renderer);
}
cb && cb();
};
ForceAtlas2GPU.prototype.getNodePositionTexture = function () {
return this._inited
// Texture already been swapped.
? this._positionPrevTex
: this._positionSourceTex;
};
ForceAtlas2GPU.prototype.getNodeUV = function (nodeIndex, uv) {
uv = uv || [];
var textureWidth = this._positionTex.width;
var textureHeight = this._positionTex.height;
uv[0] = (nodeIndex % textureWidth) / (textureWidth - 1);
uv[1] = Math.floor(nodeIndex / textureWidth) / (textureHeight - 1) || 0;
return uv;
};
ForceAtlas2GPU.prototype.getNodePosition = function (renderer, out) {
var positionArr = this._positionArr;
var width = this._positionTex.width;
var height = this._positionTex.height;
var size = width * height;
if (!positionArr || positionArr.length !== size * 4) {
positionArr = this._positionArr = new Float32Array(size * 4);
}
this._framebuffer.bind(renderer);
this._framebuffer.attach(this._positionPrevTex);
renderer.gl.readPixels(
0, 0, width, height,
renderer.gl.RGBA, renderer.gl.FLOAT,
positionArr
);
this._framebuffer.unbind(renderer);
if (!out) {
out = new Float32Array(this._nodes.length * 2);
}
for (var i = 0; i < this._nodes.length; i++) {
out[i * 2] = positionArr[i * 4];
out[i * 2 + 1] = positionArr[i * 4 + 1];
}
return out;
};
ForceAtlas2GPU.prototype.getTextureData = function (renderer, textureName) {
var tex = this['_' + textureName + 'Tex'];
var width = tex.width;
var height = tex.height;
this._framebuffer.bind(renderer);
this._framebuffer.attach(tex);
var arr = new Float32Array(width * height * 4);
renderer.gl.readPixels(0, 0, width, height, renderer.gl.RGBA, renderer.gl.FLOAT, arr);
this._framebuffer.unbind(renderer);
return arr;
};
ForceAtlas2GPU.prototype.getTextureSize = function () {
return {
width: this._positionTex.width,
height: this._positionTex.height
};
};
ForceAtlas2GPU.prototype.isFinished = function (maxSteps) {
return this._frame > maxSteps;
};
ForceAtlas2GPU.prototype._swapTexture = function () {
var tmp = this._positionPrevTex;
this._positionPrevTex = this._positionTex;
this._positionTex = tmp;
var tmp = this._forcePrevTex;
this._forcePrevTex = this._forceTex;
this._forceTex = tmp;
var tmp = this._globalSpeedPrevTex;
this._globalSpeedPrevTex = this._globalSpeedTex;
this._globalSpeedTex = tmp;
};
ForceAtlas2GPU.prototype._initFromSource = function (renderer) {
this._framebuffer.attach(this._positionPrevTex);
this._framebuffer.bind(renderer);
this._copyPass.setUniform('texture', this._positionSourceTex);
this._copyPass.render(renderer);
renderer.gl.clearColor(0, 0, 0, 0);
this._framebuffer.attach(this._forcePrevTex);
renderer.gl.clear(renderer.gl.COLOR_BUFFER_BIT);
this._framebuffer.attach(this._globalSpeedPrevTex);
renderer.gl.clear(renderer.gl.COLOR_BUFFER_BIT);
this._framebuffer.unbind(renderer);
};
ForceAtlas2GPU.prototype._resize = function (width, height) {
['_positionSourceTex', '_positionTex', '_positionPrevTex', '_forceTex', '_forcePrevTex'].forEach(function (texName) {
this[texName].width = width;
this[texName].height = height;
this[texName].dirty();
}, this);
};
ForceAtlas2GPU.prototype.dispose = function (renderer) {
this._framebuffer.dispose(renderer);
this._copyPass.dispose(renderer);
this._nodeRepulsionPass.dispose(renderer);
this._positionPass.dispose(renderer);
this._globalSpeedPass.dispose(renderer);
this._edgeForceMesh.geometry.dispose(renderer);
this._weightedSumMesh.geometry.dispose(renderer);
this._positionSourceTex.dispose(renderer);
this._positionTex.dispose(renderer);
this._positionPrevTex.dispose(renderer);
this._forceTex.dispose(renderer);
this._forcePrevTex.dispose(renderer);
this._weightedSumTex.dispose(renderer);
this._globalSpeedTex.dispose(renderer);
this._globalSpeedPrevTex.dispose(renderer);
};
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.ForceAtlas2GPU = ForceAtlas2GPU;
/* harmony default export */ __webpack_exports__["a"] = (ForceAtlas2GPU);
/***/ }),
/* 262 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.forceAtlas2.updateNodeRepulsion\n\n#define NODE_COUNT 0\n\nuniform sampler2D positionTex;\n\nuniform vec2 textureSize;\nuniform float gravity;\nuniform float scaling;\nuniform vec2 gravityCenter;\n\nuniform bool strongGravityMode;\nuniform bool preventOverlap;\n\nvarying vec2 v_Texcoord;\n\nvoid main() {\n\n vec4 n0 = texture2D(positionTex, v_Texcoord);\n\n vec2 force = vec2(0.0);\n for (int i = 0; i < NODE_COUNT; i++) {\n vec2 uv = vec2(\n mod(float(i), textureSize.x) / (textureSize.x - 1.0),\n floor(float(i) / textureSize.x) / (textureSize.y - 1.0)\n );\n vec4 n1 = texture2D(positionTex, uv);\n\n vec2 dir = n0.xy - n1.xy;\n float d2 = dot(dir, dir);\n\n if (d2 > 0.0) {\n float factor = 0.0;\n if (preventOverlap) {\n float d = sqrt(d2);\n d = d - n0.w - n1.w;\n if (d > 0.0) {\n factor = scaling * n0.z * n1.z / (d * d);\n }\n else if (d < 0.0) {\n factor = scaling * 100.0 * n0.z * n1.z;\n }\n }\n else {\n factor = scaling * n0.z * n1.z / d2;\n }\n force += dir * factor;\n }\n }\n\n vec2 dir = gravityCenter - n0.xy;\n float d = 1.0;\n if (!strongGravityMode) {\n d = length(dir);\n }\n\n force += dir * n0.z * gravity / (d + 1.0);\n\n gl_FragColor = vec4(force, 0.0, 1.0);\n}\n@end\n\n@export ecgl.forceAtlas2.updateEdgeAttraction.vertex\n\nattribute vec2 node1;\nattribute vec2 node2;\nattribute float weight;\n\nuniform sampler2D positionTex;\nuniform float edgeWeightInfluence;\nuniform bool preventOverlap;\nuniform bool linLogMode;\n\nuniform vec2 windowSize: WINDOW_SIZE;\n\nvarying vec2 v_Force;\n\nvoid main() {\n\n vec4 n0 = texture2D(positionTex, node1);\n vec4 n1 = texture2D(positionTex, node2);\n\n vec2 dir = n1.xy - n0.xy;\n float d = length(dir);\n float w;\n if (edgeWeightInfluence == 0.0) {\n w = 1.0;\n }\n else if (edgeWeightInfluence == 1.0) {\n w = weight;\n }\n else {\n w = pow(weight, edgeWeightInfluence);\n }\n vec2 offset = vec2(1.0 / windowSize.x, 1.0 / windowSize.y);\n vec2 scale = vec2((windowSize.x - 1.0) / windowSize.x, (windowSize.y - 1.0) / windowSize.y);\n vec2 pos = node1 * scale * 2.0 - 1.0;\n gl_Position = vec4(pos + offset, 0.0, 1.0);\n gl_PointSize = 1.0;\n\n float factor;\n if (preventOverlap) {\n d = d - n1.w - n0.w;\n }\n if (d <= 0.0) {\n v_Force = vec2(0.0);\n return;\n }\n\n if (linLogMode) {\n factor = w * log(d) / d;\n }\n else {\n factor = w;\n }\n v_Force = dir * factor;\n}\n@end\n\n@export ecgl.forceAtlas2.updateEdgeAttraction.fragment\n\nvarying vec2 v_Force;\n\nvoid main() {\n gl_FragColor = vec4(v_Force, 0.0, 0.0);\n}\n@end\n\n@export ecgl.forceAtlas2.calcWeightedSum.vertex\n\nattribute vec2 node;\n\nvarying vec2 v_NodeUv;\n\nvoid main() {\n\n v_NodeUv = node;\n gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n gl_PointSize = 1.0;\n}\n@end\n\n@export ecgl.forceAtlas2.calcWeightedSum.fragment\n\nvarying vec2 v_NodeUv;\n\nuniform sampler2D positionTex;\nuniform sampler2D forceTex;\nuniform sampler2D forcePrevTex;\n\nvoid main() {\n vec2 force = texture2D(forceTex, v_NodeUv).rg;\n vec2 forcePrev = texture2D(forcePrevTex, v_NodeUv).rg;\n\n float mass = texture2D(positionTex, v_NodeUv).z;\n float swing = length(force - forcePrev) * mass;\n float traction = length(force + forcePrev) * 0.5 * mass;\n\n gl_FragColor = vec4(swing, traction, 0.0, 0.0);\n}\n@end\n\n@export ecgl.forceAtlas2.calcGlobalSpeed\n\nuniform sampler2D globalSpeedPrevTex;\nuniform sampler2D weightedSumTex;\nuniform float jitterTolerence;\n\nvoid main() {\n vec2 weightedSum = texture2D(weightedSumTex, vec2(0.5)).xy;\n float prevGlobalSpeed = texture2D(globalSpeedPrevTex, vec2(0.5)).x;\n float globalSpeed = jitterTolerence * jitterTolerence\n * weightedSum.y / weightedSum.x;\n if (prevGlobalSpeed > 0.0) {\n globalSpeed = min(globalSpeed / prevGlobalSpeed, 1.5) * prevGlobalSpeed;\n }\n gl_FragColor = vec4(globalSpeed, 0.0, 0.0, 1.0);\n}\n@end\n\n@export ecgl.forceAtlas2.updatePosition\n\nuniform sampler2D forceTex;\nuniform sampler2D forcePrevTex;\nuniform sampler2D positionTex;\nuniform sampler2D globalSpeedTex;\n\nvarying vec2 v_Texcoord;\n\nvoid main() {\n vec2 force = texture2D(forceTex, v_Texcoord).xy;\n vec2 forcePrev = texture2D(forcePrevTex, v_Texcoord).xy;\n vec4 node = texture2D(positionTex, v_Texcoord);\n\n float globalSpeed = texture2D(globalSpeedTex, vec2(0.5)).r;\n float swing = length(force - forcePrev);\n float speed = 0.1 * globalSpeed / (0.1 + globalSpeed * sqrt(swing));\n\n float df = length(force);\n if (df > 0.0) {\n speed = min(df * speed, 10.0) / df;\n\n gl_FragColor = vec4(node.xy + speed * force, node.zw);\n }\n else {\n gl_FragColor = node;\n }\n}\n@end\n\n@export ecgl.forceAtlas2.edges.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\n\nattribute vec2 node;\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n\nuniform sampler2D positionTex;\n\nvoid main()\n{\n gl_Position = worldViewProjection * vec4(\n texture2D(positionTex, node).xy, -10.0, 1.0\n );\n v_Color = a_Color;\n}\n@end\n\n@export ecgl.forceAtlas2.edges.fragment\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\nvarying vec4 v_Color;\nvoid main() {\n gl_FragColor = color * v_Color;\n}\n@end");
/***/ }),
/* 263 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_Texture__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__forceAtlas2Worker_js__ = __webpack_require__(264);
var workerUrl = __WEBPACK_IMPORTED_MODULE_2__forceAtlas2Worker_js__["a" /* default */].toString();
workerUrl = workerUrl.slice(workerUrl.indexOf('{') + 1, workerUrl.lastIndexOf('}'));
var defaultConfigs = {
barnesHutOptimize: true,
barnesHutTheta: 1.5,
repulsionByDegree: true,
linLogMode: false,
strongGravityMode: false,
gravity: 1.0,
scaling: 1.0,
edgeWeightInfluence: 1.0,
jitterTolerence: 0.1,
preventOverlap: false,
dissuadeHubs: false,
gravityCenter: null
};
var ForceAtlas2 = function (options) {
for (var name in defaultConfigs) {
this[name] = defaultConfigs[name];
}
if (options) {
for (var name in options) {
this[name] = options[name];
}
}
this._nodes = [];
this._edges = [];
this._disposed = false;
this._positionTex = new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Texture2D__["a" /* default */]({
type: __WEBPACK_IMPORTED_MODULE_1_claygl_src_Texture__["a" /* default */].FLOAT,
flipY: false,
minFilter: __WEBPACK_IMPORTED_MODULE_1_claygl_src_Texture__["a" /* default */].NEAREST,
magFilter: __WEBPACK_IMPORTED_MODULE_1_claygl_src_Texture__["a" /* default */].NEAREST
});
};
ForceAtlas2.prototype.initData = function (nodes, edges) {
var bb = new Blob([workerUrl]);
var blobURL = window.URL.createObjectURL(bb);
this._worker = new Worker(blobURL);
this._worker.onmessage = this._$onupdate.bind(this);
this._nodes = nodes;
this._edges = edges;
this._frame = 0;
var nNodes = nodes.length;
var nEdges = edges.length;
var positionArr = new Float32Array(nNodes * 2);
var massArr = new Float32Array(nNodes);
var sizeArr = new Float32Array(nNodes);
var edgeArr = new Float32Array(nEdges * 2);
var edgeWeightArr = new Float32Array(nEdges);
for (var i = 0; i < nodes.length; i++) {
var node = nodes[i];
positionArr[i * 2] = node.x;
positionArr[i * 2 + 1] = node.y;
massArr[i] = node.mass == null ? 1 : node.mass;
sizeArr[i] = node.size == null ? 1 : node.size;
}
for (var i = 0; i < edges.length; i++) {
var edge = edges[i];
var source = edge.node1;
var target = edge.node2;
edgeArr[i * 2] = source;
edgeArr[i * 2 + 1] = target;
edgeWeightArr[i] = edge.weight == null ? 1 : edge.weight;
}
var textureWidth = Math.ceil(Math.sqrt(nodes.length));
var textureHeight = textureWidth;
var pixels = new Float32Array(textureWidth * textureHeight * 4);
var positionTex = this._positionTex;
positionTex.width = textureWidth;
positionTex.height = textureHeight;
positionTex.pixels = pixels;
this._worker.postMessage({
cmd: 'init',
nodesPosition: positionArr,
nodesMass: massArr,
nodesSize: sizeArr,
edges: edgeArr,
edgesWeight: edgeWeightArr
});
this._globalSpeed = Infinity;
};
ForceAtlas2.prototype.updateOption = function (options) {
var config = {};
// Default config
for (var name in defaultConfigs) {
config[name] = defaultConfigs[name];
}
var nodes = this._nodes;
var edges = this._edges;
// Config according to data scale
var nNodes = nodes.length;
if (nNodes > 50000) {
config.jitterTolerence = 10;
}
else if (nNodes > 5000) {
config.jitterTolerence = 1;
}
else {
config.jitterTolerence = 0.1;
}
if (nNodes > 100) {
config.scaling = 2.0;
}
else {
config.scaling = 10.0;
}
if (nNodes > 1000) {
config.barnesHutOptimize = true;
}
else {
config.barnesHutOptimize = false;
}
if (options) {
for (var name in defaultConfigs) {
if (options[name] != null) {
config[name] = options[name];
}
}
}
if (!config.gravityCenter) {
var min = [Infinity, Infinity];
var max = [-Infinity, -Infinity];
for (var i = 0; i < nodes.length; i++) {
min[0] = Math.min(nodes[i].x, min[0]);
min[1] = Math.min(nodes[i].y, min[1]);
max[0] = Math.max(nodes[i].x, max[0]);
max[1] = Math.max(nodes[i].y, max[1]);
}
config.gravityCenter = [(min[0] + max[0]) * 0.5, (min[1] + max[1]) * 0.5];
}
// Update inDegree, outDegree
for (var i = 0; i < edges.length; i++) {
var node1 = edges[i].node1;
var node2 = edges[i].node2;
nodes[node1].degree = (nodes[node1].degree || 0) + 1;
nodes[node2].degree = (nodes[node2].degree || 0) + 1;
}
if (this._worker) {
this._worker.postMessage({
cmd: 'updateConfig',
config: config
});
}
};
// Steps per call, to keep sync with rendering
ForceAtlas2.prototype.update = function (renderer, steps, cb) {
if (steps == null) {
steps = 1;
}
steps = Math.max(steps, 1);
this._frame += steps;
this._onupdate = cb;
if (this._worker) {
this._worker.postMessage({
cmd: 'update',
steps: Math.round(steps)
});
}
};
ForceAtlas2.prototype._$onupdate = function (e) {
// Incase the worker keep postMessage of last frame after it is disposed
if (this._disposed) {
return;
}
var positionArr = new Float32Array(e.data.buffer);
this._globalSpeed = e.data.globalSpeed;
this._positionArr = positionArr;
this._updateTexture(positionArr);
this._onupdate && this._onupdate();
};
ForceAtlas2.prototype.getNodePositionTexture = function () {
return this._positionTex;
};
ForceAtlas2.prototype.getNodeUV = function (nodeIndex, uv) {
uv = uv || [];
var textureWidth = this._positionTex.width;
var textureHeight = this._positionTex.height;
uv[0] = (nodeIndex % textureWidth) / (textureWidth - 1);
uv[1] = Math.floor(nodeIndex / textureWidth) / (textureHeight - 1);
return uv;
};
ForceAtlas2.prototype.getNodes = function () {
return this._nodes;
};
ForceAtlas2.prototype.getEdges = function () {
return this._edges;
};
ForceAtlas2.prototype.isFinished = function (maxSteps) {
return this._frame > maxSteps;
};
ForceAtlas2.prototype.getNodePosition = function (renderer, out) {
if (!out) {
out = new Float32Array(this._nodes.length * 2);
}
if (this._positionArr) {
for (var i = 0; i < this._positionArr.length; i++) {
out[i] = this._positionArr[i];
}
}
return out;
};
ForceAtlas2.prototype._updateTexture = function (positionArr) {
var pixels = this._positionTex.pixels;
var offset = 0;
for (var i = 0; i < positionArr.length;){
pixels[offset++] = positionArr[i++];
pixels[offset++] = positionArr[i++];
pixels[offset++] = 1;
pixels[offset++] = 1;
}
this._positionTex.dirty();
};
ForceAtlas2.prototype.dispose = function (renderer) {
this._disposed = true;
this._worker = null;
};
/* harmony default export */ __webpack_exports__["a"] = (ForceAtlas2);
/***/ }),
/* 264 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/****************************
* Vector2 math functions
***************************/
function forceAtlas2Worker() {
var vec2 = {
create: function() {
return new Float32Array(2);
},
dist: function(a, b) {
var x = b[0] - a[0];
var y = b[1] - a[1];
return Math.sqrt(x*x + y*y);
},
len: function(a) {
var x = a[0];
var y = a[1];
return Math.sqrt(x*x + y*y);
},
scaleAndAdd: function(out, a, b, scale) {
out[0] = a[0] + b[0] * scale;
out[1] = a[1] + b[1] * scale;
return out;
},
scale: function(out, a, b) {
out[0] = a[0] * b;
out[1] = a[1] * b;
return out;
},
add: function(out, a, b) {
out[0] = a[0] + b[0];
out[1] = a[1] + b[1];
return out;
},
sub: function(out, a, b) {
out[0] = a[0] - b[0];
out[1] = a[1] - b[1];
return out;
},
normalize: function(out, a) {
var x = a[0];
var y = a[1];
var len = x*x + y*y;
if (len > 0) {
//TODO: evaluate use of glm_invsqrt here?
len = 1 / Math.sqrt(len);
out[0] = a[0] * len;
out[1] = a[1] * len;
}
return out;
},
negate: function(out, a) {
out[0] = -a[0];
out[1] = -a[1];
return out;
},
copy: function(out, a) {
out[0] = a[0];
out[1] = a[1];
return out;
},
set: function(out, x, y) {
out[0] = x;
out[1] = y;
return out;
}
}
/****************************
* Class: Region
***************************/
function Region() {
this.subRegions = [];
this.nSubRegions = 0;
this.node = null;
this.mass = 0;
this.centerOfMass = null;
this.bbox = new Float32Array(4);
this.size = 0;
}
var regionProto = Region.prototype;
// Reset before update
regionProto.beforeUpdate = function() {
for (var i = 0; i < this.nSubRegions; i++) {
this.subRegions[i].beforeUpdate();
}
this.mass = 0;
if (this.centerOfMass) {
this.centerOfMass[0] = 0;
this.centerOfMass[1] = 0;
}
this.nSubRegions = 0;
this.node = null;
};
// Clear after update
regionProto.afterUpdate = function() {
this.subRegions.length = this.nSubRegions;
for (var i = 0; i < this.nSubRegions; i++) {
this.subRegions[i].afterUpdate();
}
};
regionProto.addNode = function(node) {
if (this.nSubRegions === 0) {
if (this.node == null) {
this.node = node;
return;
}
// Already have node, subdivide self.
else {
this._addNodeToSubRegion(this.node);
this.node = null;
}
}
this._addNodeToSubRegion(node);
this._updateCenterOfMass(node);
};
regionProto.findSubRegion = function(x, y) {
for (var i = 0; i < this.nSubRegions; i++) {
var region = this.subRegions[i];
if (region.contain(x, y)) {
return region;
}
}
};
regionProto.contain = function(x, y) {
return this.bbox[0] <= x
&& this.bbox[2] >= x
&& this.bbox[1] <= y
&& this.bbox[3] >= y;
};
regionProto.setBBox = function(minX, minY, maxX, maxY) {
// Min
this.bbox[0] = minX;
this.bbox[1] = minY;
// Max
this.bbox[2] = maxX;
this.bbox[3] = maxY;
this.size = (maxX - minX + maxY - minY) / 2;
};
regionProto._newSubRegion = function() {
var subRegion = this.subRegions[this.nSubRegions];
if (!subRegion) {
subRegion = new Region();
this.subRegions[this.nSubRegions] = subRegion;
}
this.nSubRegions++;
return subRegion;
};
regionProto._addNodeToSubRegion = function(node) {
var subRegion = this.findSubRegion(node.position[0], node.position[1]);
var bbox = this.bbox;
if (!subRegion) {
var cx = (bbox[0] + bbox[2]) / 2;
var cy = (bbox[1] + bbox[3]) / 2;
var w = (bbox[2] - bbox[0]) / 2;
var h = (bbox[3] - bbox[1]) / 2;
var xi = node.position[0] >= cx ? 1 : 0;
var yi = node.position[1] >= cy ? 1 : 0;
var subRegion = this._newSubRegion();
// Min
subRegion.setBBox(
// Min
xi * w + bbox[0],
yi * h + bbox[1],
// Max
(xi + 1) * w + bbox[0],
(yi + 1) * h + bbox[1]
);
}
subRegion.addNode(node);
};
regionProto._updateCenterOfMass = function(node) {
// Incrementally update
if (this.centerOfMass == null) {
this.centerOfMass = new Float32Array(2);
}
var x = this.centerOfMass[0] * this.mass;
var y = this.centerOfMass[1] * this.mass;
x += node.position[0] * node.mass;
y += node.position[1] * node.mass;
this.mass += node.mass;
this.centerOfMass[0] = x / this.mass;
this.centerOfMass[1] = y / this.mass;
};
/****************************
* Class: Graph Node
***************************/
function GraphNode() {
this.position = new Float32Array(2);
this.force = vec2.create();
this.forcePrev = vec2.create();
// If repulsionByDegree is true
// mass = inDegree + outDegree + 1
// Else
// mass is manually set
this.mass = 1;
this.inDegree = 0;
this.outDegree = 0;
// Optional
// this.size = 1;
}
/****************************
* Class: Graph Edge
***************************/
function GraphEdge(source, target) {
this.source = source;
this.target = target;
this.weight = 1;
}
/****************************
* Class: ForceStlas2
***************************/
function ForceAtlas2() {
//-------------
// Configs
// If auto settings is true
// barnesHutOptimize,
// barnesHutTheta,
// scaling,
// jitterTolerence
// Will be set by the system automatically
// preventOverlap will be set false
// if node size is not given
this.autoSettings = true;
// Barnes Hut
// http://arborjs.org/docs/barnes-hut
this.barnesHutOptimize = true;
this.barnesHutTheta = 1.5;
// Force Atlas2 Configs
this.repulsionByDegree = true;
this.linLogMode = false;
this.strongGravityMode = false;
this.gravity = 1.0;
this.scaling = 1.0;
this.edgeWeightInfluence = 1.0;
this.jitterTolerence = 0.1;
// TODO
this.preventOverlap = false;
this.dissuadeHubs = false;
//
this.rootRegion = new Region();
this.rootRegion.centerOfMass = vec2.create();
this.nodes = [];
this.edges = [];
this.bbox = new Float32Array(4);
this.gravityCenter = null;
this._massArr = null;
this._swingingArr = null;
this._sizeArr = null;
this._globalSpeed = 0;
}
var forceAtlas2Proto = ForceAtlas2.prototype;
forceAtlas2Proto.initNodes = function(positionArr, massArr, sizeArr) {
var nNodes = massArr.length;
this.nodes.length = 0;
var haveSize = typeof(sizeArr) != 'undefined';
for (var i = 0; i < nNodes; i++) {
var node = new GraphNode();
node.position[0] = positionArr[i * 2];
node.position[1] = positionArr[i * 2 + 1];
node.mass = massArr[i];
if (haveSize) {
node.size = sizeArr[i];
}
this.nodes.push(node);
}
this._massArr = massArr;
this._swingingArr = new Float32Array(nNodes);
if (haveSize) {
this._sizeArr = sizeArr;
}
};
forceAtlas2Proto.initEdges = function(edgeArr, edgeWeightArr) {
var nEdges = edgeArr.length / 2;
this.edges.length = 0;
for (var i = 0; i < nEdges; i++) {
var sIdx = edgeArr[i * 2];
var tIdx = edgeArr[i * 2 + 1];
var sNode = this.nodes[sIdx];
var tNode = this.nodes[tIdx];
if (!sNode || !tNode) {
console.error('Node not exists, try initNodes before initEdges');
return;
}
sNode.outDegree++;
tNode.inDegree++;
var edge = new GraphEdge(sNode, tNode);
if (edgeWeightArr) {
edge.weight = edgeWeightArr[i];
}
this.edges.push(edge);
}
}
forceAtlas2Proto.updateSettings = function() {
if (this.repulsionByDegree) {
for (var i = 0; i < this.nodes.length; i++) {
var node = this.nodes[i];
node.mass = node.inDegree + node.outDegree + 1;
}
}
else {
for (var i = 0; i < this.nodes.length; i++) {
var node = this.nodes[i];
node.mass = this._massArr[i];
}
}
};
forceAtlas2Proto.update = function() {
var nNodes = this.nodes.length;
this.updateSettings();
this.updateBBox();
// Update region
if (this.barnesHutOptimize) {
this.rootRegion.setBBox(
this.bbox[0], this.bbox[1],
this.bbox[2], this.bbox[3]
);
this.rootRegion.beforeUpdate();
for (var i = 0; i < nNodes; i++) {
this.rootRegion.addNode(this.nodes[i]);
}
this.rootRegion.afterUpdate();
}
// Reset forces
for (var i = 0; i < nNodes; i++) {
var node = this.nodes[i];
vec2.copy(node.forcePrev, node.force);
vec2.set(node.force, 0, 0);
}
// Compute forces
// Repulsion
for (var i = 0; i < nNodes; i++) {
var na = this.nodes[i];
if (this.barnesHutOptimize) {
this.applyRegionToNodeRepulsion(this.rootRegion, na);
}
else {
for (var j = i + 1; j < nNodes; j++) {
var nb = this.nodes[j];
this.applyNodeToNodeRepulsion(na, nb, false);
}
}
// Gravity
if (this.gravity > 0) {
if (this.strongGravityMode) {
this.applyNodeStrongGravity(na);
}
else {
this.applyNodeGravity(na);
}
}
}
// Attraction
for (var i = 0; i < this.edges.length; i++) {
this.applyEdgeAttraction(this.edges[i]);
}
// Handle swinging
var swingWeightedSum = 0;
var tractionWeightedSum = 0;
var tmp = vec2.create();
for (var i = 0; i < nNodes; i++) {
var node = this.nodes[i];
var swing = vec2.dist(node.force, node.forcePrev);
swingWeightedSum += swing * node.mass;
vec2.add(tmp, node.force, node.forcePrev);
var traction = vec2.len(tmp) * 0.5;
tractionWeightedSum += traction * node.mass;
// Save the value for using later
this._swingingArr[i] = swing;
}
var globalSpeed = this.jitterTolerence * this.jitterTolerence
* tractionWeightedSum / swingWeightedSum;
// NB: During our tests we observed that an excessive rise of the global speed could have a negative impact.
// That’s why we limited the increase of global speed s(t)(G) to 50% of the previous step s(t−1)(G).
if (this._globalSpeed > 0) {
globalSpeed = Math.min(globalSpeed / this._globalSpeed, 1.5) * this._globalSpeed;
}
this._globalSpeed = globalSpeed;
// Apply forces
for (var i = 0; i < nNodes; i++) {
var node = this.nodes[i];
var swing = this._swingingArr[i];
var speed = 0.1 * globalSpeed / (1 + globalSpeed * Math.sqrt(swing));
// Additional constraint to prevent local speed gets too high
var df = vec2.len(node.force);
if (df > 0) {
speed = Math.min(df * speed, 10) / df;
vec2.scaleAndAdd(node.position, node.position, node.force, speed);
}
}
};
forceAtlas2Proto.applyRegionToNodeRepulsion = (function() {
var v = vec2.create();
return function applyRegionToNodeRepulsion(region, node) {
if (region.node) { // Region is a leaf
this.applyNodeToNodeRepulsion(region.node, node, true);
}
else {
vec2.sub(v, node.position, region.centerOfMass);
var d2 = v[0] * v[0] + v[1] * v[1];
if (d2 > this.barnesHutTheta * region.size * region.size) {
var factor = this.scaling * node.mass * region.mass / d2;
vec2.scaleAndAdd(node.force, node.force, v, factor);
}
else {
for (var i = 0; i < region.nSubRegions; i++) {
this.applyRegionToNodeRepulsion(region.subRegions[i], node);
}
}
}
}
})();
forceAtlas2Proto.applyNodeToNodeRepulsion = (function() {
var v = vec2.create();
return function applyNodeToNodeRepulsion(na, nb, oneWay) {
if (na == nb) {
return;
}
vec2.sub(v, na.position, nb.position);
var d2 = v[0] * v[0] + v[1] * v[1];
// PENDING
if (d2 === 0) {
return;
}
var factor;
if (this.preventOverlap) {
var d = Math.sqrt(d2);
d = d - na.size - nb.size;
if (d > 0) {
factor = this.scaling * na.mass * nb.mass / (d * d);
}
else if (d < 0) {
// A stronger repulsion if overlap
factor = this.scaling * 100 * na.mass * nb.mass;
}
else {
// No repulsion
return;
}
}
else {
// Divide factor by an extra `d` to normalize the `v`
factor = this.scaling * na.mass * nb.mass / d2;
}
vec2.scaleAndAdd(na.force, na.force, v, factor);
vec2.scaleAndAdd(nb.force, nb.force, v, -factor);
}
})();
forceAtlas2Proto.applyEdgeAttraction = (function() {
var v = vec2.create();
return function applyEdgeAttraction(edge) {
var na = edge.source;
var nb = edge.target;
vec2.sub(v, na.position, nb.position);
var d = vec2.len(v);
var w;
if (this.edgeWeightInfluence === 0) {
w = 1;
}
else if (this.edgeWeightInfluence === 1) {
w = edge.weight;
}
else {
w = Math.pow(edge.weight, this.edgeWeightInfluence);
}
var factor;
if (this.preventOverlap) {
d = d - na.size - nb.size;
if (d <= 0) {
// No attraction
return;
}
}
if (this.linLogMode) {
// Divide factor by an extra `d` to normalize the `v`
factor = - w * Math.log(d + 1) / (d + 1);
}
else {
factor = - w;
}
vec2.scaleAndAdd(na.force, na.force, v, factor);
vec2.scaleAndAdd(nb.force, nb.force, v, -factor);
}
})();
forceAtlas2Proto.applyNodeGravity = (function() {
var v = vec2.create();
return function(node) {
vec2.sub(v, this.gravityCenter, node.position);
var d = vec2.len(v);
vec2.scaleAndAdd(node.force, node.force, v, this.gravity * node.mass / (d + 1));
}
})();
forceAtlas2Proto.applyNodeStrongGravity = (function() {
var v = vec2.create();
return function(node) {
vec2.sub(v, this.gravityCenter, node.position);
vec2.scaleAndAdd(node.force, node.force, v, this.gravity * node.mass);
}
})();
forceAtlas2Proto.updateBBox = function() {
var minX = Infinity;
var minY = Infinity;
var maxX = -Infinity;
var maxY = -Infinity;
for (var i = 0; i < this.nodes.length; i++) {
var pos = this.nodes[i].position;
minX = Math.min(minX, pos[0]);
minY = Math.min(minY, pos[1]);
maxX = Math.max(maxX, pos[0]);
maxY = Math.max(maxY, pos[1]);
}
this.bbox[0] = minX;
this.bbox[1] = minY;
this.bbox[2] = maxX;
this.bbox[3] = maxY;
};
forceAtlas2Proto.getGlobalSpeed = function () {
return this._globalSpeed;
}
/****************************
* Main process
***************************/
var forceAtlas2 = null;
self.onmessage = function(e) {
switch(e.data.cmd) {
case 'init':
forceAtlas2 = new ForceAtlas2();
forceAtlas2.initNodes(e.data.nodesPosition, e.data.nodesMass, e.data.nodesSize);
forceAtlas2.initEdges(e.data.edges, e.data.edgesWeight);
break;
case 'updateConfig':
if (forceAtlas2) {
for (var name in e.data.config) {
forceAtlas2[name] = e.data.config[name];
}
}
break;
case 'update':
var steps = e.data.steps;
if (forceAtlas2) {
for (var i = 0; i < steps; i++) {
forceAtlas2.update();
}
var nNodes = forceAtlas2.nodes.length;
var positionArr = new Float32Array(nNodes * 2);
// Callback
for (var i = 0; i < nNodes; i++) {
var node = forceAtlas2.nodes[i];
positionArr[i * 2] = node.position[0];
positionArr[i * 2 + 1] = node.position[1];
}
self.postMessage({
buffer: positionArr.buffer,
globalSpeed: forceAtlas2.getGlobalSpeed()
}, [positionArr.buffer]);
}
else {
// Not initialzied yet
var emptyArr = new Float32Array();
// Post transfer object
self.postMessage({
buffer: emptyArr.buffer,
globalSpeed: forceAtlas2.getGlobalSpeed()
}, [emptyArr.buffer]);
}
break;
}
}
}
/* harmony default export */ __webpack_exports__["a"] = (forceAtlas2Worker);
/***/ }),
/* 265 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_core_Base__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__retrieve__ = __webpack_require__(3);
/**
* @alias module:echarts-gl/util/Roam2DControl
*/
var Roam2DControl = __WEBPACK_IMPORTED_MODULE_0_claygl_src_core_Base__["a" /* default */].extend(function () {
return {
/**
* @type {module:zrender~ZRender}
*/
zr: null,
/**
* @type {module:echarts-gl/core/ViewGL}
*/
viewGL: null,
minZoom: 0.2,
maxZoom: 5,
_needsUpdate: false,
_dx: 0,
_dy: 0,
_zoom: 1
};
}, function () {
// Each Roam2DControl has it's own handler
this._mouseDownHandler = this._mouseDownHandler.bind(this);
this._mouseWheelHandler = this._mouseWheelHandler.bind(this);
this._mouseMoveHandler = this._mouseMoveHandler.bind(this);
this._mouseUpHandler = this._mouseUpHandler.bind(this);
this._update = this._update.bind(this);
}, {
init: function () {
var zr = this.zr;
zr.on('mousedown', this._mouseDownHandler);
zr.on('mousewheel', this._mouseWheelHandler);
zr.on('globalout', this._mouseUpHandler);
zr.animation.on('frame', this._update);
},
setTarget: function (target) {
this._target = target;
},
setZoom: function (zoom) {
this._zoom = Math.max(Math.min(
zoom, this.maxZoom
), this.minZoom);
this._needsUpdate = true;
},
setOffset: function (offset) {
this._dx = offset[0];
this._dy = offset[1];
this._needsUpdate = true;
},
getZoom: function () {
return this._zoom;
},
getOffset: function () {
return [this._dx, this._dy];
},
_update: function () {
if (!this._target) {
return;
}
if (!this._needsUpdate) {
return;
}
var target = this._target;
var scale = this._zoom;
target.position.x = this._dx;
target.position.y = this._dy;
target.scale.set(scale, scale, scale);
this.zr.refresh();
this._needsUpdate = false;
this.trigger('update');
},
_mouseDownHandler: function (e) {
if (e.target) {
return;
}
var x = e.offsetX;
var y = e.offsetY;
if (this.viewGL && !this.viewGL.containPoint(x, y)) {
return;
}
this.zr.on('mousemove', this._mouseMoveHandler);
this.zr.on('mouseup', this._mouseUpHandler);
var pos = this._convertPos(x, y);
this._x = pos.x;
this._y = pos.y;
},
// Convert pos from screen space to viewspace.
_convertPos: function (x, y) {
var camera = this.viewGL.camera;
var viewport = this.viewGL.viewport;
// PENDING
return {
x: (x - viewport.x) / viewport.width * (camera.right - camera.left) + camera.left,
y: (y - viewport.y) / viewport.height * (camera.bottom - camera.top) + camera.top
};
},
_mouseMoveHandler: function (e) {
var pos = this._convertPos(e.offsetX, e.offsetY);
this._dx += pos.x - this._x;
this._dy += pos.y - this._y;
this._x = pos.x;
this._y = pos.y;
this._needsUpdate = true;
},
_mouseUpHandler: function (e) {
this.zr.off('mousemove', this._mouseMoveHandler);
this.zr.off('mouseup', this._mouseUpHandler);
},
_mouseWheelHandler: function (e) {
e = e.event;
var delta = e.wheelDelta // Webkit
|| -e.detail; // Firefox
if (delta === 0) {
return;
}
var x = e.offsetX;
var y = e.offsetY;
if (this.viewGL && !this.viewGL.containPoint(x, y)) {
return;
}
var zoomScale = delta > 0 ? 1.1 : 0.9;
var newZoom = Math.max(Math.min(
this._zoom * zoomScale, this.maxZoom
), this.minZoom);
zoomScale = newZoom / this._zoom;
var pos = this._convertPos(x, y);
var fixX = (pos.x - this._dx) * (zoomScale - 1);
var fixY = (pos.y - this._dy) * (zoomScale - 1);
this._dx -= fixX;
this._dy -= fixY;
this._zoom = newZoom;
this._needsUpdate = true;
},
dispose: function () {
var zr = this.zr;
zr.off('mousedown', this._mouseDownHandler);
zr.off('mousemove', this._mouseMoveHandler);
zr.off('mouseup', this._mouseUpHandler);
zr.off('mousewheel', this._mouseWheelHandler);
zr.off('globalout', this._mouseUpHandler);
zr.animation.off('frame', this._update);
}
});
/* harmony default export */ __webpack_exports__["a"] = (Roam2DControl);
/***/ }),
/* 266 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.lines2D.vertex\n\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\n\nattribute vec2 position: POSITION;\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n\n#ifdef POSITIONTEXTURE_ENABLED\nuniform sampler2D positionTexture;\n#endif\n\nvoid main()\n{\n gl_Position = worldViewProjection * vec4(position, -10.0, 1.0);\n\n v_Color = a_Color;\n}\n\n@end\n\n@export ecgl.lines2D.fragment\n\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\n\nvarying vec4 v_Color;\n\nvoid main()\n{\n gl_FragColor = color * v_Color;\n}\n@end\n\n\n@export ecgl.meshLines2D.vertex\n\nattribute vec2 position: POSITION;\nattribute vec2 normal;\nattribute float offset;\nattribute vec4 a_Color : COLOR;\n\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform vec4 viewport : VIEWPORT;\n\nvarying vec4 v_Color;\nvarying float v_Miter;\n\nvoid main()\n{\n vec4 p2 = worldViewProjection * vec4(position + normal, -10.0, 1.0);\n gl_Position = worldViewProjection * vec4(position, -10.0, 1.0);\n\n p2.xy /= p2.w;\n gl_Position.xy /= gl_Position.w;\n\n vec2 N = normalize(p2.xy - gl_Position.xy);\n gl_Position.xy += N * offset / viewport.zw * 2.0;\n\n gl_Position.xy *= gl_Position.w;\n\n v_Color = a_Color;\n}\n@end\n\n\n@export ecgl.meshLines2D.fragment\n\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\n\nvarying vec4 v_Color;\nvarying float v_Miter;\n\nvoid main()\n{\n gl_FragColor = color * v_Color;\n}\n\n@end");
/***/ }),
/* 267 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__flowGL_FlowGLView__ = __webpack_require__(268);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__flowGL_FlowGLSeries__ = __webpack_require__(272);
/***/ }),
/* 268 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_retrieve__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__core_ViewGL__ = __webpack_require__(19);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__VectorFieldParticleSurface__ = __webpack_require__(269);
// TODO 百度地图不是 linear 的
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendChartView({
type: 'flowGL',
__ecgl__: true,
init: function (ecModel, api) {
this.viewGL = new __WEBPACK_IMPORTED_MODULE_3__core_ViewGL__["a" /* default */]('orthographic');
this.groupGL = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();
this.viewGL.add(this.groupGL);
this._particleSurface = new __WEBPACK_IMPORTED_MODULE_4__VectorFieldParticleSurface__["a" /* default */]();
var planeMesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
geometry: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].PlaneGeometry(),
material: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
shader: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader({
vertex: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.source('ecgl.color.vertex'),
fragment: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Shader.source('ecgl.color.fragment')
}),
// Must enable blending and multiply alpha.
// Or premultipliedAlpha will let the alpha useless.
transparent: true
})
});
planeMesh.material.enableTexture('diffuseMap');
this.groupGL.add(planeMesh);
this._planeMesh = planeMesh;
},
render: function (seriesModel, ecModel, api) {
var particleSurface = this._particleSurface;
// Set particleType before set others.
particleSurface.setParticleType(seriesModel.get('particleType'));
particleSurface.setSupersampling(seriesModel.get('supersampling'));
this._updateData(seriesModel, api);
this._updateCamera(api.getWidth(), api.getHeight(), api.getDevicePixelRatio());
var particleDensity = __WEBPACK_IMPORTED_MODULE_2__util_retrieve__["a" /* default */].firstNotNull(seriesModel.get('particleDensity'), 128);
particleSurface.setParticleDensity(particleDensity, particleDensity);
var planeMesh = this._planeMesh;
var time = +(new Date());
var self = this;
var firstFrame = true;
planeMesh.__percent = 0;
planeMesh.stopAnimation();
planeMesh.animate('', { loop: true })
.when(100000, {
__percent: 1
})
.during(function () {
var timeNow = + (new Date());
var dTime = Math.min(timeNow - time, 20);
time = time + dTime;
if (self._renderer) {
particleSurface.update(self._renderer, api, dTime / 1000, firstFrame);
planeMesh.material.set('diffuseMap', particleSurface.getSurfaceTexture());
// planeMesh.material.set('diffuseMap', self._particleSurface.vectorFieldTexture);
}
firstFrame = false;
})
.start();
var itemStyleModel = seriesModel.getModel('itemStyle');
var color = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(itemStyleModel.get('color'));
color[3] *= __WEBPACK_IMPORTED_MODULE_2__util_retrieve__["a" /* default */].firstNotNull(itemStyleModel.get('opacity'), 1);
planeMesh.material.set('color', color);
particleSurface.setColorTextureImage(seriesModel.get('colorTexture'), api);
particleSurface.setParticleSize(seriesModel.get('particleSize'));
particleSurface.particleSpeedScaling = seriesModel.get('particleSpeed');
particleSurface.motionBlurFactor = 1.0 - Math.pow(0.1, seriesModel.get('particleTrail'));
},
updateTransform: function (seriesModel, ecModel, api) {
this._updateData(seriesModel, api);
},
afterRender: function (globeModel, ecModel, api, layerGL) {
var renderer = layerGL.renderer;
this._renderer = renderer;
},
_updateData: function (seriesModel, api) {
var coordSys = seriesModel.coordinateSystem;
var dims = coordSys.dimensions.map(function (coordDim) {
return seriesModel.coordDimToDataDim(coordDim)[0];
});
var data = seriesModel.getData();
var xExtent = data.getDataExtent(dims[0]);
var yExtent = data.getDataExtent(dims[1]);
var gridWidth = seriesModel.get('gridWidth');
var gridHeight = seriesModel.get('gridHeight');
if (gridWidth == null || gridWidth === 'auto') {
// TODO not accurate.
var aspect = (xExtent[1] - xExtent[0]) / (yExtent[1] - yExtent[0]);
gridWidth = Math.round(Math.sqrt(aspect * data.count()));
}
if (gridHeight == null || gridHeight === 'auto') {
gridHeight = Math.ceil(data.count() / gridWidth);
}
var vectorFieldTexture = this._particleSurface.vectorFieldTexture;
// Half Float needs Uint16Array
var pixels = vectorFieldTexture.pixels;
if (!pixels || pixels.length !== gridHeight * gridWidth * 4) {
pixels = vectorFieldTexture.pixels = new Float32Array(gridWidth * gridHeight * 4);
}
else {
for (var i = 0; i < pixels.length; i++) {
pixels[i] = 0;
}
}
var maxMag = 0;
var minMag = Infinity;
var points = new Float32Array(data.count() * 2);
var offset = 0;
var bbox = [[Infinity, Infinity], [-Infinity, -Infinity]];
data.each([dims[0], dims[1], 'vx', 'vy'], function (x, y, vx, vy) {
var pt = coordSys.dataToPoint([x, y]);
points[offset++] = pt[0];
points[offset++] = pt[1];
bbox[0][0] = Math.min(pt[0], bbox[0][0]);
bbox[0][1] = Math.min(pt[1], bbox[0][1]);
bbox[1][0] = Math.max(pt[0], bbox[1][0]);
bbox[1][1] = Math.max(pt[1], bbox[1][1]);
var mag = Math.sqrt(vx * vx + vy * vy);
maxMag = Math.max(maxMag, mag);
minMag = Math.min(minMag, mag);
});
data.each(['vx', 'vy'], function (vx, vy, i) {
var xPix = Math.round((points[i * 2] - bbox[0][0]) / (bbox[1][0] - bbox[0][0]) * (gridWidth - 1));
var yPix = gridHeight - 1 - Math.round((points[i * 2 + 1] - bbox[0][1]) / (bbox[1][1] - bbox[0][1]) * (gridHeight - 1));
var idx = (yPix * gridWidth + xPix) * 4;
pixels[idx] = (vx / maxMag * 0.5 + 0.5);
pixels[idx + 1] = (vy / maxMag * 0.5 + 0.5);
pixels[idx + 3] = 1;
});
vectorFieldTexture.width = gridWidth;
vectorFieldTexture.height = gridHeight;
if (seriesModel.get('coordinateSystem') === 'bmap') {
this._fillEmptyPixels(vectorFieldTexture);
}
vectorFieldTexture.dirty();
this._updatePlanePosition(bbox[0], bbox[1], seriesModel,api);
this._updateGradientTexture(data.getVisual('visualMeta'), [minMag, maxMag]);
},
// PENDING Use grid mesh ? or delaunay triangulation?
_fillEmptyPixels: function (texture) {
var pixels = texture.pixels;
var width = texture.width;
var height = texture.height;
function fetchPixel(x, y, rg) {
x = Math.max(Math.min(x, width - 1), 0);
y = Math.max(Math.min(y, height - 1), 0);
var idx = (y * (width - 1) + x) * 4;
if (pixels[idx + 3] === 0) {
return false;
}
rg[0] = pixels[idx];
rg[1] = pixels[idx + 1];
return true;
}
function addPixel(a, b, out) {
out[0] = a[0] + b[0];
out[1] = a[1] + b[1];
}
var center = [], left = [], right = [], top = [], bottom = [];
var weight = 0;
for (var y = 0; y < height; y++) {
for (var x = 0; x < width; x++) {
var idx = (y * (width - 1) + x) * 4;
if (pixels[idx + 3] === 0) {
weight = center[0] = center[1] = 0;
if (fetchPixel(x - 1, y, left)) {
weight++; addPixel(left, center, center);
}
if (fetchPixel(x + 1, y, right)) {
weight++; addPixel(right, center, center);
}
if (fetchPixel(x, y - 1, top)) {
weight++; addPixel(top, center, center);
}
if (fetchPixel(x, y + 1, bottom)) {
weight++; addPixel(bottom, center, center);
}
center[0] /= weight;
center[1] /= weight;
// PENDING If overwrite. bilinear interpolation.
pixels[idx] = center[0];
pixels[idx + 1] = center[1];
}
pixels[idx + 3] = 1;
}
}
},
_updateGradientTexture: function (visualMeta, magExtent) {
if (!visualMeta || !visualMeta.length) {
this._particleSurface.setGradientTexture(null);
return;
}
// TODO Different dimensions
this._gradientTexture = this._gradientTexture || new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Texture2D({
image: document.createElement('canvas')
});
var gradientTexture = this._gradientTexture;
var canvas = gradientTexture.image;
canvas.width = 200;
canvas.height = 1;
var ctx = canvas.getContext('2d');
var gradient = ctx.createLinearGradient(0, 0.5, canvas.width, 0.5);
visualMeta[0].stops.forEach(function (stop) {
var offset;
if (magExtent[1] === magExtent[0]) {
offset = 0;
}
else {
offset = stop.value / magExtent[1];
offset = Math.min(Math.max(offset, 0), 1);
}
gradient.addColorStop(offset, stop.color);
});
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, canvas.width, canvas.height);
gradientTexture.dirty();
this._particleSurface.setGradientTexture(this._gradientTexture);
},
_updatePlanePosition: function (leftTop, rightBottom, seriesModel, api) {
var limitedResult = this._limitInViewportAndFullFill(leftTop, rightBottom, seriesModel, api);
leftTop = limitedResult.leftTop;
rightBottom = limitedResult.rightBottom;
this._particleSurface.setRegion(limitedResult.region);
this._planeMesh.position.set(
(leftTop[0] + rightBottom[0]) / 2,
api.getHeight() - (leftTop[1] + rightBottom[1]) / 2,
0
);
var width = rightBottom[0] - leftTop[0];
var height = rightBottom[1] - leftTop[1];
this._planeMesh.scale.set(width / 2, height / 2, 1);
this._particleSurface.resize(
Math.max(Math.min(width, 2048), 1),
Math.max(Math.min(height, 2048), 1)
);
if (this._renderer) {
this._particleSurface.clearFrame(this._renderer);
}
},
_limitInViewportAndFullFill: function (leftTop, rightBottom, seriesModel, api) {
var newLeftTop = [
Math.max(leftTop[0], 0),
Math.max(leftTop[1], 0)
];
var newRightBottom = [
Math.min(rightBottom[0], api.getWidth()),
Math.min(rightBottom[1], api.getHeight())
];
// Tiliing in lng orientation.
if (seriesModel.get('coordinateSystem') === 'bmap') {
var lngRange = seriesModel.getData().getDataExtent(seriesModel.coordDimToDataDim('lng')[0]);
// PENDING, consider grid density
var isContinuous = Math.floor(lngRange[1] - lngRange[0]) >= 359;
if (isContinuous) {
if (newLeftTop[0] > 0) {
newLeftTop[0] = 0;
}
if (newRightBottom[0] < api.getWidth()) {
newRightBottom[0] = api.getWidth();
}
}
}
var width = rightBottom[0] - leftTop[0];
var height = rightBottom[1] - leftTop[1];
var newWidth = newRightBottom[0] - newLeftTop[0];
var newHeight = newRightBottom[1] - newLeftTop[1];
var region = [
(newLeftTop[0] - leftTop[0]) / width,
1.0 - newHeight / height - (newLeftTop[1] - leftTop[1]) / height,
newWidth / width,
newHeight / height
];
return {
leftTop: newLeftTop,
rightBottom: newRightBottom,
region: region
};
},
_updateCamera: function (width, height, dpr) {
this.viewGL.setViewport(0, 0, width, height, dpr);
var camera = this.viewGL.camera;
// FIXME bottom can't be larger than top
camera.left = camera.bottom = 0;
camera.top = height;
camera.right = width;
camera.near = 0;
camera.far = 100;
camera.position.z = 10;
},
remove: function () {
this._planeMesh.stopAnimation();
this.groupGL.removeAll();
},
dispose: function () {
if (this._renderer) {
this._particleSurface.dispose(this._renderer);
}
this.groupGL.removeAll();
}
});
/***/ }),
/* 269 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_compositor_Pass__ = __webpack_require__(14);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_claygl_src_Geometry__ = __webpack_require__(13);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_claygl_src_Mesh__ = __webpack_require__(31);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_claygl_src_Material__ = __webpack_require__(17);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_claygl_src_Texture2D__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_claygl_src_Texture__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_claygl_src_camera_Orthographic__ = __webpack_require__(33);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8_claygl_src_geometry_Plane__ = __webpack_require__(37);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9_claygl_src_FrameBuffer__ = __webpack_require__(10);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__Line2D__ = __webpack_require__(270);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__vectorFieldParticle_glsl_js__ = __webpack_require__(271);
// import TemporalSS from '../../effect/TemporalSuperSampling';
__WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */]['import'](__WEBPACK_IMPORTED_MODULE_11__vectorFieldParticle_glsl_js__["a" /* default */]);
function createSpriteCanvas(size) {
var canvas = document.createElement('canvas');
canvas.width = canvas.height = size;
var ctx = canvas.getContext('2d');
ctx.fillStyle = '#fff';
ctx.arc(size / 2, size / 2, size / 2, 0, Math.PI * 2);
ctx.fill();
return canvas;
}
// import spriteUtil from '../../util/sprite';
var VectorFieldParticleSurface = function () {
/**
* @type {number}
*/
this.motionBlurFactor = 0.99;
/**
* Vector field lookup image
* @type {clay.Texture2D}
*/
this.vectorFieldTexture = new __WEBPACK_IMPORTED_MODULE_5_claygl_src_Texture2D__["a" /* default */]({
type: __WEBPACK_IMPORTED_MODULE_6_claygl_src_Texture__["a" /* default */].FLOAT,
// minFilter: Texture.NEAREST,
// magFilter: Texture.NEAREST,
flipY: false
});
/**
* Particle life range
* @type {Array.}
*/
this.particleLife = [5, 20];
this._particleType = 'point';
/**
* @type {number}
*/
this._particleSize = 1;
/**
* @type {Array.}
*/
this.particleColor = [1, 1, 1, 1];
/**
* @type {number}
*/
this.particleSpeedScaling = 1.0;
/**
* @type {clay.Texture2D}
*/
this._thisFrameTexture = null;
this._particlePass = null;
this._spawnTexture = null;
this._particleTexture0 = null;
this._particleTexture1 = null;
this._particlePointsMesh = null;
this._surfaceFrameBuffer = null;
this._elapsedTime = 0.0;
this._scene = null;
this._camera = null;
this._lastFrameTexture = null;
// this._temporalSS = new TemporalSS(50);
// this._antialising = false;
this._supersampling = 1;
this._downsampleTextures = [];
this._width = 512;
this._height = 512;
this.init();
};
VectorFieldParticleSurface.prototype = {
constructor: VectorFieldParticleSurface,
init: function () {
var parameters = {
type: __WEBPACK_IMPORTED_MODULE_6_claygl_src_Texture__["a" /* default */].FLOAT,
minFilter: __WEBPACK_IMPORTED_MODULE_6_claygl_src_Texture__["a" /* default */].NEAREST,
magFilter: __WEBPACK_IMPORTED_MODULE_6_claygl_src_Texture__["a" /* default */].NEAREST,
useMipmap: false
};
this._spawnTexture = new __WEBPACK_IMPORTED_MODULE_5_claygl_src_Texture2D__["a" /* default */](parameters);
this._particleTexture0 = new __WEBPACK_IMPORTED_MODULE_5_claygl_src_Texture2D__["a" /* default */](parameters);
this._particleTexture1 = new __WEBPACK_IMPORTED_MODULE_5_claygl_src_Texture2D__["a" /* default */](parameters);
this._frameBuffer = new __WEBPACK_IMPORTED_MODULE_9_claygl_src_FrameBuffer__["a" /* default */]({
depthBuffer: false
});
this._particlePass = new __WEBPACK_IMPORTED_MODULE_0_claygl_src_compositor_Pass__["a" /* default */]({
fragment: __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].source('ecgl.vfParticle.particle.fragment')
});
this._particlePass.setUniform('velocityTexture', this.vectorFieldTexture);
this._particlePass.setUniform('spawnTexture', this._spawnTexture);
this._downsamplePass = new __WEBPACK_IMPORTED_MODULE_0_claygl_src_compositor_Pass__["a" /* default */]({
fragment: __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].source('clay.compositor.downsample')
});
var particlePointsMesh = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_Mesh__["a" /* default */]({
// Render after last frame full quad
renderOrder: 10,
material: new __WEBPACK_IMPORTED_MODULE_3_claygl_src_Material__["a" /* default */]({
shader: new __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */](
__WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].source('ecgl.vfParticle.renderPoints.vertex'),
__WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].source('ecgl.vfParticle.renderPoints.fragment')
)
}),
mode: __WEBPACK_IMPORTED_MODULE_2_claygl_src_Mesh__["a" /* default */].POINTS,
geometry: new __WEBPACK_IMPORTED_MODULE_1_claygl_src_Geometry__["a" /* default */]({
dynamic: true,
mainAttribute: 'texcoord0'
})
});
var particleLinesMesh = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_Mesh__["a" /* default */]({
// Render after last frame full quad
renderOrder: 10,
material: new __WEBPACK_IMPORTED_MODULE_3_claygl_src_Material__["a" /* default */]({
shader: new __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */](
__WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].source('ecgl.vfParticle.renderLines.vertex'),
__WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].source('ecgl.vfParticle.renderLines.fragment')
)
}),
geometry: new __WEBPACK_IMPORTED_MODULE_10__Line2D__["a" /* default */](),
culling: false
});
var lastFrameFullQuad = new __WEBPACK_IMPORTED_MODULE_2_claygl_src_Mesh__["a" /* default */]({
material: new __WEBPACK_IMPORTED_MODULE_3_claygl_src_Material__["a" /* default */]({
shader: new __WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */](
__WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].source('ecgl.color.vertex'),
__WEBPACK_IMPORTED_MODULE_4_claygl_src_Shader__["a" /* default */].source('ecgl.color.fragment')
)
// DO NOT BLEND Blend will multiply alpha
// transparent: true
}),
geometry: new __WEBPACK_IMPORTED_MODULE_8_claygl_src_geometry_Plane__["a" /* default */]()
});
lastFrameFullQuad.material.enableTexture('diffuseMap');
this._particlePointsMesh = particlePointsMesh;
this._particleLinesMesh = particleLinesMesh;
this._lastFrameFullQuadMesh = lastFrameFullQuad;
this._camera = new __WEBPACK_IMPORTED_MODULE_7_claygl_src_camera_Orthographic__["a" /* default */]();
this._thisFrameTexture = new __WEBPACK_IMPORTED_MODULE_5_claygl_src_Texture2D__["a" /* default */]();
this._lastFrameTexture = new __WEBPACK_IMPORTED_MODULE_5_claygl_src_Texture2D__["a" /* default */]();
},
setParticleDensity: function (width, height) {
var nVertex = width * height;
var spawnTextureData = new Float32Array(nVertex * 4);
var off = 0;
var lifeRange = this.particleLife;
for (var i = 0; i < width; i++) {
for (var j = 0; j < height; j++, off++) {
// x position, range [0 - 1]
spawnTextureData[off * 4] = Math.random();
// y position, range [0 - 1]
spawnTextureData[off * 4 + 1] = Math.random();
// Some property
spawnTextureData[off * 4 + 2] = Math.random();
var life = (lifeRange[1] - lifeRange[0]) * Math.random() + lifeRange[0];
// Particle life
spawnTextureData[off * 4 + 3] = life;
}
}
if (this._particleType === 'line') {
this._setLineGeometry(width, height);
}
else {
this._setPointsGeometry(width, height);
}
this._spawnTexture.width = width;
this._spawnTexture.height = height;
this._spawnTexture.pixels = spawnTextureData;
this._particleTexture0.width = this._particleTexture1.width = width;
this._particleTexture0.height = this._particleTexture1.height = height;
this._particlePass.setUniform('textureSize', [width, height]);
},
_setPointsGeometry: function (width, height) {
var nVertex = width * height;
var geometry = this._particlePointsMesh.geometry;
var attributes = geometry.attributes;
attributes.texcoord0.init(nVertex);
var off = 0;
for (var i = 0; i < width; i++) {
for (var j = 0; j < height; j++, off++) {
attributes.texcoord0.value[off * 2] = i / width;
attributes.texcoord0.value[off * 2 + 1] = j / height;
}
}
geometry.dirty();
},
_setLineGeometry: function (width, height) {
var nLine = width * height;
var geometry = this._getParticleMesh().geometry;
geometry.setLineCount(nLine);
geometry.resetOffset();
for (var i = 0; i < width; i++) {
for (var j = 0; j < height; j++) {
geometry.addLine([i / width, j / height]);
}
}
geometry.dirty();
},
_getParticleMesh: function () {
return this._particleType === 'line' ? this._particleLinesMesh : this._particlePointsMesh;
},
update: function (renderer, api, deltaTime, firstFrame) {
var particleMesh = this._getParticleMesh();
var frameBuffer = this._frameBuffer;
var particlePass = this._particlePass;
if (firstFrame) {
this._updateDownsampleTextures(renderer, api);
}
particleMesh.material.set('size', this._particleSize * this._supersampling);
particleMesh.material.set('color', this.particleColor);
particlePass.setUniform('speedScaling', this.particleSpeedScaling);
frameBuffer.attach(this._particleTexture1);
particlePass.setUniform('firstFrameTime', firstFrame ? (this.particleLife[1] + this.particleLife[0]) / 2 : 0);
particlePass.setUniform('particleTexture', this._particleTexture0);
particlePass.setUniform('deltaTime', deltaTime);
particlePass.setUniform('elapsedTime', this._elapsedTime);
particlePass.render(renderer, frameBuffer);
particleMesh.material.set('particleTexture', this._particleTexture1);
particleMesh.material.set('prevParticleTexture', this._particleTexture0);
frameBuffer.attach(this._thisFrameTexture);
frameBuffer.bind(renderer);
renderer.gl.clear(renderer.gl.DEPTH_BUFFER_BIT | renderer.gl.COLOR_BUFFER_BIT);
var lastFrameFullQuad = this._lastFrameFullQuadMesh;
lastFrameFullQuad.material.set('diffuseMap', this._lastFrameTexture);
lastFrameFullQuad.material.set('color', [1, 1, 1, this.motionBlurFactor]);
this._camera.update(true);
renderer.renderPass([lastFrameFullQuad, particleMesh], this._camera);
frameBuffer.unbind(renderer);
this._downsample(renderer);
this._swapTexture();
this._elapsedTime += deltaTime;
},
_downsample: function (renderer) {
var downsampleTextures = this._downsampleTextures;
if (downsampleTextures.length === 0) {
return;
}
var current = 0;
var sourceTexture = this._thisFrameTexture;
var targetTexture = downsampleTextures[current];
while (targetTexture) {
this._frameBuffer.attach(targetTexture);
this._downsamplePass.setUniform('texture', sourceTexture);
this._downsamplePass.setUniform('textureSize', [sourceTexture.width, sourceTexture.height]);
this._downsamplePass.render(renderer, this._frameBuffer);
sourceTexture = targetTexture;
targetTexture = downsampleTextures[++current];
}
},
getSurfaceTexture: function () {
var downsampleTextures = this._downsampleTextures;
return downsampleTextures.length > 0
? downsampleTextures[downsampleTextures.length - 1]
: this._lastFrameTexture;
},
setRegion: function (region) {
this._particlePass.setUniform('region', region);
},
resize: function (width, height) {
this._lastFrameTexture.width = width * this._supersampling;
this._lastFrameTexture.height = height * this._supersampling;
this._thisFrameTexture.width = width * this._supersampling;
this._thisFrameTexture.height = height * this._supersampling;
this._width = width;
this._height = height;
},
setParticleSize: function (size) {
var particleMesh = this._getParticleMesh();
if (size <= 2) {
particleMesh.material.disableTexture('spriteTexture');
particleMesh.material.transparent = false;
return;
}
if (!this._spriteTexture) {
this._spriteTexture = new __WEBPACK_IMPORTED_MODULE_5_claygl_src_Texture2D__["a" /* default */]();
}
if (!this._spriteTexture.image || this._spriteTexture.image.width !== size) {
this._spriteTexture.image = createSpriteCanvas(size);
this._spriteTexture.dirty();
}
particleMesh.material.transparent = true;
particleMesh.material.enableTexture('spriteTexture');
particleMesh.material.set('spriteTexture', this._spriteTexture);
this._particleSize = size;
},
setGradientTexture: function (gradientTexture) {
var material = this._getParticleMesh().material;
material[gradientTexture ? 'enableTexture' : 'disableTexture']('gradientTexture');
material.setUniform('gradientTexture', gradientTexture);
},
setColorTextureImage: function (colorTextureImg, api) {
var material = this._getParticleMesh().material;
material.setTextureImage('colorTexture', colorTextureImg, api, {
flipY: true
});
},
setParticleType: function (type) {
this._particleType = type;
},
clearFrame: function (renderer) {
var frameBuffer = this._frameBuffer;
frameBuffer.attach(this._lastFrameTexture);
frameBuffer.bind(renderer);
renderer.gl.clear(renderer.gl.DEPTH_BUFFER_BIT | renderer.gl.COLOR_BUFFER_BIT);
frameBuffer.unbind(renderer);
},
setSupersampling: function (supersampling) {
this._supersampling = supersampling;
this.resize(this._width, this._height);
},
_updateDownsampleTextures: function (renderer, api) {
var downsampleTextures = this._downsampleTextures;
var upScale = Math.max(Math.floor(Math.log(this._supersampling / api.getDevicePixelRatio()) / Math.log(2)), 0);
var scale = 2;
var width = this._width * this._supersampling;
var height = this._height * this._supersampling;
for (var i = 0; i < upScale; i++) {
downsampleTextures[i] = downsampleTextures[i] || new __WEBPACK_IMPORTED_MODULE_5_claygl_src_Texture2D__["a" /* default */]();
downsampleTextures[i].width = width / scale;
downsampleTextures[i].height = height / scale;
scale *= 2;
}
for (;i < downsampleTextures.length; i++) {
downsampleTextures[i].dispose(renderer);
}
downsampleTextures.length = upScale;
},
_swapTexture: function () {
var tmp = this._particleTexture0;
this._particleTexture0 = this._particleTexture1;
this._particleTexture1 = tmp;
var tmp = this._thisFrameTexture;
this._thisFrameTexture = this._lastFrameTexture;
this._lastFrameTexture = tmp;
},
dispose: function (renderer) {
renderer.disposeFrameBuffer(this._frameBuffer);
// Dispose textures
renderer.disposeTexture(this.vectorFieldTexture);
renderer.disposeTexture(this._spawnTexture);
renderer.disposeTexture(this._particleTexture0);
renderer.disposeTexture(this._particleTexture1);
renderer.disposeTexture(this._thisFrameTexture);
renderer.disposeTexture(this._lastFrameTexture);
renderer.disposeGeometry(this._particleLinesMesh.geometry);
renderer.disposeGeometry(this._particlePointsMesh.geometry);
renderer.disposeGeometry(this._lastFrameFullQuadMesh.geometry);
if (this._spriteTexture) {
renderer.disposeTexture(this._spriteTexture);
}
this._particlePass.dispose(renderer);
this._downsamplePass.dispose(renderer);
this._downsampleTextures.forEach(function (texture) {
texture.dispose(renderer);
});
}
};
/* harmony default export */ __webpack_exports__["a"] = (VectorFieldParticleSurface);
/***/ }),
/* 270 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__ = __webpack_require__(13);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_echarts_lib_echarts__);
/**
* Lines geometry
* Use screen space projected lines lineWidth > MAX_LINE_WIDTH
* https://mattdesl.svbtle.com/drawing-lines-is-hard
* @module echarts-gl/util/geometry/LinesGeometry
* @author Yi Shen(http://github.com/pissang)
*/
/**
* @constructor
* @alias module:echarts-gl/chart/flowGL/Line2D
* @extends clay.Geometry
*/
var LinesGeometry = __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].extend(function () {
return {
dynamic: true,
attributes: {
position: new __WEBPACK_IMPORTED_MODULE_0_claygl_src_Geometry__["a" /* default */].Attribute('position', 'float', 3, 'POSITION')
}
};
},
/** @lends module: echarts-gl/util/geometry/LinesGeometry.prototype */
{
/**
* Reset offset
*/
resetOffset: function () {
this._vertexOffset = 0;
this._faceOffset = 0;
},
/**
* @param {number} nVertex
*/
setLineCount: function (nLine) {
var attributes = this.attributes;
var nVertex = 4 * nLine;
var nTriangle = 2 * nLine;
if (this.vertexCount !== nVertex) {
attributes.position.init(nVertex);
}
if (this.triangleCount !== nTriangle) {
if (nTriangle === 0) {
this.indices = null;
}
else {
this.indices = this.vertexCount > 0xffff ? new Uint32Array(nTriangle * 3) : new Uint16Array(nTriangle * 3);
}
}
},
addLine: function (p) {
var vertexOffset = this._vertexOffset;
this.attributes.position.set(vertexOffset, [p[0], p[1], 1]);
this.attributes.position.set(vertexOffset + 1, [p[0], p[1], -1]);
this.attributes.position.set(vertexOffset + 2, [p[0], p[1], 2]);
this.attributes.position.set(vertexOffset + 3, [p[0], p[1], -2]);
this.setTriangleIndices(
this._faceOffset++, [
vertexOffset, vertexOffset + 1, vertexOffset + 2
]
);
this.setTriangleIndices(
this._faceOffset++, [
vertexOffset + 1, vertexOffset + 2, vertexOffset + 3
]
);
this._vertexOffset += 4;
}
});
/* harmony default export */ __webpack_exports__["a"] = (LinesGeometry);
/***/ }),
/* 271 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony default export */ __webpack_exports__["a"] = ("@export ecgl.vfParticle.particle.fragment\n\nuniform sampler2D particleTexture;\nuniform sampler2D spawnTexture;\nuniform sampler2D velocityTexture;\n\nuniform float deltaTime;\nuniform float elapsedTime;\n\nuniform float speedScaling : 1.0;\n\nuniform vec2 textureSize;\nuniform vec4 region : [0, 0, 1, 1];\nuniform float firstFrameTime;\n\nvarying vec2 v_Texcoord;\n\n\nvoid main()\n{\n vec4 p = texture2D(particleTexture, v_Texcoord);\n bool spawn = false;\n if (p.w <= 0.0) {\n p = texture2D(spawnTexture, fract(v_Texcoord + elapsedTime / 10.0));\n p.w -= firstFrameTime;\n spawn = true;\n }\n vec2 v = texture2D(velocityTexture, fract(p.xy * region.zw + region.xy)).xy;\n v = (v - 0.5) * 2.0;\n p.z = length(v);\n p.xy += v * deltaTime / 10.0 * speedScaling;\n p.w -= deltaTime;\n\n if (spawn || p.xy != fract(p.xy)) {\n p.z = 0.0;\n }\n p.xy = fract(p.xy);\n\n gl_FragColor = p;\n}\n@end\n\n@export ecgl.vfParticle.renderPoints.vertex\n\n#define PI 3.1415926\n\nattribute vec2 texcoord : TEXCOORD_0;\n\nuniform sampler2D particleTexture;\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\n\nuniform float size : 1.0;\n\nvarying float v_Mag;\nvarying vec2 v_Uv;\n\nvoid main()\n{\n vec4 p = texture2D(particleTexture, texcoord);\n\n if (p.w > 0.0 && p.z > 1e-5) {\n gl_Position = worldViewProjection * vec4(p.xy * 2.0 - 1.0, 0.0, 1.0);\n }\n else {\n gl_Position = vec4(100000.0, 100000.0, 100000.0, 1.0);\n }\n\n v_Mag = p.z;\n v_Uv = p.xy;\n\n gl_PointSize = size;\n}\n\n@end\n\n@export ecgl.vfParticle.renderPoints.fragment\n\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\nuniform sampler2D gradientTexture;\nuniform sampler2D colorTexture;\nuniform sampler2D spriteTexture;\n\nvarying float v_Mag;\nvarying vec2 v_Uv;\n\nvoid main()\n{\n gl_FragColor = color;\n#ifdef SPRITETEXTURE_ENABLED\n gl_FragColor *= texture2D(spriteTexture, gl_PointCoord);\n if (color.a == 0.0) {\n discard;\n }\n#endif\n#ifdef GRADIENTTEXTURE_ENABLED\n gl_FragColor *= texture2D(gradientTexture, vec2(v_Mag, 0.5));\n#endif\n#ifdef COLORTEXTURE_ENABLED\n gl_FragColor *= texture2D(colorTexture, v_Uv);\n#endif\n}\n\n@end\n\n@export ecgl.vfParticle.renderLines.vertex\n\n#define PI 3.1415926\n\nattribute vec3 position : POSITION;\n\nuniform sampler2D particleTexture;\nuniform sampler2D prevParticleTexture;\n\nuniform float size : 1.0;\nuniform vec4 vp: VIEWPORT;\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\n\nvarying float v_Mag;\nvarying vec2 v_Uv;\n\n@import clay.util.rand\n\nvoid main()\n{\n vec4 p = texture2D(particleTexture, position.xy);\n vec4 p2 = texture2D(prevParticleTexture, position.xy);\n\n p.xy = p.xy * 2.0 - 1.0;\n p2.xy = p2.xy * 2.0 - 1.0;\n\n if (p.w > 0.0 && p.z > 1e-5) {\n vec2 dir = normalize(p.xy - p2.xy);\n vec2 norm = vec2(dir.y / vp.z, -dir.x / vp.w) * sign(position.z) * size;\n if (abs(position.z) == 2.0) {\n gl_Position = vec4(p.xy + norm, 0.0, 1.0);\n v_Uv = p.xy;\n v_Mag = p.z;\n }\n else {\n gl_Position = vec4(p2.xy + norm, 0.0, 1.0);\n v_Mag = p2.z;\n v_Uv = p2.xy;\n }\n gl_Position = worldViewProjection * gl_Position;\n }\n else {\n gl_Position = vec4(100000.0, 100000.0, 100000.0, 1.0);\n }\n}\n\n@end\n\n@export ecgl.vfParticle.renderLines.fragment\n\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\nuniform sampler2D gradientTexture;\nuniform sampler2D colorTexture;\n\nvarying float v_Mag;\nvarying vec2 v_Uv;\n\nvoid main()\n{\n gl_FragColor = color;\n #ifdef GRADIENTTEXTURE_ENABLED\n gl_FragColor *= texture2D(gradientTexture, vec2(v_Mag, 0.5));\n#endif\n#ifdef COLORTEXTURE_ENABLED\n gl_FragColor *= texture2D(colorTexture, v_Uv);\n#endif\n}\n\n@end\n");
/***/ }),
/* 272 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendSeriesModel({
type: 'series.flowGL',
dependencies: ['geo', 'grid', 'bmap'],
visualColorAccessPath: 'itemStyle.color',
getInitialData: function (option, ecModel) {
var coordSysDimensions = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.getCoordinateSystemDimensions(this.get('coordinateSystem')) || ['x', 'y'];
if (true) {
if (coordSysDimensions.length > 2) {
throw new Error('flowGL can only be used on 2d coordinate systems.')
}
}
coordSysDimensions.push('vx', 'vy');
var dimensions = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.helper.completeDimensions(coordSysDimensions, this.getSource(), {
encodeDef: this.get('encode'),
dimsDef: this.get('dimensions')
});
var data = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.List(dimensions, this);
data.initData(this.getSource());
return data;
},
defaultOption: {
coordinateSystem: 'cartesian2d',
zlevel: 10,
supersampling: 1,
// 128x128 particles
particleType: 'point',
particleDensity: 128,
particleSize: 1,
particleSpeed: 1,
particleTrail: 2,
colorTexture: null,
gridWidth: 'auto',
gridHeight: 'auto',
itemStyle: {
color: '#fff',
opacity: 0.8
}
}
});
/***/ }),
/* 273 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__linesGL_LinesGLSeries__ = __webpack_require__(274);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__linesGL_LinesGLView__ = __webpack_require__(275);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__common_opacityVisual__ = __webpack_require__(16);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.registerVisual(Object(__WEBPACK_IMPORTED_MODULE_3__common_opacityVisual__["a" /* default */])('linesGL'));
/***/ }),
/* 274 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_zrender_lib_core_util__ = __webpack_require__(12);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_zrender_lib_core_util___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_zrender_lib_core_util__);
var LinesSeries = __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendSeriesModel({
type: 'series.linesGL',
dependencies: ['grid', 'geo'],
visualColorAccessPath: 'lineStyle.color',
streamEnabled: true,
init: function (option) {
var result = this._processFlatCoordsArray(option.data);
this._flatCoords = result.flatCoords;
this._flatCoordsOffset = result.flatCoordsOffset;
if (result.flatCoords) {
option.data = new Float32Array(result.count);
}
LinesSeries.superApply(this, 'init', arguments);
},
mergeOption: function (option) {
var result = this._processFlatCoordsArray(option.data);
this._flatCoords = result.flatCoords;
this._flatCoordsOffset = result.flatCoordsOffset;
if (result.flatCoords) {
option.data = new Float32Array(result.count);
}
LinesSeries.superApply(this, 'mergeOption', arguments);
},
appendData: function (params) {
var result = this._processFlatCoordsArray(params.data);
if (result.flatCoords) {
if (!this._flatCoords) {
this._flatCoords = result.flatCoords;
this._flatCoordsOffset = result.flatCoordsOffset;
}
else {
this._flatCoords = Object(__WEBPACK_IMPORTED_MODULE_1_zrender_lib_core_util__["concatArray"])(this._flatCoords, result.flatCoords);
this._flatCoordsOffset = Object(__WEBPACK_IMPORTED_MODULE_1_zrender_lib_core_util__["concatArray"])(this._flatCoordsOffset, result.flatCoordsOffset);
}
params.data = new Float32Array(result.count);
}
this.getRawData().appendData(params.data);
},
_getCoordsFromItemModel: function (idx) {
var itemModel = this.getData().getItemModel(idx);
var coords = (itemModel.option instanceof Array)
? itemModel.option : itemModel.getShallow('coords');
if (true) {
if (!(coords instanceof Array && coords.length > 0 && coords[0] instanceof Array)) {
throw new Error('Invalid coords ' + JSON.stringify(coords) + '. Lines must have 2d coords array in data item.');
}
}
return coords;
},
getLineCoordsCount: function (idx) {
if (this._flatCoordsOffset) {
return this._flatCoordsOffset[idx * 2 + 1];
}
else {
return this._getCoordsFromItemModel(idx).length;
}
},
getLineCoords: function (idx, out) {
if (this._flatCoordsOffset) {
var offset = this._flatCoordsOffset[idx * 2];
var len = this._flatCoordsOffset[idx * 2 + 1];
for (var i = 0; i < len; i++) {
out[i] = out[i] || [];
out[i][0] = this._flatCoords[offset + i * 2];
out[i][1] = this._flatCoords[offset + i * 2 + 1];
}
return len;
}
else {
var coords = this._getCoordsFromItemModel(idx);
for (var i = 0; i < coords.length; i++) {
out[i] = out[i] || [];
out[i][0] = coords[i][0];
out[i][1] = coords[i][1];
}
return coords.length;
}
},
_processFlatCoordsArray: function (data) {
var startOffset = 0;
if (this._flatCoords) {
startOffset = this._flatCoords.length;
}
// Stored as a typed array. In format
// Points Count(2) | x | y | x | y | Points Count(3) | x | y | x | y | x | y |
if (typeof data[0] === 'number') {
var len = data.length;
// Store offset and len of each segment
var coordsOffsetAndLenStorage = new Uint32Array(len);
var coordsStorage = new Float64Array(len);
var coordsCursor = 0;
var offsetCursor = 0;
var dataCount = 0;
for (var i = 0; i < len;) {
dataCount++;
var count = data[i++];
// Offset
coordsOffsetAndLenStorage[offsetCursor++] = coordsCursor + startOffset;
// Len
coordsOffsetAndLenStorage[offsetCursor++] = count;
for (var k = 0; k < count; k++) {
var x = data[i++];
var y = data[i++];
coordsStorage[coordsCursor++] = x;
coordsStorage[coordsCursor++] = y;
if (i > len) {
if (true) {
throw new Error('Invalid data format.');
}
}
}
}
return {
flatCoordsOffset: new Uint32Array(coordsOffsetAndLenStorage.buffer, 0, offsetCursor),
flatCoords: coordsStorage,
count: dataCount
};
}
return {
flatCoordsOffset: null,
flatCoords: null,
count: data.length
};
},
getInitialData: function (option, ecModel) {
var lineData = new __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.List(['value'], this);
lineData.hasItemOption = false;
lineData.initData(option.data, [], function (dataItem, dimName, dataIndex, dimIndex) {
// dataItem is simply coords
if (dataItem instanceof Array) {
return NaN;
}
else {
lineData.hasItemOption = true;
var value = dataItem.value;
if (value != null) {
return value instanceof Array ? value[dimIndex] : value;
}
}
});
return lineData;
},
defaultOption: {
coordinateSystem: 'geo',
zlevel: 10,
progressive: 1e4,
progressiveThreshold: 5e4,
// Cartesian coordinate system
// xAxisIndex: 0,
// yAxisIndex: 0,
// Geo coordinate system
// geoIndex: 0,
// Support source-over, lighter
blendMode: 'source-over',
lineStyle: {
opacity: 0.8
},
postEffect: {
enable: false,
colorCorrection: {
exposure: 0,
brightness: 0,
contrast: 1,
saturation: 1,
enable: true
}
}
}
});
/***/ }),
/* 275 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__core_ViewGL__ = __webpack_require__(19);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_geometry_Lines2D__ = __webpack_require__(98);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__common_GLViewHelper__ = __webpack_require__(96);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__util_retrieve__ = __webpack_require__(3);
__WEBPACK_IMPORTED_MODULE_0_echarts_lib_echarts___default.a.extendChartView({
type: 'linesGL',
__ecgl__: true,
init: function (ecModel, api) {
this.groupGL = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Node();
this.viewGL = new __WEBPACK_IMPORTED_MODULE_2__core_ViewGL__["a" /* default */]('orthographic');
this.viewGL.add(this.groupGL);
this._glViewHelper = new __WEBPACK_IMPORTED_MODULE_4__common_GLViewHelper__["a" /* default */](this.viewGL);
this._nativeLinesShader = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createShader('ecgl.lines3D');
this._meshLinesShader = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createShader('ecgl.meshLines3D');
this._linesMeshes = [];
this._currentStep = 0;
},
render: function (seriesModel, ecModel, api) {
this.groupGL.removeAll();
this._glViewHelper.reset(seriesModel, api);
var linesMesh = this._linesMeshes[0];
if (!linesMesh) {
linesMesh = this._linesMeshes[0] = this._createLinesMesh(seriesModel);
}
this._linesMeshes.length = 1;
this.groupGL.add(linesMesh);
this._updateLinesMesh(seriesModel, linesMesh, 0, seriesModel.getData().count());
this.viewGL.setPostEffect(seriesModel.getModel('postEffect'), api);
},
incrementalPrepareRender: function (seriesModel, ecModel, api) {
this.groupGL.removeAll();
this._glViewHelper.reset(seriesModel, api);
this._currentStep = 0;
this.viewGL.setPostEffect(seriesModel.getModel('postEffect'), api);
},
incrementalRender: function (params, seriesModel, ecModel, api) {
var linesMesh = this._linesMeshes[this._currentStep];
if (!linesMesh) {
linesMesh = this._createLinesMesh(seriesModel);
this._linesMeshes[this._currentStep] = linesMesh;
}
this._updateLinesMesh(seriesModel, linesMesh, params.start, params.end);
this.groupGL.add(linesMesh);
api.getZr().refresh();
this._currentStep++;
},
updateTransform: function (seriesModel, ecModel, api) {
if (seriesModel.coordinateSystem.getRoamTransform) {
this._glViewHelper.updateTransform(seriesModel, api);
}
},
_createLinesMesh: function (seriesModel) {
var linesMesh = new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh({
$ignorePicking: true,
material: new __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Material({
shader: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].createShader('ecgl.lines3D'),
transparent: true,
depthMask: false,
depthTest: false
}),
geometry: new __WEBPACK_IMPORTED_MODULE_3__util_geometry_Lines2D__["a" /* default */]({
segmentScale: 10,
useNativeLine: true,
dynamic: false
}),
mode: __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh.LINES,
culling: false
});
return linesMesh;
},
_updateLinesMesh: function (seriesModel, linesMesh, start, end) {
var data = seriesModel.getData();
linesMesh.material.blend = seriesModel.get('blendMode') === 'lighter'
? __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].additiveBlend : null;
var curveness = seriesModel.get('lineStyle.curveness') || 0;
var isPolyline = seriesModel.get('polyline');
var geometry = linesMesh.geometry;
var coordSys = seriesModel.coordinateSystem;
var lineWidth = __WEBPACK_IMPORTED_MODULE_5__util_retrieve__["a" /* default */].firstNotNull(seriesModel.get('lineStyle.width'), 1);
if (lineWidth > 1) {
if (linesMesh.material.shader !== this._meshLinesShader) {
linesMesh.material.attachShader(this._meshLinesShader);
}
linesMesh.mode = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh.TRIANGLES;
}
else {
if (linesMesh.material.shader !== this._nativeLinesShader) {
linesMesh.material.attachShader(this._nativeLinesShader);
}
linesMesh.mode = __WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].Mesh.LINES;
}
start = start || 0;
end = end || data.count();
geometry.resetOffset();
var vertexCount = 0;
var triangleCount = 0;
var p0 = [];
var p1 = [];
var p2 = [];
var p3 = [];
var lineCoords = [];
var t = 0.3;
var t2 = 0.7;
function updateBezierControlPoints() {
p1[0] = (p0[0] * t2 + p3[0] * t) - (p0[1] - p3[1]) * curveness;
p1[1] = (p0[1] * t2 + p3[1] * t) - (p3[0] - p0[0]) * curveness;
p2[0] = (p0[0] * t + p3[0] * t2) - (p0[1] - p3[1]) * curveness;
p2[1] = (p0[1] * t + p3[1] * t2) - (p3[0] - p0[0]) * curveness;
}
if (isPolyline || curveness !== 0) {
for (var idx = start; idx < end; idx++) {
if (isPolyline) {
var count = seriesModel.getLineCoordsCount(idx);
vertexCount += geometry.getPolylineVertexCount(count);
triangleCount += geometry.getPolylineTriangleCount(count);
}
else {
seriesModel.getLineCoords(idx, lineCoords);
this._glViewHelper.dataToPoint(coordSys, lineCoords[0], p0);
this._glViewHelper.dataToPoint(coordSys, lineCoords[1], p3);
updateBezierControlPoints();
vertexCount += geometry.getCubicCurveVertexCount(p0, p1, p2, p3);
triangleCount += geometry.getCubicCurveTriangleCount(p0, p1, p2, p3);
}
}
}
else {
var lineCount = end - start;
vertexCount += lineCount * geometry.getLineVertexCount();
triangleCount += lineCount * geometry.getLineVertexCount();
}
geometry.setVertexCount(vertexCount);
geometry.setTriangleCount(triangleCount);
var dataIndex = start;
var colorArr = [];
for (var idx = start; idx < end; idx++) {
__WEBPACK_IMPORTED_MODULE_1__util_graphicGL__["a" /* default */].parseColor(data.getItemVisual(dataIndex, 'color'), colorArr);
var opacity = __WEBPACK_IMPORTED_MODULE_5__util_retrieve__["a" /* default */].firstNotNull(data.getItemVisual(dataIndex, 'opacity'), 1);
colorArr[3] *= opacity;
var count = seriesModel.getLineCoords(idx, lineCoords);
for (var k = 0; k < count; k++) {
this._glViewHelper.dataToPoint(coordSys, lineCoords[k], lineCoords[k]);
}
if (isPolyline) {
geometry.addPolyline(lineCoords, colorArr, lineWidth, 0, count);
}
else if (curveness !== 0) {
p0 = lineCoords[0];
p3 = lineCoords[1];
updateBezierControlPoints();
geometry.addCubicCurve(p0, p1, p2, p3, colorArr, lineWidth);
}
else {
geometry.addPolyline(lineCoords, colorArr, lineWidth, 0, 2);
}
dataIndex++;
}
},
dispose: function () {
this.groupGL.removeAll();
},
remove: function () {
this.groupGL.removeAll();
}
});
/***/ })
/******/ ]);
});