MapBox GL to BABYLON Camera Projection

:champagne: I managed to plug BABYLON in mapbox :champagne:

https://jsfiddle.net/2za498v3/2/

…But there are artefacts when we pan or zoom in the map :smirk:

I started from the sample provided for THREE.js and I’m 99% sure my babylon matrix are right.

/** Mapbox give the context(*gl*) and the perspective matrix(*matrix*).**/
render: function(gl, matrix) {
   if(this.scene) {
        let projection = BABYLON.Matrix.FromArray(matrix);
        this.scene.activeCamera.freezeProjectionMatrix(world.multiply(projection));
        this.scene.render(false);
        this.engine.wipeCaches(true);
   }
    this.map.triggerRepaint();
}

Is BABYLON approximates perspective values somewhere?

…I said that because I notice this small kind of delay :

Any ideas about where this could come ?

2 Likes

I don’t think so :frowning:
anyway you can repro on the PG?

(btw fantastic news regarding mapbox!!)

https://jsfiddle.net/2za498v3/2/

I can’t repro on the PG because I need to create the engine :confused:

I meant : Can you repro the same behavior (Without mapBox)

It’s difficult to repro because mapbox give crazy projection matrix and I don’t see how I could emulate that :stuck_out_tongue:

I didn’t found a way to isolate the bug, it’s a very specific case…

Are we sure the matrix is sent correctly?

I definitely repro the issue in your jsfiddle

I think so because they have the exact same values as the ones generated in the THREE.js sample

I triple checked: the projectionMatrix you are giving to bjs is the one used :frowning:

And the update to the world matrix is also correct?

Also is there anything done in 3js to offset the center of the world? Maybe the coordinates are REALLY big and we end up facing a precision issue?

Nothing, only the projection matrix.

They are because it is the real world coordinates :p…But precision from where ?

like if the projection is getting super large value then we could lose precision

So a repro in the PG could definitely help a lot

Ok I will do that tomorrow, thanks for helping !

always :smiley:

https://jsfiddle.net/y09ucome/ (You’ll need to put the mapbox access token back in there, as I removed it in case you don’t want it there forever)

Yeah it is a precision issue caused by the matrix class using Float32Arrays. Doing the maths as just a standard array fixes the issue entirely.

Integration with mapbox might actually be very useful, so thanks for posting this here :slight_smile:

Edit:
It’s just the conversion of the matrix provided by mapbox to a float32array (with Matrix.FromArray) that causes precision loss, so just setting the internal array to that matrix directly (and ignoring that you’re setting it to the wrong type) also solves the issue. https://jsfiddle.net/dt6ovyxL/

Ideally babylonjs would have matrix methods that allow multiplication of a matrix by an array (for both pre and post multiplication) to help with this use case. I could do a pr to add these if that sounds like a good idea @Deltakosh, though I’m weary that math.vector.ts is growing quite large.

3 Likes

Thank you @sable !!

Please add it, I really think it could serve more needs

@sharp: Do you want to add a page in the doc to explain how to integrate into MapBox?

@Deltakosh maybe better to make a small github project and link it in the doc ?

I made a dedicated layer :

const createScene = (engine) => {
    return new Promise(resolve => {
        BABYLON.SceneLoader.Load("https://docs.mapbox.com/mapbox-gl-js/assets/34M_17/", "34M_17.gltf", engine,
            (scene) => {
                new BABYLON.DirectionalLight("DirectionalLight", new BABYLON.Vector3(0, -70, 100), scene);
                new BABYLON.DirectionalLight("DirectionalLight2", new BABYLON.Vector3(0, 70, 100), scene);
                resolve(scene);
            });
    });
};

let layer = new BabylonMapboxLayer(createScene,  [148.9819, -35.39847]);

map.on("load", function() {
    map.addLayer(layer, "building")
});