数字孪生大屏必看:Cesium 3D 模型选中交互,3 种高亮效果拿来就用!

接前文,3D模型加载到页面以后肯定要执行各种各样的操作,模型在大屏上的主要作用是执行相应的建筑物交互。

问题

这里需要注意3D模型的加载仍然存在一些问题。

首先是如果你使用的GLTF文件,在某些特殊情况下可能导致模型的网格加载异常,会出现无法选中的情况。

这一点我目前没发现有什么太好的解决方案,所以这里采用GLB文件规避掉了这个问题。

如果你手里只有GLTF文件,可以考虑使用 Blender 进行一下转换。

另外模型本身离地高度都是 0 的话可能存在无法选中的问题,所以这里建议背景设置离地高度为 -0.5,普通模型正常为 0

还有就是模型选中以后的显示问题。

解决方案

模型无法选中和选择错误的问题通过两个方案进行规避,一个是height离地高度,一个是pickable拾取

首先设置背景的离地高度为 -0.5,普通可以选中的模型离地高度为 0

另外设置一下 pickPriority拾取优先级pickable是否可拾取

最后就是设置模型的选中效果,这里我简单写了三种效果给大家选择,可以自行决定。

实际代码

模型添加的时候增加拾取优先级参数:

js 复制代码
const buildingEntity = viewer.entities.add({
    id: options.id, // 唯一ID,点击交互时识别核心
    name: options.properties.name || options.id, // 建筑名称(可选)
    position: position,
    orientation: orientation, // 控制模型朝向
    pickPriority: options.pickPriority, // (核心)添加拾取优先级
    pickable: options.pickable,  // (核心)允许拾取
    model: {
        uri: options.modelUrl, // glTF/glb 模型路径
        scale: options.scale || 1.0, // 保证模型真实比例(建模时单位为米)
        minimumPixelSize: 0, // 取消最小像素限制,模型随地图缩放正常变化
        maximumScale: 20000, // 最大缩放限制
        runAnimations: false, // 静态建筑关闭动画(节省性能)
        clampToGround: true, // 贴地(自动适配地形高度,可选)
    },
    properties: options.properties || {}, // 绑定自定义属性(如状态接口)
});

这里的参数其实在模型选择那里可以再增加一层判断。

模型选中方法主要有三种:

js 复制代码
// 1. 轮廓线方案
/**
 * 选中指定模型
 * @param {Cesium.Entity} entity 要选中的模型实体
 * @param {Function} onSelect 选中回调(如展示状态弹窗)
 * @param {Function} onUnselect 取消选中回调(用于先取消之前的选中)
 */
const selectModel = (entity, onSelect, onUnselect) => {
    // 取消之前的选中状态(包括回调执行)
    if (selectedEntity) {
        unselectModel(onUnselect);
    }

    // 校验是否为模型实体
    if (!entity || !entity.model) {
        console.warn('❌ 选中的不是模型实体');
        return;
    }

    // 标记为当前选中实体
    selectedEntity = entity;

    // 轮廓线高亮(更醒目,性能略高,需 Cesium 1.90+)
    entity.model.outlineColor = Cesium.Color.RED;
    entity.model.outlineWidth = 2;
    entity.model.outline = true;

    // 执行选中回调(绑定业务逻辑)
    if (typeof onSelect === 'function') {
        onSelect(entity);
    }
};

如果没有特殊要求,轮廓线方案其实非常简单实用。

js 复制代码
// 2. 颜色高亮,修改模型材质
originalModelMaterial = entity.model.color || Cesium.Color.WHITE.clone();
entity.model.color = Cesium.Color.fromCssColorString('#fb0528').withAlpha(0.8);
// 强制刷新
viewer.scene.requestRender();

这里需要注意,修改模型材质一定要执行强制刷新

js 复制代码
// 3. 模型遮罩效果
viewer.entities.add({
    position: entity.position,
    orientation: entity.orientation,
    model: {
        uri: entity.model.uri, // 复用同一个模型文件
        scale: 0.35, // 稍微大一点
        color: Cesium.Color.fromCssColorString('#409EFF').withAlpha(0.5), // 半透明蓝
        silhouetteColor: Cesium.Color.BLUE, // 可选:配合轮廓
        silhouetteSize: 2.0
    }
});

这种效果也非常不错,复用模型文件稍大一号,让他完美的遮住原始模型,给出一个透明色作为材质,显得很有科技感。

总结

模型设计的时候推荐大家优先使用 GLB 格式替代 GLTF 规避网格加载异常问题,

另外通过pickPriority(拾取优先级)和pickable(是否可拾取)参数,从逻辑层面控制模型的交互规则,彻底解决 点错模型、点不到模型 的问题。

后续增加相关图标的单击和操作,实现小型设备的交互。

相关推荐
奶昔不会射手2 小时前
自定义vue3函数式弹窗
前端·javascript·css
new code Boy2 小时前
前端全栈之路
前端
牛奶2 小时前
为什么敲几个字母就能访问网站?DNS原理大揭秘
前端·http·dns
wuhen_n2 小时前
破冰——建立我们的AI开发实验环境
前端·javascript
HelloReader2 小时前
Flutter 自适应布局一套代码适配手机和平板(十二)
前端
牛奶2 小时前
HTTP裸奔,HTTPS穿盔甲——它们有什么区别?
前端·http·https
梓言2 小时前
tailwindcss构建执行npm exec tailwindcss init -p 报错
前端
哈罗哈皮2 小时前
龙虾(openclaw)本地快速安装及使用教程
前端·aigc·ai编程
用户23115444530582 小时前
React中实现“双向绑定”效果的几种方式
前端