Hey guys,
I’m just getting started in 3d web developement and think babylon.js is a great starting point.
My overall goal is to animate an object on a map along a path using real world data with Azure Maps.
I already modified the original sample code to make it possible to have animations:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Babylon custom WebGL layer - Azure Maps Web SDK Samples</title>
<meta charset="utf-8" />
<link rel="shortcut icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="description" content="This sample shows how to create a custom 3D layer with Babylon.js." />
<meta name="keywords" content="3D, Microsoft maps, map, gis, API, SDK, thematic, choropleth, heatmap, heat map, animation, animate, animations, county, population, data-driven, data driven styling, temporal, temporal analysis" />
<meta name="author" content="Microsoft Azure Maps" />
<meta name="screenshot" content="screenshot.jpg" />
<!-- Add references to the Azure Maps Map control JavaScript and CSS files. -->
<link href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/2/atlas.min.css" rel="stylesheet" />
<script src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/2/atlas.min.js"></script>
<!-- Babylon.js is a powerful, simple, real-time 3D and open game and rendering engine packed into a friendly framework, which Microsoft initially developed. -->
<script src="https://cdn.babylonjs.com/babylon.js"></script>
<script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
<script>
var map, layer;
// parameters to ensure the model is georeferenced correctly on the map
const worldOrigin = [148.9819, -35.39847];
const worldAltitude = 0;
const worldRotate = [Math.PI / 2, 0, 0];
const worldCoords = atlas.data.MercatorPoint.fromPosition([...worldOrigin, worldAltitude]);
console.log(worldCoords)
const worldScale = 2 * atlas.data.MercatorPoint.meterInMercatorUnits(49.923718);
var worldMatrix = BABYLON.Matrix.Compose(
new BABYLON.Vector3(worldScale, worldScale, worldScale),
BABYLON.Quaternion.FromEulerAngles(worldRotate[0], worldRotate[1], worldRotate[2]),
new BABYLON.Vector3(worldCoords[0], worldCoords[1], worldCoords[2])
);
var mesh1, mesh2;
async function animateMesh(scene) {
//Create a scaling animation at 30 FPS
var animationBox = new BABYLON.Animation("tutoAnimation", "position", 30, BABYLON.Animation.ANIMATIONTYPE_VECTOR3, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
let startPosition = atlas.data.MercatorPoint.fromPosition([...[148.9819, -35.39847], 0]);
let endPosition = atlas.data.MercatorPoint.fromPosition([...[148.977732, -35.398451], 0]);
console.log(startPosition);
console.log(endPosition);
// Animation keys
var keys = [];
keys.push({
frame: 0,
value: new BABYLON.Vector3(startPosition[0], startPosition[1], startPosition[2])
});
keys.push({
frame: 100,
value: new BABYLON.Vector3(endPosition[0], endPosition[1], endPosition[2])
});
animationBox.setKeys(keys);
mesh1.animations.push(animationBox);
setTimeout(async () => {
let anim = scene.beginAnimation(mesh1, 0, 100, true);
await anim.waitAsync();
console.log("Animation finished")
})
}
// Create a renderer that implements atlas.WebGLRenderer
var renderer = {
renderingMode: "3d",
// Method called when the layer is added to the map
onAdd: (map, gl) => {
this.map = map;
// Initialize the Babylon.js engine.
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("camera", new BABYLON.Vector3(), this.scene);
const light = new BABYLON.HemisphericLight("light", BABYLON.Vector3.One(), this.scene);
new BABYLON.AxesViewer(this.scene, 10);
BABYLON.SceneLoader.LoadAssetContainerAsync(
"./34m_17/",
"34M_17.gltf",
this.scene
).then((modelContainer) => {
modelContainer.addAllToScene();
mesh1 = modelContainer.createRootMesh();
animateMesh(this.scene);
});
},
// Method called on each animation frame
render: (gl, matrix) => {
// projection & view matrix
const cameraMatrix = BABYLON.Matrix.FromArray(matrix);
const mvpMatrix = worldMatrix.multiply(cameraMatrix);
this.camera.freezeProjectionMatrix(mvpMatrix);
this.scene.render(false);
this.map.triggerRepaint();
}
};
function GetMap() {
map = new atlas.Map("map", {
zoom: 18,
pitch: 60,
center: [148.9819, -35.39847],
//style: "satellite_road_labels",
antialias: true,
// Add authentication details for connecting to Azure Maps.
authOptions: {
// Use an Azure Maps key. Get an Azure Maps key at https://azuremaps.com/. NOTE: The primary key should be used as the key.
authType: 'subscriptionKey',
subscriptionKey: 'mykey'
}
});
// Wait until the map resources are ready
map.events.add("ready", function () {
// Create a WebGL layer
layer = new atlas.layer.WebGLLayer("babylon", { renderer });
// Add the layer to the map
map.layers.add(layer);
// Add controls
map.controls.add(
[
new atlas.control.ZoomControl(),
new atlas.control.PitchControl(),
new atlas.control.CompassControl(),
new atlas.control.StyleControl({
mapStyles: "all"
})
],
{
position: "top-right"
}
);
});
}
</script>
</head>
<body onload="GetMap()">
<div id="map" style="position:relative;width:100%;min-width:290px;height:600px;background-color:gray"></div>
<fieldset style="width:calc(100% - 30px);min-width:290px;margin-top:10px;">
<legend>Babylon.js custome WebGL layer</legend>
This sample shows how to render a 3D model using <a href="https://www.babylonjs.com/">babylon.js</a>.
Babylon.js is a powerful, simple, real-time 3D and open game and rendering engine packed into a friendly framework, which Microsoft initially developed.
</fieldset>
</body>
</html>
This works perfectly fine for changing the scale or rotation.
However, when I try to change the position by inputting real world coordinates (eg [148.977732, -35.398451]
) , as seen in my code, the movement of the model is too small to be visible.
I already figured out that the reason for this is that the values in my vector are to small. Unfortunately I have no idea what steps I have to make to be able to work with real world coordinates.
I’m really grateful for any input!
Thanks a lot
David