Mesh实体
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");