唯杰地图 logo唯杰地图
VJMAP
EN

Mesh实体

vjmap3d/references/entity/meshEntity.md 6.9 KB165 行
原文

MeshEntity 是由 实体Entity 和 MeshModule 模块组合而成的新的实体。

MeshEntity = Entity + MeshModule

常用方法

MeshEntity 是由 实体Entity 派生而来。具体 Entity 的所有属性和方法。同时也具有MeshModule 的相关方法。

方法 描述
mesh mesh对象
rawMaterial rawMaterial() 获取最开始的原生材质,为空表示没有修改过。⚠️ .d.ts 在 MeshEntity 上声明的是 nativeMaterial,但运行时混入的是 rawMaterial(meshEnt.nativeMaterial 为 undefined);TS 中需 (meshEnt as any).rawMaterial()
useMaterial 获取替换后的正使用的材质,为空表示没有修改过
material 获取原材质的克隆副本(getter,首次访问时克隆)。⚠️ 只是副本、不会自动挂到 mesh 上:改完后需 meshEnt.replaceMaterial(meshEnt.material) 才生效
addEdges 增加模型边框线
clearEdges 移除模型边框线
getEdges 获取模型边框线
replaceMaterial 替换材质
resetMaterial 恢复材质
setHeatmapDataMaterial 设置热力图数据分析材质
isHighlight 是否高亮
setHighlight 设置高亮
clearHighlight 清除高亮
highlightMaterial 获取高亮材质
setOpacity 设置透明度
opacityMaterial 获取透明度材质
clearHighlight 清除高亮

使用示例

创建一个MeshEntity

const box = new THREE.Mesh(
    new THREE.BoxGeometry(3, 3, 3),
    new THREE.MeshStandardMaterial({ color: 0xff0000 })
);
let meshEnt = new vjmap3d.MeshEntity(box);
meshEnt.addTo(app);

给实体增加事件模块

// 增加一个事件模块,用来高亮提示
meshEnt.add(vjmap3d.EventModule, {
    clickHighlight: true,
    highlightOpacity: 0.2,
    hoverSelect: true,
    hoverHtmlText: "我是MeshEntity",
    clickHtmlText: `您点击我了!`,
    popupOptions: {
        anchor: "bottom"
    }
});

生成热力图数据分析材质

// 获取实体的外包盒
let box3d = meshEnt.getBoundingBox(false);
let pointNum = 10; // 模拟十个点的业务数据
let data = []
let size = new THREE.Vector3();
box3d.getSize(size)
for(let k = 0 ; k < pointNum; k++) {
    data.push({
        x: box3d.min.x + Math.random() * size.x,
        y: box3d.min.y + Math.random() * size.y,
        z: box3d.min.z + Math.random() * size.z,
        value: Math.random() * 100
    })
}
// 设置热力图数据分析材质
await meshEnt.setHeatmapDataMaterial({
    data,
})
// 还原成原来的材质
meshEnt.resetMaterial();

⚠️ setHeatmapDataMaterial 是异步方法,返回 Promise<{ lut, material, reset }>——必须 await 后 mesh.material 才被替换成返回的材质(webgl 下是 ShaderMaterial,webgpu 下是 TSL 的 VolumeBoxMaterial 节点材质);不 await 立即读材质还是旧值(内部走 worker 插值计算)。

  • 内部走 replaceMaterial:若实体此时处于高亮(isHighlight() 为 true),只记录不替换,mesh.material 要等 clearHighlight() 后才换成热力图材质。
  • segmentX/segmentY/segmentZ 运行时默认都是 10(.d.ts 注释写的"默认20"与运行时不符)。
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
    container: "map", // 容器id
    scene: {
        gridHelper: { visible: true } // 是否显示坐标网格
    },
    camera: {  // 相机设置
        viewHelper: { enable: true, position: "leftBottom" } // 是否显示视角指示器
    }
})
//
 const box = new THREE.Mesh(
    new THREE.BoxGeometry(3, 3, 3),
    new THREE.MeshStandardMaterial({ color: 0xff0000 })
);
let meshEnt = new vjmap3d.MeshEntity(box);
meshEnt.addTo(app);
meshEnt.add(vjmap3d.EventModule, {
    clickHighlight: true,
    highlightOpacity: 0.2,
    hoverSelect: true,
    hoverHtmlText: "我是MeshEntity",
    clickHtmlText: `您点击我了!`,
    popupOptions: {
        anchor: "bottom"
    }
});
// 
let control = new vjmap3d.ButtonGroupControl({
    buttons: [
        {
            id: "id1",
            html: "数据热力图",
            style: {
                width: "100px"
            },
            onclick: async () => {
                // 获取实体的外包盒
                let box3d = meshEnt.getBoundingBox(false);
                let pointNum = 10; // 模拟十个点的业务数据
                let data = []
                let size = new THREE.Vector3();
                box3d.getSize(size)
                for(let k = 0 ; k < pointNum; k++) {
                    data.push({
                        x: box3d.min.x + Math.random() * size.x,
                        y: box3d.min.y + Math.random() * size.y,
                        z: box3d.min.z + Math.random() * size.z,
                        value: Math.random() * 100
                    })
                }
                // 设置热力图数据分析材质
                await meshEnt.setHeatmapDataMaterial({
                    data,
                })
            }
        },{
            id: "id2",
            html: "取消热力图",
            style: {
                width: "100px"
            },
            onclick: async () => {
                // 还原成原来的材质
                meshEnt.resetMaterial();
            }
        }
    ]
});
app.addControl(control, "top-right");