Module API

<< Back to Proximity Toolkit


The Proximity Toolkit is meant to consolidate proximity data from a number of different input sources into a unified data structure. The Proximity Server is designed to load input modules on startup, so .DLL files that contain the correct API can be plugged into it. The client application is not meant to be aware of the low-level details of the data, such as which device it was gathered from.

To begin creating your own custom Input Module:

  1. Start a new Visual Studio project (the name of the output library MUST match the pattern: "*module.dll")
  2. Add a reference to ProximityToolkit.dll
  3. If you wish, you can set the output path for the project directly to the Proximity Toolkit folder. Once your module has been loaded for the first time by the Proximity Server, you may wish to choose the "Ignore Changes" option for that module.

Structuring Your Module

In order to be recognized and loaded by the Proximity Server, your module must have at least one class that implements the ProximityInputModule base class. In this class you will likely wish to override the following methods to perform the appropriate functions:

Properties

  • Guid ID - Must return a constant GUID that is unique to your module. Use a GUID generator to create one.
  • string FriendlyName - A human-readable name for your module, such as "My Custom Module".

Methods

  • void OnInitialize() - Any procedure necessary to initialize your module. If you have any persistent module settings, use the DefineSetting(string key, string value) method to define the key name and a default value. Settings created in this way will be managed by the Proximity Server - automatically saved, and restored when the program starts again.
  • void OnBegin() - Called when the ProximityServer has finished initializing, and modules are ready to start running any processes.
  • void OnEnd() - Called when the ProximityServer is shutting down. Your module should terminate any running processes.
  • void OnDispose() - Called when the module is being destroyed.
  • void OnUpdate(ProximitySpace space) - Called when your module is expected to poll for proximity data. Your module is responsible for translating any data into appropriate objects in the Proximity Space.
  • void OnRender(IRenderMediator r) - Called in order to give your module a chance to render any custom visualizations to the ProximityServer's 3D viewport. PushMatrix and PopMatrix operations are automatically performed before and after this call.

Adding Data to the ProximitySpace in OnUpdate

  • Get the presence by name, for which you will be adding data. For instance, the Vicon identifies presences by name, but your custom module may prefer to use a randomly generated unique identifier, or a name reflective of the input source. ex. TrackedPresence tp = space.GetPresence("PresenceName");
  • Set the source for the presence. ex. tp.SetSource(this);
  • Add any combination of decorators to the TrackedPresence, depending on the nature of the proximity data that your module collects. For instance, here are examples for each decorator:

LocationDecorator ld = (LocationDecorator)tp.GetDecorator(typeof(LocationDecorator)); ld.Update(location, isvisible, transform);

RotationDecorator rd = (RotationDecorator)tp.GetDecorator(typeof(RotationDecorator)); rd.Update(axis, angle, isvisible, transform);

OrientationDecorator od = (OrientationDecorator)tp.GetDecorator(typeof(RotationDecorator)); od.Update(inclineangle, azimuthangle, rollangle, isvisible);

MotionDecorator mod = (MotionDecorator)tp.GetDecorator(typeof(MotionDecorator)); mod.Update(location, isvisible, transform);

MarkerDecorator md = (MarkerDecorator)tp.GetDecorator(typeof(MarkerDecorator)); md.Update(markers, LocalTransform);

PointerDecorator pd = (PointerDecorator)pd.GetDecorator(typeof(PointerDecorator)); pd.Update(pointers, LocalTransform);

Adding Items to Module Context Menu

To add custom menu items to the Module Context Menu, which appears in the ProximityServer when a module is right clicked, do the following.

In your OnInit or OnBegin override, use AddMenuItem(string text, Image icon, EventHandler handler, bool enabled). You must implement the supplied EventHandler method name to peform the desired action when the menu item is clicked.

Using Settings

Settings are persistent values for your module that are managed by the ProximityServer program. Settings can be changed, and those values restored the next time the program loads. Support for settings is built into the ProximityInputModule base class.

Creating a Setting

  • void DefineSetting(string key, string value) - Used to define a setting as part of the collection of settings for this module. These calls should only be done in the OnInitialize() overload.

Reading/Writing a Setting

  • string Settings[string key] - Used to get/set a setting value.

Saving/Loading Settings

Settings are automatically saved each time they are modified, and loaded on program startup, so no explicit Save or Load operation is necessary.

Using the IRenderMediator Object

The ProximityServer uses OpenGL to render the 3D viewport, however to keep modules clean of OpenGL references, an IRenderMediator object is used to decouple the renderring functions from the OpenGL library. The IRenderMediator has a number of useful features:

Events

  • RenderHandler PreRender(IRenderMediator r) - Fired before the current renderring cycle begins.
  • RenderHandler PostRender(IRenderMediator r) - Fired after the current renderring cycle completes.
  • RenderHandler PerspectiveChanged(IRenderMediator r) - Fired when the renderring perspective is altered by the user.

Properties

  • Vector3 Centre - The centre point that the view is focusing on.
  • Vector3 Up - The up direction of the camera.
  • Angle ViewIncline - The angle of incline (from the XZ plane) of the camera's looking direction.
  • Angle ViewAzimuth - The angle of azimuth (around the Y axis) of the camera's looking direction.
  • double ZoomDistance - the distance between the camera and the Centre point.
  • double ScaleFactor - a constant scale factor, inverse of the zoom distance, which can be used to ensure scalable primitives can appear the same size at any zoom level.

Methods

  • void DrawPoint(Vector3 point) - Draws a single point using the current point drawing style.
  • void DrawPoints(Vector3[] points) - Draws a set of points using the current point drawing style.
  • void DrawPoints(Vector3[] points, float size, Color color) - Draws a set of points with the specified size and color.
  • void DrawLine(Vector3[] point, bool closed) - Draws a line (loop?) using the set of points.
  • void DrawLine(Vector3[] points, float width, Color color) - Draws an open line using the set of points, with the specified width and color.
  • void DrawLine(Vector3[] points, float size, Color color, bool closed) - Draws a line (loop?) using the set of points, with the specified width and color.
  • void DrawTriangles(Vector3[] points) - Draws separate polygons using the current polygon style.
  • void DrawTriangles(Vector3[] points, Color[] color) - Draws separate polygons using the corresponding set of colors for each vertex.
  • void DrawTriangleStrip(Vector3[] points) Draws a strip of polygons using the current polygon style.
  • void DrawTriangleStrip(Vector3[] points, Color[] color) - Draws a strip of polygons using the corresponding set of colors for each vertex.
  • void DrawTriangleFan(Vector3[] points) Draws a fan of polygons using the current polygon style.
  • void DrawTriangleFan(Vector3[] points, Color[] color) - Draws a fan of polygons using the corresponding set of colors for each vertex.
  • void DrawCircle(float radius) - Draws the outline of a 2D circle at the origin, using the current line style.
  • void DrawCircle(float radius, float width, Color color, Vector3 centre) - Draws the outline of a 2D circle at the given centre point, with the given width and color.
  • void DrawCircle(float radius, float width, Color color, Vector3 centre, Vector3 normal) - Draws the outline of a 2D circle at the given centre point with a normal to specify its plane, with the given width and color.
  • void FillCircle(float radius) - Draws a solid 2D circle at the origin, using the current line style.
  • void FillCircle(float radius, float width, Color color, Vector3 centre) - Draws a solid 2D circle at the given centre point, with the given width and color.
  • void FillCircle(float radius, float width, Color color, Vector3 centre, Vector3 normal) - Draws a solid 2D circle at the given centre point with a normal to specify its plane, with the given width and color.
  • void SketchSphere(float radius, Vector3 centre) - Draws the approximation of a sphere (with 3 purpendicular circles), using the current line style.
  • void SketchSphere(float radius, float width, Color color, Vector3 centre) - Draws the approximation of a sphere (with 3 purpendicular circles), using the given width and color.
  • void DrawSphere(float radius, float width, Color color, Vector3 centre) - Draws a wireframe sphere using the given line width and color.
  • void DrawSphere(float radius, float width, Color color, Vector3 centre, int slices, int stacks) - Draws a wireframe sphere using the given line width and color, and given horizontal/vertical polygon resolution.
  • void FillSphere(float radius, Color color, Vector3 centre) - Draws a solid sphere using the given color.
  • void FillSphere(float radius, Color color, Vector3 centre, int slices, int stacks) - Draws a solid sphere using the given color, and given horizontal/vertical polygon resolution.
  • void SetColor(Color color) - Sets the current drawing color for lines, points, and polygons.
  • void SetPointSize(float size) - Sets the width for points.
  • void SetLineWidth(float width) - Sets the thickness for lines.
  • void SetSolidLine() - Removes all line stippling effects.
  • void SetDottedLine(int factor) - Sets a dotted line stipple pattern with the given magnification.
  • void SetDashedLine(int factor) - Sets a dashed line stipple pattern with the given magnification.
  • void Translate(double x, double y, double z) - Applies the given translation to the render matrix.
  • void Translate(Vector3 distance) - Applies the given translation to the render matrix.
  • void Scale(double x, double y, double z) - Applies the given scaling to the render matrix.
  • void Scale(Vector3 factor) - Applies the given scaling to the render matrix.
  • void Rotate(Angle angle, double axisX, double axisY, double axisZ) - Applies the specified axis rotation to the render matrix by the given factors for each axis.
  • void '''Rotate(Angle angle, Vector3 axis) - Applies the specified axis rotation to the render matrix.
  • void '''LookAt(Vector3 eye, Vector3 center, Vector3 up) - Applies the given perspective.
  • void LoadMatrix(Matrix m) - Loads the given matrix as the render matrix.
  • void MultMatrix(Matrix m) - Multiplies the render matrix by the given matrix.
  • void PushMatrix() - Pushes the current matrix onto the render matrix stack.
  • void PopMatrix() - Restores the previous matrix from the render matrix stack.
  • void DrawAxes(float length) - Draws the XYZ axes reflective of the current render matrix.

Problems

Problems are a way of notifying the user of things they need to solve in order for your module to work properly. For instance, the ViconInputModule will raise a problem if it is unable to connect to the Vicon Nexus (critical), and if the Nexus Path is not set (non-critical). A problem can be raised to prompt a user to take action, notify them that the program is waiting for a resource to become available, etc.

Your module must define a class for each "type" of problem.

Usage

Problems should only be raised in the OnBegin() or OnUpdate() methods. To do this:

  • Create an instance of your custom Problem class with all appropriate details, handlers, dependencies, etc.
  • Call the ThrowProblem(ModuleProblem problem) method.

Dependencies

A Problem can depend on the resolution of another Problem. The dependant Problem appears greyed out until the dependency signals that it has been resolved. Be extremely careful to avoid creating a dependency loop, as the ProximityServer does not check for this condition.

Property Pages

Property Pages are user interfaces that allow the user to manipulate the settings of your module. To create a Propery Page, you must create a new User Control that inherits the ModulePropertyPage class, and override the following methods:

  • PropertyPage() - Blank constructor, so that you can work with the control in Form Designer. Don't forget your InitializeComponent() call!
  • PropertyPage(InputModule module) : base(module) - Override of constructor. Don't forget your InitializeComponent() call!
  • OnRestoreSettings() - Loads the setting values into the UI controls. ex: txt.Text = Module.Setting["mysetting"];
  • OnApplySettings() - Saves the UI control values into the settings. ex: Module.Settings["mysetting"] = txt.Text;

Furthermore, your ProximityInputModule must instantiate a copy of this custom property page in the OnInitialize() override, and assign it to the protected propertypage attribute. ex: propertypage = new MyPropertyPage(this);