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](images/UAV_imageprojection.png)
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](images/sample_imageprojection.png)
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.
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.
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());
}