Permalink
Browse files

moving to OpenNI/Nite based backend

  • Loading branch information...
1 parent 315299f commit 848646f1a2c0ba002441ebb0df8d023cc18e0ec5 Roy Shilkrot committed Sep 30, 2011
@@ -4,6 +4,8 @@
<dict>
<key>Author</key>
<string>MIT Media Lab</string>
+ <key>Builder Version</key>
+ <string>6534.50</string>
<key>CFBundleDisplayName</key>
<string>DepthJS</string>
<key>CFBundleIdentifier</key>
@@ -0,0 +1,11 @@
+/*
+ * HandMessageListener.cpp
+ * OpenniTry
+ *
+ * Created by Roy Shilkrot on 9/30/11.
+ * Copyright 2011 MIT. All rights reserved.
+ *
+ */
+
+#include "HandMessageListener.h"
+
@@ -0,0 +1,133 @@
+/*
+ * HandMessageListener.h
+ * OpenniTry
+ *
+ * Created by Roy Shilkrot on 9/30/11.
+ * Copyright 2011 MIT. All rights reserved.
+ *
+ */
+
+#ifndef _HANDMESSAGELISTENER_H
+#define _HANDMESSAGELISTENER_H
+
+#include <XnCppWrapper.h>
+#include <XnVPointControl.h>
+#include <XnVFlowRouter.h>
+#include <XnVSwipeDetector.h>
+#include <XnVSelectableSlider1D.h>
+#include <XnVSteadyDetector.h>
+#include <XnVBroadcaster.h>
+#include <XnVPushDetector.h>
+#include <XnVWaveDetector.h>
+#include <XnVSessionManager.h>
+#include <XnVCircleDetector.h>
+
+#include <sstream>
+using namespace std;
+
+extern void send_event(const string& etype, const string& edata);
+
+class HandPointControl : public XnVPointControl {
+public:
+ HandPointControl(xn::DepthGenerator depthGenerator, XnVSessionManager* sessionManager):m_DepthGenerator(depthGenerator),m_SessionManager(sessionManager) {
+// m_pInnerFlowRouter = new XnVFlowRouter;
+ m_pPushDetector = new XnVPushDetector;
+// m_pSwipeDetector = new XnVSwipeDetector;
+// m_pSteadyDetector = new XnVSteadyDetector;
+// m_pWaveDetector = new XnVWaveDetector;
+ m_pCircleDetector = new XnVCircleDetector;
+
+// m_pInnerFlowRouter->SetActive(m_pPushDetector);
+
+ // Add the push detector and flow manager to the broadcaster
+// m_Broadcaster.AddListener(m_pInnerFlowRouter);
+// m_Broadcaster.AddListener(m_pPushDetector);
+
+ // Push
+ m_pPushDetector->RegisterPush(this, &Push_Pushed);
+ m_pCircleDetector->RegisterCircle(this, &ACircle);
+ //m_pWaveDetector->RegisterWave(this, &Wave_Waved);
+
+ }
+
+ void Update(XnVMessage* pMessage)
+ {
+ XnVPointControl::Update(pMessage);
+ //m_Broadcaster.Update(pMessage);
+ m_pPushDetector->Update(pMessage);
+// m_pWaveDetector->Update(pMessage);
+ m_pCircleDetector->Update(pMessage);
+ }
+
+ // Push detector
+ static void XN_CALLBACK_TYPE Push_Pushed(XnFloat fVelocity, XnFloat fAngle, void* cxt)
+ {
+ printf("Push!\n");
+ send_event("Push", "");
+ }
+
+ static void XN_CALLBACK_TYPE ACircle(XnFloat fTimes, XnBool bConfident, const XnVCircle* pCircle, void* cxt) {
+ if(bConfident) {
+ printf("Bye Bye!\n");
+ ((HandPointControl*)cxt)->KillSession();
+ }
+ }
+
+ // Wave detector
+ static void XN_CALLBACK_TYPE Wave_Waved(void* cxt)
+ {
+ printf("Bye Bye!\n");
+ ((HandPointControl*)cxt)->KillSession();
+ }
+
+ void KillSession() { m_SessionManager->EndSession(); }
+
+ /**
+ * Handle creation of a new point
+ */
+ void OnPointCreate(const XnVHandPointContext* cxt) {
+ printf("** %d\n", cxt->nID);
+ send_event("Register", "");
+ }
+
+ /**
+ * Handle new position of an existing point
+ */
+ void OnPointUpdate(const XnVHandPointContext* cxt) {
+ // positions are kept in projective coordinates, since they are only used for drawing
+ XnPoint3D ptProjective(cxt->ptPosition);
+
+// printf("Point (%f,%f,%f)", ptProjective.X, ptProjective.Y, ptProjective.Z);
+ m_DepthGenerator.ConvertRealWorldToProjective(1, &ptProjective, &ptProjective);
+// printf(" -> (%f,%f,%f)\n", ptProjective.X, ptProjective.Y, ptProjective.Z);
+
+ stringstream ss;
+ ss << "\"x\":" << (int)ptProjective.X
+ << ",\"y\":" << (int)ptProjective.Y
+ << ",\"z\":" << (int)ptProjective.Z;
+ //cout << "move: " << ss.str() << endl;
+ send_event("Move", ss.str());
+ }
+
+ /**
+ * Handle destruction of an existing point
+ */
+ void OnPointDestroy(XnUInt32 nID) {
+ printf("OnPointDestroy\n");
+ send_event("Unregister", "");
+ }
+private:
+ xn::DepthGenerator m_DepthGenerator;
+ XnVSessionManager* m_SessionManager;
+
+// XnVBroadcaster m_Broadcaster;
+ XnVPushDetector* m_pPushDetector;
+// XnVSwipeDetector* m_pSwipeDetector;
+// XnVSteadyDetector* m_pSteadyDetector;
+// XnVFlowRouter* m_pInnerFlowRouter;
+//
+// XnVWaveDetector* m_pWaveDetector;
+ XnVCircleDetector* m_pCircleDetector;
+};
+
+#endif
@@ -0,0 +1,194 @@
+/*
+ * openni_backend.cpp
+ * webkit-plugin-mac
+ *
+ * Created by Roy Shilkrot on 9/30/11.
+ * Copyright 2011 MIT. All rights reserved.
+ *
+ */
+
+#include "openni_backend.hpp"
+
+// Headers for OpenNI
+#include <XnOpenNI.h>
+#include <XnCppWrapper.h>
+#include <XnHash.h>
+#include <XnLog.h>
+
+// Header for NITE
+#include "XnVNite.h"
+
+#include "HandMessageListener.h"
+
+#include <iostream>
+
+#define CHECK_RC(rc, what) \
+ if (rc != XN_STATUS_OK) \
+ { \
+ printf("%s failed: %s\n", what, xnGetStatusString(rc)); \
+ return rc; \
+ }
+
+#define CHECK_ERRORS(rc, errors, what) \
+ if (rc == XN_STATUS_NO_NODE_PRESENT) \
+ { \
+ XnChar strError[1024]; \
+ errors.ToString(strError, 1024); \
+ printf("%s\n", strError); \
+ return (rc); \
+ }
+
+#define GESTURE_TO_USE "Wave"
+
+using namespace xn;
+using namespace std;
+
+typedef enum
+{
+ IN_SESSION,
+ NOT_IN_SESSION,
+ QUICK_REFOCUS
+} SessionState;
+
+// Callback for when the focus is in progress
+void XN_CALLBACK_TYPE FocusProgress(const XnChar* strFocus, const XnPoint3D& ptPosition, XnFloat fProgress, void* UserCxt)
+{
+ printf("Focus progress: %s @(%f,%f,%f): %f\n", strFocus, ptPosition.X, ptPosition.Y, ptPosition.Z, fProgress);
+}
+
+void XN_CALLBACK_TYPE GestureIntermediateStageCompletedHandler(xn::GestureGenerator& generator, const XnChar* strGesture, const XnPoint3D* pPosition, void* pCookie)
+{
+ printf("Gesture %s: Intermediate stage complete (%f,%f,%f)\n", strGesture, pPosition->X, pPosition->Y, pPosition->Z);
+}
+void XN_CALLBACK_TYPE GestureReadyForNextIntermediateStageHandler(xn::GestureGenerator& generator, const XnChar* strGesture, const XnPoint3D* pPosition, void* pCookie)
+{
+ printf("Gesture %s: Ready for next intermediate stage (%f,%f,%f)\n", strGesture, pPosition->X, pPosition->Y, pPosition->Z);
+}
+void XN_CALLBACK_TYPE GestureProgressHandler(xn::GestureGenerator& generator, const XnChar* strGesture, const XnPoint3D* pPosition, XnFloat fProgress, void* pCookie)
+{
+ printf("Gesture %s progress: %f (%f,%f,%f)\n", strGesture, fProgress, pPosition->X, pPosition->Y, pPosition->Z);
+}
+
+void XN_CALLBACK_TYPE SessionStarting(const XnPoint3D& ptPosition, void* UserCxt);
+void XN_CALLBACK_TYPE SessionEnding(void* UserCxt);
+void XN_CALLBACK_TYPE NoHands(void* UserCxt);
+
+// xml to initialize OpenNI
+#define SAMPLE_XML_PATH "/Users/royshilkrot/Downloads/NITE-Bin-MacOSX-v1.4.1.2/Data/Sample-Tracking.xml"
+
+
+class OpenNIBackend {
+public:
+ OpenNIBackend():g_SessionState(NOT_IN_SESSION),running(true) {}
+
+ void run() {
+ printf("start openni backend thread");
+ while (running) {
+ XnMapOutputMode mode;
+ g_DepthGenerator.GetMapOutputMode(mode);
+ // Read next available data
+ g_Context.WaitOneUpdateAll(g_DepthGenerator);
+ // Update NITE tree
+ g_pSessionManager->Update(&g_Context);
+ }
+ printf("end openni backend thread");
+ }
+ void stop() { running = false; }
+ bool isDead() { return !running; }
+ int init() {
+
+ XnStatus rc = XN_STATUS_OK;
+ xn::EnumerationErrors errors;
+
+ // Initialize OpenNI
+ rc = g_Context.InitFromXmlFile(SAMPLE_XML_PATH, g_ScriptNode, &errors);
+ CHECK_ERRORS(rc, errors, "InitFromXmlFile");
+ CHECK_RC(rc, "InitFromXmlFile");
+
+ rc = g_Context.FindExistingNode(XN_NODE_TYPE_DEPTH, g_DepthGenerator);
+ CHECK_RC(rc, "Find depth generator");
+ rc = g_Context.FindExistingNode(XN_NODE_TYPE_HANDS, g_HandsGenerator);
+ CHECK_RC(rc, "Find hands generator");
+ rc = g_Context.FindExistingNode(XN_NODE_TYPE_GESTURE, g_GestureGenerator);
+ CHECK_RC(rc, "Find gesture generator");
+
+ // XnCallbackHandle h;
+ // if (g_HandsGenerator.IsCapabilitySupported(XN_CAPABILITY_HAND_TOUCHING_FOV_EDGE))
+ // {
+ // g_HandsGenerator.GetHandTouchingFOVEdgeCap().RegisterToHandTouchingFOVEdge(TouchingCallback, NULL, h);
+ // }
+
+ XnCallbackHandle hGestureIntermediateStageCompleted, hGestureProgress, hGestureReadyForNextIntermediateStage;
+ g_GestureGenerator.RegisterToGestureIntermediateStageCompleted(GestureIntermediateStageCompletedHandler, NULL, hGestureIntermediateStageCompleted);
+ g_GestureGenerator.RegisterToGestureReadyForNextIntermediateStage(GestureReadyForNextIntermediateStageHandler, NULL, hGestureReadyForNextIntermediateStage);
+ g_GestureGenerator.RegisterGestureCallbacks(NULL, GestureProgressHandler, NULL, hGestureProgress);
+
+ g_HandsGenerator.SetSmoothing(0.1);
+
+ // Create NITE objects
+ g_pSessionManager = new XnVSessionManager;
+ rc = g_pSessionManager->Initialize(&g_Context, "Click,Wave", "RaiseHand");
+ CHECK_RC(rc, "SessionManager::Initialize");
+
+ g_pSessionManager->RegisterSession(this, SessionStarting, SessionEnding, FocusProgress);
+
+ g_pHandListener = new HandPointControl(g_DepthGenerator,g_pSessionManager);
+ g_pFlowRouter = new XnVFlowRouter;
+ g_pFlowRouter->SetActive(g_pHandListener);
+
+ g_pSessionManager->AddListener(g_pFlowRouter);
+
+ g_pHandListener->RegisterNoPoints(this, NoHands);
+
+ // Initialization done. Start generating
+ rc = g_Context.StartGeneratingAll();
+ CHECK_RC(rc, "StartGenerating");
+
+ }
+
+ SessionState g_SessionState;
+private:
+ bool running;
+
+ // OpenNI objects
+ xn::Context g_Context;
+ xn::ScriptNode g_ScriptNode;
+ xn::DepthGenerator g_DepthGenerator;
+ xn::HandsGenerator g_HandsGenerator;
+ xn::GestureGenerator g_GestureGenerator;
+
+ // NITE objects
+ XnVSessionManager* g_pSessionManager;
+ XnVFlowRouter* g_pFlowRouter;
+
+ HandPointControl* g_pHandListener;
+};
+
+// callback for session start
+void XN_CALLBACK_TYPE SessionStarting(const XnPoint3D& ptPosition, void* UserCxt)
+{
+ printf("Session start: (%f,%f,%f)\n", ptPosition.X, ptPosition.Y, ptPosition.Z);
+ ((OpenNIBackend*)UserCxt)->g_SessionState = IN_SESSION;
+}
+// Callback for session end
+void XN_CALLBACK_TYPE SessionEnding(void* UserCxt)
+{
+ printf("Session end\n");
+ ((OpenNIBackend*)UserCxt)->g_SessionState = NOT_IN_SESSION;
+}
+void XN_CALLBACK_TYPE NoHands(void* UserCxt)
+{
+ if (((OpenNIBackend*)UserCxt)->g_SessionState != NOT_IN_SESSION)
+ {
+ printf("Quick refocus\n");
+ ((OpenNIBackend*)UserCxt)->g_SessionState = QUICK_REFOCUS;
+ }
+}
+
+
+OpenNIBackend onib;
+
+int openni_backend(void* _arg) { onib.run(); }
+void kill_openni_backend() { onib.stop(); }
+bool is_openni_backend_dead() { return onib.isDead(); }
+int init_openni_backend() { return onib.init(); }
@@ -0,0 +1,18 @@
+/*
+ * openni_backend.h
+ * webkit-plugin-mac
+ *
+ * Created by Roy Shilkrot on 9/30/11.
+ * Copyright 2011 MIT. All rights reserved.
+ *
+ */
+
+#ifndef _OPENNI_BACKEND_HPP
+#define _OPENNI_BACKEND_HPP
+
+int openni_backend(void* _arg);
+void kill_openni_backend();
+bool is_openni_backend_dead();
+int init_openni_backend();
+
+#endif
Oops, something went wrong.

0 comments on commit 848646f

Please sign in to comment.