I used adding gltf 3D Model on map using mapbox gl with three.js from the link
but adding single 3D gltf model in single separate layer and adding them to map is working fine,but is there any way to add mulitple 3D gltf model in a single layer on the map.
Map code:
this.modelOrigin = [148.9819, -35.3981];
this.modelOrigin2 = [148.9819, -35.4981];
this.iconImage = "https://docs.mapbox.com/mapbox-gl-js/assets/34M_17/34M_17.gltf";
//map info here
var map = new mapboxgl.Map({
container: 'map', // container id
style: 'mapbox://styles/mapbox/streets-v9', //stylesheet location
center: [148.9819, -35.3981], // starting position[35.890, -75.664]
zoom: 17.5, // starting zoom
hash: true,
minZoom: 0,
maxZoom: 22,
preserveDrawingBuffer: true,
pitch: 60
});
var self = this;
map.on('style.load', function () {
//adding separate 3d model on map
map.addLayer(new AddMapCustomLayer(self.modelOrigin, self.iconImage));
map.addLayer(new AddMapCustomLayer(self.modelOrigin2, self.iconImage));
});
code for the custom Layer:
class AddMapCustomLayer {
id;
type="custom";
renderingMode="3d";
//
modelOrigin;
modelAltitude = 0;
modelRotate = [Math.PI / 2, 0, 0];
modelScale = 5.41843220338983e-8;
modelTransform;
camera;
scene;
map;
renderer;
iconImage;
constructor(modelOrigin, iconImage) {
this.id = '3d-model' + this.uuidv4();
this.type = 'custom';
this.renderingMode = '3d';
this.modelOrigin = modelOrigin;
this.iconImage = iconImage;
// transformation parameters to position, rotate and scale the 3D model onto the map
this.modelTransformation(this.modelOrigin,this.iconImage)
}
modelTransformation(modelOrigin,modelAltitude){
this.modelTransform = {
translateX: mapboxgl.MercatorCoordinate.fromLngLat(modelOrigin, modelAltitude).x,
translateY: mapboxgl.MercatorCoordinate.fromLngLat(modelOrigin, modelAltitude).y,
translateZ: mapboxgl.MercatorCoordinate.fromLngLat(modelOrigin, modelAltitude).z,
rotateX: this.modelRotate[0],
rotateY: this.modelRotate[1],
rotateZ: this.modelRotate[2],
scale: this.modelScale
};
}
uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
};
onAdd(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(this.iconImage, (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(gl, matrix) {
var rotationX = new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(1, 0, 0), this.modelTransform.rotateX);
var rotationY = new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(0, 1, 0), this.modelTransform.rotateY);
var rotationZ = new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(0, 0, 1), this.modelTransform.rotateZ);
var m = new THREE.Matrix4().fromArray(matrix);
var l = new THREE.Matrix4().makeTranslation(this.modelTransform.translateX, this.modelTransform.translateY, this.modelTransform.translateZ)
.scale(new THREE.Vector3(this.modelTransform.scale, -this.modelTransform.scale, this.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();
}
So Please give suggestion, how i can achive adding same model dyanmically at different different location on the map by single layer.