Overlays

The term Overlays in HOOPS Communicator refers to rectangular areas with an associated camera that is layered on top of the main 3D scene. While Overlays can contain any kind of data they are not meant to display large amounts of geometry and should not be used for example to create multiple views of a model. Instead, they are useful for displaying light-weight geometry like navigation widgets (e.g. NavCube, AxisTriad) or data associated with the main model like a legend bar.

Currently, Overlays can only be created via the HOOPS Web Viewer API. They cannot be authored when creating a SC model.

Creating a new Overlay

All Overlays are managed by the OverlayManager. Depending on the hardware there is a fixed amount of Overlays available which are referenced by a 0-based index. To find out the number of available overlays you can use the maxIndex() function.

hwv.overlayManager.maxIndex()

Result: 7

Setting the Viewport

You don’t need to do anything special to create a new Overlay. Instead, you can just start using any of the available Overlays by setting a viewport and then attaching geometry and a camera to it.

hwv.overlayManager.setViewport(0, Communicator.OverlayAnchor.UpperRightCorner, 10, Communicator.OverlayUnit.Pixels,
10, Communicator.OverlayUnit.Pixels, 100, Communicator.OverlayUnit.Pixels, 100, Communicator.OverlayUnit.Pixels);

The setViewport() function above sets Overlay #0 to the new viewport.

There are various options to define the size and location of the viewport using the aforementioned function: its second parameter specifies the "anchor" position of the Overlay which specifies what its position is relative to. The Unit parameter then lets you define the Units of the size and position values.

In the above example, we have created the overlay with a viewport that is 10 pixels offset horizontally and vertically from the upper right corner of the screen and has a width and height of 100 pixels.

For more information on the various parameters of setViewport() navigate to the following page.

A simple overlay inserted with the Viewport specified above.

Assigning Geometry

To make an Overlay useful you need to assign it geometry to render. Call the addNodes() function with an array of NodeIds containing the geometry you want to place into the overlay:

hwv.overlayManager.addNodes(0, [nodeid]);

The code above places all geometry into a single node inside Overlay #0.

Assigning a Camera

Just like the main scene each active Overlay needs to have a camera which defines from where the geometry it contains will be rendered. To assign a camera to an overlay simple create a new Camera Object and use the setCamera() function.

var camera = new Communicator.Camera();
camera.setPosition(new Communicator.Point3(0, 0, 1));
camera.setWidth(2);
camera.setHeight(2);
camera.setTarget(Communicator.Point3.zero());
camera.setUp(new Communicator.Point3(0, 1, 0));
camera.setProjection(Communicator.Projection.Orthographic);
hwv.overlayManager.setCamera(0, camera);

The above code creates an orthographic camera pointing to the origin and assigns it to Overlay #0.

Complete Example

Below is a complete example that demonstrates how to create an overlay with a simple X/Y/Z AxisTriad at the top right of the screen.

var overlaypanelindex = 1;
hwv.overlayManager.setViewport(overlaypanelindex, Communicator.OverlayAnchor.UpperRightCorner, 10, Communicator.OverlayUnit.Pixels,
10, Communicator.OverlayUnit.Pixels, 100, Communicator.OverlayUnit.Pixels, 100, Communicator.OverlayUnit.Pixels);
var meshData = new Communicator.MeshData();
meshData.addPolyline([0.0, 0.0, 0.0, 1.0, 0.0, 0.0], new Uint8Array([255, 0, 0, 255, 255, 0, 0, 255])); // x
meshData.addPolyline([0.0, 0.0, 0.0, 0.0, 1.0, 0.0], new Uint8Array([0, 255, 0, 255, 0, 255, 0, 255])); // y
meshData.addPolyline([0.0, 0.0, 0.0, 0.0, 0.0, 1.0], new Uint8Array([0, 0, 255, 255, 0, 0, 255, 255])); // z
hwv.model.createMesh(meshData).then(function (meshId) {
var meshInstanceData = new Communicator.MeshInstanceData(meshId);
meshInstanceData.setCreationFlags(Communicator.MeshInstanceCreationFlags.DoNotLight);
hwv.model.createMeshInstance(meshInstanceData).then(function (instanceId) {
hwv.overlayManager.addNodes(overlaypanelindex, [instanceId]);
});
});
var camera = new Communicator.Camera();
camera.setPosition(new Communicator.Point3(0, 0, 1));
camera.setWidth(2);
camera.setHeight(2);
camera.setTarget(Communicator.Point3.zero());
camera.setUp(new Communicator.Point3(0, 1, 0));
camera.setProjection(Communicator.Projection.Orthographic);
hwv.overlayManager.setCamera(overlaypanelindex, camera);

Selection

You can determine if a selection occurred inside an Overlay and act based on that information by retrieving the overlayIndex() value of the selectionItem.

var config = new Communicator.PickConfig();
hwv.view.pickFromPoint(new Communicator.Point2(800, 500), config).then(function (selectionItem) {
if (selectionItem.overlayIndex() != null)
{
var faceId = selectionItem.getFaceEntity().getCadFaceIndex();
var view = hwv.view;
switch (faceId) {
case 0:
view.setViewOrientation(Communicator.ViewOrientation.Back);
break;
case 1:
view.setViewOrientation(Communicator.ViewOrientation.Front);
break;
case 2:
view.setViewOrientation(Communicator.ViewOrientation.Bottom);
break;
case 3:
view.setViewOrientation(Communicator.ViewOrientation.Top);
break;
case 4:
view.setViewOrientation(Communicator.ViewOrientation.Left);
break;
case 5:
view.setViewOrientation(Communicator.ViewOrientation.Right);
break;
} }
});

Hiding and Destroying an Overlay

You can either choose to temporarily hide an Overlay or destroy it. To hide it use the setVisibility() function:

hwv.overlayManager.setVisibility(0, false);

Other Considerations

In the case of a navigation widget (like the NavCube or AxisTriad built into the HOOPS Web Viewer), you might want to ensure that the camera orientation of the main camera is reflected in the overlay. This can be achieved by using the camera callback and updating the modeling matrix (not necessarily the camera) of the node inside the overlay.

hwv.setCallbacks({
camera: function () {
onCameraUpdate();
}
});
function onCameraUpdate() {
var viewMatrix = hwv.view.getViewMatrix();
viewMatrix.m[3] = 0.0;
viewMatrix.m[7] = 0.0;
viewMatrix.m[11] = 0.0;
viewMatrix.m[12] = 0.0;
viewMatrix.m[13] = 0.0;
viewMatrix.m[14] = 0.0;
viewMatrix.m[15] = 1.0;
hwv.model.setNodeMatrix(cubenodeid, viewMatrix);
}

In the above code, we are first setting the camera callback (usually at the start of the application). Inside the callback, we retrieve the view matrix of the camera and remove any translate and scale components from that matrix before setting it on the top level node of the overlay. By doing that any camera changes in the main scene are reflected in the Overlay.

top_level:2 prog_guide:0 viewing:1