gltf 模型(GLTFLayer)
gltf(GL Transmission Format)是三维场景中传输模型的通用格式。maptalks 使用 GLTFLayer 图层和 GLTFMarker 模型来加载和展示 gltf 模型。
加载模型
GLTFMarker 是一个带地理位置的三维模型,通过 symbol.url 指定模型文件地址,加入 GLTFLayer 后放入 GroupGLLayer:
js
import { Map } from "maptalks";
import { GroupGLLayer, GLTFLayer, GLTFMarker } from "@maptalks/gl-layers";
const map = new Map("map", {
center: [-74.01252272617671, 40.70709931736744],
zoom: 16,
pitch: 80,
});
const symbol = {
url: "/models/alien/alien.gltf", // 模型文件地址
modelHeight: 240, // 模型高度(米),会自动按模型比例缩放
rotationZ: 180, // 绕 Z 轴旋转角度
};
const gltfLayer = new GLTFLayer("gltf");
const gltfMarker = new GLTFMarker(map.getCenter(), {
symbol,
}).addTo(gltfLayer);
const groupLayer = new GroupGLLayer("group", [gltfLayer]).addTo(map);GLTFMarker 与普通几何图形一样,坐标是经纬度,通过 symbol 控制模型的显示:
url:模型文件地址,支持.gltf/.glb格式。modelHeight:模型高度(米)。gltf 模型没有真实世界的尺度,设置高度后引擎会按模型原始比例自动缩放。scaleX/scaleY/scaleZ:三个轴向的缩放。rotationZ:绕 Z 轴的旋转角度。animation/loop:加载带骨骼动画的模型时,animation: true播放动画,loop控制是否循环。
添加多个模型
一个 GLTFLayer 可以添加任意多个 GLTFMarker,通过坐标偏移放置在不同的位置:
js
const gltfLayer = new GLTFLayer("gltf");
const position = map.getCenter();
const marker1 = new GLTFMarker(position, {
symbol: { url: "/models/alien/alien.gltf", modelHeight: 240 },
}).addTo(gltfLayer);
// position.add(dx, dy) 按经纬度偏移
const marker2 = new GLTFMarker(position.add(0.01, 0), {
symbol: { url: "/models/robot/scene.gltf", animation: true, loop: true, modelHeight: 500 },
}).addTo(gltfLayer);模型交互
模型事件
GLTFMarker 与二维几何一样支持鼠标事件:
js
gltfMarker.on("click", (e) => {
console.log("点击了模型", e.target);
});
gltfMarker.on("mouseenter", () => {
gltfMarker.setUniform("polygonFill", [0.0, 0.8, 0.0, 1.0]); // 悬停时改变模型颜色
});
gltfMarker.on("mouseleave", () => {
gltfMarker.setUniform("polygonFill", [1.0, 1.0, 1.0, 1.0]);
});setUniform 可以修改模型着色器的 uniform 值,常用于实现悬停高亮。
拾取(identify)
在地图事件中通过 gltfLayer.identify(coordinate) 拾取该坐标处的模型:
js
map.on("click", (e) => {
const picks = gltfLayer.identify(e.coordinate);
if (picks && picks.length > 0) {
const target = picks[0].data; // 命中的模型
target.setUniform("polygonFill", [0.2, 0.2, 1.0, 1.0]);
}
});自定义属性
给模型附加业务数据,用于后续的查询与联动:
js
gltfMarker.setProperties({ num: 100, value: 1 });
gltfMarker.on("click", (e) => {
const properties = e.target.getProperties();
console.log(properties);
});模型加载完成事件
多个模型(尤其大模型)加载是异步的,可以在图层上监听 modelload 事件:
js
gltfLayer.on("modelload", () => {
console.log("所有模型载入完成");
});