bool EyeSluggerRendererEx::updateObjectFrame()
{
	if (m_holdMode == HOLD_NORMAL) {
		return EyeSluggerRenderer::updateObjectFrame();
	} else if (m_holdMode == HOLD_IN_HAND) {

		const float OFFSET = 200;

		UserDetector* ud = m_henshinDetector->getUserDetector();
		m_origin = ud->getSkeletonJointPosition(XU_SKEL_RIGHT_HAND);
		XV3 fv = -(m_origin - ud->getSkeletonJointPosition(XU_SKEL_NECK));
		XV3 uv = fv.cross(ud->getSkeletonJointPosition(XU_SKEL_LEFT_SHOULDER) - ud->getSkeletonJointPosition(XU_SKEL_RIGHT_SHOULDER));
		uv.normalizeM();
		m_origin -= uv * OFFSET;

		m_objectFrame.SetOrigin(m_origin.X, m_origin.Y, m_origin.Z);
		m_objectFrame.SetForwardVector(fv.X, fv.Y, fv.Z);
		m_objectFrame.SetUpVector(uv.X, uv.Y, uv.Z);
		m_objectFrame.Normalize();

		return true;
	} else {
		return false;
	}
}
/**
 *  OpenGL display function.
 *
 *  This function is called every 25 milliseconds by the update
 *  function.
 */
void glutDisplay (void)
{
    /**
     *  Update every node of OpenNI.
     */
    g_Context.WaitOneUpdateAll(g_DepthGenerator);

    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(40.0, 1.05, 1.0, 10000.0);
    gluLookAt(320.0, -300.0, 4200.0,
              320.0, 240.0, 1500.0,
              0.0,-1.0, 0.0);

    glMatrixMode(GL_MODELVIEW);

    glLoadIdentity();

    glPushMatrix();

    // Checking fot game starting and finishing
    g_SFBgame.checkUsers();

    if (g_SFBgame.isGameOn()) {
        
        g_UserDetector.changeStopDetection(true);
        g_SFBgame.checkGameOver();

        if (!g_SFBgame.isGameOver()) {
            g_BusterDetector -> detectPose();
            g_IceRodDetector -> detectPose();
        } 
        else {
            STATUS_CHECK(g_Context.StopGeneratingAll(), 
                "Context generation shutdown");
        }
    }
    else {
        // Detects poses
        g_ZamusDetector -> detectPose();
        g_LinqDetector -> detectPose();
    }
    
   
    /**
     *  Use the draw functions of every class to display the game with
     *  OpenGL.
     */
    g_SceneRenderer.drawScene();
    g_SFBgame.drawFireBalls();
    g_SFBgame.drawGameInfo();
    g_SFBgame.nextFrame();

    glPopMatrix();
    glutSwapBuffers();
}
void WorldRenderer::getHenshinData(XnUserID* pUserID, const XnLabel** ppLabel, XV3* pHeadCenter, XV3* pHeadDirection)
{
	UserDetector* userDetector = m_ball_manager->user_detector();

	XnUserID userID = *pUserID = userDetector->getTrackedUserID();

	if (userID) {
		SceneMetaData smd;
		userDetector->getUserGenerator()->GetUserPixels(userID, smd);
		*ppLabel = smd.Data();

		XV3 ps[2];
		//ps[0].assign(m_kkhStatus->center);
		ps[0].assign(userDetector->getSkeletonJointPosition(XN_SKEL_HEAD));
		ps[1].assign(userDetector->getSkeletonJointPosition(XN_SKEL_NECK));
		m_depthGen->ConvertRealWorldToProjective(3, ps, ps);
		normalizeProjective(&ps[0]);
		normalizeProjective(&ps[1]);
		//normalizeProjective(&ps[2]);
		//*pLightCenter = ps[0];
		*pHeadCenter = ps[0];
		*pHeadDirection = ps[0] - ps[1];
	}
}
/**
 * Initialize XN functions
 */
void initialize() 
{
    ImageMetaData imageMD;
    XnStatus status;
    int dummy;
    
    srand ( time(NULL) );

    // Initializing context and checking for enumeration errors
    status = g_Context.InitFromXmlFile(XML_CONFIG_FILE, &g_Error);
    checkEnumError(status, g_Error);

    // Finding nodes and checking for errors
    STATUS_CHECK(g_Context.FindExistingNode(XN_NODE_TYPE_DEPTH, g_DepthGenerator), "Finding depth node");
    STATUS_CHECK(g_Context.FindExistingNode(XN_NODE_TYPE_SCENE, g_SceneAnalyzer), "Finding scene analizer");


    //  Note: when the image generation node is handled the program gets
    //  too slow.

    // STATUS_CHECK(g_Context.FindExistingNode(XN_NODE_TYPE_IMAGE, g_ImageGenerator), "Finding image node");

    // Set view point of Depth generator to the image generator point of
    // view.
    // STATUS_CHECK(g_DepthGenerator.GetAlternativeViewPointCap().SetViewPoint(g_ImageGenerator), "Set View Point");

    STATUS_CHECK(g_Context.FindExistingNode(XN_NODE_TYPE_USER, g_UserGenerator), "Finding user node");
    
    //g_ImageGenerator.GetMetaData(imageMD);
    
    // Checking camera pixel format
    //if (imageMD.PixelFormat() != XN_PIXEL_FORMAT_RGB24) {
    //    reportError("Camera format not supported...!\n");
    //}

    // Checking user generator capabilities
    if(!g_UserGenerator.IsCapabilitySupported(XN_CAPABILITY_SKELETON)) {
        reportError("Skeleton capability not supported\n");
    }
    
    if(!g_UserGenerator.IsCapabilitySupported(XN_CAPABILITY_POSE_DETECTION)) {
        reportError("Pose detection capability not supported\n");
    }

    printf("Number of players: ");
    dummy = scanf("%d", &g_MaxPlayers);
    printf("\n");

    //Initialize user detector object
    g_UserDetector = UserDetector(g_UserGenerator, g_DepthGenerator);
    g_UserDetector.registerCallbacks();
    
    g_ZamusDetector = new Zamus(&g_UserDetector);
    g_LinqDetector = new Linq(&g_UserDetector);
    g_BusterDetector = new BusterDetector(g_ZamusDetector, &g_UserDetector);
    g_IceRodDetector = new IceRodDetector(g_LinqDetector, &g_UserDetector);

    // Initialize image render object
    g_SceneRenderer = SceneRenderer(&g_ImageGenerator,
                                    &g_DepthGenerator,
                                    &g_SceneAnalyzer,
                                    &g_UserDetector,
                                    g_ZamusDetector,
                                    g_LinqDetector);

    STATUS_CHECK(g_Context.StartGeneratingAll(), "Context generation");

    g_SFBgame = SuperFiremanBrothers(&g_UserDetector, 
                                     &g_SceneAnalyzer, 
                                     g_ZamusDetector, 
                                     g_LinqDetector, 
                                     g_MaxPlayers
                                    );

}