Skip to content

Commit

Permalink
add 3D model with three.js example (#7977)
Browse files Browse the repository at this point in the history
* new example using three.js and custom layers to add a 3D model

* use MercatorCoordinate

* comments and example image

* fix lint
  • Loading branch information
andrewharvey authored and mourner committed Mar 5, 2019
1 parent d858a76 commit 2ae5621
Show file tree
Hide file tree
Showing 11 changed files with 2,082 additions and 0 deletions.
Binary file added docs/img/src/add-3d-model.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/pages/assets/34M_17/34M_17.bin
Binary file not shown.
1,984 changes: 1,984 additions & 0 deletions docs/pages/assets/34M_17/34M_17.gltf

Large diffs are not rendered by default.

Binary file added docs/pages/assets/34M_17/base_AO.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/pages/assets/34M_17/frame_AO.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/pages/assets/34M_17/stairs_plt_AO.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/pages/assets/34M_17/truss_2_AO.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/pages/assets/34M_17/truss_dish_AO.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/pages/assets/34M_17/wheels_AO.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
88 changes: 88 additions & 0 deletions docs/pages/example/add-3d-model.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<script src='https://unpkg.com/three@0.102.0/build/three.min.js'></script>
<script src="https://unpkg.com/three@0.102.0/examples/js/loaders/GLTFLoader.js"></script>
<div id='map'></div>
<script>
var map = window.map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/light-v9',
zoom: 17.5,
center: [148.9819, -35.3981],
pitch: 60
});

// parameters to ensure the model is georeferenced correctly on the map
var modelOrigin = [148.98190, -35.39847];
var modelAltitude = 0;
var modelRotate = [Math.PI / 2, 0, 0];
var modelScale = 5.41843220338983e-8;

// transformation parameters to position, rotate and scale the 3D model onto the map
var modelTransform = {
translateX: mapboxgl.MercatorCoordinate.fromLngLat(modelOrigin, modelAltitude).x,
translateY: mapboxgl.MercatorCoordinate.fromLngLat(modelOrigin, modelAltitude).y,
translateZ: mapboxgl.MercatorCoordinate.fromLngLat(modelOrigin, modelAltitude).z,
rotateX: modelRotate[0],
rotateY: modelRotate[1],
rotateZ: modelRotate[2],
scale: modelScale
};

var THREE = window.THREE;

// configuration of the custom layer for a 3D model per the CustomLayerInterface
var customLayer = {
id: '3d-model',
type: 'custom',
renderingMode: '3d',
onAdd: function(map, gl) {
this.camera = new THREE.Camera();
this.scene = new THREE.Scene();

// create two three.js lights to illuminate the model
var directionalLight = new THREE.DirectionalLight(0xffffff);
directionalLight.position.set(0, -70, 100).normalize();
this.scene.add(directionalLight);

var directionalLight2 = new THREE.DirectionalLight(0xffffff);
directionalLight2.position.set(0, 70, 100).normalize();
this.scene.add(directionalLight2);

// use the three.js GLTF loader to add the 3D model to the three.js scene
var loader = new THREE.GLTFLoader();
loader.load('https://docs.mapbox.com/mapbox-gl-js/assets/34M_17/34M_17.gltf', (function (gltf) {
this.scene.add(gltf.scene);
}).bind(this));
this.map = map;

// use the Mapbox GL JS map canvas for three.js
this.renderer = new THREE.WebGLRenderer({
canvas: map.getCanvas(),
context: gl
});

this.renderer.autoClear = false;
},
render: function(gl, matrix) {
var rotationX = new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(1, 0, 0), modelTransform.rotateX);
var rotationY = new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(0, 1, 0), modelTransform.rotateY);
var rotationZ = new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(0, 0, 1), modelTransform.rotateZ);

var m = new THREE.Matrix4().fromArray(matrix);
var l = new THREE.Matrix4().makeTranslation(modelTransform.translateX, modelTransform.translateY, modelTransform.translateZ)
.scale(new THREE.Vector3(modelTransform.scale, -modelTransform.scale, modelTransform.scale))
.multiply(rotationX)
.multiply(rotationY)
.multiply(rotationZ);

this.camera.projectionMatrix.elements = matrix;
this.camera.projectionMatrix = m.multiply(l);
this.renderer.state.reset();
this.renderer.render(this.scene, this.camera);
this.map.triggerRepaint();
}
};

map.on('style.load', function() {
map.addLayer(customLayer, 'waterway-label');
});
</script>
10 changes: 10 additions & 0 deletions docs/pages/example/add-3d-model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*---
title: Add a 3D model
description: Use a [custom style layer](/mapbox-gl-js/api/#customlayerinterface) with [three.js](https://threejs.org) to add a 3D model to the map.
tags:
- layers
pathname: /mapbox-gl-js/example/add-3d-model/
---*/
import Example from '../../components/example';
import html from './add-3d-model.html';
export default Example(html);

0 comments on commit 2ae5621

Please sign in to comment.