Some months ago, the support solid particles management has been added to the Dynamic Terrain in order to render objects on a map : Adding Objects to a Dynamic Terrain - Babylon.js Documentation
At this time, the custom instance buffers weren’t available in the current BJS version. Now they are.
So the DynamicTerrain can now also manage instances , exactly like it does with solid particles.
Both can even work together.
Usage :
- As usual create a map to depict the relief and the landscape
mapData
: successive ground coordinates in a large array. - Create also a map of objects beside. This map can hold different object types. This map can be as large as wanted and can contain hundred thousands or millions objects.
var instanceMapData = [ [], [], [] ]; // this object map can hold data for 3 object types
// type 0
instanceMapData[0] = [posx1, posy1, posz1, rotx1, roty1, rotz1, sclx1, scly1, sclz1, posx2, posxy2, ...];
// type 1
instanceMapData[1] = [posx1, posy1, posz1, rotx1, roty1, rotz1, sclx1, scly1, sclz1, posx2, posxy2, ...];
// type 2
instanceMapData[2] = [posx1, posy1, posz1, rotx1, roty1, rotz1, sclx1, scly1, sclz1, posx2, posxy2, ...];
- Then create (or import) one mesh per object type, store it in an array
sourceMeshes
and create a pool of instances for this mesh.
// assuming mesh1, mesh2 and mesh3 are created
// create the wanted pools of instances of each one, say 1000 per type here
for (var i = 0; i < 1000; i++) {
mesh1.createInstance("mesh1" + i);
mesh2.createInstance("mesh2" + i);
mesh3.createInstance("mesh3" + i);
}
var sourceMeshes = [mesh1, mesh2, mesh3];
// mesh1 will be the object type 0, mesh2 the object type1 and mesh3 the object type2
The order of the meshes in the sourceMeshes
array is the object type order in the object map.
- At last, just create your terrain with the parameters
instanceMapData
andsourceMeshes
this time
var terrainSub = 100; // terrain subdivisions
var terrainOptions = {
terrainSub: terrainSub,
mapData: mapData, mapSubX: mapSubX, mapSubZ: mapSubZ,
instanceMapData: instanceMapData,
sourceMeshes: meshes
};
var terrain = new BABYLON.DynamicTerrain("dt", terrainOptions, scene);
That’s all.
Now the terrain will recycle the instances from each pool and use them to render the objects from the map.
Note that you can also use colors like with the solid particles.
Just create an extra array to hold the instance colors (r, g, b, a floats) per type :
var instanceColorData = [[], [], []];
instanceColorData[0] = [r1, g1, b1, a1, r2, g2, b2, a2...];
instanceColorData[1] = [r1, g1, b1, a1, r2, g2, b2, a2...];
instanceColorData[2] = [r1, g1, b1, a1, r2, g2, b2, a2...];
and pass it to the terrain constructor with the parameter instanceColorData
:
var terrainSub = 100; // terrain subdivisions
var terrainOptions = {
terrainSub: terrainSub,
mapData: mapData, mapSubX: mapSubX, mapSubZ: mapSubZ,
mapColors: mapColors,
instanceMapData: instanceMapData,
instanceColorData: instanceColorData,
sourceMeshes: meshes
};
var terrain = new BABYLON.DynamicTerrain("dt", terrainOptions, scene);