Lightspeed views supports the projection of images on a 3D terrain. A typical use case consists of representing the field of view recorded from a moving Unmanned Aerial Vehicle (UAV).

UAV imageprojection
Figure 1. Image projected from a UAV

This article explains how to get started with the LuciadLightspeed image projection API. The package com.luciad.view.lightspeed.layer.imageprojection defines the tools to accomplish such image projections. The sample lightspeed.imageprojection provides a demonstration of a moving plane projecting a sequence of images.

sample imageprojection
Figure 2. Sample of image projection in a Lightspeed view

Using TLspImageProjectionLayerBuilder and ILspImageProjector

You can visualize image projections in ILspImageProjectionLayer layers only. The ILspImageProjectionLayer interface is not intended for implementation. Create the layer with the layer builder TLspImageProjectionLayerBuilder.

As usual when you are building a Lightspeed layer, you need to assign a styler to the layer. The styler must map each domain object of the model to a TLspImageProjectionStyle. You need instances of TLspImageProjector and ALspTextureObject to build a TLspImageProjectionStyle. They represent the projector and the projected image respectively.

Program: Create a TLspImageProjectionStyle for a single element model (from samples/lightspeed/imageprojection/ProjectionStyler)
TLspImageProjectionStyle style = TLspImageProjectionStyle
    .newBuilder()
    .image(domainObject.getTexture())
    .projector(domainObject.getProjector())
    .build();

The most common ALspTextureObject implementation is TLsp2DImageTextureObject, which is used here to project a buffered image. The TLspImageProjector interface defines the location and the direction of the projector. There is a default implementation, called TLspImageProjector, which contains setters for the projector parameters.

Program: Change the point of view of a Projector (from samples/lightspeed/imageprojection/ImageProjector)
public void update(VirtualCamera aCamera) {
  TLcdDefaultModelXYZWorldTransformation transformation = new TLcdDefaultModelXYZWorldTransformation();
  transformation.setModelReference(fVideoReference);
  transformation.setXYZWorldReference(fReference);
  TLcdXYZPoint eye = new TLcdXYZPoint();
  TLcdXYZPoint ref = new TLcdXYZPoint();
  try {
    transformation.modelPoint2worldSFCT(aCamera.getEye(), eye);
    transformation.modelPoint2worldSFCT(aCamera.getRef(), ref);
  } catch (TLcdOutOfBoundsException e) {
    // not visible
    eye.move3D(Double.NaN, Double.NaN, Double.NaN);
    ref.move3D(Double.NaN, Double.NaN, Double.NaN);
  }
  fProjector.setEyePoint(eye);
  fProjector.setReferencePoint(ref);
  fProjector.setUpVector(aCamera.getUp());
  fProjector.setFieldOfView(aCamera.getFov());
  fProjector.setAspectRatio(aCamera.getAspectRatio());
  fProjector.setRange(1e5);

  fTexture.setImage(aCamera.getImage());
}