3.3. C# Scripts Overview¶
The important overall picture is covered here, for more detailed notes about the implementation see the code itself, Crl
+ Q
with Rider or generate the doxygen documentation locally with CMake.
In the Scripts
folder, the subfolders correspond to the namespaces. Beware that Editor
folders are treated specially by Unity and will not be included in a build.
Libigl - This is where most of the interesting code is: modifying/updating the geometry, making calls to C++, threading, anything related to the meshes.
Editor - Scripts related to importing and pre-processing models so that we can modify them with libigl.
XrInput - This is where interface with the controllers is, reading values, setting up controllers when detected, note setting up tracking is done in the scene with the XR Interaction Toolkit components
UI - This is about the 2D user interfaces. How to generate the UI panels, update them and defining the click behaviour.
Components - This contains lots of smaller scripts to define the behaviour of a generated component. See
Assets/Prefabs/UI
.Hints - Behaviour and data related to displaying 2D UI hints over the controllers to show what each button does. This is quite context sensitive for each tool and sub-state. Uses ScriptableObjects so that we can enter the data in the Unity Editor.
Util - Some helper scripts
Testing - Scripts here are not used but might be of interest to see how the Unity APIs work (particularly the mesh API).
Warning
The C# code documentation is ‘custom’ made. If something is displayed completely incorrectly, please create an issue so it can be fixed. You can always see the doxygen documentation locally or view the code comments themselves in the IDE.
3.3.1. Libigl Overview¶
-
namespace
Libigl
-
class
DirtyFlag
Marks which data has changed in UMeshData as a bitmask and needs to be applied to the mesh.
This is used to selectively update the Unity mesh and is only for data that Unity requires. Use these constants along with the bitwise operators.
-
class
LibiglBehaviour
: public IDisposable This is where the behaviour that interfaces with libigl is. It follows a Pre/Post/Execute threading pattern. This is a
partial
class, meaning it is split between several files.Input: This handles collecting data from the main thread for the worker thread. It sets up the MeshInputState for the Actions. This is where we decide what to execute on the worker thread.
Actions: This handles executing things on the worker thread. Actions, in this context, are things that can be executed on the worker thread. They are the entry points to the C++ code (mostly). These actions correspond to the Do* variables in the MeshInputState
Transform: This handles anything related to transformations of the mesh or selections. This is only used for calculating which transformation to do for the selections. The code for applying the transformation to selections is in Actions
See also Libigl.LibiglMesh which handles the threading and calls the Pre/Post/Execute callbacks.
-
class
LibiglMesh
: public MonoBehaviour This component needs to be attached to any GameObject that you want to modify with libigl.
Any libigl related code is defined in the LibiglBehaviour class. This class only handles the threading and connection with the Unity Mesh components.
-
struct
MeshInputState
Struct for storing the current input for a mesh. (This is a value type so assigning will copy). Anything that may change as we are executing should be in the InputState, as it is copied in PreExecute. Anything that is the same between all meshes may be put into the InputState. Anything related to what should be executed on the worker thread should be put here (e.g. DoSelect).
Variables that correspond to triggering Actions start with
Do
e.g.DoSelect
-
class
MeshManager
: public MonoBehaviour Handles loading EditableMeshes and stores references, notably to the ActiveMesh.
-
struct
MeshState
The C++ state for a mesh in column major. This is linked to Unity and the RowMajor version via UMeshData. It stores only pointers to the Eigen data so this can be shared between C++ and C#. The mesh data is allocated in C++ during the Native.InitializeMesh function using UMeshDataNative.
The DirtyState indicates what has been changed and needs to be applied to the Unity mesh.
As this struct is shared between a managed (C#) and native (C++) context, you must consider Marshalling when adding new variables.
void*
usually represents an Eigen matrix, but can be anything.
-
class
Native
Contains all C++ function declarations. C# to C++
Handles initialization of the DLL and works with the UnityNativeTool for easy reloading/recompilation.
Convention: Pass the MeshState as the first argument if the function modifies a mesh.
-
class
NativeCallbacks
Contains all callbacks from the native context. C++ to C#
Callbacks should be annotated with the MonoPInvokeCallbackAttribute so that IL2CPP builds will compile properly. Each callback needs to have a corresponding delegate (/type).
-
struct
TransformDelta
Stores information about a single transformation.
-
class
UMeshData
: public IDisposable Stores a copy of the Unity Mesh’s arrays. This is purely for the interface between the Libigl Mesh MeshState and the Unity Mesh / what will be rendered. Important: Uses RowMajor as that is how it is stored by Unity and on the GPU.
-
struct
UMeshDataNative
Stores pointers to the native arrays in UMeshData so we can pass this to C++. Pointers are to the first element in the respective NativeArray.
Important: As Native arrays are not managed memory, the underlying array is fixed and will not move due to Garbage Collection. So an instance’s pointers will remain valid.
-
namespace
Editor
-
class
MeshImportPostprocessor
: public AssetPostprocessor Used for post-processing meshes after importing in the Editor. Only for file formats that Unity recognizes. Simplified version of OffMeshImporter
-
class
OffMeshImporter
: public ScriptedImporter A custom importer for .off mesh files, which Unity does not recognize or know how to import by default. See tooltips.
-
class
-
class
3.3.2. XrInput Overview¶
-
namespace
XrInput
Enums
-
enum
ToolType
Which tool is being used, InputState.ActiveTool.
Values:
-
Transform
-
Select
-
-
enum
ToolSelectMode
The sub-state of the Select tool.
Values:
-
Idle
-
Selecting
-
TransformingL
-
TransformingR
-
TransformingLr
-
-
enum
ToolTransformMode
The sub-state of the Transform tool.
Values:
-
Idle
-
TransformingL
-
TransformingR
-
TransformingLr
-
-
enum
SelectionMode
How to modify the selection.
Values:
-
Add
-
Subtract
-
Invert
-
-
enum
PivotMode
How to rotate the mesh/selection.
Values:
-
Mesh
-
Hand
-
Selection
-
-
class
InputManager
: public MonoBehaviour This script handles the controller input and is based on the Unity XR Interaction Toolkit. An important part is that this is where the InputState can be accessed and is updated.
-
struct
InputState
This is the ‘shared’ input state. It is also where you can access the filtered controller input. Stores input that is shared between meshes as well as the raw input that has not been mapped to actions. Raw input has been filtered to prevent conflicts with UI and grabbables.
-
class
XrBrush
: public MonoBehaviour Functionality related to the sphere ‘bubble’ brush. Currently handles resizing the brush, getting the center and finding overlapping bounding boxes via trigger colliders.
-
enum
3.3.3. UI Overview¶
-
namespace
UI
-
class
Icons
: public MonoBehaviour Stores references to icon sprites. Names are mostly the same as the asset names.
-
class
UiManager
: public MonoBehaviour Handles easy creation of operations to be done on a mesh and the user interaction (2D UI, speech, gestures) that comes with it.
-
class
UiMeshDetails
: public MonoBehaviour Contains all functionality related to the mesh UI panel. There is one of these per LibiglMesh. Contains most UI generation.
-
namespace
Components
-
class
UiCollapsible
: public MonoBehaviour UI Component header that hides items when clicked/toggled.
-
class
UiIconAction
: public MonoBehaviour UI Component with two buttons, one icon sized.
-
class
UiPivotMode
: public MonoBehaviour Similar to UiSelectionMode, effectively an enum field.
-
class
UiProgressIcon
: public MonoBehaviour Handles showing the progress icon and animating it based on the PreExecute and PostExecute. This indicates the state of the libigl thread.
-
class
UiSelection
: public MonoBehaviour UI for one selection of a mesh (one row)
-
class
UiSelectionMode
: public MonoBehaviour Handles the selection mode UI, onclick behaviour. There are several modes from SelectionMode as well as the newSelectionOnDrawBtn where a new selection is added on each stroke.
-
class
UiToggleAction
: public MonoBehaviour A toggle and button UI element. The toggle and button are independent by default
-
class
-
namespace
Hints
-
class
UiInputHints
: public MonoBehaviour Defines the behaviour of the input hints of one hand. Important functions are: AddTooltip(GameObject, string), SetData and Repaint.
In short, tooltips can be added so when we hover over a UI element it displays some text. Repaint is called with the collection to set out the default hints for a particular state. This can then be overriden by scripting, e.g. see RepaintTriggerColor where we set the trigger hint color ot the active selection color.
-
class
UiInputHintsData
: public ScriptableObject Data for one hand and one state of the ActiveTool. Used by the UiInputHints. We have one UiInputLabelData per button/axis.
-
class
UiInputHintsDataCollection
: public ScriptableObject Stores the hints for all possible states of the ActiveTool and sub-states. These are stored as a hierarchy. UiInputHints.Repaint defines how this data is applied. There will be one instance for the left and one for the right hand.
-
class
UiInputLabel
: public MonoBehaviour A label for a physical input button/axis to give a hint to what it does.
-
struct
UiInputLabelData
Defines the content for a UiInputLabel.
-
class
-
class