//----------------------------------- end of public functions --------------------------------------//
    void Awake()
    {
        if (instance == null)
        {
            instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            if (instance != this)
            {
                Destroy(gameObject);
            }
        }
        //CalibrationText = GameObject.Find("CalibrationText");
        int hr = 0;

        try
        {
            hr = KinectWrapper.NuiInitialize(KinectWrapper.NuiInitializeFlags.UsesSkeleton |
                KinectWrapper.NuiInitializeFlags.UsesDepthAndPlayerIndex |
                (ComputeColorMap ? KinectWrapper.NuiInitializeFlags.UsesColor : 0));
            if (hr != 0)
            {
                throw new Exception("NuiInitialize Failed");
            }

            hr = KinectWrapper.NuiSkeletonTrackingEnable(IntPtr.Zero, 8);  // 0, 12,8
            if (hr != 0)
            {
                throw new Exception("Cannot initialize Skeleton Data");
            }

            depthStreamHandle = IntPtr.Zero;
            if(ComputeUserMap)
            {
                hr = KinectWrapper.NuiImageStreamOpen(KinectWrapper.NuiImageType.DepthAndPlayerIndex,
                    KinectWrapper.Constants.DepthImageResolution, 0, 2, IntPtr.Zero, ref depthStreamHandle);
                if (hr != 0)
                {
                    throw new Exception("Cannot open depth stream");
                }
            }

            colorStreamHandle = IntPtr.Zero;
            if(ComputeColorMap)
            {
                hr = KinectWrapper.NuiImageStreamOpen(KinectWrapper.NuiImageType.Color,
                    KinectWrapper.Constants.ColorImageResolution, 0, 2, IntPtr.Zero, ref colorStreamHandle);
                if (hr != 0)
                {
                    throw new Exception("Cannot open color stream");
                }
            }

            // set kinect elevation angle
            KinectWrapper.NuiCameraElevationSetAngle(SensorAngle);

            // init skeleton structures
            skeletonFrame = new KinectWrapper.NuiSkeletonFrame()
                            {
                                SkeletonData = new KinectWrapper.NuiSkeletonData[KinectWrapper.Constants.NuiSkeletonCount]
                            };

            // values used to pass to smoothing function
            smoothParameters = new KinectWrapper.NuiTransformSmoothParameters();

            switch(smoothing)
            {
                case Smoothing.Default:
                    smoothParameters.fSmoothing = 0.5f;
                    smoothParameters.fCorrection = 0.5f;
                    smoothParameters.fPrediction = 0.5f;
                    smoothParameters.fJitterRadius = 0.05f;
                    smoothParameters.fMaxDeviationRadius = 0.04f;
                    break;
                case Smoothing.Medium:
                    smoothParameters.fSmoothing = 0.5f;
                    smoothParameters.fCorrection = 0.1f;
                    smoothParameters.fPrediction = 0.5f;
                    smoothParameters.fJitterRadius = 0.1f;
                    smoothParameters.fMaxDeviationRadius = 0.1f;
                    break;
                case Smoothing.Aggressive:
                    smoothParameters.fSmoothing = 0.7f;
                    smoothParameters.fCorrection = 0.3f;
                    smoothParameters.fPrediction = 1.0f;
                    smoothParameters.fJitterRadius = 1.0f;
                    smoothParameters.fMaxDeviationRadius = 1.0f;
                    break;
            }

            // init the tracking state filter
            trackingStateFilter = new TrackingStateFilter[KinectWrapper.Constants.NuiSkeletonMaxTracked];
            for(int i = 0; i < trackingStateFilter.Length; i++)
            {
                trackingStateFilter[i] = new TrackingStateFilter();
                trackingStateFilter[i].Init();
            }

            // init the bone orientation filter
            boneOrientationFilter = new BoneOrientationsFilter[KinectWrapper.Constants.NuiSkeletonMaxTracked];
            for(int i = 0; i < boneOrientationFilter.Length; i++)
            {
                boneOrientationFilter[i] = new BoneOrientationsFilter();
                boneOrientationFilter[i].Init();
            }

            // init the clipped legs filter
            clippedLegsFilter = new ClippedLegsFilter[KinectWrapper.Constants.NuiSkeletonMaxTracked];
            for(int i = 0; i < clippedLegsFilter.Length; i++)
            {
                clippedLegsFilter[i] = new ClippedLegsFilter();
            }

            // init the bone orientation constraints
            boneConstraintsFilter = new BoneOrientationsConstraint();
            boneConstraintsFilter.AddDefaultConstraints();
            // init the self intersection constraints
            selfIntersectionConstraint = new SelfIntersectionConstraint();

            // create arrays for joint positions and joint orientations
            int skeletonJointsCount = (int)KinectWrapper.NuiSkeletonPositionIndex.Count;

            player1JointsTracked = new bool[skeletonJointsCount];
            player2JointsTracked = new bool[skeletonJointsCount];
            player1PrevTracked = new bool[skeletonJointsCount];
            player2PrevTracked = new bool[skeletonJointsCount];

            player1JointsPos = new Vector3[skeletonJointsCount];
            player2JointsPos = new Vector3[skeletonJointsCount];

            player1JointsOri = new Matrix4x4[skeletonJointsCount];
            player2JointsOri = new Matrix4x4[skeletonJointsCount];

            gestureTrackingAtTime = new float[KinectWrapper.Constants.NuiSkeletonMaxTracked];

            //create the transform matrix that converts from kinect-space to world-space
            Quaternion quatTiltAngle = new Quaternion();
            quatTiltAngle.eulerAngles = new Vector3(-SensorAngle, 0.0f, 0.0f);

            //float heightAboveHips = SensorHeight - 1.0f;

            // transform matrix - kinect to world
            //kinectToWorld.SetTRS(new Vector3(0.0f, heightAboveHips, 0.0f), quatTiltAngle, Vector3.one);
            kinectToWorld.SetTRS(new Vector3(0.0f, SensorHeight, 0.0f), quatTiltAngle, Vector3.one);
            flipMatrix = Matrix4x4.identity;
            flipMatrix[2, 2] = -1;

            instance = this;
            DontDestroyOnLoad(gameObject);
        }
        catch(DllNotFoundException e)
        {
            string message = "Please check the Kinect SDK installation.";
            Debug.LogError(message);
            Debug.LogError(e.ToString());
            if(CalibrationText != null)
                CalibrationText.GetComponent<GUIText>().text = message;

            return;
        }
        catch (Exception e)
        {
            string message = e.Message + " - " + KinectWrapper.GetNuiErrorString(hr);
            Debug.LogError(message);
            Debug.LogError(e.ToString());
            if(CalibrationText != null)
                CalibrationText.GetComponent<GUIText>().text = message;

            return;
        }

        if(ComputeUserMap)
        {
            // Initialize depth & label map related stuff
            usersMapSize = KinectWrapper.GetDepthWidth() * KinectWrapper.GetDepthHeight();
            usersLblTex = new Texture2D(KinectWrapper.GetDepthWidth(), KinectWrapper.GetDepthHeight());
            usersMapColors = new Color32[usersMapSize];
            usersPrevState = new ushort[usersMapSize];

            usersDepthMap = new ushort[usersMapSize];
            usersHistogramMap = new float[8192];
        }

        if(ComputeColorMap)
        {
            // Initialize color map related stuff
            usersClrTex = new Texture2D(KinectWrapper.GetColorWidth(), KinectWrapper.GetColorHeight());

            colorImage = new Color32[KinectWrapper.GetColorWidth() * KinectWrapper.GetColorHeight()];
            usersColorMap = new byte[colorImage.Length << 2];
        }

        // try to automatically find the available avatar controllers in the scene
        if(Player1Avatars.Count == 0 && Player2Avatars.Count == 0)
        {
            AvatarController[] avatars = FindObjectsOfType(typeof(AvatarController)) as AvatarController[];

            foreach(AvatarController avatar in avatars)
            {
                Player1Avatars.Add(avatar.gameObject);
            }
        }

        // Initialize user list to contain ALL users.
        allUsers = new List<uint>();

        // Pull the AvatarController from each of the players Avatars.
        Player1Controllers = new List<AvatarController>();
        Player2Controllers = new List<AvatarController>();

        // Add each of the avatars' controllers into a list for each player.
        foreach(GameObject avatar in Player1Avatars)
        {
            if(avatar != null && avatar.activeInHierarchy)
            {
                Player1Controllers.Add(avatar.GetComponent<AvatarController>());
            }
        }

        foreach(GameObject avatar in Player2Avatars)
        {
            if(avatar != null && avatar.activeInHierarchy)
            {
                Player2Controllers.Add(avatar.GetComponent<AvatarController>());
            }
        }

        // create the list of gesture listeners
        gestureListeners = new List<KinectGestures.GestureListenerInterface>();

        foreach(MonoBehaviour script in GestureListeners)
        {
            if(script && (script is KinectGestures.GestureListenerInterface))
            {
                KinectGestures.GestureListenerInterface listener = (KinectGestures.GestureListenerInterface)script;
                gestureListeners.Add(listener);
            }
        }

        // GUI Text.
        if(CalibrationText != null)
        {
            CalibrationText.GetComponent<GUIText>().text = "WAITING FOR USERS";
        }

        Debug.Log("Waiting for users.");

        KinectInitialized = true;
    }
	void StartKinect() 
	{
		try
		{
			// try to initialize the default Kinect2 sensor
			KinectInterop.FrameSource dwFlags = KinectInterop.FrameSource.TypeBody;

			if(computeUserMap != UserMapType.None)
				dwFlags |= KinectInterop.FrameSource.TypeDepth | KinectInterop.FrameSource.TypeBodyIndex;
			if(computeColorMap)
				dwFlags |= KinectInterop.FrameSource.TypeColor;
			if(computeInfraredMap)
				dwFlags |= KinectInterop.FrameSource.TypeInfrared;
//			if(useAudioSource)
//				dwFlags |= KinectInterop.FrameSource.TypeAudio;

			// open the default sensor
			BackgroundRemovalManager brManager = gameObject.GetComponentInChildren<BackgroundRemovalManager>();
			sensorData = KinectInterop.OpenDefaultSensor(sensorInterfaces, dwFlags, sensorAngle, useMultiSourceReader, computeUserMap, brManager);

			if (sensorData == null)
			{
				if(sensorInterfaces == null || sensorInterfaces.Count == 0)
					throw new Exception("No sensor found. Make sure you have installed the SDK and the sensor is connected.");
				else
					throw new Exception("OpenDefaultSensor failed.");
			}

			// enable or disable getting height and angle info
			sensorData.hintHeightAngle = (autoHeightAngle != AutoHeightAngle.DontUse);

			//create the transform matrix - kinect to world
			Quaternion quatTiltAngle = Quaternion.Euler(-sensorAngle, 0.0f, 0.0f);
			kinectToWorld.SetTRS(new Vector3(0.0f, sensorHeight, 0.0f), quatTiltAngle, Vector3.one);
		}
		catch(DllNotFoundException ex)
		{
			string message = ex.Message + " cannot be loaded. Please check the Kinect SDK installation.";
			
			Debug.LogError(message);
			Debug.LogException(ex);
			
			if(calibrationText != null)
			{
				calibrationText.text = message;
			}
			
			return;
		}
		catch(Exception ex)
		{
			string message = ex.Message;

			Debug.LogError(message);
			Debug.LogException(ex);
			
			if(calibrationText != null)
			{
				calibrationText.text = message;
			}
			
			return;
		}

		// set the singleton instance
		instance = this;
		
		// init skeleton structures
		bodyFrame = new KinectInterop.BodyFrameData(sensorData.bodyCount, KinectInterop.Constants.MaxJointCount); // sensorData.jointCount
		bodyFrame.bTurnAnalisys = allowTurnArounds;

		KinectInterop.SmoothParameters smoothParameters = new KinectInterop.SmoothParameters();
		
		switch(smoothing)
		{
			case Smoothing.Default:
				smoothParameters.smoothing = 0.5f;
				smoothParameters.correction = 0.5f;
				smoothParameters.prediction = 0.5f;
				smoothParameters.jitterRadius = 0.05f;
				smoothParameters.maxDeviationRadius = 0.04f;
				break;
			case Smoothing.Medium:
				smoothParameters.smoothing = 0.5f;
				smoothParameters.correction = 0.1f;
				smoothParameters.prediction = 0.5f;
				smoothParameters.jitterRadius = 0.1f;
				smoothParameters.maxDeviationRadius = 0.1f;
				break;
			case Smoothing.Aggressive:
				smoothParameters.smoothing = 0.7f;
				smoothParameters.correction = 0.3f;
				smoothParameters.prediction = 1.0f;
				smoothParameters.jitterRadius = 1.0f;
				smoothParameters.maxDeviationRadius = 1.0f;
				break;
		}
		
		// init data filters
		jointPositionFilter = new JointPositionsFilter();
		jointPositionFilter.Init(smoothParameters);
		
		// init the bone orientation constraints
		if(useBoneOrientationConstraints)
		{
			boneConstraintsFilter = new BoneOrientationsConstraint();
			boneConstraintsFilter.AddDefaultConstraints();
			boneConstraintsFilter.SetDebugText(calibrationText);
		}

		if(computeUserMap != UserMapType.None && computeUserMap != UserMapType.RawUserDepth)
		{
			// Initialize depth & label map related stuff
			usersLblTex = new Texture2D(sensorData.depthImageWidth, sensorData.depthImageHeight, TextureFormat.ARGB32, false);

			usersMapSize = sensorData.depthImageWidth * sensorData.depthImageHeight;
			usersHistogramImage = new Color32[usersMapSize];
			usersPrevState = new ushort[usersMapSize];
	        usersHistogramMap = new float[5001];
		}
		
		if(computeColorMap)
		{
			// Initialize color map related stuff
			//usersClrTex = new Texture2D(sensorData.colorImageWidth, sensorData.colorImageHeight, TextureFormat.RGBA32, false);
			usersClrSize = sensorData.colorImageWidth * sensorData.colorImageHeight;
		}

		// try to automatically use the available avatar controllers in the scene
		if(avatarControllers.Count == 0)
		{
			MonoBehaviour[] monoScripts = FindObjectsOfType(typeof(MonoBehaviour)) as MonoBehaviour[];

			foreach(MonoBehaviour monoScript in monoScripts)
			{
				if(typeof(AvatarController).IsAssignableFrom(monoScript.GetType()) && monoScript.enabled)
				{
					AvatarController avatar = (AvatarController)monoScript;
					avatarControllers.Add(avatar);
				}
			}
		}

		// set up the gesture manager, if not already set
		if(gestureManager == null)
		{
			MonoBehaviour[] monoScripts = FindObjectsOfType(typeof(MonoBehaviour)) as MonoBehaviour[];
			
			foreach(MonoBehaviour monoScript in monoScripts)
			{
				if(typeof(KinectGestures).IsAssignableFrom(monoScript.GetType()) && monoScript.enabled)
				{
					gestureManager = (KinectGestures)monoScript;
					break;
				}
			}

		}

		// try to automatically use the available gesture listeners in the scene
		if(gestureListeners.Count == 0)
		{
			MonoBehaviour[] monoScripts = FindObjectsOfType(typeof(MonoBehaviour)) as MonoBehaviour[];
			
			foreach(MonoBehaviour monoScript in monoScripts)
			{
				if(typeof(KinectGestures.GestureListenerInterface).IsAssignableFrom(monoScript.GetType()) &&
				   monoScript.enabled)
				{
					//KinectGestures.GestureListenerInterface gl = (KinectGestures.GestureListenerInterface)monoScript;
					gestureListeners.Add(monoScript);
				}
			}
		}
		
        // Initialize user list to contain all users.
        //alUserIds = new List<Int64>();
        //dictUserIdToIndex = new Dictionary<Int64, int>();

//		// start the background reader
//		kinectReaderThread = new System.Threading.Thread(UpdateKinectStreamsThread);
//		kinectReaderThread.Name = "KinectReaderThread";
//		kinectReaderThread.IsBackground = true;
//		kinectReaderThread.Start();
//		kinectReaderRunning = true;

		kinectInitialized = true;

#if USE_SINGLE_KM_IN_MULTIPLE_SCENES
		DontDestroyOnLoad(gameObject);
#endif
		
		// GUI Text.
		if(calibrationText != null)
		{
			calibrationText.text = "WAITING FOR USERS";
		}
		
		Debug.Log("Waiting for users.");
	}
    void Awake()
    {
        WrapperTools.EnsureKinectWrapperPresence();
        int hr = 0;

        try
        {
            hr = KinectWrapper.NuiInitialize(KinectWrapper.NuiInitializeFlags.UsesSkeleton |
                                             KinectWrapper.NuiInitializeFlags.UsesDepthAndPlayerIndex);
            if (hr != 0)
            {
                throw new Exception("NuiInitialize Failed");
            }

            hr = KinectWrapper.NuiSkeletonTrackingEnable(IntPtr.Zero, 8);              // 0, 12,8
            if (hr != 0)
            {
                throw new Exception("Cannot initialize Skeleton Data");
            }

            depthStreamHandle = IntPtr.Zero;

            // set kinect elevation angle
            KinectWrapper.NuiCameraElevationSetAngle(SensorAngle);

            // init skeleton structures
            skeletonFrame = new KinectWrapper.NuiSkeletonFrame()
            {
                SkeletonData = new KinectWrapper.NuiSkeletonData[KinectWrapper.Constants.NuiSkeletonCount]
            };

            // values used to pass to smoothing function
            smoothParameters = new KinectWrapper.NuiTransformSmoothParameters();

            switch (smoothing)
            {
            case Smoothing.Default:
                smoothParameters.fSmoothing          = 0.5f;
                smoothParameters.fCorrection         = 0.5f;
                smoothParameters.fPrediction         = 0.5f;
                smoothParameters.fJitterRadius       = 0.05f;
                smoothParameters.fMaxDeviationRadius = 0.04f;
                break;

            case Smoothing.Medium:
                smoothParameters.fSmoothing          = 0.5f;
                smoothParameters.fCorrection         = 0.1f;
                smoothParameters.fPrediction         = 0.5f;
                smoothParameters.fJitterRadius       = 0.1f;
                smoothParameters.fMaxDeviationRadius = 0.1f;
                break;

            case Smoothing.Aggressive:
                smoothParameters.fSmoothing          = 0.7f;
                smoothParameters.fCorrection         = 0.3f;
                smoothParameters.fPrediction         = 1.0f;
                smoothParameters.fJitterRadius       = 1.0f;
                smoothParameters.fMaxDeviationRadius = 1.0f;
                break;
            }

            // init the tracking state filter
            trackingStateFilter = new TrackingStateFilter[KinectWrapper.Constants.NuiSkeletonMaxTracked];
            for (int i = 0; i < trackingStateFilter.Length; i++)
            {
                trackingStateFilter[i] = new TrackingStateFilter();
                trackingStateFilter[i].Init();
            }

            // init the bone orientation filter
            boneOrientationFilter = new BoneOrientationsFilter[KinectWrapper.Constants.NuiSkeletonMaxTracked];
            for (int i = 0; i < boneOrientationFilter.Length; i++)
            {
                boneOrientationFilter[i] = new BoneOrientationsFilter();
                boneOrientationFilter[i].Init();
            }

            // init the clipped legs filter
            clippedLegsFilter = new ClippedLegsFilter[KinectWrapper.Constants.NuiSkeletonMaxTracked];
            for (int i = 0; i < clippedLegsFilter.Length; i++)
            {
                clippedLegsFilter[i] = new ClippedLegsFilter();
            }

            // init the bone orientation constraints
            boneConstraintsFilter = new BoneOrientationsConstraint();
            boneConstraintsFilter.AddDefaultConstraints();
            // init the self intersection constraints
            selfIntersectionConstraint = new SelfIntersectionConstraint();

            // create arrays for joint positions and joint orientations
            int skeletonJointsCount = (int)KinectWrapper.NuiSkeletonPositionIndex.Count;

            player1JointsTracked = new bool[skeletonJointsCount];
            player1PrevTracked   = new bool[skeletonJointsCount];

            player1JointsPos = new Vector3[skeletonJointsCount];

            player1JointsOri = new Matrix4x4[skeletonJointsCount];

            gestureTrackingAtTime = new float[KinectWrapper.Constants.NuiSkeletonMaxTracked];

            //create the transform matrix that converts from kinect-space to world-space
            Quaternion quatTiltAngle = new Quaternion();
            quatTiltAngle.eulerAngles = new Vector3(-SensorAngle, 0.0f, 0.0f);

            //float heightAboveHips = SensorHeight - 1.0f;

            // transform matrix - kinect to world
            kinectToWorld.SetTRS(new Vector3(0.0f, SensorHeight, 0.0f), quatTiltAngle, Vector3.one);
            flipMatrix       = Matrix4x4.identity;
            flipMatrix[2, 2] = -1;
        }
        catch (DllNotFoundException e)
        {
            string message = "Please check the Kinect SDK installation.";
            Debug.LogError(message);
            Debug.LogError(e.ToString());

            return;
        }
        catch (Exception e)
        {
            string message = e.Message + " - " + KinectWrapper.GetNuiErrorString(hr);
            Debug.LogError(message);
            Debug.LogError(e.ToString());

            return;
        }

        // Initialize user list to contain ALL users.
        allUsers = new List <uint>();

        KinectInitialized = true;
    }
    //----------------------------------- end of public functions --------------------------------------//
    void Start()
    {
        CalibrationText = GameObject.Find("CalibrationText");
        int hr = 0;

        try
        {
            hr = KinectWrapper.NuiInitialize(KinectWrapper.NuiInitializeFlags.UsesDepthAndPlayerIndex |
                KinectWrapper.NuiInitializeFlags.UsesSkeleton |
                (ComputeColorMap ? KinectWrapper.NuiInitializeFlags.UsesColor : 0));
            if (hr != 0)
            {
                throw new Exception("NuiInitialize Failed");
            }

            hr = KinectWrapper.NuiSkeletonTrackingEnable(IntPtr.Zero, 8);  // 0, 12,8
            if (hr != 0)
            {
                throw new Exception("Cannot initialize Skeleton Data");
            }

            depthStreamHandle = IntPtr.Zero;
            if(ComputeUserMap)
            {
                hr = KinectWrapper.NuiImageStreamOpen(KinectWrapper.NuiImageType.DepthAndPlayerIndex,
                    KinectWrapper.Constants.ImageResolution, 0, 2, IntPtr.Zero, ref depthStreamHandle);
                if (hr != 0)
                {
                    throw new Exception("Cannot open depth stream");
                }
            }

            colorStreamHandle = IntPtr.Zero;
            if(ComputeColorMap)
            {
                hr = KinectWrapper.NuiImageStreamOpen(KinectWrapper.NuiImageType.Color,
                    KinectWrapper.Constants.ImageResolution, 0, 2, IntPtr.Zero, ref colorStreamHandle);
                if (hr != 0)
                {
                    throw new Exception("Cannot open color stream");
                }
            }

            // set kinect elevation angle
            KinectWrapper.NuiCameraElevationSetAngle(SensorAngle);

            // init skeleton structures
            skeletonFrame = new KinectWrapper.NuiSkeletonFrame()
                            {
                                SkeletonData = new KinectWrapper.NuiSkeletonData[KinectWrapper.Constants.NuiSkeletonCount]
                            };

            // values used to pass to smoothing function
            smoothParameters = new KinectWrapper.NuiTransformSmoothParameters();

            switch(smoothing)
            {
                case Smoothing.Default:
                    smoothParameters.fSmoothing = 0.5f;
                    smoothParameters.fCorrection = 0.5f;
                    smoothParameters.fPrediction = 0.5f;
                    smoothParameters.fJitterRadius = 0.05f;
                    smoothParameters.fMaxDeviationRadius = 0.04f;
                    break;
                case Smoothing.Medium:
                    smoothParameters.fSmoothing = 0.5f;
                    smoothParameters.fCorrection = 0.1f;
                    smoothParameters.fPrediction = 0.5f;
                    smoothParameters.fJitterRadius = 0.1f;
                    smoothParameters.fMaxDeviationRadius = 0.1f;
                    break;
                case Smoothing.Aggressive:
                    smoothParameters.fSmoothing = 0.7f;
                    smoothParameters.fCorrection = 0.3f;
                    smoothParameters.fPrediction = 1.0f;
                    smoothParameters.fJitterRadius = 1.0f;
                    smoothParameters.fMaxDeviationRadius = 1.0f;
                    break;
            }

            // init the tracking state filter
            trackingStateFilter = new TrackingStateFilter[KinectWrapper.Constants.NuiSkeletonMaxTracked];
            for(int i = 0; i < trackingStateFilter.Length; i++)
            {
                trackingStateFilter[i] = new TrackingStateFilter();
                trackingStateFilter[i].Init();
            }

            // init the bone orientation filter
            boneOrientationFilter = new BoneOrientationsFilter[KinectWrapper.Constants.NuiSkeletonMaxTracked];
            for(int i = 0; i < boneOrientationFilter.Length; i++)
            {
                boneOrientationFilter[i] = new BoneOrientationsFilter();
                boneOrientationFilter[i].Init();
            }

            // init the clipped legs filter
            clippedLegsFilter = new ClippedLegsFilter[KinectWrapper.Constants.NuiSkeletonMaxTracked];
            for(int i = 0; i < clippedLegsFilter.Length; i++)
            {
                clippedLegsFilter[i] = new ClippedLegsFilter();
            }

            // init the bone orientation constraints
            boneConstraintsFilter = new BoneOrientationsConstraint();
            boneConstraintsFilter.AddDefaultConstraints();
            // init the self intersection constraints
            selfIntersectionConstraint = new SelfIntersectionConstraint();

            // create arrays for joint positions and joint orientations
            int skeletonJointsCount = (int)KinectWrapper.NuiSkeletonPositionIndex.Count;

            player1JointsTracked = new bool[skeletonJointsCount];
            player2JointsTracked = new bool[skeletonJointsCount];
            player1PrevTracked = new bool[skeletonJointsCount];
            player2PrevTracked = new bool[skeletonJointsCount];

            player1JointsPos = new Vector3[skeletonJointsCount];
            player2JointsPos = new Vector3[skeletonJointsCount];

            player1JointsOri = new Matrix4x4[skeletonJointsCount];
            player2JointsOri = new Matrix4x4[skeletonJointsCount];

            //create the transform matrix that converts from kinect-space to world-space
            Quaternion quatTiltAngle = new Quaternion();
            quatTiltAngle.eulerAngles = new Vector3(-SensorAngle, 0.0f, 0.0f);

            float heightAboveHips = SensorHeight - 1.0f;

            // transform matrix - kinect to world
            kinectToWorld.SetTRS(new Vector3(0.0f, heightAboveHips, 0.0f), quatTiltAngle, Vector3.one);
            flipMatrix = Matrix4x4.identity;
            flipMatrix[2, 2] = -1;

            instance = this;
            // roger> DontDestroyOnLoad(gameObject); // comment this, we want to reset and reopen kinect every time
        }
        catch (Exception e)
        {
            string message = e.Message + " - " + KinectWrapper.GetNuiErrorString(hr);
            Debug.LogError(message);
            if(CalibrationText != null)
                CalibrationText.guiText.text = message;

            return;
        }

        if(ComputeUserMap)
        {
            // Initialize depth & label map related stuff
            usersMapSize = KinectWrapper.GetDepthWidth() * KinectWrapper.GetDepthHeight();
            usersLblTex = new Texture2D(KinectWrapper.GetDepthWidth(), KinectWrapper.GetDepthHeight());
            usersMapColors = new Color[usersMapSize];
            // roger> user map size
            usersMapRect = new Rect(Screen.width, Screen.height - usersLblTex.height / 2, -usersLblTex.width / 2, usersLblTex.height / 2);
            //usersMapRect = new Rect(0, 0, Screen.width, Screen.height);

            usersDepthMap = new short[usersMapSize];
            usersHistogramMap = new float[5000];
        }

        if(ComputeColorMap)
        {
            // Initialize color map related stuff
            usersClrTex = new Texture2D(KinectWrapper.GetDepthWidth(), KinectWrapper.GetDepthHeight());
            //usersClrColors = new Color[usersMapSize];
            usersClrRect = new Rect(Screen.width, Screen.height - usersClrTex.height / 2, -usersClrTex.width / 2, usersClrTex.height / 2);

            if(ComputeUserMap)
                usersMapRect.x -= usersClrTex.width / 2;

            colorImage = new Color32[KinectWrapper.GetDepthWidth() * KinectWrapper.GetDepthHeight()];
        }

        // Initialize user list to contain ALL users.
        allUsers = new List<uint>();

        // Pull the AvatarController from each of the players Avatars.
        Player1Controllers = new List<TrainingAvatarController>();
        Player2Controllers = new List<TrainingAvatarController>();

        // Add each of the avatars' controllers into a list for each player.
        foreach(GameObject avatar in Player1Avatars)
        {
            if(avatar.activeInHierarchy)
            {
                Player1Controllers.Add(avatar.GetComponent<TrainingAvatarController>());
            }
        }

        foreach(GameObject avatar in Player2Avatars)
        {
            if(avatar.activeInHierarchy)
            {
                Player2Controllers.Add(avatar.GetComponent<TrainingAvatarController>());
            }
        }

        // GUI Text.
        if(CalibrationText != null)
        {
            CalibrationText.guiText.text = "WAITING FOR USERS";
        }

        Debug.Log("Waiting for users.");

        KinectInitialized = true;
    }
    void StartKinect()
    {
        try
        {
            // try to initialize the default Kinect2 sensor
            KinectInterop.FrameSource dwFlags = KinectInterop.FrameSource.TypeBody;

            if(computeUserMap)
                dwFlags |= KinectInterop.FrameSource.TypeDepth | KinectInterop.FrameSource.TypeBodyIndex;
            if(computeColorMap)
                dwFlags |= KinectInterop.FrameSource.TypeColor;
            if(computeInfraredMap)
                dwFlags |= KinectInterop.FrameSource.TypeInfrared;
        //			if(useAudioSource)
        //				dwFlags |= KinectInterop.FrameSource.TypeAudio;

            // open the default sensor
            sensorData = KinectInterop.OpenDefaultSensor(sensorInterfaces, dwFlags, sensorAngle, useMultiSourceReader);
            if (sensorData == null)
            {
                throw new Exception("OpenDefaultSensor failed");
            }

            //create the transform matrix - kinect to world
            Quaternion quatTiltAngle = new Quaternion();
            quatTiltAngle.eulerAngles = new Vector3(-sensorAngle, 0.0f, 0.0f);

            kinectToWorld.SetTRS(new Vector3(0.0f, sensorHeight, 0.0f), quatTiltAngle, Vector3.one);
        }
        catch(DllNotFoundException ex)
        {
            string message = ex.Message + " cannot be loaded. Please check the Kinect SDK installation.";

            Debug.LogError(message);
            Debug.LogException(ex);

            if(calibrationText != null)
            {
                calibrationText.guiText.text = message;
            }

            return;
        }
        catch(Exception ex)
        {
            string message = ex.Message;

            Debug.LogError(message);
            Debug.LogException(ex);

            if(calibrationText != null)
            {
                calibrationText.guiText.text = message;
            }

            return;
        }

        // set the singleton instance
        instance = this;

        // init skeleton structures
        bodyFrame = new KinectInterop.BodyFrameData(sensorData.bodyCount, KinectInterop.Constants.JointCount); // sensorData.jointCount

        KinectInterop.SmoothParameters smoothParameters = new KinectInterop.SmoothParameters();

        switch(smoothing)
        {
            case Smoothing.Default:
                smoothParameters.smoothing = 0.5f;
                smoothParameters.correction = 0.5f;
                smoothParameters.prediction = 0.5f;
                smoothParameters.jitterRadius = 0.05f;
                smoothParameters.maxDeviationRadius = 0.04f;
                break;
            case Smoothing.Medium:
                smoothParameters.smoothing = 0.5f;
                smoothParameters.correction = 0.1f;
                smoothParameters.prediction = 0.5f;
                smoothParameters.jitterRadius = 0.1f;
                smoothParameters.maxDeviationRadius = 0.1f;
                break;
            case Smoothing.Aggressive:
                smoothParameters.smoothing = 0.7f;
                smoothParameters.correction = 0.3f;
                smoothParameters.prediction = 1.0f;
                smoothParameters.jitterRadius = 1.0f;
                smoothParameters.maxDeviationRadius = 1.0f;
                break;
        }

        // init data filters
        jointPositionFilter = new JointPositionsFilter();
        jointPositionFilter.Init(smoothParameters);

        // init the bone orientation constraints
        if(useBoneOrientationConstraints)
        {
            boneConstraintsFilter = new BoneOrientationsConstraint();
            boneConstraintsFilter.AddDefaultConstraints();
            //boneConstraintsFilter.SetDebugText(calibrationText);
        }

        // get the main camera rectangle
        Rect cameraRect = Camera.main.pixelRect;

        // calculate map width and height in percent, if needed
        if(DisplayMapsWidthPercent == 0f)
        {
            DisplayMapsWidthPercent = (sensorData.depthImageWidth / 2) * 100 / cameraRect.width;
        }

        if(computeUserMap)
        {
            float displayMapsWidthPercent = DisplayMapsWidthPercent / 100f;
            float displayMapsHeightPercent = displayMapsWidthPercent * sensorData.depthImageHeight / sensorData.depthImageWidth;

            float displayWidth = cameraRect.width * displayMapsWidthPercent;
            float displayHeight = cameraRect.width * displayMapsHeightPercent;

            // Initialize depth & label map related stuff
            usersLblTex = new Texture2D(sensorData.depthImageWidth, sensorData.depthImageHeight);
            usersMapRect = new Rect(cameraRect.width - displayWidth, cameraRect.height, displayWidth, -displayHeight);

            usersMapSize = sensorData.depthImageWidth * sensorData.depthImageHeight;
            usersHistogramImage = new Color32[usersMapSize];
            usersPrevState = new ushort[usersMapSize];
            usersHistogramMap = new float[5001];
        }

        if(computeColorMap)
        {
            float displayMapsWidthPercent = DisplayMapsWidthPercent / 100f;
            float displayMapsHeightPercent = displayMapsWidthPercent * sensorData.colorImageHeight / sensorData.colorImageWidth;

            float displayWidth = cameraRect.width * displayMapsWidthPercent;
            float displayHeight = cameraRect.width * displayMapsHeightPercent;

            // Initialize color map related stuff
            usersClrTex = new Texture2D(sensorData.colorImageWidth, sensorData.colorImageHeight, TextureFormat.RGBA32, false);
            usersClrRect = new Rect(cameraRect.width - displayWidth, cameraRect.height, displayWidth, -displayHeight);
            usersClrSize = sensorData.colorImageWidth * sensorData.colorImageHeight;

        //			if(computeUserMap && displayColorMap)
        //			{
        //				usersMapRect.x -= cameraRect.width * displayMapsWidthPercent;
        //			}
        }

        // try to automatically use the available avatar controllers in the scene
        if(avatarControllers.Count == 0)
        {
            MonoBehaviour[] monoScripts = FindObjectsOfType(typeof(MonoBehaviour)) as MonoBehaviour[];

            foreach(MonoBehaviour monoScript in monoScripts)
            {
                if(typeof(AvatarController).IsAssignableFrom(monoScript.GetType()))
                {
                    AvatarController avatar = (AvatarController)monoScript;
                    avatarControllers.Add(avatar);
                }
            }
        }

        // try to automatically use the available gesture listeners in the scene
        if(gestureListeners.Count == 0)
        {
            MonoBehaviour[] monoScripts = FindObjectsOfType(typeof(MonoBehaviour)) as MonoBehaviour[];

            foreach(MonoBehaviour monoScript in monoScripts)
            {
                if(typeof(KinectGestures.GestureListenerInterface).IsAssignableFrom(monoScript.GetType()))
                {
                    print ("Found Listener");
                    //KinectGestures.GestureListenerInterface gl = (KinectGestures.GestureListenerInterface)monoScript;
                    gestureListeners.Add(monoScript);
                }
            }
        }

        // Initialize user list to contain all users.
        alUserIds = new List<Int64>();
        dictUserIdToIndex = new Dictionary<Int64, int>();

        kinectInitialized = true;
        DontDestroyOnLoad(gameObject);

        // GUI Text.
        if(calibrationText != null)
        {
            calibrationText.guiText.text = "WAITING FOR USERS";
        }

        Debug.Log("Waiting for users.");
    }
    void Start()
    {
        //		int hr = 0;

        try
        {
        //			if(startKinectServer)
        //			{
        //				// start the Kinect-server app
        //				hr = StartKinectServer();
        //	            if (hr != 0)
        //				{
        //	            	throw new Exception("Kinect2Server not started");
        //				}
        //			}

            // try to initialize the default Kinect2 sensor
            KinectInterop.FrameSource dwFlags = KinectInterop.FrameSource.TypeBody;
            if(computeUserMap)
                dwFlags |= KinectInterop.FrameSource.TypeDepth | KinectInterop.FrameSource.TypeBodyIndex;
            if(computeColorMap)
                dwFlags |= KinectInterop.FrameSource.TypeColor;
            if(computeInfraredMap)
                dwFlags |= KinectInterop.FrameSource.TypeInfrared;

        //			hr = KinectInterop.InitDefaultKinectSensor(dwFlags, KinectInterop.Constants.ColorImageWidth, KinectInterop.Constants.ColorImageHeight);
        //            if (hr != 0)
        //			{
        //            	throw new Exception("InitDefaultKinectSensor failed");
        //			}

            // open the default kinect sensor
            sensorData = KinectInterop.OpenDefaultKinectSensor(dwFlags);
            if (sensorData == null)
            {
                throw new Exception("OpenDefaultKinectSensor failed");
            }

            // transform matrix - kinect to world
            kinectToWorld.SetTRS(new Vector3(0.0f, sensorHeight, 0.0f), Quaternion.identity, Vector3.one);
        }
        catch(DllNotFoundException ex)
        {
            string message = ex.Message + " cannot be loaded. Please check the Kinect SDK installation.";

            Debug.LogError(message);
            Debug.LogException(ex);

            if(calibrationText != null)
            {
                calibrationText.guiText.text = message;
            }

            return;
        }
        catch(Exception ex)
        {
            string message = ex.Message;

            Debug.LogError(message);
            Debug.LogException(ex);

            if(calibrationText != null)
            {
                calibrationText.guiText.text = message;
            }

            return;
        }

        // init skeleton structures
        bodyFrame = new KinectInterop.BodyFrameData(true);

        KinectInterop.SmoothParameters smoothParameters = new KinectInterop.SmoothParameters();

        switch(smoothing)
        {
            case Smoothing.Default:
                smoothParameters.smoothing = 0.5f;
                smoothParameters.correction = 0.5f;
                smoothParameters.prediction = 0.5f;
                smoothParameters.jitterRadius = 0.05f;
                smoothParameters.maxDeviationRadius = 0.04f;
                break;
            case Smoothing.Medium:
                smoothParameters.smoothing = 0.5f;
                smoothParameters.correction = 0.1f;
                smoothParameters.prediction = 0.5f;
                smoothParameters.jitterRadius = 0.1f;
                smoothParameters.maxDeviationRadius = 0.1f;
                break;
            case Smoothing.Aggressive:
                smoothParameters.smoothing = 0.7f;
                smoothParameters.correction = 0.3f;
                smoothParameters.prediction = 1.0f;
                smoothParameters.jitterRadius = 1.0f;
                smoothParameters.maxDeviationRadius = 1.0f;
                break;
        }

        // init data filters
        jointPositionFilter = new JointPositionsFilter();
        jointPositionFilter.Init(smoothParameters);

        // init the bone orientation constraints
        if(useBoneOrientationConstraints)
        {
            boneConstraintsFilter = new BoneOrientationsConstraint();
            boneConstraintsFilter.AddDefaultConstraints();
            boneConstraintsFilter.SetDebugText(calibrationText);
        }

        // get the main camera rectangle
        Rect cameraRect = Camera.main.pixelRect;

        // calculate map width and height in percent, if needed
        if(MapsPercentWidth == 0f)
            MapsPercentWidth = (sensorData.depthImageWidth / 2) / cameraRect.width;
        if(MapsPercentHeight == 0f)
            MapsPercentHeight = (sensorData.depthImageHeight / 2) / cameraRect.height;

        if(computeUserMap)
        {
            // init user-depth structures
            //depthImage = new KinectInterop.DepthBuffer(true);
            //bodyIndexImage = new KinectInterop.BodyIndexBuffer(true);

            // Initialize depth & label map related stuff
            usersLblTex = new Texture2D(sensorData.depthImageWidth, sensorData.depthImageHeight);
            usersMapRect = new Rect(cameraRect.width - cameraRect.width * MapsPercentWidth, cameraRect.height, cameraRect.width * MapsPercentWidth, -cameraRect.height * MapsPercentHeight);

            usersMapSize = sensorData.depthImageWidth * sensorData.depthImageHeight;
            usersHistogramImage = new Color32[usersMapSize];
            usersPrevState = new ushort[usersMapSize];
            usersHistogramMap = new float[5001];
        }

        if(computeColorMap)
        {
            // init color image structures
            //colorImage = new KinectInterop.ColorBuffer(true);

            // Initialize color map related stuff
            usersClrTex = new Texture2D(sensorData.colorImageWidth, sensorData.colorImageHeight, TextureFormat.RGBA32, false);
            usersClrRect = new Rect(cameraRect.width - 320, cameraRect.height, 320, -180);
            usersCaliBox = new Rect(cameraRect.width - 160 - 320 / 14, cameraRect.height - 90, 320 / 7, 90);
            usersClrSize = sensorData.colorImageWidth * sensorData.colorImageHeight;

            if(computeUserMap && displayColorMap)
            {
                usersMapRect.x -= cameraRect.width * MapsPercentWidth; //usersClrTex.width / 2;
            }
        }

        // try to automatically find the available avatar controllers at the scene
        if(avatarControllers.Count == 0)
        {
            AvatarController[] avatars = FindObjectsOfType(typeof(AvatarController)) as AvatarController[];

            foreach(AvatarController avatar in avatars)
            {
                avatarControllers.Add(avatar);
            }
        }

        // Initialize user list to contain all users.
        alUserIds = new List<Int64>();
        dictUserIdToIndex = new Dictionary<Int64, int>();

        kinectInitialized = true;
        instance = this;

        //DontDestroyOnLoad(gameObject);

        // GUI Text.
        if(calibrationText != null)
        {
            calibrationText.guiText.text = "WAITING FOR USERS";
        }

        Debug.Log("Waiting for users.");
    }