3DTiles是一种用于组织和传输大规模地理数据的规范,旨在提供一种高效、可扩展的方式来加载和显示复杂的3D模型。它革新了地理数据可视化领域,为创建逼真的三维地图提供了新的可能性。
3DTiles采用了一种层次化的数据结构,将地理信息按照空间范围划分成小块,类似于3D瓦片。每个瓦片包含地理实体的几何形状、纹理贴图和层次结构信息。这种切片和分层的方式使得数据可以根据需要按需加载,从而降低了网络传输和计算资源的需求。
使用3DTiles,开发人员可以加载和呈现各种地理数据,如建筑物、地形、植被和其他点云数据等。它为基于Web的GIS应用提供了更好的性能和交互体验。用户可以在浏览器中平滑地导航和浏览模型,实时更改视图和展示参数。
此外,3DTiles的规范性设计使得它可以与其他GIS和地理数据标准(如地理坐标系、投影等)无缝集成。它的开放性和普及性使得很多GIS软件和服务已经支持3DTiles标准,从而为用户和开发人员提供了丰富的工具和资源。
总之,3DTiles为地理数据的可视化和交互提供了一种全新的方式。其中,加载3DTiles模型并实现选中和高亮效果是常见的需求之一。
因此,本文将介绍如何实现模型的选中和高亮效果。我们将详细讨论Cesium中的picking机制,引导读者根据用户的鼠标点击或触摸事件来选中模型。进一步,我们将讨论如何改变选中模型的外观,例如更改颜色、变更材质等,从而实现高亮效果。
如代码所示,主要通过修改片元着色器或color属性,实现模型的左键选中,右键取消效果,移入高亮效果;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
<meta name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<title>3D Tiles</title>
<link href="../../Build/Cesium/Widgets/widgets.css" rel="stylesheet">
<link href="./css/pretty.css" rel="stylesheet">
<script src="./js/jquery.min.js"></script>
<script type="text/javascript" src="../../Build/Cesium/Cesium.js"></script>
</head>
<body>
<div id="cesiumContainer"></div>
<script>
function onload(Cesium) {
console.log(Cesium.Ellipsoid.WGS84)
var obj = [6378137.0, 6378137.0, 6356752.3142451793];
Cesium.Ellipsoid.WGS84 = Object.freeze(new Cesium.Ellipsoid(obj[0], obj[1], obj[2]));
var viewer = new Cesium.Viewer('cesiumContainer');
const options = {
skipLevelOfDetail: true,
shadows: Cesium.ShadowMode.CAST_ONLY,
baseScreenSpaceError: 1024,
skipScreenSpaceErrorFactor: 16,
skipLevels: 1,
immediatelyLoadDesiredLevelOfDetail: false,
loadSiblings: false,
cullWithChildrenBounds: true,
dynamicScreenSpaceError: true,
dynamicScreenSpaceErrorHeightFalloff: 0.5,
url: './SampleData/line/tileset.json'
}
const tileset = new Cesium.Cesium3DTileset(options)
viewer.terrainProvider.visible = false;
var ts = viewer.scene.primitives.add(tileset);
console.log("ts", ts)
ts.readyPromise.then(function () {
var boundingSphere = ts.boundingSphere;
viewer.camera.viewBoundingSphere(boundingSphere, new Cesium.HeadingPitchRange(0.0, -0.5, boundingSphere.radius));
viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);
}).otherwise(function (error) {
throw (error);
});
var screenSpaceEventHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
let pickedObjectArr = [], shader = null
screenSpaceEventHandler.setInputAction(function (e) {
let pickedObject = viewer.scene.pick(e.position);
if (pickedObject && pickedObject._content && pickedObject._content._features && pickedObject._content._features.length > 0) {
pickedObjectArr.push(pickedObject)
let feature = pickedObject._content._features[0]
const _model = feature.content._model
_model._shouldRegenerateShaders = true
console.log(_model._sourcePrograms)
console.log(_model._rendererResources.sourceShaders)
shader = _model._rendererResources.sourceShaders[1]
_model._rendererResources.sourceShaders[1] = _model._rendererResources.sourceShaders[1].replace("gl_FragColor = vec4(color, 1.0);", "gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);");
setTimeout(() => {
_model._shouldRegenerateShaders = false
}, 1000)
console.log(_model._rendererResources.sourceShaders[1])
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
screenSpaceEventHandler.setInputAction(function (e) {
while (pickedObjectArr.length > 0) {
let element = pickedObjectArr.shift();
let feature = element._content._features[0]
const _model = feature.content._model
_model._shouldRegenerateShaders = true
console.log(_model._sourcePrograms)
console.log(_model._rendererResources.sourceShaders)
_model._rendererResources.sourceShaders[1] = shader
console.log(shader)
}
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
let feature, _feature, tile
const highlightColor = new Cesium.Color(1.0, 1.0, 0.0, 0.4);
const oldColor = new Cesium.Color();
screenSpaceEventHandler.setInputAction(function (e) {
const picked = viewer.scene.pick(e.endPosition);
if (picked instanceof Cesium.Cesium3DTileFeature) {
// Picked a feature
feature = picked;
if (feature === _feature && feature !== undefined) {
console.log("相同")
return
}
const currentFeature = _feature;
if (currentFeature && !currentFeature.content.isDestroyed()) {
currentFeature.color = oldColor;
// viewer.scene.requestRender();
}
tile = picked.content.tile;
Cesium.Color.clone(feature.color, oldColor);
feature.color = highlightColor;
// viewer.scene.requestRender();
_feature = feature;
} else {
if (feature !== undefined && feature !== null) {
console.log("非模型,清除颜色")
feature.color = oldColor;
// viewer.scene.requestRender();
feature = null
_feature = null
}
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
$('#loadingbar').remove();
}
if (typeof Cesium !== 'undefined') {
window.startupCalled = true;
onload(Cesium);
}
</script>
</body>
</html>
文章来源:https://www.toymoban.com/news/detail-723879.html
文章来源地址https://www.toymoban.com/news/detail-723879.html
到了这里,关于cesium——加载3DTiles,模型的选中,高亮效果的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!