Exemplo n.º 1
0
        /// <summary>
        /// Adds a new gesture to library and then saves it to the xml.
        /// The trick here is that we don't reload the newly saved xml.
        /// It would have been a waste of resources. Instead, we just add
        /// the new gesture to the list of gestures (the library).
        /// </summary>
        /// <param name="gesture">The gesture to add</param>
        /// <returns>True if addition is succesful</returns>
        public bool AddGesture(Gesture gesture)
        {
            // Create the xml node to add to the xml file
            XmlElement rootElement = gestureLibrary.DocumentElement;
            XmlElement gestureNode = gestureLibrary.CreateElement("gesture");
            gestureNode.SetAttribute("name", gesture.Name);

            foreach (Vector2 v in gesture.Points) {
                XmlElement gesturePoint = gestureLibrary.CreateElement("point");
                gesturePoint.SetAttribute("x", v.x.ToString());
                gesturePoint.SetAttribute("y", v.y.ToString());

                gestureNode.AppendChild(gesturePoint);
            }

            // Append the node to xml file contents
            rootElement.AppendChild(gestureNode);

            try {

                // Add the new gesture to the list of gestures
                this.Library.Add(gesture);

                // Save the file if it is not the web player, because
                // web player cannot have write permissions.
            #if !UNITY_WEBPLAYER && !UNITY_EDITOR
                FileTools.Write(persistentLibraryPath, gestureLibrary.OuterXml);
            #elif UNITY_EDITOR && !UNITY_WEBPLAYER
                FileTools.Write(resourcesPath, gestureLibrary.OuterXml);
            #endif

                return true;
            } catch (Exception e) {
                Debug.Log(e.Message);
                return false;
            }
        }
Exemplo n.º 2
0
 /// <summary>
 /// Gets the average distance between two gestures at a specified angle
 /// </summary>
 /// <param name="gesture">Gesture to compare to</param>
 /// <param name="angle">The angle to rotate this gesture</param>
 /// <returns>Distance between two gestures</returns>
 public float GetDistanceAtAngle(Gesture gesture, float angle)
 {
     List<Vector2> newPoints = this.RotateBy(angle);
     return Gesture.GetDistanceBetweenPaths(newPoints, gesture.Points);
 }
Exemplo n.º 3
0
        /// <summary>
        /// $1 algorithm works like this:
        /// - Take a gesture: with any number of points
        /// - Resample: so that it has exactly NUMBER_OF_POINTS number of points which are equidistant to each other
        /// - Rotate: based on the indicative angle (angle between the centroid and the first point)
        /// - Scale and translate: so that it can fit into a predefined sized square
        /// - Find the most optimized angle by Golden Section Search so that it has the best score
        /// 
        /// Resampling, rotating, scaling and translating ensures that gestures are somewhat "more" similar. By doing these
        /// operations, we make them easier to compare. After these operations, the distance between two gestures 
        /// (which is the average distance between each points: d = sum(d1, d2, ..., dn) / n) is calculated. The gesture
        /// with the least distance is the result and this result is converted to a score between [0, 1].
        /// 
        /// To get the best score, each gesture is rotated to the best indicative angle which is found by using
        /// Golden Section Search.
        /// </summary>
        /// <param name="gesture">Gesture to compare</param>
        /// <param name="a">Negative angle range</param>
        /// <param name="b">Positive angle range</param>
        /// <param name="threshold">Angle precision</param>
        /// <returns>Score</returns>
        public float DollarOneAlgorithm(Gesture gesture, float a, float b, float threshold)
        {
            float x1 = this.PHI * a + (1f - this.PHI) * b;
            float f1 = this.GetDistanceAtAngle(gesture, x1);
            float x2 = (1f - this.PHI) * a + this.PHI * b;
            float f2 = this.GetDistanceAtAngle(gesture, x2);

            while (Mathf.Abs(b - a) > threshold) {
                if (f1 < f2) {
                    b = x2;
                    x2 = x1;
                    f2 = f1;
                    x1 = this.PHI * a + (1f - this.PHI) * b;
                    f1 = this.GetDistanceAtAngle(gesture, x1);
                } else {
                    a = x1;
                    x1 = x2;
                    f1 = f2;
                    x2 = (1f - this.PHI) * a + this.PHI * b;
                    f2 = this.GetDistanceAtAngle(gesture, x2);
                }
            }

            return Mathf.Min(f1, f2);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Loads the library from an XML file
        /// </summary>
        public void LoadLibrary()
        {
            // Uses the XML file in resources folder if it is webplayer or the editor.
            string xmlContents = "";
            string floatSeparator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;

            #if !UNITY_WEBPLAYER && !UNITY_EDITOR
            xmlContents = FileTools.Read(persistentLibraryPath);
            #else
            xmlContents = Resources.Load<TextAsset>(libraryName).text;
            #endif

            gestureLibrary.LoadXml(xmlContents);

            // Get "gesture" elements
            XmlNodeList xmlGestureList = gestureLibrary.GetElementsByTagName("gesture");

            // Parse "gesture" elements and add them to library
            foreach (XmlNode xmlGestureNode in xmlGestureList) {

                string gestureName = xmlGestureNode.Attributes.GetNamedItem("name").Value;
                XmlNodeList xmlPoints = xmlGestureNode.ChildNodes;
                List<Vector2> gesturePoints = new List<Vector2>();

                foreach (XmlNode point in xmlPoints) {

                    Vector2 gesturePoint = new Vector2();
                    gesturePoint.x = (float)System.Convert.ToDouble(point.Attributes.GetNamedItem("x").Value.Replace(",", floatSeparator).Replace(".", floatSeparator));
                    gesturePoint.y = (float)System.Convert.ToDouble(point.Attributes.GetNamedItem("y").Value.Replace(",", floatSeparator).Replace(".", floatSeparator));
                    gesturePoints.Add(gesturePoint);

                }

                Gesture gesture = new Gesture(gesturePoints, gestureName);
                library.Add(gesture);
            }
        }
Exemplo n.º 5
0
 private void OnClickRemoveGesture()
 {
     currentLibrary.Gestures.Remove(currentGesture);
     currentGesture = null;
     EditorUtility.SetDirty(currentLibrary);
 }
Exemplo n.º 6
0
        private void DrawInstructions()
        {
            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();

            GUILayout.Label("Draw your gesture, enter a name in the text field and then click 'Add'");

            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            GUILayout.FlexibleSpace();

            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();

            newGestureName = GUILayout.TextField(newGestureName, 32, GUILayout.Width(200));

            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();

            if (newGestureName == "")
            {
                GUI.enabled = false;
            }

            if (GUILayout.Button("Add", GUILayout.Width(100)))
            {
                Gesture g = new Gesture(points.ToArray(), newGestureName);
                currentLibrary.Gestures.Add(g);
                ClearGesture();
                isAddingGesture = false;
                EditorUtility.SetDirty(currentLibrary);
            }

            GUI.enabled = true;

            if (points.Count == 0)
            {
                GUI.enabled = false;
            }

            if (GUILayout.Button("Clear", GUILayout.Width(100)))
            {
                ClearGesture();
                EditorUtility.SetDirty(currentLibrary);
            }

            GUI.enabled = true;

            if (GUILayout.Button("Cancel", GUILayout.Width(100)))
            {
                ClearGesture();
                isAddingGesture = false;
                EditorUtility.SetDirty(currentLibrary);
            }

            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();
        }
Exemplo n.º 7
0
 public void SaveToLibraryGesture(Gesture gesture)
 {
 }