// Remove a lost UserId public virtual int RemoveUser(ulong userId, KinectManager.UserDetectionOrder userDetectionOrder) { //int uidIndex = alUserIds.IndexOf(userId); int uidIndex = System.Array.IndexOf(aUserIndexIds, userId); // clear calibration data for this user if (playerCalibrationData.ContainsKey(userId)) { playerCalibrationData.Remove(userId); } // clean up the outdated calibration data in the data dictionary List <ulong> alCalDataKeys = new List <ulong>(playerCalibrationData.Keys); foreach (ulong calUserID in alCalDataKeys) { KinectGestureManager.GestureData gestureData = playerCalibrationData[calUserID]; if ((gestureData.timestamp + 60f) < Time.realtimeSinceStartup) { playerCalibrationData.Remove(calUserID); } } alCalDataKeys.Clear(); // remove user-id from the global users lists dictUserIdToIndex.Remove(userId); dictUserIdToTime.Remove(userId); alUserIds.Remove(userId); if (uidIndex >= 0) { FreeEmptyUserSlot(uidIndex, userDetectionOrder); } // if this was the primary user, update the primary user-id if (liPrimaryUserId == userId) { if (aUserIndexIds.Length > 0) { liPrimaryUserId = aUserIndexIds[0]; } else { liPrimaryUserId = 0; } } if (alUserIds.Count == 0) { //Debug.Log("Waiting for users."); } return(uidIndex); }
// releases the user slot. rearranges the remaining users. protected virtual void FreeEmptyUserSlot(int uidIndex, KinectManager.UserDetectionOrder userDetectionOrder) { aUserIndexIds[uidIndex] = 0; if (userDetectionOrder != KinectManager.UserDetectionOrder.Appearance) { // rearrange the remaining users for (int u = uidIndex; u < (aUserIndexIds.Length - 1); u++) { aUserIndexIds[u] = aUserIndexIds[u + 1]; if (aUserIndexIds[u + 1] != 0) { Debug.Log(string.Format("Reindexing user {0} to {1}, ID: {2}.", u + 1, u, aUserIndexIds[u + 1])); } } // make sure the last slot is free aUserIndexIds[aUserIndexIds.Length - 1] = 0; } // rearrange the remaining users RearrangeUserIndices(userDetectionOrder); }
// Adds UserId to the list of users public virtual int CalibrateUser(ulong userId, int bodyIndex, ref KinectInterop.BodyData[] alTrackedBodies, KinectManager.UserDetectionOrder userDetectionOrder, GestureType playerCalibrationPose, KinectGestureManager gestureManager) { if (!alUserIds.Contains(userId)) { if (CheckForCalibrationPose(userId, bodyIndex, playerCalibrationPose, gestureManager, ref alTrackedBodies)) { //int uidIndex = alUserIds.Count; int uidIndex = GetEmptyUserSlot(userId, bodyIndex, ref alTrackedBodies, userDetectionOrder); if (uidIndex >= 0) { aUserIndexIds[uidIndex] = userId; } else { // no empty user-index slot return(-1); } dictUserIdToIndex[userId] = bodyIndex; dictUserIdToTime[userId] = Time.time; alUserIds.Add(userId); // set primary user-id, if there is none if (liPrimaryUserId == 0 && aUserIndexIds.Length > 0) { liPrimaryUserId = aUserIndexIds[0]; // userId } return(uidIndex); } } return(-1); }
/// <summary> /// Rearranges the user indices, according to the current criteria /// </summary> public virtual void RearrangeUserIndices(KinectManager.UserDetectionOrder userDetectionOrder) { if (userDetectionOrder != KinectManager.UserDetectionOrder.Appearance) { // get current user positions Vector3[] userPos = new Vector3[aUserIndexIds.Length]; for (int i = 0; i < aUserIndexIds.Length; i++) { ulong userId = aUserIndexIds[i]; userPos[i] = userId != 0 ? kinectManager.GetUserPosition(userId) : Vector3.zero; } // bubble sort bool reorderDone = false; for (int i = aUserIndexIds.Length - 1; i >= 1; i--) { bool switchDone = false; for (int j = 0; j < i; j++) { float userDist1 = 0f; if (userDetectionOrder == KinectManager.UserDetectionOrder.Distance) { userDist1 = Mathf.Abs(userPos[j].x) + Mathf.Abs(userPos[j].z); } else if (userDetectionOrder == KinectManager.UserDetectionOrder.LeftToRight) { userDist1 = userPos[j].x; } if (Mathf.Abs(userDist1) < 0.01f) { userDist1 = 1000f; // far away } float userDist2 = 0f; if (userDetectionOrder == KinectManager.UserDetectionOrder.Distance) { userDist2 = Mathf.Abs(userPos[j + 1].x) + Mathf.Abs(userPos[j + 1].z); } else if (userDetectionOrder == KinectManager.UserDetectionOrder.LeftToRight) { userDist2 = userPos[j + 1].x; } if (Mathf.Abs(userDist2) < 0.01f) { userDist2 = 1000f; // far away } if (userDist1 > userDist2) { // switch them ulong tmpUserId = aUserIndexIds[j]; aUserIndexIds[j] = aUserIndexIds[j + 1]; aUserIndexIds[j + 1] = tmpUserId; reorderDone = switchDone = true; } } if (!switchDone) // check for sorted array { break; } } if (reorderDone) { System.Text.StringBuilder sbUsersOrder = new System.Text.StringBuilder(); sbUsersOrder.Append("Users reindexed: "); for (int i = 0; i < aUserIndexIds.Length; i++) { if (aUserIndexIds[i] != 0) { sbUsersOrder.Append(i).Append(":").Append(aUserIndexIds[i]).Append(" "); } } Debug.Log(sbUsersOrder.ToString()); } } }
// Returns empty user slot for the given user Id protected virtual int GetEmptyUserSlot(ulong userId, int bodyIndex, ref KinectInterop.BodyData[] alTrackedBodies, KinectManager.UserDetectionOrder userDetectionOrder) { // rearrange current users RearrangeUserIndices(userDetectionOrder); int uidIndex = -1; if (userDetectionOrder != KinectManager.UserDetectionOrder.Appearance) { // add the new user, depending on the distance Vector3 userPos = alTrackedBodies[bodyIndex].position; float userDist = 0f; if (userDetectionOrder == KinectManager.UserDetectionOrder.Distance) { userDist = Mathf.Abs(userPos.x) + Mathf.Abs(userPos.z); } else if (userDetectionOrder == KinectManager.UserDetectionOrder.LeftToRight) { userDist = userPos.x; } for (int i = 0; i < aUserIndexIds.Length; i++) { if (aUserIndexIds[i] == 0) { // free user slot uidIndex = i; break; } else { ulong uidUserId = aUserIndexIds[i]; Vector3 uidUserPos = kinectManager.GetUserPosition(uidUserId); float uidUserDist = 0; if (userDetectionOrder == KinectManager.UserDetectionOrder.Distance) { uidUserDist = Mathf.Abs(uidUserPos.x) + Mathf.Abs(uidUserPos.z); } else if (userDetectionOrder == KinectManager.UserDetectionOrder.LeftToRight) { uidUserDist = uidUserPos.x; } if (userDist < uidUserDist) { // current user is left to the compared one for (int u = (aUserIndexIds.Length - 2); u >= i; u--) { aUserIndexIds[u + 1] = aUserIndexIds[u]; if (aUserIndexIds[u] != 0) { Debug.Log(string.Format("Reindexing user {0} to {1}, ID: {2}, pos: {3}, other-pos: {4}.", u, u + 1, aUserIndexIds[u], userPos, uidUserPos)); } } aUserIndexIds[i] = 0; // cleanup current index uidIndex = i; break; } } } } else { // look for the 1st available slot for (int i = 0; i < aUserIndexIds.Length; i++) { if (aUserIndexIds[i] == 0) { uidIndex = i; break; } } } return(uidIndex); }