.. centered:: |image0|

.. centered:: **Imstk-Unity**

.. centered:: *User Documentation*

Introduction
============

This document describes the iMSTK-Unity interface as well as how to build and develop it.

Overview
-----------------------

Imstk is a free & open source C++ toolkit for prototyping of interactive multi-modal surgical simulations.

Unity is a game engine written in C/C++ with a nice GUI interface. Unity provides three coding interfaces C#, “UnityScript (flavor of javascript)”, and `Boo <https://en.wikipedia.org/wiki/Boo_(programming_language)>`_.

Imstk-Unity exists as an interface for Imstk to Unity. This is acomplished with the creation of two components. A **C wrapper for Imstk** and a **C# Interface for Unity**. The C wrapper exposes Imstk in a non object oriented way. It is still built with C++ compilers, and links to object oriented code but does not implement any classes itself. The C# interface is then a very Unity specific piece of code which imports function from the C wrapper. In the future a C# wrapper may exist independently.

.. centered:: |image1|

Project Structure
-----------------------

The code repository is on gitlab `here <https://gitlab.kitware.com/iMSTK/imstk-unity>`_. You can see its issues with various labels. It contains two parts as depicted in the previous section. The C wrapper and C# wrapper.

The C Wrapper is a shared library that can be built with CMake. It statically links to Imstk and dynamically to a few of its dependencies. See build instructions for step-by-step guide on how to get working with it. By default it will install to the adjacent DemoProject from the repo. Optionally you can set it to install to a different Unity project.

The C# Wrapper exists in the "Demo Project" for development. Ultimately certain directories will be stripped out to form a Unity package that users can install (see .gitignore file). The following directories are currently used:

   - **Assets/Editor**: This directory is for the editor scripts of the plugin. Editor scripts may use runtime scripts.

   - **Assets/Scripts**: This directory is for the runtime scripts of the plugin. Runtime scripts may not use to editor scripts.

   - **Assets/Resources**: This directory contains resources required during runtime.

   - **Assets/Editor/Resources**: This directory contains resources required in the editor (such as style sheets or UI markup).

   - **Assets/Plugins**: This directory is for libraries (dlls/so) that Unity needs to load.

Directories needed for the project but not relevant to the plugin:

   - **Assets/Models, Materials, & Textures**: These directories are for various assets used by the Demo. They are not part of the plugin.

   - **Packages**: This directory contains the manifest for external packages (such as probuilder).

   - **ProjectSettings**: This directory contains settings related to the demo project.

Setup for Development
=====================

Imstk uses CMake for its build system. Imstk is a superbuild meaning it builds, includes, and links to all of its dependencies. There is no need to go find them.

Imstk-Unity's C wrapper also uses CMake for its build system. Imstk is currently its only dependency. It is not yet a superbuild. Because of this one needs to first download and build Imstk. A tag is maintained over at Imstk for the most recent compatible versions of Imstk. See `Imstk Tags <https://gitlab.kitware.com/iMSTK/iMSTK/-/tags>`_.

Warning: Do not open the DemoProject until the C wrapper has been installed. Custom Unity Importers will run at startup. If our importers are not installed before startup, assets won't be imported. If this occurs it can be fixed by installing and reimporting the assets.

Configuration and Build
-------------------------

   - Clone the Imstk repository from the url: https://gitlab.kitware.com/iMSTK/iMSTK.git
   
   - Checkout the UnityIntegration branch: git checkout UnityIntegration
   
   - Build Imstk (refer to instructions on the Imstk `repo page <https://gitlab.kitware.com/iMSTK/iMSTK>`_)

   - Clone imstk-unity repository from the url into a separate folder: https://gitlab.kitware.com/iMSTK/imstk-unity.git
   
   - Run cmake with:

      - source directory = <your cloned repo>/iMSTKUnityWrapper
      - build directory = <somewhere outside of this repo>
      - iMSTK_DIR = <path to your iMSTK build directory>/install/lib/cmake/iMSTK-3.0
   
   - Optionally one may change the CMAKE_INSTALL_PREFIX to install to a different Unity project. It defaults to the adjacent demo project.

   - Then build the install target of the resulting project. This will copy your built library as well as the dependencies to the install directory.

After your project is up and running you can make modifications and build install.

Debugging
-------------------------

To debug in visual studios:

   - Build and install Imstk debug configuration

   - Build and install Imstk-Unity debug configuration

   - Toggle "Project Settings->Imstk Settings->Use Debug" to true in the Unity Editor to inform it to use the debug dll

   - In the iMSTKUnityWrapper project after selecting debug config click "Debug->Attach to Process" and select the Unity exe.

Usage
============

For minimal usage of Imstk-Unity, two things must be added to a Unity Scene.

   - A GameObject with a SimulationManager attached to it
   - A GameObject with a Model attached to it.

Commonly a PhysicsGeometry is also needed on the Model GameObject.

Notes on C Wrapper
-------------------------
The C wrapper uses c style patterns to stay independent of Unity and be useable outside of Unity. This means one must manage their own objects. Similar to HDF5 and OpenGL one is reponsible for deleting whatever they create. With gen, delete calls, and integer object handles. Unlike these pure c APIs, if objects are not deleted, the dll will hang (because of an existing reference) and Unity will likely not launch on the second run.

Importers
-------------------------
Imstk-Unity provides a single custom Unity importer to import geometry using Imstk. This may import point, line, surface, tetrahedral, & hexahedral meshes (vtk, vtu, stl, ply, veg, ...). If the mesh importing is a point, line, or surface mesh then it will be imported as a Unity Mesh object. Anything else is not suported by Unity thus is loaded as an Imstk Geometry. If a volumetric mesh is imported the accompanying surface is extracted and provided as a separate asset.

SimulationManager
-------------------------
SimulationManager is a GameObject Component responsible for managing the simulation. It has a corresponding gen and delete call, there may only exist one. It also controls the construction, initialization, and destruction of ImstkBehaviour's to ensure this ordering: Simulation Manager created -> Imstk objects created and internally initialized -> Imstk objects externally initialized -> SimulationManager Start -> ... -> Imstk objects cleaned up -> SimulationManager cleaned up.

This Component is required to be on one GameObject for simulations to run. It is created before any other Imstk Components on any GameObjects. It implements the start, stop, pause, and other global scene related tasks.

ImstkBehaviour
-------------------------
An extension of MonoBehaviour to provide different callbacks for special construction, initialization, and destruction.

Geometry
-------------------------
Geometry is a ScriptableObject that holds geometry. This class will see extension in the future as geometric needs evolve. This class has two purposes. First, to provide a minimal class that mirrors Imstk's geometries, providing functionality that Unity Meshes would not. Second, to serve as an interface to the c api Geometry. It has a corresponding gen and delete call.

This provides two functions of big importance. ImportGeometry and ExportGeometry. These allow one to transfer data between the c api using an object handle. When geometry is exported it returns a handle. This handle can be used to refer to that geometry later. To do operations with it in the c api. Get info about it. Or import it back to managed memory/C#. In both export and import data is copied. In the future we plan to expirement with coupling functionalities. As well as GPU coupling.

GeometryComponent
-------------------------
GeometryComponent is an abstract GameObject Component that may hold either an Imstk Geometry or Unity Mesh. There are currently two subclasses, PhysicsGeometry and CollisionGeometry. These implement the 3 geometries used by Imstk. Physics, Collision, and Visual. Unity's MeshFilter serves as VisualGeometry.

These geometries ultimately don't do anything. They are just used by other components. They may also refer to another type of geometry. If they don't exist when a model is added they are created with default parameters. They default to using the visual geometry.

Dynamical Models
-------------------------
DynamicalModel is an abstract class implemented by Imstk's various Models. They require a Transform and MeshFilter on the respective object and may optionally use a PhysicsGeometry and/or CollisionGeometry. Currently FemModel and PbdModel are implemented. All the subclasses do is initialize the object while their base class takes care of the rest. The DynamicalModel is responsible for updating the visual geometry of these models.

Editor
-------------------------
Imstk-Unity provides extensions to the Unity editor. These extensions include:

   - Custom inspectors for the models and geometry components.
   - A global settings menu.
   - Menu Items for quick creation of GameObjects with Imstk items already setup.
   - Collision Graph for specification of the Imstk collision graph. This specifies the interaciton between different models. Very much a work in progress.

Bibliography
------------

.. [sample-bib] Sample reference.

.. |image0| image:: media/logo.png
   :width: 3.5in
   :height: 1.28515625in

.. |image1| image:: media/ImstkUnityArchitecture1.png
   :width: 5.5in
   :height: 0.92513863216in