@vtx/cs-map
Version:
React components for Vortex
204 lines (197 loc) • 9.13 kB
JavaScript
;
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