mapbox+babylon加载三维模型

本文介绍了如何在Vue应用中利用babylonjs和mapbox-gl库创建3D模型,并展示了如何实现CustomLayerInterface以加载.babylon、.gltf和.glb模型,以及处理可能的文件下载问题。

 1.加载模型需要npm相关依赖,参考babylonjs-loaders - npm

2.引入相关依赖,构建mapbox地图场景

import mapboxgl from 'mapbox-gl';
import {onMounted} from "vue";
import * as BABYLON from 'babylonjs';
import 'babylonjs-loaders';

mapboxgl.accessToken = 'pk.eyJ1Ijoibm9haDk3MTMiLCJhIjoiY2p4aXppNXZoMTc4YTN5bzhzMWY0emw3cyJ9.7GhaVOSALR-DwV5Lpn_h4Q';

const map = new mapboxgl.Map({
    container: 'mapContainer',
    style: 'mapbox://styles/mapbox/streets-v11',
    zoom: 18,
    center: [120, 31],
    pitch: 60,
    antialias: true // create the gl context with MSAA antialiasing, so custom layers are antialiased
});

2.根据CustomLayerInterface定义一个BabylonLayer,分别加载了.babylon模型、.gltf模型、.glb模型。

class BabylonLayer implements CustomLayerInterface {
    readonly id: string;
    readonly type: 'custom' = 'custom';
    readonly renderingMode: '3d' = '3d';

    private map: Map | undefined;
    private scene: BABYLON.Scene | undefined;
    private camera: BABYLON.Camera | undefined;
    private modelMatrix: BABYLON.Matrix | undefined;

    constructor(id: string) {
        this.id = id;
    }

    onAdd = (map: Map, gl: WebGLRenderingContext) => {
        this.map = map;
        const engine = new BABYLON.Engine(gl, true, {
            useHighPrecisionMatrix: true
        }, true);

        this.scene = new BABYLON.Scene(engine);
        this.scene.autoClear = false;
        this.scene.detachControl();
        this.scene.beforeRender = function () {
            engine.wipeCaches(true);
        }
        this.camera = new BABYLON.Camera("mapbox-camera", new BABYLON.Vector3(), this.scene);
        const light = new BABYLON.HemisphericLight("mapbox-light", BABYLON.Vector3.One(), this.scene);

        // 加载.babylon模型
        BABYLON.SceneLoader.ImportMeshAsync("", "./data/model/", "Dude.babylon", this.scene)

        // 加载.gltf模型
        BABYLON.SceneLoader.ImportMeshAsync("", "https://docs.mapbox.com/mapbox-gl-js/assets/34M_17/", "34M_17.gltf", this.scene)

        // 加载.glb模型
        BABYLON.SceneLoader.ImportMeshAsync("", "https://assets.babylonjs.com/meshes/", "village.glb");

        // 模型加载到地图上相关参数
        const modelOrigin = [120, 31];
        const modelAltitude = 0;
        const modelRotate = [Math.PI / 2, 0, 0];
        const modelCoords = mapboxgl.MercatorCoordinate.fromLngLat(
            modelOrigin,
            modelAltitude
        );
        const modelScale = modelCoords.meterInMercatorCoordinateUnits();

        this.modelMatrix = BABYLON.Matrix.Compose(
            new BABYLON.Vector3(modelScale, modelScale, modelScale),
            BABYLON.Quaternion.FromEulerAngles(modelRotate[0], modelRotate[1], modelRotate[2]),
            new BABYLON.Vector3(modelCoords.x, modelCoords.y, modelCoords.z)
        );
    }

    render = (gl: WebGLRenderingContext, matrix: number[]) => {
        const cameraMatrix = BABYLON.Matrix.FromArray(matrix);
        const mvpMatrix = this.modelMatrix!.multiply(cameraMatrix);
        this.camera!.freezeProjectionMatrix(mvpMatrix);
        this.scene!.render(false);
        this.map!.triggerRepaint();
    }
}

3.添加BabylonLayer至mapbox场景

map.on('style.load', () => {
    const babylonLayer = new BabylonLayer('babylon-layer');
    map.addLayer(babylonLayer);
});

实现效果:

踩坑:

1、要引入babylonjs-loaders

2、文件可能需下载到本地才能完成加载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值