-
Notifications
You must be signed in to change notification settings - Fork 453
/
babylon.html
173 lines (143 loc) · 7.88 KB
/
babylon.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
<!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="version" content="1.0" />
<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/3/atlas.min.css" rel="stylesheet" />
<script src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/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;
var scene;
//A list of the mesh names in the model that we want to limit interaction to when "picking" the scene, as some models will include items we to exclude, such as the background.
var interactiveMeshes = ['dish', 'dish_center', 'quad', 'truss_dish'];
// 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);
};
//Store a reference to the scene so we can pick from it later.
scene = this.scene;
this.camera = new BABYLON.Camera("camera", new BABYLON.Vector3(), this.scene);
const light = new BABYLON.HemisphericLight("light", BABYLON.Vector3.One(), this.scene);
BABYLON.SceneLoader.Append(
'/3d-layer/babylon.js/34m_17/',
'34M_17.gltf',
this.scene
)
// parameters to ensure the model is georeferenced correctly on the map
const modelOrigin = [148.9819, -35.39847];
const modelAltitude = 0;
const modelRotate = [Math.PI / 2, 0, 0];
const modelCoords = atlas.data.MercatorPoint.fromPosition([...modelOrigin, modelAltitude]);
const modelScale = 2 * atlas.data.MercatorPoint.meterInMercatorUnits(-35.39847);
this.modelMatrix = BABYLON.Matrix.Compose(
new BABYLON.Vector3(modelScale, modelScale, modelScale),
BABYLON.Quaternion.FromEulerAngles(modelRotate[0], modelRotate[1], modelRotate[2]),
new BABYLON.Vector3(modelCoords[0], modelCoords[1], modelCoords[2])
);
},
// Method called on each animation frame
render: (gl, matrix) => {
// projection & view matrix
const cameraMatrix = BABYLON.Matrix.FromArray(matrix);
const mvpMatrix = this.modelMatrix.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.3981],
style: "satellite_road_labels",
antialias: true,
// Add authentication details for connecting to Azure Maps.
authOptions: {
//Use Microsoft Entra ID authentication.
authType: 'anonymous',
clientId: 'e6b6ab59-eb5d-4d25-aa57-581135b927f0', // Your Azure Maps client id for accessing your Azure Maps account.
getToken: function (resolve, reject, map) {
// URL to your authentication service that retrieves an Microsoft Entra ID Token.
var tokenServiceUrl = 'https://samples.azuremaps.com/api/GetAzureMapsToken';
fetch(tokenServiceUrl).then(r => r.text()).then(token => resolve(token));
}
// 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: '[YOUR_AZURE_MAPS_KEY]'
}
});
// 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"
}
);
//Add click event to the map.
map.events.add('click', mapClicked);
});
}
function mapClicked(e) {
//Get the pixel location that was clicked.
var pixel = e.pixel;
//Alternatively, you can get a pixel for a geo-position and use that.
//var pixel = map.positionsToPixels([e.position])[0];
//Pick all meshes that intersect in the scene.
var pickResults = scene.multiPick(pixel[0], pixel[1]);
//Loop through and check to see if one of our prefered meshes was picked.
pickResults.forEach(pickResult => {
//Check that the pick has a hit and is one of the meshes we want to interact with.
if (pickResult.hit && interactiveMeshes.indexOf(pickResult.pickedMesh.name) !== -1) {
//A mesh we allow to be interacted with in the model has been clicked!
alert(`The ${pickResult.pickedMesh.name} mesh of the model has been clicked!`);
}
})
}
</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.
This sample allows a subset of meshes within the model to be interacted with.
</fieldset>
</body>
</html>