Esempio n. 1
0
        private bool IsPositionInTriangle(Vector3 pos, NavMeshTriangle triangle)
        {
            // Compute vectors
            Vector3 v0 = triangle.vertex2.Position - triangle.vertex1.Position;
            Vector3 v1 = triangle.vertex3.Position - triangle.vertex1.Position;
            Vector3 v2 = pos - triangle.vertex1.Position;

            // Compute dot products
            float dot00 = Vector3.Dot(v0, v0);
            float dot01 = Vector3.Dot(v0, v1);
            float dot02 = Vector3.Dot(v0, v2);
            float dot11 = Vector3.Dot(v1, v1);
            float dot12 = Vector3.Dot(v1, v2);

            // Compute barycentric coordinates
            float invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
            float u        = (dot11 * dot02 - dot01 * dot12) * invDenom;
            float v        = (dot00 * dot12 - dot01 * dot02) * invDenom;

            // Check if point is in triangle
            if ((u >= 0) && (v >= 0) && (u + v < 1))
            {
                return(true);
            }
            return(false);
        }
Esempio n. 2
0
 private void Start()
 {
     navMesh          = new AStarNavMeshNavigation(navMeshHolder);
     SelectedTriangle = navMeshHolder.GetRandomTriangle();
     if (SelectedTriangle != null)
     {
         SelectedTriangle.isSelected = true;
     }
 }
        public bool IsAdjacent(NavMeshTriangle tri)
        {
            // Check Vertex 1
            bool vert1 = tri.vertex1.Equals(vertex1) || tri.vertex2.Equals(vertex1) || tri.vertex3.Equals(vertex1);
            bool vert2 = tri.vertex1.Equals(vertex2) || tri.vertex2.Equals(vertex2) || tri.vertex3.Equals(vertex2);
            bool vert3 = tri.vertex1.Equals(vertex3) || tri.vertex2.Equals(vertex3) || tri.vertex3.Equals(vertex3);

            return(vert1 || vert2 || vert3);
        }
Esempio n. 4
0
        public override void OnInspectorGUI()
        {
            serializedObject.Update();
            if (GUILayout.Button("Update Generator Values"))
            {
                navMesh.UpdateInformation();
            }
            if (GUILayout.Button("Update Adjacent Triangles"))
            {
                navMesh.UpdateAdjacentTriangles();
            }
            SerializedProperty prop = serializedObject.FindProperty("m_Script");

            EditorGUILayout.PropertyField(prop, true, new GUILayoutOption[0]);
            showPosition = EditorGUILayout.Foldout(showPosition, "triangles");
            if (showPosition)
            {
                GUIContent ShowButtonGUIContent = new GUIContent("Show Buttons");
                showButton = EditorGUILayout.Toggle(ShowButtonGUIContent, showButton);
                EditorGUI.indentLevel++;
                for (int i = 0; i < navMesh.Triangles.Length; i++)
                {
                    SerializedProperty triangle = triangles.GetArrayElementAtIndex(i);

                    GUIContent gUIContent = new GUIContent(triangle.FindPropertyRelative("ID").intValue + (triangle.FindPropertyRelative("isSelected").boolValue ? " Selected" : ""));
                    EditorGUILayout.PropertyField(triangle, gUIContent, true); // draw property with it's children
                    if (showButton && GUILayout.Button("Select Vertex"))
                    {
                        currentVertex = 0;
                        if (selectedTriangle != null)
                        {
                            selectedTriangle.isSelected = false;
                        }
                        selectedTriangle            = navMesh.Triangles[i];
                        selectedTriangle.isSelected = true;
                    }
                }
                EditorGUI.indentLevel--;
                if (GUILayout.Button("Insert Triangle"))
                {
                    navMesh.AddNewTriangle();
                }
            }
            if (GUI.changed)
            {
                EditorUtility.SetDirty(navMesh);
                EditorSceneManager.MarkSceneDirty(navMesh.gameObject.scene);
            }
            ////EditorGUILayout.LabelField(Selection.activeGameObject.name);
            //EditorGUILayout.Space();
            //DrawDefaultInspector();

            EditorGUILayout.PropertyField(entrancePoints, true);

            serializedObject.ApplyModifiedProperties();
        }
Esempio n. 5
0
        public void CreateTriangle(Vertex vert1, Vertex vert2, Vertex vert3)
        {
            NavMeshTriangle tri = AddNewTriangle();

            tri.vertex1 = vert1;
            tri.vertex2 = vert2;
            tri.vertex3 = vert3;
            AddTriangleVertexesToAdjacencyList(tri);
            AddAdjacentTriangles(tri);
        }
Esempio n. 6
0
        private static void AddTriangleVertexesToAdjacencyList(NavMeshTriangle triangle)
        {
            AddVertexesToAdjacentList(triangle.vertex1, triangle.vertex2);
            AddVertexesToAdjacentList(triangle.vertex1, triangle.vertex3);

            AddVertexesToAdjacentList(triangle.vertex2, triangle.vertex1);
            AddVertexesToAdjacentList(triangle.vertex2, triangle.vertex3);

            AddVertexesToAdjacentList(triangle.vertex3, triangle.vertex1);
            AddVertexesToAdjacentList(triangle.vertex3, triangle.vertex2);
        }
Esempio n. 7
0
 public NavMeshTriangle AddNewTriangle()
 {
     NavMeshTriangle[] newTriangles = new NavMeshTriangle[triangles.Length + 1];
     for (int i = 0; i < triangles.Length; i++)
     {
         newTriangles[i] = triangles[i];
     }
     newTriangles[newTriangles.Length - 1] = new NavMeshTriangle();
     newTriangles[newTriangles.Length - 1].adjacentTriangles = new List <int>();
     triangles = newTriangles;
     return(newTriangles[newTriangles.Length - 1]);
 }
Esempio n. 8
0
        private void Update()
        {
            if (getRandomPoint)
            {
                SelectedTriangle.isSelected = false;
                SelectedTriangle            = navMeshHolder.GetRandomTriangle();
                if (SelectedTriangle != null)
                {
                    SelectedTriangle.isSelected = true;
                }
            }

            path = navMesh.GetPathFromTo(this.transform.position, getRandomPoint ? navMeshHolder.GetRandomPointInTriangle(SelectedTriangle) : end.position);
        }
Esempio n. 9
0
        public Vector3 GetRandomPointInTriangle(NavMeshTriangle triangle)
        {
            float x = Random.value;
            float y = Random.value;

            while (x + y > 1)
            {
                x = Random.value;
                y = Random.value;
            }
            Vector3 insideTriangle = (triangle.vertex2.Position - triangle.vertex1.Position) * x + (triangle.vertex3.Position - triangle.vertex1.Position) * y;

            return(triangle.vertex1.Position + insideTriangle);
        }
        public List <NavMeshMovementLine> SmoothPath(List <NavMeshMovementLine> oldPath)
        {
            if (oldPath.Count <= 2)
            {
                return(oldPath);
            }
            NavMeshTriangle triangle = null;

            for (int i = 0; i < oldPath.Count - 2; i++)
            {
                if (oldPath[i] == null)
                {
                    continue;
                }
                currentPoint = oldPath[i];
                for (int j = i + 2; j - (i + 2) <= 5 && j < oldPath.Count; j++)
                {
                    if (oldPath[j] == null)
                    {
                        continue;
                    }
                    bool    canRemove = true;
                    Vector3 nextStep  = Vector3.Lerp(currentPoint.point, oldPath[j].point, 0);
                    for (int k = 1; k < numberOfSteps; k++)
                    {
                        triangle = navMesh.GetContainingTriangle(nextStep);
                        if (triangle == null)
                        {
                            canRemove = false;
                            break;
                        }
                        nextStep = Vector3.Lerp(currentPoint.point, oldPath[j].point, k / (float)numberOfSteps);
                    }
                    if (canRemove)
                    {
                        oldPath[j - 1] = null;
                    }
                }
            }
            List <NavMeshMovementLine> newPath = new List <NavMeshMovementLine>();

            oldPath.ForEach((item) => { if (item != null)
                                        {
                                            newPath.Add(item);
                                        }
                            });
            //List<NavMeshMovementLine> newPath = AvoidWalls(newPath);
            return(newPath);
        }
        public override void OnInspectorGUI()
        {
            serializedObject.Update();
            // Add script drawer
            SerializedProperty prop = serializedObject.FindProperty("m_Script");

            EditorGUILayout.PropertyField(prop, true, new GUILayoutOption[0]);

            //if (GUILayout.Button("Add Adjacent Tris"))
            //{
            //    navMesh.UpdateAdjacentTris();
            //    EditorUtility.SetDirty(navMesh);
            //    EditorSceneManager.MarkSceneDirty(navMesh.gameObject.scene);
            //}
            showPosition = EditorGUILayout.Foldout(showPosition, "triangles");
            if (showPosition)
            {
                EditorGUI.indentLevel++;
                for (int i = 0; i < navMesh.Triangles.Length; i++)
                {
                    SerializedProperty triangle = triangles.GetArrayElementAtIndex(i);

                    GUIContent gUIContent = new GUIContent(triangle.FindPropertyRelative("ID").intValue + (triangle.FindPropertyRelative("isSelected").boolValue ? " Selected" : ""));
                    EditorGUILayout.PropertyField(triangle, gUIContent, true); // draw property with it's children
                    if (GUILayout.Button("Select Triangle"))
                    {
                        currentVertex = 0;
                        if (selectedTriangle != null)
                        {
                            selectedTriangle.isSelected = false;
                        }
                        selectedTriangle            = navMesh.Triangles[i];
                        selectedTriangle.isSelected = true;
                    }
                }
                EditorGUI.indentLevel--;
            }

            serializedObject.ApplyModifiedProperties();
        }
Esempio n. 12
0
        private void AddAdjacentTriangles(NavMeshTriangle tri)
        {
            tri.adjacentTriangles.Clear();
            // Check if a duo of verts share more than 1 adjacent vertex
            NavMeshTriangle triangle = GetAdjacentTriangle(tri.vertex1, tri.vertex2, tri.vertex3);

            if (triangle != null)
            {
                tri.adjacentTriangles.Add(triangle.ID);
            }

            triangle = GetAdjacentTriangle(tri.vertex2, tri.vertex3, tri.vertex1);
            if (triangle != null)
            {
                tri.adjacentTriangles.Add(triangle.ID);
            }

            triangle = GetAdjacentTriangle(tri.vertex3, tri.vertex1, tri.vertex2);
            if (triangle != null)
            {
                tri.adjacentTriangles.Add(triangle.ID);
            }
        }
Esempio n. 13
0
        // override object.Equals
        public override bool Equals(object obj)
        {
            //
            // See the full list of guidelines at
            //   http://go.microsoft.com/fwlink/?LinkID=85237
            // and also the guidance for operator== at
            //   http://go.microsoft.com/fwlink/?LinkId=85238
            //

            if (obj == null || GetType() != obj.GetType())
            {
                return(false);
            }
            NavMeshTriangle tri = obj as NavMeshTriangle;

            if (tri == null)
            {
                return(false);
            }
            return((tri.vertex1 != null && tri.vertex1.Equals(this.vertex1)) &&
                   (tri.vertex2 != null && tri.vertex2.Equals(this.vertex2)) &&
                   (tri.vertex3 != null && tri.vertex3.Equals(this.vertex3)));
        }
        public List <NavMeshMovementLine> GetPathFromTo(Vector3 from, Vector3 to)
        {
            if (actualPoints.Length == 0)
            {
                return(new List <NavMeshMovementLine>());
            }
            for (int i = 0; i < actualPoints.Length; i++)
            {
                actualPoints[i].inClosed = false;
                actualPoints[i].f        = 0;
                actualPoints[i].g        = 0;
                actualPoints[i].h        = 0;
                actualPoints[i].parent   = null;
            }
            triStart = navMesh.GetContainingTriangle(from);
            if (triStart == null)
            {
                return(new List <NavMeshMovementLine>());
            }
            triEnd = navMesh.GetContainingTriangle(to);
            if (triEnd == null)
            {
                return(new List <NavMeshMovementLine>());
            }
            path.Clear();

            // If the points are on the same triangle, send back a straight line between both points
            if (triStart.ID == triEnd.ID)
            {
                path.Add(new NavMeshMovementLine {
                    point = from
                });
                path.Add(new NavMeshMovementLine {
                    point = to
                });
                return(path);
            }

            open.Clear();
            // Add the starting triangle vertexes to the open list
            open.Add(UpdateAStarPoint(GetPointValue(triStart.vertex1.ID), 0, 0, to));
            open.Add(UpdateAStarPoint(GetPointValue(triStart.vertex2.ID), 0, 0, to));
            open.Add(UpdateAStarPoint(GetPointValue(triStart.vertex3.ID), 0, 0, to));

            // The starting point does not need to be kept in the closed list

            while (open.Count > 0)
            {
                open.Sort((a, b) => a.f.CompareTo(b.f));
                current = open[0];

                if (current.vert.ID == (triEnd.vertex1.ID) ||
                    current.vert.ID == (triEnd.vertex2.ID) ||
                    current.vert.ID == (triEnd.vertex3.ID))
                {
                    return(ReconstructPath(current, to, from));
                }

                open.RemoveAt(0);
                current.inClosed = true;
                if (open.Count > 4000)
                {
                    break;
                }
                for (int i = 0; i < current.vert.Count; i++)
                {
                    AStarPoint aStarPointExisting = GetPointValue(current.vert.GetAdjacentVertex(i).ID);
                    if (aStarPointExisting.inClosed)
                    {
                        continue;
                    }

                    float      cost       = current.g + (current.vert.Position - current.vert.GetAdjacentVertex(i).Position).magnitude;
                    AStarPoint aStarPoint = open.Find((item) => item.vert.Equals(current.vert.GetAdjacentVertex(i)));
                    if (aStarPoint == null)
                    {
                        aStarPoint = UpdateAStarPoint(aStarPointExisting, current.g, (Mathf.Pow((current.vert.Position.x - current.vert.GetAdjacentVertex(i).Position.x), 2) + Mathf.Pow((current.vert.Position.y - current.vert.GetAdjacentVertex(i).Position.y), 2)), to, current);

                        open.Add(aStarPoint);
                    }
                    else
                    {
                        if (cost < aStarPoint.g)
                        {
                            aStarPoint.g      = cost;
                            aStarPoint.f      = aStarPoint.g + aStarPoint.h;
                            aStarPoint.parent = current;
                        }
                    }
                }
            }

            return(path);
        }
Esempio n. 15
0
        private void HandleKeyboard()
        {
            Event current = Event.current;

            if (current.type != EventType.KeyDown)
            {
                return;
            }

            EditorGUI.BeginChangeCheck();
            switch (current.keyCode)
            {
            case KeyCode.DownArrow:
                switch (currentVertex)
                {
                case 0:
                    selectedTriangle.vertex1 = Selection.activeGameObject.GetComponent <Vertex>();
                    break;

                case 1:
                    selectedTriangle.vertex2 = Selection.activeGameObject.GetComponent <Vertex>();
                    break;

                case 2:
                    selectedTriangle.vertex3 = Selection.activeGameObject.GetComponent <Vertex>();
                    break;

                default:
                    break;
                }
                currentVertex++;
                if (currentVertex >= 3)
                {
                    currentVertex = 0;
                }
                current.Use();
                break;

            case KeyCode.UpArrow:
                currentVertex = 0;
                if (selectedTriangle != null)
                {
                    selectedTriangle.isSelected = false;
                }
                selectedTriangle            = navMesh.AddNewTriangle();
                selectedTriangle.isSelected = true;
                current.Use();
                break;

            case KeyCode.Return:
            case KeyCode.KeypadEnter:
                current.Use();
                break;

            case KeyCode.LeftArrow:
            case KeyCode.Backspace:
                //current.Use();
                break;

            case KeyCode.RightArrow:
                //current.Use();
                break;

            case KeyCode.Escape:
                current.Use();
                break;
            }
            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(target, "Changed triangle Vertex");
            }
        }