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 GeoCanvas instance is passed as the first parameter of the FeaturePainter paint methods.

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 allows you to specify 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. The glTF format allows you to specify all kinds of properties of the mesh.

  • 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. It allows you 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 are not georeferenced. Instead, it is assumed 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

It is also assumed that the unit of measure is meters. If that is not the case, you can use the scale factor of the style to scale to a different unit.

The mesh is placed in the world at the location of the feature that is being styled. For example, in Figure 2, “Three icons, sharing the same mesh, placed in the world”, three icons are 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, the specified rotation is applied to the mesh in its local coordinate system before it is placed 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

Using the rotation property, we point the icons of Figure 2, “Three icons, sharing the same mesh, placed in the world” in a different direction in Figure 4, “Rotated icons placed in the world”.

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 have to calculate the correct rotation for each position because the appropriate amount of rotation for each icon depends on its location on the earth.

To make 3D icon positioning easier, icons are not placed in the world according to the combination of the axes of the local and global coordinate system only. You can first orient each icon in a certain way, using the orientation property of Icon3DStyle. It allows you to set a heading, pitch and roll value. If no orientation is specified, or it has the 0 value, a default orientation will be applied.

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. The heading is calculated 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
  }
};

Usually, once you have defined the rotation of a mesh for one icon, other icons using the same mesh are oriented with the orientation property. You do not need to change the rotation for other instances.

Refer to the API documentation of Icon3DStyle, Simple3DMeshFactory and MeshFactory for additional detail.