/// @brief calculates an updated priority for the user /// /// Base implementation is: priority is based on the z axis of the center of mass and the state /// @param user The user object whose priority we need to calculate protected virtual void UpdateUserPriority(NIPlayerCandidateObject user) { NIPlayerCOMCandidateObject userCom = user as NIPlayerCOMCandidateObject; if (userCom == null) { return; // irrelevant } Vector3 com = m_contextManager.UserGenrator.GetUserCenterOfMass(userCom.OpenNIUserID); userCom.m_priority = com.z; if (userCom.m_priority > 0) { userCom.m_priority = -m_maxAllowedDistance; // as far away as possible for an illegal value } if (user.PlayerStatus == UserStatus.Selected || user.PlayerStatus == UserStatus.Tracking) { userCom.m_priority += m_hysteresis; } if (userCom.PlayerStatus == UserStatus.Failure) { com -= userCom.m_COMWhenFail; if (com.magnitude < m_minCOMChangeForFailure) { userCom.m_priority -= m_failurePenalty; } } }
/// @brief Mono behavior update public void Update() { foreach (NIPlayerCandidateObject user in m_users) { UpdateUserPriority(user); } // now we sort the users by priority for (int i = 0; i < m_users.Count; i++) { NIPlayerCOMCandidateObject bestUser = m_users[i] as NIPlayerCOMCandidateObject; int bestIndex = i; for (int j = i + 1; j < m_users.Count; j++) { NIPlayerCOMCandidateObject curUser = m_users[j] as NIPlayerCOMCandidateObject; if (curUser.m_priority > bestUser.m_priority) { bestUser = curUser; bestIndex = j; } } if (bestIndex != i) { m_users[bestIndex] = m_users[i]; m_users[i] = bestUser; } } // now that we are ordered, we need to fill the players. The first N users should be players // and the rest should not when N is the number of allowed players. int numUsersToPlayers = Math.Min(m_players.Count, m_users.Count); // the actual number of users which are players // first we will unselect all irrelevant players for (int i = numUsersToPlayers; i < m_users.Count; i++) { int playerNum = GetPlayerIdFromUser(m_users[i]); UnselectPlayer(playerNum); } // now we just have selected players so we need to select the good ones and put them // in empty places for (int i = 0; i < numUsersToPlayers; i++) { int playerNum = GetPlayerIdFromUser(m_users[i]); if (playerNum >= 0) { continue; // it is already selected. } for (int j = 0; j < m_players.Count; j++) { if (m_players[j].Valid == false) { m_players[j].User = m_users[i]; m_players[j].User.SelectUser(m_numRetries); break; } } } }