Leap Motion - Konfiguration
Zoltan Ruzman 5007
Abstract
Die Konfiguration von vielen Leap Motion Projekten ist gleich oder ähnlich. In diesem Blogpost wird aufgezeigt, wie mithilfe des Build-Patterns die einzelnen Parameter gespeichert und die Konfiguration elegant zusammengebaut wird. Als Grundlage wird mein Leap Motion Framework genommen, dass bereits eine "zentrale" Klasse zur Konfiguration eines Leap Motion Projekts besitzt, aber aktuell nicht sonderlich flexibel ist.
Hintergrund
Normalerweise lade ich zuerst die nativen Libraries der Leap Motion passend zum Betriebssystem. Zudem lege ich oft die minimale bzw. maximale Anzahl an Händen fest, welche die Applikation benötigt. Des Weiteren ist es bei 2D-Applikationen notwendig die Fenstergröße zu ermitteln. Die Angaben sind für das X/Y-Mapping relevant. Außerdem lege ich gerne die Größe des Interaktionsraums fest ...
Initial
Alle diese Optionen und noch viele mehr möchte ich zentral in der Klasse LeapApp
hinterlegen.
Diese folgt dem Singleton-Pattern, sodass zu jedem Zeitpunkt lediglich eine Instanz von LeapApp
existiert.
Die Initialisierung der Klasse LeapApp
erfolgt mit dem Build-Pattern.
public class LeapApp {
private static LeapApp instance;
private LeapApp() {}
public static class LeapAppBuilder {
public LeapAppBuilder() {
if(instance == null) {
instance = new LeapApp();
}
}
public LeapApp initLeapApp() {
return instance;
}
}
}
In den nachfolgen Kapiteln werden die einzelnen Parameter schrittweise hinzugefügt.
Parameter - Native Libraries
Über den Konstruktor des LeapAppBuilder
s möchten wir die Option bieten die nativen Libraries zu laden.
Im ursprünglichen Code wurden die Libraries automatisch aus dem Ordner "native" geladen.
public LeapAppBuilder() {
this(true);
}
public LeapAppBuilder(boolean shouldLoadNativeLibraries) {
this(shouldLoadNativeLibraries, "native");
}
public LeapAppBuilder(boolean shouldLoadNativeLibraries, String path) {
if (shouldLoadNativeLibraries) {
NativeLibrary.loadSystem(path);
}
if(instance == null) {
instance = new LeapApp(new Controller());
}
}
Mit dieser Änderung passiert das weiterhin.
Der Entwickler kann dies aber mit den Parametern shouldLoadNativeLibraries
unterbinden oder mit path
einen anderen Pfad wählen.
Parameter - TrackingBox
Nun definieren wir einen globalen Interaktionsraum, der für alle Hände, Finger und Tools gilt.
Dieser Parameter ist optional und kann bei Bedarf gesetzt werden.
Standardmäßig nutzen wir eine TrackingBox
, welche sich aus den Werten der InteractionBox
zusammensetzt.
Der folgende Quellcode zeigt exemplarisch, wie ein Parameter in LeapAppBuilder
und LeapApp
aufgenommen wird.
In den anderen Abschnitten wird die Vorgehensweise analog ausgeführt und nicht mehr explizit erwähnt.
// 1. Setter in der LeapAppBuild-Klasse zur Verfügung stellen.
public LeapAppBuilder trackingBox(TrackingBox trackingBox) {
this.trackingBox = trackingBox;
return this;
}
// 2. Parameter beim Aufruf von initLeapApp() an die Klasse LeapApp weiterreichen.
public LeapApp initLeapApp() {
instance.init(trackingBox);
return instance;
}
// 3. Parameter entgegennehmen und die LeapApp-Instanz korrekt befüllen.
private void init(TrackingBox trackingBox) {
this.trackingBox = trackingBox;
controller.addListener(LeapEventHandler.getInstance());
}
// 4. Getter und Setter zur Interaktion mit der Klasse LeapApp zur Verfügung stellen.
public static void setTrackingBox(TrackingBox trackingBox) {
instance.trackingBox = trackingBox;
}
public static TrackingBox getTrackingBox() {
return instance.trackingBox;
}
Parameter - Min / Max Hände
Für einige Applikationen ist die Anzahl der getrackten Hände fix.
Mit dem Parameter minimumHandNumber
und maximumHandNumber
legen wir das Limit fest.
Standardmäßig wird zur Ausführung der "Leap-Logik" mindestens eine Hand benötigt.
Aus diesem Grund liegt die min. Anzahl bei 1 und die max. Anzahl an Händen bei Integer.MAX_VALUE
.
Parameter - Screen Width / Height
Insbesondre zur Berechnung der X/Y-Koordinaten in 2D-Applikationen werden die Höhe und Breite des Monitors benötigt. Sofern die Angaben nicht manuell gesetzt werden, nutzen wir die Bildschirmauflösung des Default-Monitors.
Parameter - Polling
Es gibt zwei Wege um an den aktuellen Frame
der Leap Motion zu gelangen.
Über die Klasse Listener
oder mit controller.frame()
.
Ich bevorzuge die zweite Variante, da man sich dabei nicht um das Multithreading kümmern muss und die Daten kurz vor dem zeichnen / rendern nur einmal aktualisiert werden.
Standardmäßig wird Polling deshalb aktiviert.
Quellcode
Im LeapAppBuilder
sind noch ein paar weitere Parameter implementiert.
Diese sind nur für das Framework relevant und werden deshalb hier nicht besprochen.
Wer selbst mal ein bisschen probieren möchte, kann sich das Leap Motion Projekt bei GitHub auschecken.
Dort lassen sich die verschiedenen Konfigurationen an dem Projekt in der Klasse de.ruzman.hand.App
austesten.