/// utility method to fix the index of gestures after changes (assuming the string is always /// fine while the index might change because of changes done to the GestureManager). /// @param axis the axis to fix. protected void fixGestureIndex(NIAxis axis) { if (axis.m_gestureIndex < m_gestureStrings.Length && m_gestureStrings[axis.m_gestureIndex].CompareTo(axis.m_gestureString) == 0) { return; // we match } // if we are not a "gesture" type, lets just make it the "none" gesture if (axis.m_Type != NIAxis.NIInputTypes.Gesture) { axis.m_gestureIndex = m_gestureStrings.Length - 1; axis.m_gestureString = m_gestureStrings[axis.m_gestureIndex]; return; } // we now know we are a gesture type so lets look for a match for (int i = 0; i < m_gestureStrings.Length; i++) { if (m_gestureStrings[i].CompareTo(axis.m_gestureString) == 0) { axis.m_gestureIndex = i; return; // we found a match } } // if we are here, the gesture no longer exist. We therefore will set ourselves to not be a gesture // anymore but instead a hand movement type. axis.m_gestureIndex = m_gestureStrings.Length - 1; axis.m_Type = NIAxis.NIInputTypes.HandMovementFromStartingPoint; axis.m_gestureString = m_gestureStrings[axis.m_gestureIndex]; }
/// This method takes one axis and calculates its value /// @param axis the axis we calculate on /// @param raw true if raw input is used, false if smooth input is used /// @return the axis value protected float CalcNumberForAxis(NIAxis axis, bool raw) { switch (axis.m_Type) { case NIAxis.NIInputTypes.Gesture: { float val = axis.m_sourceGesture.GestureInProgress(); if (axis.m_invert) { val = -val; } return(val * axis.m_sensitivity); } case NIAxis.NIInputTypes.HandMovement: { Vector3 pos = raw ? axis.m_sourceTracker.CurPosRaw : axis.m_sourceTracker.CurPos; // now we need the relevant axis float axisValue = GetAxisFromPos(pos, axis.m_axisUsed); return(NormalizeAxisPos(axisValue, axis.m_maxMovement, axis.m_invert, axis.m_sensitivity, axis.m_deadZone)); } case NIAxis.NIInputTypes.HandMovementFromStartingPoint: { Vector3 pos = raw ? axis.m_sourceTracker.CurPosFromStartRaw : axis.m_sourceTracker.CurPosFromStart; // now we need the relevant axis float axisValue = GetAxisFromPos(pos, axis.m_axisUsed); return(NormalizeAxisPos(axisValue, axis.m_maxMovement, axis.m_invert, axis.m_sensitivity, axis.m_deadZone)); } case NIAxis.NIInputTypes.DeltaHandMovement: { Vector3 pos = raw ? axis.m_sourceTracker.CurDeltaPosRaw : axis.m_sourceTracker.CurDeltaPos; // now we need the relevant axis float axisValue = GetAxisFromPos(pos, axis.m_axisUsed); // we use -1 for the range because we never normalize the delta values return(NormalizeAxisPos(axisValue, -1, axis.m_invert, axis.m_sensitivity, axis.m_deadZone)); } default: { throw (new System.Exception("" + axis.m_Type + " not implemented yet")); } } }
/// utility method to fix the index of point trackers after changes (assuming the string is always /// fine while the index might change because of changes done to the pointsTrackingManager). /// @param axis the axis to fix. protected void fixTrackerIndex(NIAxis axis) { if (axis.m_sourceTrackerIndex < m_pointTrackerStrings.Length && m_pointTrackerStrings[axis.m_sourceTrackerIndex].CompareTo(axis.m_sourceTrackerString) == 0) { return; // we match } for (int i = 0; i < m_pointTrackerStrings.Length; i++) { if (m_pointTrackerStrings[i].CompareTo(axis.m_sourceTrackerString) == 0) { axis.m_sourceTrackerIndex = i; return; // we found a match } } // if we are here, the tracker no longer exist. We therefore will set ourselves // the "none" tracker axis.m_sourceTrackerIndex = m_pointTrackerStrings.Length - 1; axis.m_sourceTrackerString = m_pointTrackerStrings[axis.m_sourceTrackerIndex]; }
/// utility method to fix the index of point trackers after changes (assuming the string is always /// fine while the index might change because of changes done to the pointsTrackingManager). /// @param axis the axis to fix. protected void fixTrackerIndex(NIAxis axis) { if (axis.m_sourceTrackerIndex < m_pointTrackerStrings.Length && m_pointTrackerStrings[axis.m_sourceTrackerIndex].CompareTo(axis.m_sourceTrackerString) == 0) return; // we match for (int i = 0; i < m_pointTrackerStrings.Length; i++) { if (m_pointTrackerStrings[i].CompareTo(axis.m_sourceTrackerString) == 0) { axis.m_sourceTrackerIndex = i; return; // we found a match } } // if we are here, the tracker no longer exist. We therefore will set ourselves // the "none" tracker axis.m_sourceTrackerIndex = m_pointTrackerStrings.Length - 1; axis.m_sourceTrackerString = m_pointTrackerStrings[axis.m_sourceTrackerIndex]; }
/// utility method to fix the index of gestures after changes (assuming the string is always /// fine while the index might change because of changes done to the GestureManager). /// @param axis the axis to fix. protected void fixGestureIndex(NIAxis axis) { if(axis.m_gestureIndex<m_gestureStrings.Length && m_gestureStrings[axis.m_gestureIndex].CompareTo(axis.m_gestureString)==0) return; // we match // if we are not a "gesture" type, lets just make it the "none" gesture if(axis.m_Type != NIAxis.NIInputTypes.Gesture) { axis.m_gestureIndex=m_gestureStrings.Length-1; axis.m_gestureString=m_gestureStrings[axis.m_gestureIndex]; return; } // we now know we are a gesture type so lets look for a match for (int i = 0; i < m_gestureStrings.Length; i++) { if (m_gestureStrings[i].CompareTo(axis.m_gestureString) == 0) { axis.m_gestureIndex = i; return; // we found a match } } // if we are here, the gesture no longer exist. We therefore will set ourselves to not be a gesture // anymore but instead a hand movement type. axis.m_gestureIndex = m_gestureStrings.Length - 1; axis.m_Type = NIAxis.NIInputTypes.HandMovementFromStartingPoint; axis.m_gestureString = m_gestureStrings[axis.m_gestureIndex]; }
/// implementation of the Editor inspector GUI (this is what is called to see the inspector). public override void OnInspectorGUI() { if(EditorApplication.isPlaying) return; InitGestureStrings(); InitPointTrackerStrings(); EditorGUIUtility.LookLikeInspector(); NIInput inp = target as NIInput; EditorGUI.indentLevel = 0; m_myContent.text = "Hand trackers manager"; m_myContent.tooltip = "The hands tracker manager which holds which hand tracking source we have"; inp.m_pointsTrackingManager = EditorGUILayout.ObjectField(m_myContent, inp.m_pointsTrackingManager, typeof(NIPointTrackerManager), true) as NIPointTrackerManager; m_myContent.text = "Gestures manager"; m_myContent.tooltip = "The gestures manager which holds which gestures we can use"; inp.m_gestureManager = EditorGUILayout.ObjectField(m_myContent, inp.m_gestureManager, typeof(NIGestureManager), true) as NIGestureManager; m_myContent.text = "Axes"; m_myContent.tooltip = "All the axes to use for Natural Interactions"; inp.m_foldAllAxes = EditorGUILayout.Foldout(inp.m_foldAllAxes, m_myContent); if (inp.m_foldAllAxes == false) return; EditorGUI.indentLevel += 2; if (arraySize < 0) arraySize = inp.m_axisList.Count; m_myContent.text = "Size"; m_myContent.tooltip = "The number of axes used"; int numElements = EditorGUILayout.IntField(m_myContent, arraySize); arraySize = numElements; Event e = Event.current; if (e.keyCode == KeyCode.Return) { if (numElements == 0) { numElements = inp.m_axisList.Count; // don't allow to make it into 0 to avoid "deleting" to change something. arraySize = numElements; } if (numElements != inp.m_axisList.Count) { if (numElements < inp.m_axisList.Count) { while (numElements < inp.m_axisList.Count) { inp.m_axisList.RemoveAt(inp.m_axisList.Count - 1); } } else { for (int i = inp.m_axisList.Count; i < numElements; i++) { NIAxis newAxis = new NIAxis(); newAxis.m_gestureIndex = m_gestureStrings.Length - 1; // initialize to none inp.m_axisList.Add(newAxis); } } List<bool> newFoldout = new List<bool>(); int size = inp.m_foldAxisElement.Count; if (size > inp.m_axisList.Count) size = inp.m_axisList.Count; for (int i = 0; i < size; i++) { newFoldout.Add(inp.m_foldAxisElement[i]); } for (int i = size; i < inp.m_axisList.Count; i++) newFoldout.Add(false); inp.m_foldAxisElement = newFoldout; } } for (int i = 0; i < inp.m_foldAxisElement.Count; i++) { inp.m_foldAxisElement[i] = EditorGUILayout.Foldout(inp.m_foldAxisElement[i], inp.m_axisList[i].m_axisName); if(inp.m_foldAxisElement[i]==false) continue; EditorGUI.indentLevel += 2; m_myContent.text = "Name"; m_myContent.tooltip = "Change the name of the current axis"; inp.m_axisList[i].m_axisName = EditorGUILayout.TextField(m_myContent, inp.m_axisList[i].m_axisName); m_myContent.text = "NIInput axis?"; m_myContent.tooltip = "if checked, the axis is used only by NIInput, if not, it is also used by the input manager"; inp.m_axisList[i].m_NIInputAxisOnly = EditorGUILayout.Toggle(m_myContent, inp.m_axisList[i].m_NIInputAxisOnly); m_myContent.text = "Descriptive Name"; m_myContent.tooltip = "Name presented to the user if relevant"; inp.m_axisList[i].m_descriptiveName = EditorGUILayout.TextField(m_myContent, inp.m_axisList[i].m_descriptiveName); fixGestureIndex(inp.m_axisList[i]); inp.m_axisList[i].m_gestureIndex = EditorGUILayout.Popup("Gesture", inp.m_axisList[i].m_gestureIndex,m_gestureStrings); inp.m_axisList[i].m_gestureString = m_gestureStrings[inp.m_axisList[i].m_gestureIndex]; if (inp.m_axisList[i].m_gestureIndex != m_gestureStrings.Length - 1) inp.m_axisList[i].m_Type = NIAxis.NIInputTypes.Gesture; // to make sure we use either m_myContent.text = "Dead"; m_myContent.tooltip = "Movement of less than this value (when changes are used) will be ignored and considered 0"; float deadZone=EditorGUILayout.FloatField(m_myContent,inp.m_axisList[i].m_deadZone); inp.m_axisList[i].m_deadZone = deadZone < NIAxis.m_minDeadZone ? NIAxis.m_minDeadZone : deadZone; m_myContent.text = "Sensitivity"; m_myContent.tooltip = "A scaling factor"; float sensitivity = EditorGUILayout.FloatField(m_myContent, inp.m_axisList[i].m_sensitivity); inp.m_axisList[i].m_sensitivity = sensitivity < NIAxis.m_minSensitivity ? NIAxis.m_minSensitivity : sensitivity; m_myContent.text = "Invert"; m_myContent.tooltip = "Flip the values between positive and negative"; inp.m_axisList[i].m_invert = EditorGUILayout.Toggle(m_myContent, inp.m_axisList[i].m_invert); m_myContent.text = "Type"; m_myContent.tooltip = "The type of movement to do"; inp.m_axisList[i].m_Type = (NIAxis.NIInputTypes)EditorGUILayout.EnumPopup(m_myContent, (System.Enum)inp.m_axisList[i].m_Type); if (inp.m_axisList[i].m_Type != NIAxis.NIInputTypes.Gesture) { inp.m_axisList[i].m_gestureIndex = m_gestureStrings.Length - 1; // make it a "none" gesture } m_myContent.text = "Normalization"; m_myContent.tooltip = "Defines a transformation of the hand's axis to [-1,1] range (clipped)."; m_myContent.tooltip += " -1 is anything smaller than the center minus m_maxMovement,"; m_myContent.tooltip += " +1 is anything larger than the center plus m_maxMovement"; m_myContent.tooltip += " and the values in between are a linear change."; m_myContent.tooltip += " The center is defined based on the type (0 for HandMovement, focus point"; m_myContent.tooltip += " for HandMovementFromFocusPoint etc.). If m_maxMovement is 0 or negative"; m_myContent.tooltip += " then there will be no transformation. \n"; m_myContent.tooltip += "Note the actual value is still multiplied by the sensitivity, "; m_myContent.tooltip += " changed to 0 in the dead zone and can base inverted. "; inp.m_axisList[i].m_maxMovement = EditorGUILayout.FloatField(m_myContent, inp.m_axisList[i].m_maxMovement); m_myContent.text = "Axis"; m_myContent.tooltip = "Axis to use"; inp.m_axisList[i].m_axisUsed = (NIAxis.AxesList)EditorGUILayout.EnumPopup(m_myContent, (System.Enum)inp.m_axisList[i].m_axisUsed); fixTrackerIndex(inp.m_axisList[i]); inp.m_axisList[i].m_sourceTrackerIndex = EditorGUILayout.Popup("Tracker to use", inp.m_axisList[i].m_sourceTrackerIndex, m_pointTrackerStrings); inp.m_axisList[i].m_sourceTrackerString = m_pointTrackerStrings[inp.m_axisList[i].m_sourceTrackerIndex]; EditorGUILayout.Space(); EditorGUI.indentLevel -= 2; } EditorGUI.indentLevel -= 2; EditorGUI.indentLevel = 0; EditorGUILayout.Space(); if(GUI.changed) EditorUtility.SetDirty(target); }
/// implementation of the Editor inspector GUI (this is what is called to see the inspector). override public void OnInspectorGUI() { if (EditorApplication.isPlaying) { return; } InitGestureStrings(); InitPointTrackerStrings(); EditorGUIUtility.LookLikeInspector(); NIInput inp = target as NIInput; EditorGUI.indentLevel = 0; m_myContent.text = "Hand trackers manager"; m_myContent.tooltip = "The hands tracker manager which holds which hand tracking source we have"; inp.m_pointsTrackingManager = EditorGUILayout.ObjectField(m_myContent, inp.m_pointsTrackingManager, typeof(NIPointTrackerManager), true) as NIPointTrackerManager; m_myContent.text = "Gestures manager"; m_myContent.tooltip = "The gestures manager which holds which gestures we can use"; inp.m_gestureManager = EditorGUILayout.ObjectField(m_myContent, inp.m_gestureManager, typeof(NIGestureManager), true) as NIGestureManager; m_myContent.text = "Axes"; m_myContent.tooltip = "All the axes to use for Natural Interactions"; inp.m_foldAllAxes = EditorGUILayout.Foldout(inp.m_foldAllAxes, m_myContent); if (inp.m_foldAllAxes == false) { return; } EditorGUI.indentLevel += 2; if (arraySize < 0) { arraySize = inp.m_axisList.Count; } m_myContent.text = "Size"; m_myContent.tooltip = "The number of axes used"; int numElements = EditorGUILayout.IntField(m_myContent, arraySize); arraySize = numElements; Event e = Event.current; if (e.keyCode == KeyCode.Return) { if (numElements == 0) { numElements = inp.m_axisList.Count; // don't allow to make it into 0 to avoid "deleting" to change something. arraySize = numElements; } if (numElements != inp.m_axisList.Count) { if (numElements < inp.m_axisList.Count) { while (numElements < inp.m_axisList.Count) { inp.m_axisList.RemoveAt(inp.m_axisList.Count - 1); } } else { for (int i = inp.m_axisList.Count; i < numElements; i++) { NIAxis newAxis = new NIAxis(); newAxis.m_gestureIndex = m_gestureStrings.Length - 1; // initialize to none inp.m_axisList.Add(newAxis); } } List <bool> newFoldout = new List <bool>(); int size = inp.m_foldAxisElement.Count; if (size > inp.m_axisList.Count) { size = inp.m_axisList.Count; } for (int i = 0; i < size; i++) { newFoldout.Add(inp.m_foldAxisElement[i]); } for (int i = size; i < inp.m_axisList.Count; i++) { newFoldout.Add(false); } inp.m_foldAxisElement = newFoldout; } } for (int i = 0; i < inp.m_foldAxisElement.Count; i++) { inp.m_foldAxisElement[i] = EditorGUILayout.Foldout(inp.m_foldAxisElement[i], inp.m_axisList[i].m_axisName); if (inp.m_foldAxisElement[i] == false) { continue; } EditorGUI.indentLevel += 2; m_myContent.text = "Name"; m_myContent.tooltip = "Change the name of the current axis"; inp.m_axisList[i].m_axisName = EditorGUILayout.TextField(m_myContent, inp.m_axisList[i].m_axisName); m_myContent.text = "NIInput axis?"; m_myContent.tooltip = "if checked, the axis is used only by NIInput, if not, it is also used by the input manager"; inp.m_axisList[i].m_NIInputAxisOnly = EditorGUILayout.Toggle(m_myContent, inp.m_axisList[i].m_NIInputAxisOnly); m_myContent.text = "Descriptive Name"; m_myContent.tooltip = "Name presented to the user if relevant"; inp.m_axisList[i].m_descriptiveName = EditorGUILayout.TextField(m_myContent, inp.m_axisList[i].m_descriptiveName); fixGestureIndex(inp.m_axisList[i]); inp.m_axisList[i].m_gestureIndex = EditorGUILayout.Popup("Gesture", inp.m_axisList[i].m_gestureIndex, m_gestureStrings); inp.m_axisList[i].m_gestureString = m_gestureStrings[inp.m_axisList[i].m_gestureIndex]; if (inp.m_axisList[i].m_gestureIndex != m_gestureStrings.Length - 1) { inp.m_axisList[i].m_Type = NIAxis.NIInputTypes.Gesture; // to make sure we use either } m_myContent.text = "Dead"; m_myContent.tooltip = "Movement of less than this value (when changes are used) will be ignored and considered 0"; float deadZone = EditorGUILayout.FloatField(m_myContent, inp.m_axisList[i].m_deadZone); inp.m_axisList[i].m_deadZone = deadZone < NIAxis.m_minDeadZone ? NIAxis.m_minDeadZone : deadZone; m_myContent.text = "Sensitivity"; m_myContent.tooltip = "A scaling factor"; float sensitivity = EditorGUILayout.FloatField(m_myContent, inp.m_axisList[i].m_sensitivity); inp.m_axisList[i].m_sensitivity = sensitivity < NIAxis.m_minSensitivity ? NIAxis.m_minSensitivity : sensitivity; m_myContent.text = "Invert"; m_myContent.tooltip = "Flip the values between positive and negative"; inp.m_axisList[i].m_invert = EditorGUILayout.Toggle(m_myContent, inp.m_axisList[i].m_invert); m_myContent.text = "Type"; m_myContent.tooltip = "The type of movement to do"; inp.m_axisList[i].m_Type = (NIAxis.NIInputTypes)EditorGUILayout.EnumPopup(m_myContent, (System.Enum)inp.m_axisList[i].m_Type); if (inp.m_axisList[i].m_Type != NIAxis.NIInputTypes.Gesture) { inp.m_axisList[i].m_gestureIndex = m_gestureStrings.Length - 1; // make it a "none" gesture } m_myContent.text = "Normalization"; m_myContent.tooltip = "Defines a transformation of the hand's axis to [-1,1] range (clipped)."; m_myContent.tooltip += " -1 is anything smaller than the center minus m_maxMovement,"; m_myContent.tooltip += " +1 is anything larger than the center plus m_maxMovement"; m_myContent.tooltip += " and the values in between are a linear change."; m_myContent.tooltip += " The center is defined based on the type (0 for HandMovement, focus point"; m_myContent.tooltip += " for HandMovementFromFocusPoint etc.). If m_maxMovement is 0 or negative"; m_myContent.tooltip += " then there will be no transformation. \n"; m_myContent.tooltip += "Note the actual value is still multiplied by the sensitivity, "; m_myContent.tooltip += " changed to 0 in the dead zone and can base inverted. "; inp.m_axisList[i].m_maxMovement = EditorGUILayout.FloatField(m_myContent, inp.m_axisList[i].m_maxMovement); m_myContent.text = "Axis"; m_myContent.tooltip = "Axis to use"; inp.m_axisList[i].m_axisUsed = (NIAxis.AxesList)EditorGUILayout.EnumPopup(m_myContent, (System.Enum)inp.m_axisList[i].m_axisUsed); fixTrackerIndex(inp.m_axisList[i]); inp.m_axisList[i].m_sourceTrackerIndex = EditorGUILayout.Popup("Tracker to use", inp.m_axisList[i].m_sourceTrackerIndex, m_pointTrackerStrings); inp.m_axisList[i].m_sourceTrackerString = m_pointTrackerStrings[inp.m_axisList[i].m_sourceTrackerIndex]; EditorGUILayout.Space(); EditorGUI.indentLevel -= 2; } EditorGUI.indentLevel -= 2; EditorGUI.indentLevel = 0; EditorGUILayout.Space(); if (GUI.changed) { EditorUtility.SetDirty(target); } }
/// This method takes one axis and calculates its value /// @param axis the axis we calculate on /// @param raw true if raw input is used, false if smooth input is used /// @return the axis value protected float CalcNumberForAxis(NIAxis axis,bool raw) { switch (axis.m_Type) { case NIAxis.NIInputTypes.Gesture: { float val = axis.m_sourceGesture.GestureInProgress(); if (axis.m_invert) val = -val; return val * axis.m_sensitivity; } case NIAxis.NIInputTypes.HandMovement: { Vector3 pos = raw ? axis.m_sourceTracker.CurPosRaw : axis.m_sourceTracker.CurPos; // now we need the relevant axis float axisValue = GetAxisFromPos(pos, axis.m_axisUsed); return NormalizeAxisPos(axisValue, axis.m_maxMovement, axis.m_invert, axis.m_sensitivity, axis.m_deadZone); } case NIAxis.NIInputTypes.HandMovementFromStartingPoint: { Vector3 pos = raw ? axis.m_sourceTracker.CurPosFromStartRaw : axis.m_sourceTracker.CurPosFromStart; // now we need the relevant axis float axisValue = GetAxisFromPos(pos, axis.m_axisUsed); return NormalizeAxisPos(axisValue, axis.m_maxMovement, axis.m_invert, axis.m_sensitivity, axis.m_deadZone); } case NIAxis.NIInputTypes.DeltaHandMovement: { Vector3 pos = raw ? axis.m_sourceTracker.CurDeltaPosRaw : axis.m_sourceTracker.CurDeltaPos; // now we need the relevant axis float axisValue = GetAxisFromPos(pos, axis.m_axisUsed); // we use -1 for the range because we never normalize the delta values return NormalizeAxisPos(axisValue, -1, axis.m_invert, axis.m_sensitivity, axis.m_deadZone); } default: { throw (new System.Exception("" + axis.m_Type + " not implemented yet")); } } }
/// utility function, chooses the correct axis from a vector /// @param vec the vector we got /// @param axis the axis we want from the vector /// @return the value of the relevant vector protected float GetAxisFromPos(Vector3 vec, NIAxis.AxesList axis) { switch (axis) { case NIAxis.AxesList.xAxis: return vec.x; case NIAxis.AxesList.yAxis: return vec.y; case NIAxis.AxesList.zAxis: return vec.z; } throw (new System.Exception("unimplemented axis type "+axis)); }