/// @brief updates the skeleton /// /// This method is responsible for updating the skeleton based on new information. /// It is called by an external manager with the correct user which controls this specific skeleton. /// @param userID the user id of the user which controls us. @note this is the NI user ID! /// @param skeleton the skeleton object to use. /// @param centerOffset the offset we should use on the center (when moving the root). /// This is usually the starting position (so the skeleton will not "jump" when doing the first update public void UpdateSkeleton(int userID, NIUserAndSkeleton skeleton, Vector3 centerOffset) { if (skeleton.Valid == false) { return; // no skeleton } if (skeleton.GetUserCalibrationState(userID) != NIUserAndSkeleton.CalibrationState.calibrated) { return; // we are not calibrated. } if (skeleton.Skeleton.IsTracking(userID) == false) { return; // we are not tracking } // we use the torso as root SkeletonJointTransformation skelTrans = skeleton.Skeleton.GetSkeletonJoint(userID, SkeletonJoint.Torso); UpdateRoot(skelTrans.Position, centerOffset); // update each joint with data from OpenNI foreach (SkeletonJoint joint in Enum.GetValues(typeof(SkeletonJoint))) { if (skeleton.Skeleton.IsJointAvailable(joint)) { SkeletonJointTransformation skelTransJoint = skeleton.Skeleton.GetSkeletonJoint(userID, joint); UpdateJoint(joint, skelTransJoint, skelTrans.Position); } } }
/// editor OnInspectorGUI to control the NIEventLogger properties override public void OnInspectorGUI() { EditorGUI.indentLevel = 0; EditorGUIUtility.LookLikeInspector(); NIUserPoseGestureFactory detector = target as NIUserPoseGestureFactory; string[] legalPoses = NIUserAndSkeleton.GetLegalPoses(); if (legalPoses != null) { int selectedIndex; if (detector.m_poseName == null) { selectedIndex = 0; } else { for (selectedIndex = 0; selectedIndex < legalPoses.Length; selectedIndex++) { if (detector.m_poseName.CompareTo(legalPoses[selectedIndex]) == 0) { break; } } } if (selectedIndex >= legalPoses.Length) { selectedIndex = 0; } selectedIndex = EditorGUILayout.Popup("pose to detect", selectedIndex, legalPoses); detector.m_poseName = legalPoses[selectedIndex]; } else { EditorGUILayout.LabelField("Pose to detect", detector.m_poseName); } detector.m_timeToHoldPose = EditorGUILayout.FloatField("Time to hold pose", detector.m_timeToHoldPose); if (detector.m_timeToHoldPose < 0) { detector.m_timeToHoldPose = 0; } detector.m_Context = EditorGUILayout.ObjectField("Context", detector.m_Context, typeof(OpenNISettingsManager), true) as OpenNISettingsManager; if (EditorApplication.isPlaying == false) { if (GUILayout.Button("Update legal poses (might take some time)")) { OpenNISettingsManager.InspectorReloadAnInstance(); } } if (GUI.changed) { EditorUtility.SetDirty(target); } }
/// @brief initializes the class with a new user. /// /// initializes the class with a new user (The class is invalid (m_uniqueID<0) until this is done successfully) /// @param usersGenerator the users generator which holds the users. /// @param uniqueID the uniqueID of the user we should initialize to. /// @return true on success and false on failure (making the object invalid, i.e. m_uniqueID<0). public bool InitInternalSkeleton(NIUserAndSkeleton usersGenerator, int uniqueID) { m_uniqueID = -1; // to make sure we are invalid until we are sure we are valid. if (usersGenerator.Valid == false) return false; // must have a valid users generator to do anything m_userID = usersGenerator.GetNIUserId(uniqueID); if (m_userID < 0) return false; // means the uniqueID was illegal if (usersGenerator.GetUserCalibrationState(m_userID) != NIUserAndSkeleton.CalibrationState.calibrated) return false; // we only initialize calibrated users as we need the skeleton. int numJoints = 0; // holds the place to position the next joint. foreach (SkeletonJoint joint in Enum.GetValues(typeof(SkeletonJoint))) { if (usersGenerator.Skeleton.IsJointAvailable(joint)==false) continue; // an irrelevant joint. // we need to add the joint but we don't want to create a new one unless we need to. if (numJoints < m_jointsIDs.Count) { m_jointsIDs[numJoints] = joint; } else { m_jointsIDs.Add(joint); } // we need to add the joint transformation but we don't want to create a new one unless we need to. if(numJoints<m_jointsTrans.Count) { m_jointsTrans[numJoints]=usersGenerator.Skeleton.GetSkeletonJoint(m_userID, joint); } else { SkeletonJointTransformation skelTrans = usersGenerator.Skeleton.GetSkeletonJoint(m_userID, joint); m_jointsTrans.Add(skelTrans); } numJoints++; } if (numJoints < m_jointsIDs.Count) { for (; numJoints < m_jointsIDs.Count; numJoints++) m_jointsIDs[numJoints] = SkeletonJoint.Invalid; } m_uniqueID = uniqueID; return true; }
protected override void DrawPlayerManager() { base.DrawPlayerManager(); NIPlayerManagerPoseSelection manager = target as NIPlayerManagerPoseSelection; string[] legalPoses = NIUserAndSkeleton.GetLegalPoses(); if (legalPoses != null) { int selectedIndex; if (manager.m_PoseToSelect == null) { selectedIndex = 0; } else { for (selectedIndex = 0; selectedIndex < legalPoses.Length; selectedIndex++) { if (manager.m_PoseToSelect.CompareTo(legalPoses[selectedIndex]) == 0) { break; } } } if (selectedIndex >= legalPoses.Length) { selectedIndex = 0; } selectedIndex = EditorGUILayout.Popup("pose to select", selectedIndex, legalPoses); manager.m_PoseToSelect = legalPoses[selectedIndex]; bool useUnselectionPose = manager.m_PoseToUnselect != null && manager.m_PoseToUnselect.CompareTo("") != 0; useUnselectionPose = EditorGUILayout.Toggle("Use unselection pose", useUnselectionPose); if (useUnselectionPose == false) { manager.m_PoseToUnselect = ""; } else { if (manager.m_PoseToUnselect == null) { selectedIndex = 0; } else { for (selectedIndex = 0; selectedIndex < legalPoses.Length; selectedIndex++) { if (manager.m_PoseToUnselect.CompareTo(legalPoses[selectedIndex]) == 0) { break; } } } if (selectedIndex >= legalPoses.Length) { selectedIndex = 0; } selectedIndex = EditorGUILayout.Popup("Pose to unselect", selectedIndex, legalPoses); manager.m_PoseToUnselect = legalPoses[selectedIndex]; } } else { EditorGUILayout.LabelField("Pose to Select", manager.m_PoseToSelect); EditorGUILayout.LabelField("Pose to Unselect", manager.m_PoseToUnselect); } manager.m_timeToSwitch = EditorGUILayout.FloatField("Time between switching", manager.m_timeToSwitch); if (manager.m_timeToSwitch < 0.0f) { manager.m_timeToSwitch = 0; } if (EditorApplication.isPlaying == false) { if (GUILayout.Button("Update legal poses (might take some time)")) { OpenNISettingsManager.InspectorReloadAnInstance(); } } }
/// @brief Initializes everything /// /// This is a mono-behavior Awake which is used to initialize everything. Note that since internal objects /// such as the context are singleton, they are constructed before BUT they are initialized here. /// This means that before the Awake function is called, all public members (such as m_Logger, m_query /// and m_XMLFileName) must have been initialized and that no one can use NIConfigurableContext before this /// is finished. public void Awake() { m_context = NIContext.Instance; if(m_context.Valid==false) { // we need to initialize... if (m_context.Init(m_Logger, m_query, m_XMLFileName, m_recordingFilename) == false) { m_Logger.Log("FAILED TO INITIALIZE CONTEXT!!!", NIEventLogger.Categories.Initialization, NIEventLogger.Sources.BaseObjects, NIEventLogger.VerboseLevel.Errors); return; } } try { Mirror = m_initMirroring; } catch (System.Exception e) { Debug.Log("Failed to set mirroring. Are you using an XML initialization from a recording without setting the playback option in the inspector?"); throw e; } m_image = NIImage.Instance; if (m_useImageGenerator) m_image.Init(m_Logger, m_context); else m_image.Dispose(); // to make sure it is invalid m_userAndSkeletonControl = NIUserAndSkeleton.Instance; if (m_useSkeleton) { m_userAndSkeletonControl.Init(m_Logger, m_context); m_userAndSkeletonControl.SkeletonSmoothingFactor = m_smoothingFactor; } else m_userAndSkeletonControl.Dispose(); // to make sure it is invalid UpdateNodeInformation(); }