Instancing
==========

There are three methods of instancing in Katana, described in more detail
below.

1. ``instance.ID`` attributes
2. ``instance source`` and ``instance`` locations.
3. ``instance source`` and ``instance array`` locations.


Using Instance IDs
~~~~~~~~~~~~~~~~~~

When several copies of the same geometry are already present in the Katana
project, they can be annotated with the ``instance.ID`` attribute. When
cooking the scene, the renderer typically takes the first location with a
previously unseen ``instance.ID`` value as the instance source for further
locations with the same ID.


.. list-table::
    :header-rows: 1
    :widths: 5 20 75

    - * Type
      * Attribute
      * Description

    - * :kat:type:`string`
      * :kat:attr:`instance.ID`
      * A user-chosen string that uniquely identifies the geometry. Other
        locations with the same ID are considered instances of each other by
        the renderer.


Using Instance Sources
~~~~~~~~~~~~~~~~~~~~~~

Instances can also be created when geometry is imported into Katana.

To define the source, import the geometry into an empty group and set the
group's ``type`` attribute to ``instance source``. Instance sources are not
rendered.

To define an instance, create an empty location and set its
``geometry.instanceSource`` attribute to the path of the scene graph location
of the instance source. For clarity, the location's ``type`` can be changed to
``instance``. Instances can be shaded and transformed as usual.


.. list-table::
    :header-rows: 1
    :widths: 5 20 75

    - * Type
      * Attribute
      * Description

    - * :kat:type:`string`
      * :kat:attr:`geometry.instanceSource`
      * Path of scene graph location of the instance source.


Using Instance Arrays
~~~~~~~~~~~~~~~~~~~~~

Instance arrays are useful when instances are positioned programmatically and
do not need to be interactively transformed.

Instance sources are defined as above.

An instance array is a scene graph location declaring multiple instances of one
or more instance sources. Its ``type`` must be ``instance array``.


.. list-table::
    :header-rows: 1
    :widths: 5 20 75

    - * Type
      * Attribute
      * Description

    - * :kat:type:`string[n]`
      * :kat:attr:`geometry.instanceSource`
      * Array of paths of scene graph locations of instance sources.

    - * :kat:type:`int[n]`
      * :kat:attr:`geometry.instanceIndex`
      * Per-instance index into the ``instanceSource`` array, to determine
        which source location to use for each instance.

        In other words, ``instanceIndex`` constitutes a mapping from instance
        index to instance source index.

        Optional if ``instanceSource`` contains a single path only, in which
        case that instance source is used for all instances in the instance
        array.

    - * :kat:type:`int[]`
      * :kat:attr:`geometry.instanceSkipIndex`
      * Optional. Sparse array of indices of instances to skip.

    - * :kat:type:`double[16n]`
        :kat:type:`double[3n]`
        :kat:type:`double[4n]`
        :kat:type:`double[4n]`
        :kat:type:`double[4n]`
        :kat:type:`double[3n]`
      * :kat:attr:`geometry.instanceMatrix`
        :kat:attr:`geometry.instanceTranslate`
        :kat:attr:`geometry.instanceRotateX`
        :kat:attr:`geometry.instanceRotateY`
        :kat:attr:`geometry.instanceRotateZ`
        :kat:attr:`geometry.instanceScale`
      * Each attribute is a flat array of per-instance transformations. The
        meaning of each attribute is the same as for conventional
        :doc:`transformation <Transformations>` attributes. Can be
        multi-sampled to support animation.

    - * :kat:type:`group`
      * :kat:attr:`geometry.arbitrary`
      * Optional - see :doc:`ArbitraryAttributes`. The ``value`` or ``index``
        attributes must contain data for every instance.