########
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. :doc:`NavCube </api_ref/viewing/classes/Communicator.NavCube>`, :doc:`AxisTriad </api_ref/viewing/classes/Communicator.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 :doc:`OverlayManager </api_ref/viewing/classes/Communicator.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 :ref:`maxIndex()  <api_ref/viewing/classes/Communicator.OverlayManager:maxindex>` function.

.. literalinclude:: /../../applications/client/docs/PG_Viewing_overlays.ts
   :start-after: //! [webviewer_overlays_maxindex]
   :end-before: //! [webviewer_overlays_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.
	
.. literalinclude:: /../../applications/client/docs/PG_Viewing_overlays.ts
   :start-after: //! [webviewer_overlays_setviewport]
   :end-before: //! [webviewer_overlays_setviewport]
   
The :ref:`setViewport() <api_ref/viewing/classes/Communicator.OverlayManager: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 :ref:`page <api_ref/viewing/classes/Communicator.OverlayManager:setviewport>`.

.. image:: images/overlays_microengine_viewport.png

*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 :ref:`addNodes()  <api_ref/viewing/classes/Communicator.OverlayManager:addnodes>` function with an array of :ref:`NodeIds <api_ref/viewing/modules/Communicator:nodeid>` containing the geometry you want to place into the overlay:

.. literalinclude:: /../../applications/client/docs/PG_Viewing_overlays.ts
   :start-after: //! [webviewer_overlays_addnodes]
   :end-before: //! [webviewer_overlays_addnodes]
	
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 :doc:`Camera </api_ref/viewing/classes/Communicator.Camera>` object and use the :ref:`setCamera()  <api_ref/viewing/classes/Communicator.OverlayManager:setcamera>` function.

.. literalinclude:: /../../applications/client/docs/PG_Viewing_overlays.ts
   :start-after: //! [webviewer_overlays_setcamera]
   :end-before: //! [webviewer_overlays_setcamera]

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 :ref:`AxisTriad <api_ref/viewing/classes/Communicator.AxisTriad>` at the top right of the screen.
	
.. literalinclude:: /../../applications/client/docs/PG_Viewing_overlays.ts
   :start-after: //! [webviewer_overlays_complete]
   :end-before: //! [webviewer_overlays_complete]
   
   
Selection
=========

You can determine if a selection occurred inside an overlay and act based on that information by retrieving the :ref:`overlayIndex()  <api_ref/viewing/classes/Communicator.Selection.SelectionItem:overlayindex>` value of the selectionItem.

.. literalinclude:: /../../applications/client/docs/PG_Viewing_overlays.ts
   :start-after: //! [webviewer_overlays_selection]
   :end-before: //! [webviewer_overlays_selection]


Hiding and destroying an overlay
================================

You can either choose to temporarily hide an overlay or destroy it. To hide it use the :ref:`setVisibility() <api_ref/viewing/classes/Communicator.OverlayManager:setvisibility>` function:

.. literalinclude:: /../../applications/client/docs/PG_Viewing_overlays.ts
   :start-after: //! [webviewer_overlays_hide]
   :end-before: //! [webviewer_overlays_hide]
	

Other considerations
====================

In the case of a navigation widget (like the :doc:`NavCube  </api_ref/viewing/classes/Communicator.NavCube>` or :doc:`AxisTriad  </api_ref/viewing/classes/Communicator.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.
	
.. literalinclude:: /../../applications/client/docs/PG_Viewing_overlays.ts
   :start-after: //! [webviewer_overlays_cameracallback]
   :end-before: //! [webviewer_overlays_cameracallback]

In the above code, we are first setting the camera callback (usually at the start of the application). Inside the callback, we retrieve the :ref:`view matrix  <api_ref/viewing/classes/Communicator.Camera:getviewmatrix>` 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.
