Created
March 22, 2011 12:50
-
-
Save jaspervdj/881159 to your computer and use it in GitHub Desktop.
Quick & dirty stereo projection hack
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/**************************************************************************** | |
* * | |
* Nite 1.3 - Players Sample * | |
* * | |
* Author: Oz Magal * | |
* * | |
****************************************************************************/ | |
/**************************************************************************** | |
* * | |
* Nite 1.3 * | |
* Copyright (C) 2006 PrimeSense Ltd. All Rights Reserved. * | |
* * | |
* This file has been provided pursuant to a License Agreement containing * | |
* restrictions on its use. This data contains valuable trade secrets * | |
* and proprietary information of PrimeSense Ltd. and is protected by law. * | |
* * | |
****************************************************************************/ | |
#include <XnOpenNI.h> | |
#include <XnCodecIDs.h> | |
#include <XnCppWrapper.h> | |
#include "SceneDrawer.h" | |
xn::Context g_Context; | |
xn::DepthGenerator g_DepthGenerator; | |
xn::UserGenerator g_UserGenerator; | |
xn::Recorder* g_pRecorder; | |
XnUserID g_nPlayer = 0; | |
XnBool g_bCalibrated = FALSE; | |
#ifdef USE_GLUT | |
#include <GL/glut.h> | |
#else | |
//#include "opengles.h" | |
#include "kbhit.h" | |
#endif | |
//#include "signal_catch.h" | |
#ifndef USE_GLUT | |
static EGLDisplay display = EGL_NO_DISPLAY; | |
static EGLSurface surface = EGL_NO_SURFACE; | |
static EGLContext context = EGL_NO_CONTEXT; | |
#endif | |
#define GL_WIN_SIZE_X (720 * 2) | |
#define GL_WIN_SIZE_Y (480) | |
#define START_CAPTURE_CHECK_RC(rc, what) \ | |
if (nRetVal != XN_STATUS_OK) \ | |
{ \ | |
printf("Failed to %s: %s\n", what, xnGetStatusString(rc)); \ | |
StopCapture(); \ | |
return ; \ | |
} | |
XnBool g_bPause = false; | |
XnBool g_bRecord = false; | |
XnBool g_bQuit = false; | |
void StopCapture() | |
{ | |
g_bRecord = false; | |
if (g_pRecorder != NULL) | |
{ | |
g_pRecorder->RemoveNodeFromRecording(g_DepthGenerator); | |
g_pRecorder->Unref(); | |
delete g_pRecorder; | |
} | |
g_pRecorder = NULL; | |
} | |
void CleanupExit() | |
{ | |
if (g_pRecorder) | |
g_pRecorder->RemoveNodeFromRecording(g_DepthGenerator); | |
StopCapture(); | |
g_Context.Shutdown(); | |
exit (1); | |
} | |
#define GL_WIN_SIZE_X (720 * 2) | |
void StartCapture() | |
{ | |
char recordFile[256] = {0}; | |
time_t rawtime; | |
struct tm *timeinfo; | |
time(&rawtime); | |
timeinfo = localtime(&rawtime); | |
XnUInt32 size; | |
xnOSStrFormat(recordFile, sizeof(recordFile)-1, &size, | |
"%d_%02d_%02d[%02d_%02d_%02d].oni", | |
timeinfo->tm_year + 1900, timeinfo->tm_mon + 1, timeinfo->tm_mday, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); | |
if (g_pRecorder != NULL) | |
{ | |
StopCapture(); | |
} | |
XnStatus nRetVal = XN_STATUS_OK; | |
g_pRecorder = new xn::Recorder; | |
g_Context.CreateAnyProductionTree(XN_NODE_TYPE_RECORDER, NULL, *g_pRecorder); | |
START_CAPTURE_CHECK_RC(nRetVal, "Create recorder"); | |
nRetVal = g_pRecorder->SetDestination(XN_RECORD_MEDIUM_FILE, recordFile); | |
START_CAPTURE_CHECK_RC(nRetVal, "set destination"); | |
nRetVal = g_pRecorder->AddNodeToRecording(g_DepthGenerator, XN_CODEC_16Z_EMB_TABLES); | |
START_CAPTURE_CHECK_RC(nRetVal, "add node"); | |
g_bRecord = true; | |
} | |
XnBool AssignPlayer(XnUserID user) | |
{ | |
if (g_nPlayer != 0) | |
return FALSE; | |
XnPoint3D com; | |
g_UserGenerator.GetCoM(user, com); | |
if (com.Z == 0) | |
return FALSE; | |
printf("Matching for existing calibration\n"); | |
g_UserGenerator.GetSkeletonCap().LoadCalibrationData(user, 0); | |
g_UserGenerator.GetSkeletonCap().StartTracking(user); | |
g_nPlayer = user; | |
return TRUE; | |
} | |
void XN_CALLBACK_TYPE NewUser(xn::UserGenerator& generator, XnUserID user, void* pCookie) | |
{ | |
if (!g_bCalibrated) // check on player0 is enough | |
{ | |
printf("Look for pose\n"); | |
g_UserGenerator.GetPoseDetectionCap().StartPoseDetection("Psi", user); | |
return; | |
} | |
AssignPlayer(user); | |
// if (g_nPlayer == 0) | |
// { | |
// printf("Assigned user\n"); | |
// g_UserGenerator.GetSkeletonCap().LoadCalibrationData(user, 0); | |
// g_UserGenerator.GetSkeletonCap().StartTracking(user); | |
// g_nPlayer = user; | |
// } | |
} | |
void FindPlayer() | |
{ | |
if (g_nPlayer != 0) | |
{ | |
return; | |
} | |
XnUserID aUsers[20]; | |
XnUInt16 nUsers = 20; | |
g_UserGenerator.GetUsers(aUsers, nUsers); | |
for (int i = 0; i < nUsers; ++i) | |
{ | |
if (AssignPlayer(aUsers[i])) | |
return; | |
} | |
} | |
void LostPlayer() | |
{ | |
g_nPlayer = 0; | |
FindPlayer(); | |
} | |
void XN_CALLBACK_TYPE LostUser(xn::UserGenerator& generator, XnUserID user, void* pCookie) | |
{ | |
printf("Lost user %d\n", user); | |
if (g_nPlayer == user) | |
{ | |
LostPlayer(); | |
} | |
} | |
void XN_CALLBACK_TYPE PoseDetected(xn::PoseDetectionCapability& pose, const XnChar* strPose, XnUserID user, void* cxt) | |
{ | |
printf("Found pose \"%s\" for user %d\n", strPose, user); | |
g_UserGenerator.GetSkeletonCap().RequestCalibration(user, TRUE); | |
g_UserGenerator.GetPoseDetectionCap().StopPoseDetection(user); | |
} | |
void XN_CALLBACK_TYPE CalibrationStarted(xn::SkeletonCapability& skeleton, XnUserID user, void* cxt) | |
{ | |
printf("Calibration started\n"); | |
} | |
void XN_CALLBACK_TYPE CalibrationEnded(xn::SkeletonCapability& skeleton, XnUserID user, XnBool bSuccess, void* cxt) | |
{ | |
printf("Calibration done [%d] %ssuccessfully\n", user, bSuccess?"":"un"); | |
if (bSuccess) | |
{ | |
if (!g_bCalibrated) | |
{ | |
g_UserGenerator.GetSkeletonCap().SaveCalibrationData(user, 0); | |
g_nPlayer = user; | |
g_UserGenerator.GetSkeletonCap().StartTracking(user); | |
g_bCalibrated = TRUE; | |
} | |
XnUserID aUsers[10]; | |
XnUInt16 nUsers = 10; | |
g_UserGenerator.GetUsers(aUsers, nUsers); | |
for (int i = 0; i < nUsers; ++i) | |
g_UserGenerator.GetPoseDetectionCap().StopPoseDetection(aUsers[i]); | |
} | |
} | |
void DrawProjectivePoints(XnPoint3D& ptIn, int width, double r, double g, double b) | |
{ | |
static XnFloat pt[3]; | |
pt[0] = ptIn.X; | |
pt[1] = ptIn.Y; | |
pt[2] = 0; | |
glColor4f(r, | |
g, | |
b, | |
1.0f); | |
glPointSize(width); | |
glVertexPointer(3, GL_FLOAT, 0, pt); | |
glDrawArrays(GL_POINTS, 0, 1); | |
glFlush(); | |
} | |
// this function is called each frame | |
void glutDisplay (float dir) | |
{ | |
// Setup the OpenGL viewpoint | |
glMatrixMode(GL_PROJECTION); | |
glLoadIdentity(); | |
gluPerspective(45, GL_WIN_SIZE_X / 2 / GL_WIN_SIZE_Y, 0.001f, 10000.0f); | |
gluLookAt(1.3f * dir, 0.0f, -2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); | |
xn::SceneMetaData sceneMD; | |
xn::DepthMetaData depthMD; | |
g_DepthGenerator.GetMetaData(depthMD); | |
glOrtho(0, depthMD.XRes(), depthMD.YRes(), 0, -100.0, 100.0); | |
// glFrustum(0, depthMD.XRes(), depthMD.YRes(), 0, -100.0, 100.0); | |
glDisable(GL_TEXTURE_2D); | |
if (!g_bPause) | |
{ | |
// Read next available data | |
g_Context.WaitAndUpdateAll(); | |
} | |
// Process the data | |
//DRAW | |
g_DepthGenerator.GetMetaData(depthMD); | |
g_UserGenerator.GetUserPixels(0, sceneMD); | |
DrawDepthMap(depthMD, sceneMD, g_nPlayer); | |
if (g_nPlayer != 0) | |
{ | |
XnPoint3D com; | |
g_UserGenerator.GetCoM(g_nPlayer, com); | |
if (com.Z == 0) | |
{ | |
g_nPlayer = 0; | |
FindPlayer(); | |
} | |
} | |
glLoadIdentity(); | |
} | |
void glutDisplayViewports(void) | |
{ | |
/* Clear shizzle */ | |
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
/* Select left half and draw */ | |
glViewport(0, 0, GL_WIN_SIZE_X / 2, GL_WIN_SIZE_Y); | |
glutDisplay(-1); | |
/* Select right half and draw */ | |
glViewport(GL_WIN_SIZE_X / 2, 0, GL_WIN_SIZE_X / 2, GL_WIN_SIZE_Y); | |
glutDisplay(1); | |
glViewport(0, 0, GL_WIN_SIZE_X, GL_WIN_SIZE_Y); | |
/* Swap buffers */ | |
glutSwapBuffers(); | |
} | |
#ifdef USE_GLUT | |
void glutIdle (void) | |
{ | |
if (g_bQuit) { | |
CleanupExit(); | |
} | |
// Display the frame | |
glutPostRedisplay(); | |
} | |
void glutKeyboard (unsigned char key, int x, int y) | |
{ | |
switch (key) | |
{ | |
case 27: | |
CleanupExit(); | |
case'p': | |
g_bPause = !g_bPause; | |
break; | |
case 'k': | |
if (g_pRecorder == NULL) | |
StartCapture(); | |
else | |
StopCapture(); | |
printf("Record turned %s\n", g_pRecorder ? "on" : "off"); | |
break; | |
} | |
} | |
void glInit (int * pargc, char ** argv) | |
{ | |
glutInit(pargc, argv); | |
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); | |
glutCreateWindow ("Prime Sense Nite Players Viewer"); | |
//glutInitWindowSize(GL_WIN_SIZE_X, GL_WIN_SIZE_Y); | |
glutFullScreen(); | |
glutSetCursor(GLUT_CURSOR_NONE); | |
glutKeyboardFunc(glutKeyboard); | |
glutDisplayFunc(glutDisplayViewports); | |
glutIdleFunc(glutIdle); | |
glDisable(GL_DEPTH_TEST); | |
glEnable(GL_TEXTURE_2D); | |
glEnableClientState(GL_VERTEX_ARRAY); | |
glDisableClientState(GL_COLOR_ARRAY); | |
} | |
#endif | |
#define SAMPLE_XML_PATH "../../Data/Sample-User.xml" | |
#define CHECK_RC(rc, what) \ | |
if (rc != XN_STATUS_OK) \ | |
{ \ | |
printf("%s failed: %s\n", what, xnGetStatusString(rc)); \ | |
return rc; \ | |
} | |
int main(int argc, char **argv) | |
{ | |
XnStatus rc = XN_STATUS_OK; | |
rc = g_Context.InitFromXmlFile(SAMPLE_XML_PATH); | |
CHECK_RC(rc, "InitFromXml"); | |
rc = g_Context.FindExistingNode(XN_NODE_TYPE_DEPTH, g_DepthGenerator); | |
CHECK_RC(rc, "Find depth generator"); | |
rc = g_Context.FindExistingNode(XN_NODE_TYPE_USER, g_UserGenerator); | |
CHECK_RC(rc, "Find user generator"); | |
if (!g_UserGenerator.IsCapabilitySupported(XN_CAPABILITY_SKELETON) || | |
!g_UserGenerator.IsCapabilitySupported(XN_CAPABILITY_POSE_DETECTION)) | |
{ | |
printf("User generator doesn't support either skeleton or pose detection.\n"); | |
return XN_STATUS_ERROR; | |
} | |
g_UserGenerator.GetSkeletonCap().SetSkeletonProfile(XN_SKEL_PROFILE_ALL); | |
rc = g_Context.StartGeneratingAll(); | |
CHECK_RC(rc, "StartGenerating"); | |
XnCallbackHandle hUserCBs, hCalibrationCBs, hPoseCBs; | |
g_UserGenerator.RegisterUserCallbacks(NewUser, LostUser, NULL, hUserCBs); | |
g_UserGenerator.GetSkeletonCap().RegisterCalibrationCallbacks(CalibrationStarted, CalibrationEnded, NULL, hCalibrationCBs); | |
g_UserGenerator.GetPoseDetectionCap().RegisterToPoseCallbacks(PoseDetected, NULL, NULL, hPoseCBs); | |
#ifdef USE_GLUT | |
glInit(&argc, argv); | |
glutMainLoop(); | |
#else | |
if (!opengles_init(GL_WIN_SIZE_X, GL_WIN_SIZE_Y, &display, &surface, &context)) | |
{ | |
printf("Error initing opengles\n"); | |
CleanupExit(); | |
} | |
glDisable(GL_DEPTH_TEST); | |
// glEnable(GL_TEXTURE_2D); | |
glEnableClientState(GL_VERTEX_ARRAY); | |
glDisableClientState(GL_COLOR_ARRAY); | |
while ((!_kbhit()) && (!g_bQuit)) | |
{ | |
glutDisplay(); | |
eglSwapBuffers(display, surface); | |
} | |
opengles_shutdown(display, surface, context); | |
CleanupExit(); | |
#endif | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment