UNPKG

@vtx/cs-map

Version:

React components for Vortex

204 lines (197 loc) 9.13 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _cesium = require("cesium"); function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } // 三维模型裁剪 var Cut = /*#__PURE__*/function () { function Cut(tileset, opt) { _classCallCheck(this, Cut); if (!tileset) { console.log("缺少模型"); return; } this.tileset = tileset; this.opt = opt || {}; /** * @property {Boolean} iscutOutter 是否为外部裁剪,默认为内部裁剪 */ this._iscutOutter = this.opt.iscutOutter; // 是否为外部裁剪 默认为内部裁剪 this.cutRegions = []; // 当前裁剪面数组对象 /* this.modelMatrix = new Matrix4(); // 世界坐标系--》模型坐标系 Matrix4.inverseTransformation(this.tileset.root.computedTransform, this.modelMatrix) */ // 建立模型中心点坐标系 var center = this.tileset.boundingSphere.center; var enuMtx4 = _cesium.Transforms.eastNorthUpToFixedFrame(center); this.modelMatrix = _cesium.Matrix4.inverse(enuMtx4, new _cesium.Matrix4()); this.canvas = undefined; } return _createClass(Cut, [{ key: "iscutOutter", get: function get() { return this._iscutOutter; }, set: function set(val) { this._iscutOutter = val; this.updateShader(); } /** * 添加裁剪面 * @param {Object} attr 参数 * @param {Cartesian3[]} attr.positions 压平面坐标 * @param {Number} attr.id 唯一标识 */ }, { key: "addRegion", value: function addRegion(attr) { var _ref = attr || {}, positions = _ref.positions, id = _ref.id; if (!id) id = new Date().getTime() + "" + Number(Math.random() * 1000).toFixed(0); if (!positions || positions.length < 3) { console.log("缺少裁剪面坐标"); return; } var index = this.cutRegions.findIndex(function (item) { return item.id === id; }); if (index == -1) { this.cutRegions.push({ id: id, positions: positions }); } else { this.cutRegions[index].positions = positions; } this.updateShader(); } /** * 移除裁剪面 * @param {String} id */ }, { key: "removeRegionById", value: function removeRegionById(id) { if (id) { // 表示移除所有的裁剪面 var index = this.cutRegions.findIndex(function (item) { return item.id === id; }); if (index != -1) this.cutRegions.splice(index, 1); } else { // 表示移除单个的裁剪面 this.cutRegions = []; } this.updateShader(); } /** * 销毁 */ }, { key: "destroy", value: function destroy() { this.tileset.customShader = undefined; } /** * 修改模型着色器 */ }, { key: "updateShader", value: function updateShader() { var _this = this; // 定义着色器中裁剪函数 var fs_textureMapRect = "\n vec4 textureMapRect(vec4 rect, sampler2D map, vec2 xy) {\n // \u5224\u65AD\u5F53\u524D\u56FE\u5143\u5750\u6807\u548C\u591A\u8FB9\u5F62\u5173\u7CFB \u5982\u679C\u5728\u591A\u8FB9\u5F62\u5185 \u8FDB\u884C\u7EB9\u7D20\u62FE\u53D6\n if (xy.x >= rect.x && xy.x <= rect.z && xy.y >= rect.y && xy.y <= rect.w) {\n float w = rect.z - rect.x;\n float h = rect.w - rect.y;\n float s = (xy.x - rect.x) / w;\n float t = (xy.y - rect.y) / h;\n vec4 color = texture(map, vec2(s, 1.0 - t));\n return color;\n }\n return vec4(1.0);\n }\n "; var allUniforms = { u_inverseModel: { type: _cesium.UniformType.MAT4, value: this.modelMatrix.clone() }, u_unionCutRegions: { type: _cesium.UniformType.BOOL, value: this._iscutOutter } }; // 构建多区域着色器 var fs = ""; this.cutRegions.forEach(function (element) { var uniforms = _this.createUniforms(element.positions, element.id); allUniforms = (0, _cesium.combine)(allUniforms, uniforms); fs += "\n vec4 color_".concat(element.id, " = textureMapRect(u_rect_").concat(element.id, ", u_map_").concat(element.id, ", xy);\n cutColor *= color_").concat(element.id, ";\n "); }); fs += "\n if (u_unionCutRegions) {\n material.diffuse *= (vec3(1.0) - cutColor.rgb);\n } else {\n material.diffuse *= cutColor.rgb;\n }\n if (material.diffuse.r <= 0.0001 && material.diffuse.g <= 0.0001 && material.diffuse.b <= 0.0001) {\n discard;\n }\n "; this.tileset.customShader = new _cesium.CustomShader({ uniforms: allUniforms, fragmentShaderText: "\n ".concat(fs_textureMapRect, "\n void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {\n vec4 positionMC = u_inverseModel * vec4(fsInput.attributes.positionWC, 1.0);\n vec2 xy = positionMC.xy;\n vec4 cutColor = vec4(1.0);\n ").concat(fs, "\n }") }); } /** * 根据坐标创建片元着色器 * @param {Cartesian3[]} positions * @param {String} id */ }, { key: "createUniforms", value: function createUniforms(positions, id) { var _this2 = this; if (!positions || positions.length < 3) { console.log("缺少裁剪面坐标"); return; } id = id || Math.ceil(Math.random() * 100000) + '_' + Math.ceil(Math.random() * 100000); // 根据世界坐标范围计算相对模型坐标范围 var xs = [], ys = [], zs = []; // 计算模型坐标系下坐标 var modelPoints = positions.map(function (p) { var point = _cesium.Matrix4.multiplyByPoint(_this2.modelMatrix, p, new _cesium.Cartesian3()); xs.push(point.x); ys.push(point.y); zs.push(point.z); return point; }); // 计算当前裁剪面边界范围(模型坐标系下) var rect = new _cesium.Cartesian4(Math.min.apply(null, xs), Math.min.apply(null, ys), Math.max.apply(null, xs), Math.max.apply(null, ys)); var canvas = document.createElement('canvas'); canvas.width = 1024; canvas.height = 1024; var width = rect.z - rect.x; var height = rect.w - rect.y; var ctx = canvas.getContext('2d'); ctx.fillStyle = '#fff'; // 设置整体背景为白色 ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.beginPath(); ctx.moveTo(canvas.width * (modelPoints[0].x - rect.x) / width, canvas.height * (modelPoints[0].y - rect.y) / height); for (var i = 1; i < modelPoints.length; i++) { ctx.lineTo(canvas.width * (modelPoints[i].x - rect.x) / width, canvas.height * (modelPoints[i].y - rect.y) / height); } ctx.closePath(); ctx.fillStyle = '#000'; // 根据填充的黑色来裁剪模型 ctx.fill(); this.canvas = canvas; var uniforms = {}; uniforms["u_rect_".concat(id)] = { type: _cesium.UniformType.VEC4, value: rect }; uniforms["u_map_".concat(id)] = { type: _cesium.UniformType.SAMPLER_2D, value: new _cesium.TextureUniform({ url: canvas.toDataURL() }), minificationFilter: _cesium.TextureMinificationFilter.LINEAR, magnificationFilter: _cesium.TextureMagnificationFilter.LINEAR }; return uniforms; } }]); }(); var _default = exports["default"] = Cut; //# sourceMappingURL=Cut.js.map