In LuciadRIA , you can draw a 3D object as a mesh.

A mesh is a collection of three-dimensional points, lines, and surfaces that describe the shape of the object. You can paint all 3D icons using a FeaturePainter in combination with an Icon3DStyle.

To style a feature as a 3D icon mesh, you call drawIcon3D on a view/style/GeoCanvas instance. The FeaturePainter paint methods pass the GeoCanvas instance as the first parameter.

Program: Draw a 3D icon using a FeaturePainter
const painter = new FeaturePainter();
painter.paintBody = function(geoCanvas, feature, shape, map, layer, state) {
  const icon3DStyle = {
    meshUrl: "car.gltf"
  };
  geoCanvas.drawIcon3D(shape, icon3DStyle);
};

Icon3DStyle gives you access to all kinds of options, but the one thing you must specify is the mesh to paint. You can do so by:

  • Specifying a URL to a GL Transmission Format (glTF) file with meshUrl. glTF files are JSON files that describe the structure and composition of a scene containing 3D models. In this case, they describe the meshes of the 3D objects that appear in the scene.

    meshUrl must point to a glTF file. You can specify all kinds of mesh properties in the glTF format.

  • Creating a simple configurable mesh using Simple3DMeshFactory.

  • Creating a mesh at the triangle level with MeshFactory:

    Program: Configuring the style with a mesh created by Simple3DMeshFactory (from samples/icons3d/StyleFactory.js)
    const style = {
      mesh: Simple3DMeshFactory.create3DDome(1000, 50),
      color: "rgba(255, 55, 55, 0.5)",
      rotation: {
        x: 180
      }
    };

    If you want more control over the creation of the meshes, you can use MeshFactory. You can use it to specify the individual triangles:

    Program: Using MeshFactory
    //Use the factory method from the MeshFactory module to create a 3D mesh
    const mesh = create3DMesh([
      0, 0, 0, // Vertex 0
      100000, 0, 100000, // Vertex 1
      0, 0, 100000  // Vertex 2
    ], [
      0, 1, 2  // Triangle 0-1-2
    ]);
    
    const featurePainter = new FeaturePainter();
    featurePainter.paintBody = function(geocanvas, feature, shape, layer, map, paintState) {
      geocanvas.drawIcon3D(shape, {mesh: mesh});
    };
    return featurePainter;

Placing a mesh in the world

The vertices of a mesh aren’t georeferenced. Instead, LuciadRIA assumes that the mesh is modeled in its own local coordinate system.

For example, Figure 1, “A 3D icon with its local coordinate system” shows a mesh that you want to place somewhere in the world.

mesh
Figure 1. A 3D icon with its local coordinate system

LuciadRIA also assumes that the unit of measure is meters. If that’s not the case, you can use the scale factor of the style to scale to a different unit.

LuciadRIA places the mesh in the world at the location of the feature that you are styling, as in Figure 2, “Three icons, sharing the same mesh, placed in the world”. They share the same style so their orientation is the same. They all point in a certain direction. It depends on both the local and global coordinate system what direction that is.

meshalignedwithworldcoordinatesystem
Figure 2. Three icons, sharing the same mesh, placed in the world

Rotating the icon in its local reference

If you want to change the direction of an icon, you can specify a rotation property on Icon3DStyle. As a result, LuciadRIA applies the specified rotation to the mesh in its local coordinate system before it places it in the world. For example Figure 3, “A rotated 3D icon in its local coordinate system” shows a rotated version of the mesh in Figure 1, “A 3D icon with its local coordinate system”.

rotatedmesh
Figure 3. A rotated 3D icon in its local coordinate system
meshmanualorientation
Figure 4. Rotated icons placed in the world

Orienting the icon in the world

Technically, the options described so far are enough to place, scale, and orient your 3D icon in every possible way, but they are not always practical. For example, if you want to point all three icons in Figure 4, “Rotated icons placed in the world” to the north, you must calculate the correct rotation for each position. You need to do that because the appropriate amount of rotation for each icon depends on its location on the earth.

To make 3D icon positioning easier, LuciadRIA doesn’t just use the combination of the axes of the local and global coordinate system to place icons in the world. You can first orient each icon, using the orientation property of Icon3DStyle. You can set heading, pitch, and roll values. If you don’t specify any orientation, or if it has value 0, LuciadRIA applies a default orientation.

In the default orientation, the x-axis of the mesh points north, the y-axis points west, and the z-axis points up, perpendicular to the surface of the earth at that location.

If you want the icons to face east for example, you specify a heading of 90 degrees. LuciadRIA calculates the heading clockwise from the north.

Figure 5, “Three icons sharing the default orientation” shows the result of specifying the default orientation for the icons of Figure 4, “Rotated icons placed in the world”.

meshorientation
Figure 5. Three icons sharing the default orientation

Program: Configuring the style for a 3D icon shows, among other things, the usage of the orientation property.

Program: Configuring the style for a 3D icon (from samples/icons3d/StyleFactory.js)
const style = {
  meshUrl: URLUtil.toDataRoot("gltf/goldengate/golden_gate.gltf"),
  rotation: {
    x: 180,
    y: 90,
    z: 90
  },
  orientation: {
    heading: 0
  },
  scale: {
    x: 1,
    y: 1,
    z: 1
  }
};

Once you have defined the rotation of a mesh for one icon, other icons using the same mesh orient themselves with the orientation property. You don’t need to change the rotation for other instances.

See the API documentation of Icon3DStyle, Simple3DMeshFactory and MeshFactory for more detail.